1
0
mirror of https://gitlab.com/bramw/baserow.git synced 2024-11-21 23:37:55 +00:00
bramw_baserow/web-frontend/test/unit/database/view.spec.js

498 lines
17 KiB
JavaScript

import { TestApp } from '@baserow/test/helpers/testApp'
import Table from '@baserow/modules/database/pages/table'
import {
DEFAULT_VIEW_ID_COOKIE_NAME,
readDefaultViewIdFromCookie,
decodeDefaultViewIdPerTable,
encodeDefaultViewIdPerTable,
} from '@baserow/modules/database/utils/view'
// Mock out debounce so we don't have to wait or simulate waiting for the various
// debounces in the search functionality.
jest.mock('lodash/debounce', () => jest.fn((fn) => fn))
describe('View Tests', () => {
let testApp = null
let mockServer = null
let originalReplaceFunc = null
beforeAll(() => {
testApp = new TestApp()
mockServer = testApp.mockServer
// Mock the redirect function so we can test the component without having to
// worry about the router.
originalReplaceFunc = testApp._app.$router.replace
testApp._app.$router.replace = ({ params }) => {
return Table.asyncData({
app: testApp._app,
store: testApp._app.store,
params,
})
}
})
afterEach(() => testApp.afterEach())
afterAll(() => {
testApp._app.$router.replace = originalReplaceFunc
})
test('Default view is being set correctly initially', async () => {
const allCookies = testApp.store.$cookies
const { application, table, views } =
await givenATableInTheServerWithMultipleViews()
const gridView = views[0]
const galleryView = views[1]
// The first view is the Grid view, the Default view is the Gallery view which
// is going to be rendered initially:
const tableComponent = await testApp.mount(Table, {
asyncDataParams: {
databaseId: application.id,
tableId: table.id,
viewId: galleryView.id,
},
})
const tableId = gridView.table_id
// Check if Vuex store is updated correctly (first view):
expect(testApp.store.getters['view/first'].id).toBe(gridView.id)
// Check if cookie is updated correctly (default view):
const defaultViewId = readDefaultViewIdFromCookie(allCookies, tableId)
expect(defaultViewId).not.toBe(null)
const defaultView = testApp.store.getters['view/get'](defaultViewId)
expect(defaultView.table_id).toBe(tableId)
expect(defaultView.id).toBe(galleryView.id)
// Check if Vuex store is updated correctly (default view):
expect(testApp.store.getters['view/defaultId']).toBe(galleryView.id)
// Check if component is rendered:
expect(tableComponent.find('div.gallery-view').exists()).toBe(true)
expect(tableComponent.find('div.grid-view').exists()).toBe(false)
})
test('Default view is being set correctly after changing views', async () => {
const { application, table, views } =
await givenATableInTheServerWithMultipleViews()
const gridView = views[0]
const galleryView = views[1]
// The first view is the Grid view, the Default view is the Gallery view which
// is going to be rendered initially:
const tableComponent = await testApp.mount(Table, {
asyncDataParams: {
databaseId: application.id,
tableId: table.id,
viewId: galleryView.id,
},
})
const allCookies = testApp.store.$cookies
const tableId = gridView.table_id
// Check if Vuex store is updated correctly (first view):
expect(testApp.store.getters['view/first'].id).toBe(gridView.id)
// Check if cookie is updated correctly (default view):
const defaultViewId = readDefaultViewIdFromCookie(allCookies, tableId)
expect(defaultViewId).not.toBe(null)
const defaultView = testApp.store.getters['view/get'](defaultViewId)
expect(defaultView.table_id).toBe(tableId)
expect(defaultView.id).toBe(galleryView.id)
// Check if Vuex store is updated correctly (default view):
expect(testApp.store.getters['view/defaultId']).toBe(galleryView.id)
// Check if component is rendered:
expect(tableComponent.find('div.gallery-view').exists()).toBe(true)
expect(tableComponent.find('div.grid-view').exists()).toBe(false)
// Let's switch back (select) the Grid (first) view:
testApp.store.dispatch('view/selectById', gridView.id)
// Check if Vuex store is updated correctly (first view):
expect(testApp.store.getters['view/first'].id).toBe(gridView.id)
// Check if cookie is updated correctly (default view):
const updatedCookieValue = decodeDefaultViewIdPerTable(
allCookies.get(DEFAULT_VIEW_ID_COOKIE_NAME)
)
expect(updatedCookieValue.length).toBe(1)
const updatedDefaultViewId = readDefaultViewIdFromCookie(
allCookies,
tableId
)
const updatedDefaultView =
testApp.store.getters['view/get'](updatedDefaultViewId)
expect(updatedDefaultView.table_id).toBe(tableId)
expect(updatedDefaultView.id).toBe(gridView.id)
// Check if Vuex store is updated correctly (default view):
expect(testApp.store.getters['view/defaultId']).toBe(gridView.id)
})
test('Default view is being set correctly after switching tables', async () => {
const { application, tables, views } =
await givenATableInTheServerWithMultipleTables()
const firstTable = tables[0]
const secondTable = tables[1]
const firstTableGridView = views[0]
const secondTableGridView = views[1]
// The first (and default) view is the Grid view, which is going to be rendered
// initially for the firstTable:
const firstTableComponent = await testApp.mount(Table, {
asyncDataParams: {
databaseId: application.id,
tableId: firstTable.id,
},
})
const allCookies = testApp.store.$cookies
// Check if Vuex store is updated correctly (first view):
expect(testApp.store.getters['view/first'].id).toBe(firstTableGridView.id)
// Check if cookie is updated correctly (default view):
const cookieValue = decodeDefaultViewIdPerTable(
allCookies.get(DEFAULT_VIEW_ID_COOKIE_NAME)
)
expect(cookieValue.length).toBe(1)
const defaultViewId = readDefaultViewIdFromCookie(
allCookies,
firstTableGridView.table_id
)
expect(defaultViewId).not.toBe(null)
const defaultView = testApp.store.getters['view/get'](defaultViewId)
expect(defaultView.table_id).toBe(firstTableGridView.table_id)
expect(defaultView.id).toBe(firstTableGridView.id)
// Check if Vuex store is updated correctly (default view):
expect(testApp.store.getters['view/defaultId']).toBe(firstTableGridView.id)
// Check if component is rendered:
expect(firstTableComponent.find('div.grid-view').exists()).toBe(true)
expect(firstTableComponent.find('div.gallery-view').exists()).toBe(false)
// The first (and default) view is the Grid view, which is going to be rendered
// initially for the secondTable:
await testApp.mount(Table, {
asyncDataParams: {
databaseId: application.id,
tableId: secondTable.id,
},
})
// Let's switch to a different table in the database:
testApp.store.dispatch('table/selectById', {
databaseId: application.id,
tableId: secondTable.id,
})
testApp.store.dispatch('view/selectById', secondTableGridView.id)
const allCookiesAfterChangingTable = testApp.store.$cookies
const cookieValueAfterChangingTable = decodeDefaultViewIdPerTable(
allCookiesAfterChangingTable.get(DEFAULT_VIEW_ID_COOKIE_NAME)
)
// Check if Vuex store is updated correctly (first view):
expect(testApp.store.getters['view/first'].id).toBe(secondTableGridView.id)
// Check if cookie is updated correctly (default view):
expect(cookieValueAfterChangingTable.length).toBe(2)
const defaultViewIdAfterChangingTable = readDefaultViewIdFromCookie(
allCookies,
secondTableGridView.table_id
)
expect(defaultViewIdAfterChangingTable).not.toBe(null)
const defaultViewAfterChangingTable = testApp.store.getters['view/get'](
defaultViewIdAfterChangingTable
)
expect(defaultViewAfterChangingTable.table_id).toBe(
secondTableGridView.table_id
)
expect(defaultViewAfterChangingTable.id).toBe(secondTableGridView.id)
// Check if Vuex store is updated correctly (default view):
expect(testApp.store.getters['view/defaultId']).toBe(secondTableGridView.id)
// Check if component is rendered:
expect(firstTableComponent.find('div.grid-view').exists()).toBe(true)
expect(firstTableComponent.find('div.gallery-view').exists()).toBe(false)
// Let's switch back to the first table in the database and see if first table's
// default view is appended to the *end* of remembered views array:
await testApp.mount(Table, {
asyncDataParams: {
databaseId: application.id,
tableId: firstTable.id,
},
})
testApp.store.dispatch('table/selectById', {
databaseId: application.id,
tableId: firstTable.id,
})
testApp.store.dispatch('view/selectById', firstTableGridView.id)
const allCookiesAfterSwitchingBack = testApp.store.$cookies
// Check if Vuex store is updated correctly (first view):
expect(testApp.store.getters['view/first'].id).toBe(firstTableGridView.id)
// Check if cookie is updated correctly (default view):
const cookieValueAfterSwitchingBack = decodeDefaultViewIdPerTable(
allCookiesAfterSwitchingBack.get(DEFAULT_VIEW_ID_COOKIE_NAME)
)
expect(cookieValueAfterSwitchingBack.length).toBe(2)
const defaultViewIdAfterSwitchingBack = readDefaultViewIdFromCookie(
allCookiesAfterSwitchingBack,
firstTableGridView.table_id
)
expect(defaultViewIdAfterSwitchingBack).not.toBe(null)
const defaultViewAfterSwitchingBack = testApp.store.getters['view/get'](
defaultViewIdAfterSwitchingBack
)
expect(defaultViewAfterSwitchingBack.table_id).toBe(
firstTableGridView.table_id
)
expect(defaultViewAfterSwitchingBack.id).toBe(firstTableGridView.id)
// Check if Vuex store is updated correctly (default view):
expect(testApp.store.getters['view/defaultId']).toBe(firstTableGridView.id)
})
test('Default view is being set correctly only from cookie', async () => {
// set the cookie, render table without view id passed in, this should render
// the default (Gallery) view
const { application, table, views } =
await givenATableInTheServerWithMultipleViews()
const gridView = views[0]
const galleryView = views[1]
const tableId = gridView.table_id
const allCookies = testApp.store.$cookies
// Set the cookie for defaultView manually:
const defaultViewIdData = []
defaultViewIdData.push({
tableId: galleryView.table_id,
viewId: galleryView.id,
})
allCookies.set(
DEFAULT_VIEW_ID_COOKIE_NAME,
encodeDefaultViewIdPerTable(defaultViewIdData)
)
// The first view is the Grid view, the Default view is the Gallery view,
// we're not rendering any view initially and Default view (Gallery view)
// should be picked up from the cookie
const tableComponent = await testApp.mount(Table, {
asyncDataParams: {
databaseId: application.id,
tableId: table.id,
},
})
// Check if Vuex store is updated correctly (first view):
expect(testApp.store.getters['view/first'].id).toBe(gridView.id)
// Check if cookie is updated correctly (default view):
const cookieValue = decodeDefaultViewIdPerTable(
allCookies.get(DEFAULT_VIEW_ID_COOKIE_NAME)
)
expect(cookieValue.length).toBe(1)
const defaultViewId = readDefaultViewIdFromCookie(allCookies, tableId)
expect(defaultViewId).not.toBe(null)
const defaultView = testApp.store.getters['view/get'](defaultViewId)
expect(defaultView.table_id).toBe(tableId)
expect(defaultView.id).toBe(galleryView.id)
// Check if Vuex store is updated correctly (default view):
expect(testApp.store.getters['view/defaultId']).toBe(galleryView.id)
// Check if component is rendered:
expect(tableComponent.find('div.gallery-view').exists()).toBe(true)
expect(tableComponent.find('div.grid-view').exists()).toBe(false)
})
test('Changing default view updates cookies array correctly', async () => {
const { application, table, views } =
await givenATableInTheServerWithMultipleViews()
const gridView = views[0]
// Generate random data to fill up the cookie
// Our cookie has a limit of 2kb, so we need to generate enough data to fill it up
// For sure one entry will need more than 1 byte, so we can't just generate 2048
// entries
const targetSize = 2048
const randomData = []
for (let i = 0; i < targetSize; i++) {
const randomTableId = i
const randomViewId = i
const entry = { tableId: randomTableId, viewId: randomViewId }
randomData.push(entry)
}
const allCookies = testApp.store.$cookies
allCookies.set(
DEFAULT_VIEW_ID_COOKIE_NAME,
encodeDefaultViewIdPerTable(randomData)
)
const originalDataLength = randomData.length
// Mount the component, which should update the cookies
await testApp.mount(Table, {
asyncDataParams: {
databaseId: application.id,
tableId: table.id,
viewId: gridView.id,
},
})
// The Default view is the Grid view and it should be set (appended) in the cookie
const cookieValue = decodeDefaultViewIdPerTable(
allCookies.get(DEFAULT_VIEW_ID_COOKIE_NAME)
)
expect(cookieValue.length).toBeGreaterThan(0)
const defaultViewIdObject = cookieValue[cookieValue.length - 1]
expect(defaultViewIdObject.tableId).toBe(gridView.table_id)
expect(defaultViewIdObject.viewId).toBe(gridView.id)
// Check if gridView is set as the last view in the array
expect(cookieValue[cookieValue.length - 1]).toMatchObject(
defaultViewIdObject
)
// Ensure that the first element is removed from the cookie array
const updatedCookieValue = decodeDefaultViewIdPerTable(
allCookies.get(DEFAULT_VIEW_ID_COOKIE_NAME)
)
expect(updatedCookieValue).not.toContainEqual(randomData[0])
expect(updatedCookieValue.length).toBeLessThan(originalDataLength)
})
async function givenATableInTheServerWithMultipleViews() {
const table = mockServer.createTable()
const { application } = await mockServer.createAppAndWorkspace(table)
const gridView = mockServer.createGridView(application, table, {
viewId: 1,
})
const galleryView = mockServer.createGalleryView(application, table, {
viewId: 2,
})
mockServer.mock
.onGet(`/database/views/table/${table.id}/`)
.reply(200, [gridView, galleryView])
const fields = mockServer.createFields(application, table, [
{
name: 'Name',
type: 'text',
primary: true,
},
{
name: 'Last name',
type: 'text',
},
{
name: 'Notes',
type: 'long_text',
},
{
name: 'Active',
type: 'boolean',
},
])
const rows = [
{
id: 1,
order: 0,
field_1: 'name',
field_2: 'last_name',
field_3: 'notes',
field_4: false,
},
]
mockServer.createGridRows(gridView, fields, rows)
mockServer.createFields(application, table, fields)
mockServer.createGalleryRows(galleryView, fields, rows)
const views = []
views.push(gridView)
views.push(galleryView)
return { application, table, views }
}
async function givenATableInTheServerWithMultipleTables() {
const firstTable = mockServer.createTable(1, 'Test Table 1')
const secondTable = mockServer.createTable(2, 'Test Table 2')
const { application } =
await mockServer.createAppAndWorkspaceWithMultipleTables([
firstTable,
secondTable,
])
// First table - 1 view:
const firstTableGridView = mockServer.createGridView(
application,
firstTable,
{
viewId: 1,
}
)
mockServer.mock
.onGet(`/database/views/table/${firstTable.id}/`)
.reply(200, [firstTableGridView])
// Second table - 1 view:
const secondTableGridView = mockServer.createGridView(
application,
secondTable,
{
viewId: 2,
}
)
mockServer.mock
.onGet(`/database/views/table/${secondTable.id}/`)
.reply(200, [secondTableGridView])
const fields = mockServer.createFields(application, firstTable, [
{
name: 'Name',
type: 'text',
primary: true,
},
{
name: 'Last name',
type: 'text',
},
{
name: 'Notes',
type: 'long_text',
},
{
name: 'Active',
type: 'boolean',
},
])
const rows = [
{
id: 1,
order: 0,
field_1: 'name',
field_2: 'last_name',
field_3: 'notes',
field_4: false,
},
]
mockServer.createGridRows(firstTableGridView, fields, rows)
mockServer.createGridRows(secondTableGridView, fields, rows)
mockServer.createFields(application, firstTable, fields)
mockServer.createFields(application, secondTable, fields)
const views = []
views.push(firstTableGridView)
views.push(secondTableGridView)
const tables = []
tables.push(firstTable)
tables.push(secondTable)
return { application, tables, views }
}
})