Skip to content

Commit

Permalink
feat(blog-category): add search functionality to BlogCategoryService
Browse files Browse the repository at this point in the history
  • Loading branch information
Reaganz-Wat committed Mar 2, 2025
1 parent 4966505 commit 0a6733c
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 2 deletions.
23 changes: 22 additions & 1 deletion src/modules/blog-category/blog-category.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
import { Body, Controller, Post, UseGuards, Request, Patch, Param } from '@nestjs/common';
import {
Body,
Controller,
Post,
UseGuards,
Request,
Patch,
Param,
Get,
Query,
NotFoundException,
} from '@nestjs/common';
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { SuperAdminGuard } from '../../guards/super-admin.guard';
import { BlogCategoryService } from './blog-category.service';
Expand Down Expand Up @@ -36,4 +47,14 @@ export class BlogCategoryController {
async updateBlogCategory(@Param('id') id: string, @Body() updateBlogCategoryDto: UpdateBlogCategoryDto) {
return await this.blogCategoryService.updateOrganisationCategory(id, updateBlogCategoryDto);
}

@Get('search')
@ApiOperation({ summary: 'Search blog categories by name' })
@ApiResponse({ status: 200, description: 'Categories found' })
@ApiResponse({ status: 404, description: 'No categories found' })
async searchCategories(@Query('term') searchTerm: string) {
console.log('Search Term: ', searchTerm);
const result = await this.blogCategoryService.searchCategories(searchTerm);
return result;
}
}
35 changes: 34 additions & 1 deletion src/modules/blog-category/blog-category.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { BlogCategory } from './entities/blog-category.entity';
import { Repository } from 'typeorm';
import { Like, Repository } from 'typeorm';
import { CreateBlogCategoryDto } from './dto/create-blog-category.dto';
import { CustomHttpException } from '../../helpers/custom-http-filter';
import { CATEGORY_NOT_FOUND, ORG_NOT_FOUND } from '../../helpers/SystemMessages';
Expand Down Expand Up @@ -29,4 +29,37 @@ export class BlogCategoryService {
await this.blogCategoryRepository.save(category);
return { data: category, message: 'Organisation category updated successfully.' };
}

async searchCategories(searchTerm: string): Promise<{
status: string;
status_code: number;
message: string;
data: { categories: BlogCategory[]; total: number };
}> {
// Handle empty search term
if (!searchTerm || searchTerm.trim() === '') {
return {
status: 'success',
status_code: 200,
message: 'No search term provided',
data: { categories: [], total: 0 },
};
}

// Perform a case-insensitive search
const categories = await this.blogCategoryRepository
.createQueryBuilder('category')
.where('LOWER(category.name) LIKE LOWER(:searchTerm)', {
searchTerm: `%${searchTerm}%`,
})
.getMany();

// Return the results in the desired format
return {
status: 'success',
status_code: 200,
message: categories.length > 0 ? 'Categories found successfully' : 'No categories found',
data: { categories, total: categories.length },
};
}
}
62 changes: 62 additions & 0 deletions src/modules/blog-category/tests/blog-category.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,66 @@ describe('BlogCategoryService', () => {

await expect(service.createOrganisationCategory(createBlogCategoryDto)).rejects.toThrow('Save failed');
});

it('should return empty array and total 0 for empty search term', async () => {
const result = await service.searchCategories('');
expect(result).toEqual({
status: 'success',
status_code: 200,
message: 'No search term provided',
data: { categories: [], total: 0 },
});
});

it('should return matching categories for partial search term', async () => {
const mockCategories = [
{ id: '1', name: 'Technology' },
{ id: '2', name: 'Tech News' },
];

jest.spyOn(repository, 'createQueryBuilder').mockReturnValue({
where: jest.fn().mockReturnThis(),
getMany: jest.fn().mockResolvedValue(mockCategories),
} as any);

const result = await service.searchCategories('tech');
expect(result).toEqual({
status: 'success',
status_code: 200,
message: 'Categories found successfully',
data: { categories: mockCategories, total: 2 },
});
});

it('should return empty array and total 0 for no matches', async () => {
jest.spyOn(repository, 'createQueryBuilder').mockReturnValue({
where: jest.fn().mockReturnThis(),
getMany: jest.fn().mockResolvedValue([]),
} as any);

const result = await service.searchCategories('nonexistent');
expect(result).toEqual({
status: 'success',
status_code: 200,
message: 'No categories found',
data: { categories: [], total: 0 },
});
});

it('should handle search term with special characters', async () => {
const mockCategories = [{ id: '1', name: 'C# Programming' }];

jest.spyOn(repository, 'createQueryBuilder').mockReturnValue({
where: jest.fn().mockReturnThis(),
getMany: jest.fn().mockResolvedValue(mockCategories),
} as any);

const result = await service.searchCategories('C#');
expect(result).toEqual({
status: 'success',
status_code: 200,
message: 'Categories found successfully',
data: { categories: mockCategories, total: 1 },
});
});
});

0 comments on commit 0a6733c

Please sign in to comment.