mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
Add seed data initialization tests
This commit is contained in:
71
frontends/nextjs/src/seed-data/index.test.ts
Normal file
71
frontends/nextjs/src/seed-data/index.test.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||
|
||||
const {
|
||||
initializeUsers,
|
||||
initializeComponents,
|
||||
initializeScripts,
|
||||
initializeWorkflows,
|
||||
initializePages,
|
||||
initializePackages,
|
||||
} = vi.hoisted(() => ({
|
||||
initializeUsers: vi.fn(),
|
||||
initializeComponents: vi.fn(),
|
||||
initializeScripts: vi.fn(),
|
||||
initializeWorkflows: vi.fn(),
|
||||
initializePages: vi.fn(),
|
||||
initializePackages: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('./users', () => ({ initializeUsers }))
|
||||
vi.mock('./components', () => ({ initializeComponents }))
|
||||
vi.mock('./scripts', () => ({ initializeScripts }))
|
||||
vi.mock('./workflows', () => ({ initializeWorkflows }))
|
||||
vi.mock('./pages', () => ({ initializePages }))
|
||||
vi.mock('./packages', () => ({ initializePackages }))
|
||||
|
||||
import { initializeAllSeedData } from './index'
|
||||
|
||||
describe('initializeAllSeedData', () => {
|
||||
beforeEach(() => {
|
||||
initializeUsers.mockReset()
|
||||
initializeComponents.mockReset()
|
||||
initializeScripts.mockReset()
|
||||
initializeWorkflows.mockReset()
|
||||
initializePages.mockReset()
|
||||
initializePackages.mockReset()
|
||||
})
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: 'run seeders in order',
|
||||
errorStep: null as string | null,
|
||||
expectedCalls: ['users', 'components', 'scripts', 'workflows', 'pages', 'packages'],
|
||||
},
|
||||
{
|
||||
name: 'stop when a seeder fails',
|
||||
errorStep: 'scripts',
|
||||
expectedCalls: ['users', 'components', 'scripts'],
|
||||
},
|
||||
])('should $name', async ({ errorStep, expectedCalls }) => {
|
||||
const callOrder: string[] = []
|
||||
initializeUsers.mockImplementation(async () => callOrder.push('users'))
|
||||
initializeComponents.mockImplementation(async () => callOrder.push('components'))
|
||||
initializeScripts.mockImplementation(async () => {
|
||||
callOrder.push('scripts')
|
||||
if (errorStep === 'scripts') {
|
||||
throw new Error('seed failed')
|
||||
}
|
||||
})
|
||||
initializeWorkflows.mockImplementation(async () => callOrder.push('workflows'))
|
||||
initializePages.mockImplementation(async () => callOrder.push('pages'))
|
||||
initializePackages.mockImplementation(async () => callOrder.push('packages'))
|
||||
|
||||
if (errorStep) {
|
||||
await expect(initializeAllSeedData()).rejects.toThrow('seed failed')
|
||||
} else {
|
||||
await expect(initializeAllSeedData()).resolves.toBeUndefined()
|
||||
}
|
||||
|
||||
expect(callOrder).toEqual(expectedCalls)
|
||||
})
|
||||
})
|
||||
32
frontends/nextjs/src/seed-data/packages.test.ts
Normal file
32
frontends/nextjs/src/seed-data/packages.test.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||
|
||||
const { initializePackageSystem } = vi.hoisted(() => ({
|
||||
initializePackageSystem: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/package-loader', () => ({
|
||||
initializePackageSystem,
|
||||
}))
|
||||
|
||||
import { initializePackages } from '@/seed-data/packages'
|
||||
|
||||
describe('initializePackages', () => {
|
||||
beforeEach(() => {
|
||||
initializePackageSystem.mockReset()
|
||||
})
|
||||
|
||||
it.each([
|
||||
{ name: 'resolve when initializer succeeds', error: null as Error | null },
|
||||
{ name: 'propagate errors from initializer', error: new Error('init failed') },
|
||||
])('should $name', async ({ error }) => {
|
||||
if (error) {
|
||||
initializePackageSystem.mockRejectedValueOnce(error)
|
||||
await expect(initializePackages()).rejects.toThrow('init failed')
|
||||
} else {
|
||||
initializePackageSystem.mockResolvedValueOnce(undefined)
|
||||
await expect(initializePackages()).resolves.toBeUndefined()
|
||||
}
|
||||
|
||||
expect(initializePackageSystem).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
60
frontends/nextjs/src/seed-data/pages.test.ts
Normal file
60
frontends/nextjs/src/seed-data/pages.test.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||
|
||||
const { getPages } = vi.hoisted(() => ({
|
||||
getPages: vi.fn(),
|
||||
}))
|
||||
|
||||
const { initializeDefaultPages } = vi.hoisted(() => ({
|
||||
initializeDefaultPages: vi.fn(),
|
||||
}))
|
||||
|
||||
const { getPageDefinitionBuilder } = vi.hoisted(() => ({
|
||||
getPageDefinitionBuilder: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/database', () => ({
|
||||
Database: {
|
||||
getPages,
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/page-definition-builder', () => ({
|
||||
getPageDefinitionBuilder,
|
||||
}))
|
||||
|
||||
import { initializePages } from '@/seed-data/pages'
|
||||
|
||||
describe('initializePages', () => {
|
||||
beforeEach(() => {
|
||||
getPages.mockReset()
|
||||
getPageDefinitionBuilder.mockReset()
|
||||
initializeDefaultPages.mockReset()
|
||||
})
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: 'skip initialization when pages exist',
|
||||
existingPages: [{ id: 'page1' }],
|
||||
shouldInitialize: false,
|
||||
},
|
||||
{
|
||||
name: 'initialize defaults when no pages exist',
|
||||
existingPages: [],
|
||||
shouldInitialize: true,
|
||||
},
|
||||
])('should $name', async ({ existingPages, shouldInitialize }) => {
|
||||
getPages.mockResolvedValue(existingPages)
|
||||
getPageDefinitionBuilder.mockReturnValue({ initializeDefaultPages })
|
||||
|
||||
await initializePages()
|
||||
|
||||
expect(getPages).toHaveBeenCalledTimes(1)
|
||||
if (shouldInitialize) {
|
||||
expect(getPageDefinitionBuilder).toHaveBeenCalledTimes(1)
|
||||
expect(initializeDefaultPages).toHaveBeenCalledTimes(1)
|
||||
} else {
|
||||
expect(getPageDefinitionBuilder).not.toHaveBeenCalled()
|
||||
expect(initializeDefaultPages).not.toHaveBeenCalled()
|
||||
}
|
||||
})
|
||||
})
|
||||
56
frontends/nextjs/src/seed-data/scripts.test.ts
Normal file
56
frontends/nextjs/src/seed-data/scripts.test.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||
|
||||
const { getLuaScripts, addLuaScript } = vi.hoisted(() => ({
|
||||
getLuaScripts: vi.fn(),
|
||||
addLuaScript: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/database', () => ({
|
||||
Database: {
|
||||
getLuaScripts,
|
||||
addLuaScript,
|
||||
},
|
||||
}))
|
||||
|
||||
import { initializeScripts } from '@/seed-data/scripts'
|
||||
|
||||
const expectedScriptIds = [
|
||||
'script_welcome_message',
|
||||
'script_format_date',
|
||||
'script_validate_email',
|
||||
'script_permission_check',
|
||||
'script_page_load_analytics',
|
||||
]
|
||||
|
||||
describe('initializeScripts', () => {
|
||||
beforeEach(() => {
|
||||
getLuaScripts.mockReset()
|
||||
addLuaScript.mockReset()
|
||||
})
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: 'skip seeding when scripts exist',
|
||||
existingScripts: [{ id: 'existing' }],
|
||||
expectedAdds: 0,
|
||||
},
|
||||
{
|
||||
name: 'seed default scripts when none exist',
|
||||
existingScripts: [],
|
||||
expectedAdds: expectedScriptIds.length,
|
||||
},
|
||||
])('should $name', async ({ existingScripts, expectedAdds }) => {
|
||||
getLuaScripts.mockResolvedValue(existingScripts)
|
||||
|
||||
await initializeScripts()
|
||||
|
||||
expect(getLuaScripts).toHaveBeenCalledTimes(1)
|
||||
expect(addLuaScript).toHaveBeenCalledTimes(expectedAdds)
|
||||
|
||||
if (expectedAdds > 0) {
|
||||
expectedScriptIds.forEach(id => {
|
||||
expect(addLuaScript).toHaveBeenCalledWith(expect.objectContaining({ id }))
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
98
frontends/nextjs/src/seed-data/users.test.ts
Normal file
98
frontends/nextjs/src/seed-data/users.test.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||
|
||||
const {
|
||||
getUsers,
|
||||
setCredential,
|
||||
setFirstLoginFlag,
|
||||
addUser,
|
||||
setGodCredentialsExpiry,
|
||||
hashPassword,
|
||||
} = vi.hoisted(() => ({
|
||||
getUsers: vi.fn(),
|
||||
setCredential: vi.fn(),
|
||||
setFirstLoginFlag: vi.fn(),
|
||||
addUser: vi.fn(),
|
||||
setGodCredentialsExpiry: vi.fn(),
|
||||
hashPassword: vi.fn(),
|
||||
}))
|
||||
|
||||
const { getScrambledPassword } = vi.hoisted(() => ({
|
||||
getScrambledPassword: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/database', () => ({
|
||||
Database: {
|
||||
getUsers,
|
||||
setCredential,
|
||||
setFirstLoginFlag,
|
||||
addUser,
|
||||
setGodCredentialsExpiry,
|
||||
},
|
||||
hashPassword,
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/auth', () => ({
|
||||
getScrambledPassword,
|
||||
}))
|
||||
|
||||
import { initializeUsers } from '@/seed-data/users'
|
||||
|
||||
const expectedUsernames = ['supergod', 'god', 'admin', 'alice', 'bob']
|
||||
|
||||
describe('initializeUsers', () => {
|
||||
beforeEach(() => {
|
||||
getUsers.mockReset()
|
||||
setCredential.mockReset()
|
||||
setFirstLoginFlag.mockReset()
|
||||
addUser.mockReset()
|
||||
setGodCredentialsExpiry.mockReset()
|
||||
hashPassword.mockReset()
|
||||
getScrambledPassword.mockReset()
|
||||
})
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: 'skip seeding when users exist',
|
||||
existingUsers: [{ id: 'existing' }],
|
||||
expectedAdds: 0,
|
||||
},
|
||||
{
|
||||
name: 'seed users when none exist',
|
||||
existingUsers: [],
|
||||
expectedAdds: expectedUsernames.length,
|
||||
},
|
||||
])('should $name', async ({ existingUsers, expectedAdds }) => {
|
||||
const nowSpy = vi.spyOn(Date, 'now').mockReturnValue(1000)
|
||||
getUsers.mockResolvedValue(existingUsers)
|
||||
getScrambledPassword.mockImplementation((username: string) => `scrambled-${username}`)
|
||||
hashPassword.mockImplementation(async (value: string) => `hash-${value}`)
|
||||
|
||||
if (expectedAdds === 0) {
|
||||
await initializeUsers()
|
||||
} else {
|
||||
await expect(initializeUsers()).resolves.toBeUndefined()
|
||||
}
|
||||
|
||||
expect(getUsers).toHaveBeenCalledTimes(1)
|
||||
expect(addUser).toHaveBeenCalledTimes(expectedAdds)
|
||||
expect(setCredential).toHaveBeenCalledTimes(expectedAdds)
|
||||
expect(setFirstLoginFlag).toHaveBeenCalledTimes(expectedAdds)
|
||||
|
||||
if (expectedAdds === 0) {
|
||||
expect(getScrambledPassword).not.toHaveBeenCalled()
|
||||
expect(hashPassword).not.toHaveBeenCalled()
|
||||
expect(setGodCredentialsExpiry).not.toHaveBeenCalled()
|
||||
} else {
|
||||
expectedUsernames.forEach(username => {
|
||||
expect(getScrambledPassword).toHaveBeenCalledWith(username)
|
||||
expect(hashPassword).toHaveBeenCalledWith(`scrambled-${username}`)
|
||||
expect(setCredential).toHaveBeenCalledWith(username, `hash-scrambled-${username}`)
|
||||
expect(setFirstLoginFlag).toHaveBeenCalledWith(username, true)
|
||||
expect(addUser).toHaveBeenCalledWith(expect.objectContaining({ username }))
|
||||
})
|
||||
expect(setGodCredentialsExpiry).toHaveBeenCalledWith(1000 + 60 * 60 * 1000)
|
||||
}
|
||||
|
||||
nowSpy.mockRestore()
|
||||
})
|
||||
})
|
||||
54
frontends/nextjs/src/seed-data/workflows.test.ts
Normal file
54
frontends/nextjs/src/seed-data/workflows.test.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||
|
||||
const { getWorkflows, addWorkflow } = vi.hoisted(() => ({
|
||||
getWorkflows: vi.fn(),
|
||||
addWorkflow: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/lib/database', () => ({
|
||||
Database: {
|
||||
getWorkflows,
|
||||
addWorkflow,
|
||||
},
|
||||
}))
|
||||
|
||||
import { initializeWorkflows } from '@/seed-data/workflows'
|
||||
|
||||
const expectedWorkflowIds = [
|
||||
'workflow_user_registration',
|
||||
'workflow_page_access',
|
||||
'workflow_comment_submission',
|
||||
]
|
||||
|
||||
describe('initializeWorkflows', () => {
|
||||
beforeEach(() => {
|
||||
getWorkflows.mockReset()
|
||||
addWorkflow.mockReset()
|
||||
})
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: 'skip seeding when workflows exist',
|
||||
existingWorkflows: [{ id: 'existing' }],
|
||||
expectedAdds: 0,
|
||||
},
|
||||
{
|
||||
name: 'seed default workflows when none exist',
|
||||
existingWorkflows: [],
|
||||
expectedAdds: expectedWorkflowIds.length,
|
||||
},
|
||||
])('should $name', async ({ existingWorkflows, expectedAdds }) => {
|
||||
getWorkflows.mockResolvedValue(existingWorkflows)
|
||||
|
||||
await initializeWorkflows()
|
||||
|
||||
expect(getWorkflows).toHaveBeenCalledTimes(1)
|
||||
expect(addWorkflow).toHaveBeenCalledTimes(expectedAdds)
|
||||
|
||||
if (expectedAdds > 0) {
|
||||
expectedWorkflowIds.forEach(id => {
|
||||
expect(addWorkflow).toHaveBeenCalledWith(expect.objectContaining({ id }))
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user