diff --git a/src/modules/blogs/blogs.service.ts b/src/modules/blogs/blogs.service.ts index 6a14a1a26..e9ce8ce8f 100644 --- a/src/modules/blogs/blogs.service.ts +++ b/src/modules/blogs/blogs.service.ts @@ -128,10 +128,12 @@ export class BlogService { ...result.data, blogs: includeDeleted ? result.data.blogs - : result.data.blogs.map(blog => { - const { deletedAt, ...rest } = blog; - return rest; - }), + : result.data.blogs + .filter(blog => !blog.deletedAt) + .map(blog => { + const { deletedAt, ...rest } = blog; + return rest; + }), }, }; } diff --git a/src/modules/blogs/tests/blogs.service.spec.ts b/src/modules/blogs/tests/blogs.service.spec.ts index 8c9f452e3..5505c564f 100644 --- a/src/modules/blogs/tests/blogs.service.spec.ts +++ b/src/modules/blogs/tests/blogs.service.spec.ts @@ -418,6 +418,228 @@ describe('BlogService', () => { relations: ['author'], }); }); + + it('should return an empty list if no blogs are found', async () => { + jest.spyOn(blogRepository, 'findAndCount').mockResolvedValue([[], 0]); + + const result = await service.getAllBlogs(1, 10); + + expect(result).toEqual({ + status_code: 200, + message: SYS_MSG.BLOG_FETCHED_SUCCESSFUL, + data: { + currentPage: 1, + totalPages: 0, + totalResults: 0, + blogs: [], + meta: { + hasNext: false, + total: 0, + nextPage: null, + prevPage: null, + }, + }, + }); + expect(blogRepository.findAndCount).toHaveBeenCalledWith({ + where: { deletedAt: null }, + skip: 0, + take: 10, + relations: ['author'], + }); + }); + + it('should handle pagination correctly', async () => { + const blog = new Blog(); + blog.id = 'blog-id'; + blog.title = 'Test Blog'; + blog.content = 'Test Content'; + blog.tags = ['test']; + blog.image_urls = ['http://example.com/image.jpg']; + blog.author = new User(); + blog.author.first_name = 'John'; + blog.author.last_name = 'Doe'; + blog.created_at = new Date(); + blog.updated_at = new Date(); + + jest.spyOn(blogRepository, 'findAndCount').mockResolvedValue([[blog], 1]); + + const result = await service.getAllBlogs(2, 1); + + expect(result).toEqual({ + status_code: 200, + message: SYS_MSG.BLOG_FETCHED_SUCCESSFUL, + data: { + currentPage: 2, + totalPages: 1, + totalResults: 1, + blogs: [ + { + blog_id: 'blog-id', + title: 'Test Blog', + content: 'Test Content', + tags: ['test'], + image_urls: ['http://example.com/image.jpg'], + author: 'John Doe', + created_at: blog.created_at, + deletedAt: undefined, + }, + ], + meta: { + hasNext: false, + total: 1, + nextPage: null, + prevPage: 1, + }, + }, + }); + expect(blogRepository.findAndCount).toHaveBeenCalledWith({ + where: { deletedAt: null }, + skip: 1, + take: 1, + relations: ['author'], + }); + }); + + it('should return all blogs excluding deleted with multiple mock data', async () => { + const blog1 = new Blog(); + blog1.id = 'blog-id-1'; + blog1.title = 'Test Blog 1'; + blog1.content = 'Test Content 1'; + blog1.tags = ['test1']; + blog1.image_urls = ['http://example.com/image1.jpg']; + blog1.author = new User(); + blog1.author.first_name = 'John'; + blog1.author.last_name = 'Doe'; + blog1.created_at = new Date(); + blog1.updated_at = new Date(); + blog1.deletedAt = null; + + const blog2 = new Blog(); + blog2.id = 'blog-id-2'; + blog2.title = 'Test Blog 2'; + blog2.content = 'Test Content 2'; + blog2.tags = ['test2']; + blog2.image_urls = ['http://example.com/image2.jpg']; + blog2.author = new User(); + blog2.author.first_name = 'Jane'; + blog2.author.last_name = 'Doe'; + blog2.created_at = new Date(); + blog2.updated_at = new Date(); + blog2.deletedAt = new Date(); + + jest.spyOn(blogRepository, 'findAndCount').mockResolvedValue([[blog1, blog2], 2]); + + const result = await service.getAllBlogs(1, 10); + + expect(result).toEqual({ + status_code: 200, + message: SYS_MSG.BLOG_FETCHED_SUCCESSFUL, + data: { + currentPage: 1, + totalPages: 1, + totalResults: 2, + blogs: [ + { + blog_id: 'blog-id-1', + title: 'Test Blog 1', + content: 'Test Content 1', + tags: ['test1'], + image_urls: ['http://example.com/image1.jpg'], + author: 'John Doe', + created_at: blog1.created_at, + }, + ], + meta: { + hasNext: false, + total: 2, + nextPage: null, + prevPage: null, + }, + }, + }); + expect(blogRepository.findAndCount).toHaveBeenCalledWith({ + where: { deletedAt: null }, + skip: 0, + take: 10, + relations: ['author'], + }); + }); + + it('should return all blogs including deleted with multiple mock data', async () => { + const blog1 = new Blog(); + blog1.id = 'blog-id-1'; + blog1.title = 'Test Blog 1'; + blog1.content = 'Test Content 1'; + blog1.tags = ['test1']; + blog1.image_urls = ['http://example.com/image1.jpg']; + blog1.author = new User(); + blog1.author.first_name = 'John'; + blog1.author.last_name = 'Doe'; + blog1.created_at = new Date(); + blog1.updated_at = new Date(); + blog1.deletedAt = null; + + const blog2 = new Blog(); + blog2.id = 'blog-id-2'; + blog2.title = 'Test Blog 2'; + blog2.content = 'Test Content 2'; + blog2.tags = ['test2']; + blog2.image_urls = ['http://example.com/image2.jpg']; + blog2.author = new User(); + blog2.author.first_name = 'Jane'; + blog2.author.last_name = 'Doe'; + blog2.created_at = new Date(); + blog2.updated_at = new Date(); + blog2.deletedAt = new Date(); + + jest.spyOn(blogRepository, 'findAndCount').mockResolvedValue([[blog1, blog2], 2]); + + const result = await service.getAllBlogs(1, 10, true); + + expect(result).toEqual({ + status_code: 200, + message: SYS_MSG.BLOG_FETCHED_SUCCESSFUL, + data: { + currentPage: 1, + totalPages: 1, + totalResults: 2, + blogs: [ + { + blog_id: 'blog-id-1', + title: 'Test Blog 1', + content: 'Test Content 1', + tags: ['test1'], + image_urls: ['http://example.com/image1.jpg'], + author: 'John Doe', + created_at: blog1.created_at, + deletedAt: null, + }, + { + blog_id: 'blog-id-2', + title: 'Test Blog 2', + content: 'Test Content 2', + tags: ['test2'], + image_urls: ['http://example.com/image2.jpg'], + author: 'Jane Doe', + created_at: blog2.created_at, + deletedAt: blog2.deletedAt, + }, + ], + meta: { + hasNext: false, + total: 2, + nextPage: null, + prevPage: null, + }, + }, + }); + expect(blogRepository.findAndCount).toHaveBeenCalledWith({ + where: {}, + skip: 0, + take: 10, + relations: ['author'], + }); + }); }); describe('getDeletedBlogs', () => { @@ -475,5 +697,163 @@ describe('BlogService', () => { relations: ['author'], }); }); + + it('should return an empty list if no deleted blogs are found', async () => { + jest.spyOn(blogRepository, 'findAndCount').mockResolvedValue([[], 0]); + + const result = await service.getDeletedBlogs(1, 10); + + expect(result).toEqual({ + status_code: 200, + message: SYS_MSG.BLOG_FETCHED_SUCCESSFUL, + data: { + currentPage: 1, + totalPages: 0, + totalResults: 0, + blogs: [], + meta: { + hasNext: false, + total: 0, + nextPage: null, + prevPage: null, + }, + }, + }); + expect(blogRepository.findAndCount).toHaveBeenCalledWith({ + where: { deletedAt: Not(IsNull()) }, + skip: 0, + take: 10, + relations: ['author'], + }); + }); + + it('should handle pagination correctly for deleted blogs', async () => { + const blog = new Blog(); + blog.id = 'blog-id'; + blog.title = 'Test Blog'; + blog.content = 'Test Content'; + blog.tags = ['test']; + blog.image_urls = ['http://example.com/image.jpg']; + blog.author = new User(); + blog.author.first_name = 'John'; + blog.author.last_name = 'Doe'; + blog.created_at = new Date(); + blog.updated_at = new Date(); + blog.deletedAt = new Date(); + + jest.spyOn(blogRepository, 'findAndCount').mockResolvedValue([[blog], 1]); + + const result = await service.getDeletedBlogs(2, 1); + + expect(result).toEqual({ + status_code: 200, + message: SYS_MSG.BLOG_FETCHED_SUCCESSFUL, + data: { + currentPage: 2, + totalPages: 1, + totalResults: 1, + blogs: [ + { + blog_id: 'blog-id', + title: 'Test Blog', + content: 'Test Content', + tags: ['test'], + image_urls: ['http://example.com/image.jpg'], + author: 'John Doe', + created_at: blog.created_at, + deletedAt: blog.deletedAt, + }, + ], + meta: { + hasNext: false, + total: 1, + nextPage: null, + prevPage: 1, + }, + }, + }); + expect(blogRepository.findAndCount).toHaveBeenCalledWith({ + where: { deletedAt: Not(IsNull()) }, + skip: 1, + take: 1, + relations: ['author'], + }); + }); + + it('should return all deleted blogs with multiple mock data', async () => { + const blog1 = new Blog(); + blog1.id = 'blog-id-1'; + blog1.title = 'Test Blog 1'; + blog1.content = 'Test Content 1'; + blog1.tags = ['test1']; + blog1.image_urls = ['http://example.com/image1.jpg']; + blog1.author = new User(); + blog1.author.first_name = 'John'; + blog1.author.last_name = 'Doe'; + blog1.created_at = new Date(); + blog1.updated_at = new Date(); + blog1.deletedAt = new Date(); + + const blog2 = new Blog(); + blog2.id = 'blog-id-2'; + blog2.title = 'Test Blog 2'; + blog2.content = 'Test Content 2'; + blog2.tags = ['test2']; + blog2.image_urls = ['http://example.com/image2.jpg']; + blog2.author = new User(); + blog2.author.first_name = 'Jane'; + blog2.author.last_name = 'Doe'; + blog2.created_at = new Date(); + blog2.updated_at = new Date(); + blog2.deletedAt = new Date(); + + jest.spyOn(blogRepository, 'findAndCount').mockResolvedValue([[blog1, blog2], 2]); + + const result = await service.getDeletedBlogs(1, 10); + + expect(result).toEqual({ + status_code: 200, + message: SYS_MSG.BLOG_FETCHED_SUCCESSFUL, + data: { + currentPage: 1, + totalPages: 1, + totalResults: 2, + blogs: [ + { + blog_id: 'blog-id-1', + title: 'Test Blog 1', + content: 'Test Content 1', + tags: ['test1'], + image_urls: ['http://example.com/image1.jpg'], + author: 'John Doe', + created_at: blog1.created_at, + deletedAt: blog1.deletedAt, + }, + { + blog_id: 'blog-id-2', + title: 'Test Blog 2', + content: 'Test Content 2', + tags: ['test2'], + image_urls: ['http://example.com/image2.jpg'], + author: 'Jane Doe', + created_at: blog2.created_at, + deletedAt: blog2.deletedAt, + }, + ], + meta: { + hasNext: false, + total: 2, + nextPage: null, + prevPage: null, + }, + }, + }); + expect(blogRepository.findAndCount).toHaveBeenCalledWith({ + where: { deletedAt: Not(IsNull()) }, + skip: 0, + take: 10, + relations: ['author'], + }); + }); }); });