Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #20

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,26 @@ jobs:
app: [driver, notification, gateway, ride, user-service, auth, user]

steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Checkout code
uses: actions/checkout@v2

- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: '20'
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: '20'

- name: Install dependencies
run: npm install
- run: npm install
- run: npm test

- name: Install dependencies for ${{ matrix.app }}
working-directory: apps/${{ matrix.app }}
run: npm install

- name: Install dependencies for ${{ matrix.app }}
working-directory: apps/${{ matrix.app }}
run: npm install

- name: Start ${{ matrix.app }}
working-directory: apps/${{ matrix.app }}
run: nest start ${{ matrix.app }} &
- name: Start ${{ matrix.app }}
working-directory: apps/${{ matrix.app }}
run: nest start ${{ matrix.app }} &

- name: Run tests for all apps
run: npm run test



11 changes: 10 additions & 1 deletion apps/notification/src/notification.module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { Module } from '@nestjs/common';
import { NotificationController } from './notification.controller';
import { NotificationService } from './notification.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DatabaseModule } from '@app/database';

@Module({
imports: [],
imports: [
TypeOrmModule.forFeature([]),
DatabaseModule.forRoot(
process.env.DATABASE_URI,
process.env.DATABASE_NAME,
process.env.DATABASE_TYPE as 'mongodb' | 'postgres'
),
],
controllers: [NotificationController],
providers: [NotificationService],
})
Expand Down
213 changes: 213 additions & 0 deletions apps/user/src/__tests__/user.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { ClientProxy, ClientProxyFactory, Transport } from '@nestjs/microservices';
import { UserService } from '../user.service';
import { User } from '../model/user.entity';
import { UserCreateCommand } from '../command/user.create.cmd';
import { hashPassword } from '../util/hash.pass';



const mockDriverServiceClient = {
send: jest.fn().mockResolvedValue('Driver created successfully'),
};

describe('UserService', () => {
let service: UserService;
let userRepository: Repository<User>;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UserService,
{
provide: getRepositoryToken(User),
useClass: Repository,
},
{
provide: CACHE_MANAGER,
useValue: {
get: jest.fn(),
set: jest.fn(),
},
},
{
provide: ClientProxy,
useValue: mockDriverServiceClient,
},
],
}).compile();

service = module.get<UserService>(UserService);
userRepository = module.get(getRepositoryToken(User));
});

describe('createUser', () => {
it('should create a new user and call the DriverService', async () => {
const command: UserCreateCommand = {
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
password: 'password123',
confirmPassword: 'password123',
};

const hashedPassword = await hashPassword(command.password);
const mockUser = {
id: '123',
firstName: command.firstName,
lastName: command.lastName,
email: command.email,
password: hashedPassword,
} as User;

// Mock the repository methods
userRepository.create = jest.fn().mockReturnValue(mockUser);
userRepository.save = jest.fn().mockResolvedValue(mockUser);
userRepository.findOne = jest.fn().mockResolvedValue(null); // Ensure no user exists

const createdUser = await service.createUser(command);

expect(userRepository.create).toHaveBeenCalledWith({
firstName: command.firstName,
lastName: command.lastName,
email: command.email,
password: hashedPassword,
});
expect(userRepository.save).toHaveBeenCalledWith(mockUser);
expect(createdUser).toEqual(mockUser);
expect(mockDriverServiceClient.send).toHaveBeenCalledWith({ cmd: 'create' }, mockUser.id);
});

it('should throw an error if the email already exists', async () => {
const command: UserCreateCommand = {
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
password: 'password123',
confirmPassword: 'password123',
};

// Mock the findOne method to simulate existing user
userRepository.findOne = jest.fn().mockResolvedValue({
id: '123',
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
} as User);

await expect(service.createUser(command)).rejects.toThrowError();
});
});

describe('findUserById', () => {
it('should find a user by id and return the user from cache', async () => {
const userId = '123';
const mockUser = {
id: userId,
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
} as User;

// Mock the cache manager methods
const cacheManager = service['cacheManager'];
cacheManager.get = jest.fn().mockResolvedValue(mockUser);

// Mock the findOne method (not called in this case)
userRepository.findOne = jest.fn();

const user = await service.findUserById(userId);

expect(cacheManager.get).toHaveBeenCalledWith(`user-${userId}`);
expect(user).toEqual(mockUser);
expect(userRepository.findOne).not.toHaveBeenCalled(); // Ensure repository is not called
});

it('should find a user by id and store in cache', async () => {
const userId = '123';
const mockUser = {
id: userId,
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
} as User;

// Mock the cache manager methods
const cacheManager = service['cacheManager'];
cacheManager.get = jest.fn().mockResolvedValue(null); // Simulate no cached user
cacheManager.set = jest.fn();

// Mock the findOne method
userRepository.findOne = jest.fn().mockResolvedValue(mockUser);

const user = await service.findUserById(userId);

expect(cacheManager.get).toHaveBeenCalledWith(`user-${userId}`);
expect(cacheManager.set).toHaveBeenCalledWith(`user-${userId}`, mockUser, 600);
expect(userRepository.findOne).toHaveBeenCalledWith({ where: { id: userId } });
expect(user).toEqual(mockUser);
});

it('should throw an error if the user is not found', async () => {
const userId = '123';
userRepository.findOne = jest.fn().mockResolvedValue(null);

await expect(service.findUserById(userId)).rejects.toThrowError();
});
});

describe('getAll', () => {
it('should fetch all users and return from cache', async () => {
const mockUsers = [
{
id: '123',
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
} as User,
];

// Mock the cache manager methods
const cacheManager = service['cacheManager'];
cacheManager.get = jest.fn().mockResolvedValue(mockUsers);

// Mock the find method (not called in this case)
userRepository.find = jest.fn();

const users = await service.getAll();

expect(cacheManager.get).toHaveBeenCalledWith('all-users');
expect(users).toEqual(mockUsers);
expect(userRepository.find).not.toHaveBeenCalled(); // Ensure repository is not called
});

it('should fetch all users and store in cache', async () => {
const mockUsers = [
{
id: '123',
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
} as User,
];

// Mock the cache manager methods
const cacheManager = service['cacheManager'];
cacheManager.get = jest.fn().mockResolvedValue(null); // Simulate no cached users
cacheManager.set = jest.fn();

// Mock the find method
userRepository.find = jest.fn().mockResolvedValue(mockUsers);

const users = await service.getAll();

expect(cacheManager.get).toHaveBeenCalledWith('all-users');
expect(cacheManager.set).toHaveBeenCalledWith('all-users', mockUsers, 600);
expect(userRepository.find).toHaveBeenCalled();
expect(users).toEqual(mockUsers);
});
});
});
1 change: 1 addition & 0 deletions apps/user/src/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { MessagePattern } from '@nestjs/microservices';
import { User } from './model/user.entity';
import { UserCreateCommand } from './command/user.create.cmd';


@Controller('user')
export class UserController {

Expand Down
1 change: 1 addition & 0 deletions libs/database/src/database.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { MongooseModule, MongooseModuleOptions } from '@nestjs/mongoose';
@Module({})
export class DatabaseModule {


private static logger = new Logger(DatabaseModule.name);

static forRoot(uri: string, dbName: string, dbType: 'mongodb' | 'postgres'): DynamicModule {
Expand Down
Loading