feat(seo): generate slugs for brands, categories and products, add GET /sitemap and the Postman collection (#5)
This commit is contained in:
@@ -12,7 +12,13 @@ describe('AppController (e2e)', () => {
|
||||
const hiboutikService = { startSync: jest.fn() };
|
||||
// Rate limiting counters (ThrottlerDatabaseStorage): the database answers "not blocked" unless a test says otherwise
|
||||
const notBlocked = { totalHits: 1, timeToExpire: 60, isBlocked: false, timeToBlockExpire: 0 };
|
||||
const prisma = { $queryRaw: jest.fn(), throttlerRecord: { deleteMany: jest.fn().mockResolvedValue({ count: 0 }) } };
|
||||
const prisma = {
|
||||
$queryRaw: jest.fn(),
|
||||
throttlerRecord: { deleteMany: jest.fn().mockResolvedValue({ count: 0 }) },
|
||||
brand: { findMany: jest.fn() },
|
||||
category: { findMany: jest.fn() },
|
||||
product: { findMany: jest.fn() },
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
hiboutikService.startSync.mockReset();
|
||||
@@ -47,6 +53,37 @@ describe('AppController (e2e)', () => {
|
||||
expect(hiboutikService.startSync).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('GET /sitemap lists the public pages', async () => {
|
||||
prisma.brand.findMany.mockResolvedValue([{ slug: 'bts' }]);
|
||||
prisma.category.findMany.mockResolvedValue([{ slug: 'albums' }]);
|
||||
prisma.product.findMany.mockResolvedValue([
|
||||
{ slug: 'bts-proof', hiboutikUpdatedAt: new Date('2026-11-05T08:00:00Z') },
|
||||
{ slug: 'bts-wings', hiboutikUpdatedAt: null },
|
||||
]);
|
||||
|
||||
await request(app.getHttpServer())
|
||||
.get('/sitemap')
|
||||
.expect(200)
|
||||
.expect('Cache-Control', 'public, max-age=600')
|
||||
.expect({
|
||||
brands: [{ slug: 'bts' }],
|
||||
categories: [{ slug: 'albums' }],
|
||||
products: [
|
||||
{ slug: 'bts-proof', updatedAt: '2026-11-05T08:00:00.000Z' },
|
||||
{ slug: 'bts-wings', updatedAt: null },
|
||||
],
|
||||
});
|
||||
// only public rows with a slug are read; products are dated by Hiboutik, not by the last sync
|
||||
expect(prisma.brand.findMany).toHaveBeenCalledWith(expect.objectContaining({ where: { slug: { not: null }, enabled: true } }));
|
||||
expect(prisma.category.findMany).toHaveBeenCalledWith(expect.objectContaining({ where: { slug: { not: null }, webEnabled: true } }));
|
||||
expect(prisma.product.findMany).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
where: { slug: { not: null }, enabled: true, archived: false },
|
||||
select: { slug: true, hiboutikUpdatedAt: true },
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.close();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user