import { describe, it, expect, beforeEach, vi } from 'vitest' import { prisma } from '../db' import { claimLists, getClaimableLists, hasExistingLists } from '../migration-actions' import bcrypt from 'bcryptjs' // Mock auth vi.mock('@/auth', () => ({ auth: vi.fn(), })) const { auth } = await import('@/auth') describe('Migration Actions', () => { let testUser: any let testLists: any[] beforeEach(async () => { // Clean up test data await prisma.list.deleteMany({}) await prisma.user.deleteMany({}) // Create test user const passwordHash = await bcrypt.hash('password123', 10) testUser = await prisma.user.create({ data: { email: 'test@example.com', name: 'Test User', passwordHash, }, }) // Create test lists owned by test user testLists = await Promise.all([ prisma.list.create({ data: { title: 'Test List 1', color: '#FF0000', ownerId: testUser.id, }, }), prisma.list.create({ data: { title: 'Test List 2', color: '#00FF00', ownerId: testUser.id, }, }), ]) }) describe('getClaimableLists', () => { it('should return lists that exist in the database', async () => { const listIds = testLists.map(l => l.id) const claimable = await getClaimableLists(listIds) expect(claimable).toHaveLength(2) expect(claimable[0].title).toBe('Test List 1') expect(claimable[1].title).toBe('Test List 2') expect(claimable[0].itemCount).toBe(0) }) it('should return empty array for non-existent list IDs', async () => { const claimable = await getClaimableLists(['non-existent-id']) expect(claimable).toHaveLength(0) }) it('should return empty array for empty input', async () => { const claimable = await getClaimableLists([]) expect(claimable).toHaveLength(0) }) }) describe('claimLists', () => { let newUser: any beforeEach(async () => { // Create a new user to claim lists const passwordHash = await bcrypt.hash('password456', 10) newUser = await prisma.user.create({ data: { email: 'newuser@example.com', name: 'New User', passwordHash, }, }) }) it('should transfer lists to the authenticated user', async () => { // Mock auth to return new user vi.mocked(auth).mockResolvedValue({ user: { id: newUser.id, email: newUser.email, name: newUser.name }, expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), }) const listIds = testLists.map(l => l.id) const result = await claimLists(listIds) expect(result.success).toBe(true) expect(result.migratedCount).toBe(2) // Verify lists are now owned by new user const updatedLists = await prisma.list.findMany({ where: { id: { in: listIds } }, }) updatedLists.forEach(list => { expect(list.ownerId).toBe(newUser.id) }) }) it('should preserve all list data during migration', async () => { // Mock auth vi.mocked(auth).mockResolvedValue({ user: { id: newUser.id, email: newUser.email, name: newUser.name }, expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), }) const originalList = testLists[0] const listIds = [originalList.id] await claimLists(listIds) // Verify list data is preserved const updatedList = await prisma.list.findUnique({ where: { id: originalList.id }, }) expect(updatedList).toBeDefined() expect(updatedList!.title).toBe(originalList.title) expect(updatedList!.color).toBe(originalList.color) expect(updatedList!.createdAt.getTime()).toBe(originalList.createdAt.getTime()) // Only ownerId should change expect(updatedList!.ownerId).toBe(newUser.id) }) it('should return error when not authenticated', async () => { // Mock auth to return null vi.mocked(auth).mockResolvedValue(null) const result = await claimLists([testLists[0].id]) expect(result.success).toBe(false) expect(result.error).toContain('Unauthorized') }) it('should handle empty list IDs', async () => { // Mock auth vi.mocked(auth).mockResolvedValue({ user: { id: newUser.id, email: newUser.email, name: newUser.name }, expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), }) const result = await claimLists([]) expect(result.success).toBe(true) expect(result.migratedCount).toBe(0) }) }) describe('hasExistingLists', () => { it('should return true when user has lists', async () => { // Mock auth vi.mocked(auth).mockResolvedValue({ user: { id: testUser.id, email: testUser.email, name: testUser.name }, expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), }) const result = await hasExistingLists() expect(result).toBe(true) }) it('should return false when user has no lists', async () => { // Create user with no lists const passwordHash = await bcrypt.hash('password789', 10) const emptyUser = await prisma.user.create({ data: { email: 'empty@example.com', name: 'Empty User', passwordHash, }, }) // Mock auth vi.mocked(auth).mockResolvedValue({ user: { id: emptyUser.id, email: emptyUser.email, name: emptyUser.name }, expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), }) const result = await hasExistingLists() expect(result).toBe(false) }) it('should return false when not authenticated', async () => { // Mock auth to return null vi.mocked(auth).mockResolvedValue(null) const result = await hasExistingLists() expect(result).toBe(false) }) }) })