Scrum4Me/__tests__/api/products.test.ts
Madhura68 eafdef4d5a test(products): add unit tests for GET /api/products
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 18:31:35 +02:00

103 lines
2.9 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
vi.mock('@/lib/prisma', () => ({
prisma: {
product: {
findMany: vi.fn(),
},
},
}))
vi.mock('@/lib/api-auth', () => ({
authenticateApiRequest: vi.fn(),
}))
import { prisma } from '@/lib/prisma'
import { authenticateApiRequest } from '@/lib/api-auth'
import { GET as getProducts } from '@/app/api/products/route'
const mockPrisma = prisma as unknown as {
product: { findMany: ReturnType<typeof vi.fn> }
}
const mockAuth = authenticateApiRequest as ReturnType<typeof vi.fn>
function makeRequest(): Request {
return new Request('http://localhost/api/products', {
method: 'GET',
headers: { Authorization: 'Bearer test-token' },
})
}
describe('GET /api/products', () => {
beforeEach(() => {
vi.clearAllMocks()
mockAuth.mockResolvedValue({ userId: 'user-1', isDemo: false })
})
// TC-P-04
it('returns products owned by the authenticated user', async () => {
mockPrisma.product.findMany.mockResolvedValue([
{ id: 'prod-1', name: 'Alpha', repo_url: null },
{ id: 'prod-2', name: 'Beta', repo_url: 'https://github.com/example/beta' },
])
const res = await getProducts(makeRequest())
const data = await res.json()
expect(res.status).toBe(200)
expect(data).toHaveLength(2)
expect(data[0]).toMatchObject({ id: 'prod-1', name: 'Alpha' })
expect(data[1]).toMatchObject({ id: 'prod-2', name: 'Beta' })
})
// TC-P-05
it('includes products where the user is a team member via productAccessFilter', async () => {
mockPrisma.product.findMany.mockResolvedValue([
{ id: 'prod-shared', name: 'Shared Product', repo_url: null },
])
const res = await getProducts(makeRequest())
const data = await res.json()
expect(res.status).toBe(200)
expect(data).toHaveLength(1)
expect(mockPrisma.product.findMany).toHaveBeenCalledWith(
expect.objectContaining({
where: expect.objectContaining({
archived: false,
OR: expect.arrayContaining([
{ user_id: 'user-1' },
{ members: { some: { user_id: 'user-1' } } },
]),
}),
})
)
})
// TC-P-06
it('returns empty array when user has no products', async () => {
mockPrisma.product.findMany.mockResolvedValue([])
const res = await getProducts(makeRequest())
const data = await res.json()
expect(res.status).toBe(200)
expect(data).toEqual([])
})
// TC-P-07
it('excludes archived products by querying with archived: false', async () => {
mockPrisma.product.findMany.mockResolvedValue([
{ id: 'prod-active', name: 'Active', repo_url: null },
])
const res = await getProducts(makeRequest())
expect(res.status).toBe(200)
expect(mockPrisma.product.findMany).toHaveBeenCalledWith(
expect.objectContaining({
where: expect.objectContaining({ archived: false }),
})
)
})
})