Add storefront blog pages with nav, templates, and SEO meta.

Wire blogEnabled into shop render locals and expose public blog index and detail routes when the shop toggle is on.
This commit is contained in:
2026-09-16 13:55:12 +02:00
parent 73f7ffed00
commit a3d1842fb3
23 changed files with 359 additions and 5 deletions
@@ -0,0 +1,42 @@
import { NotFoundException } from '@nestjs/common';
import type { Repository } from 'typeorm';
import { BlogPost } from '../../blog/entities/BlogPost';
import { StorefrontBlogPostsService } from './StorefrontBlogPostsService';
describe('StorefrontBlogPostsService', () => {
let service: StorefrontBlogPostsService;
let blogPostRepo: {
find: jest.Mock;
findOne: jest.Mock;
};
beforeEach(() => {
blogPostRepo = {
find: jest.fn().mockResolvedValue([]),
findOne: jest.fn().mockResolvedValue(null)
};
service = new StorefrontBlogPostsService(blogPostRepo as unknown as Repository<BlogPost>);
});
it('lists live posts ordered by createdAt descending', async () => {
await service.listLivePosts();
expect(blogPostRepo.find).toHaveBeenCalledWith({
where: { isDraft: false },
order: { createdAt: 'DESC' }
});
});
it('returns a live post by id', async () => {
const post = { id: 'post-1', title: 'Hello', isDraft: false } as BlogPost;
blogPostRepo.findOne.mockResolvedValue(post);
await expect(service.getLivePost('post-1')).resolves.toBe(post);
});
it('throws when a draft or missing post is requested', async () => {
await expect(service.getLivePost('missing-id')).rejects.toThrow(NotFoundException);
});
});