From 7c2105d43723288b7d7cca37bc11dbe11534cc99 Mon Sep 17 00:00:00 2001 From: Bradley Shellnut Date: Tue, 13 Aug 2024 16:42:10 -0700 Subject: [PATCH] Adding more tests for services. --- .../server/api/services/user_roles.service.ts | 4 +- .../server/api/tests/hashing.service.test.ts | 32 ++++++++++ .../server/api/tests/tokens.service.test.ts | 49 +++++++++++++++ .../api/tests/user_roles.service.test.ts | 62 +++++++++++++++++++ .../server/api/tests/users.service.test.ts | 7 --- 5 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 src/lib/server/api/tests/hashing.service.test.ts create mode 100644 src/lib/server/api/tests/tokens.service.test.ts create mode 100644 src/lib/server/api/tests/user_roles.service.test.ts diff --git a/src/lib/server/api/services/user_roles.service.ts b/src/lib/server/api/services/user_roles.service.ts index 63a56b2..04ad1d0 100644 --- a/src/lib/server/api/services/user_roles.service.ts +++ b/src/lib/server/api/services/user_roles.service.ts @@ -1,8 +1,6 @@ import {inject, injectable} from "tsyringe"; import {type CreateUserRole, UserRolesRepository} from "$lib/server/api/repositories/user_roles.repository"; -import db from "$db"; import {RolesService} from "$lib/server/api/services/roles.service"; -import { user_roles } from "../infrastructure/database/tables"; @injectable() export class UserRolesService { @@ -32,7 +30,7 @@ export class UserRolesService { } // Create a UserRole entry linking the user and the role - return db.insert(user_roles).values({ + return this.userRolesRepository.create({ user_id: userId, role_id: role.id, primary, diff --git a/src/lib/server/api/tests/hashing.service.test.ts b/src/lib/server/api/tests/hashing.service.test.ts new file mode 100644 index 0000000..94c7f89 --- /dev/null +++ b/src/lib/server/api/tests/hashing.service.test.ts @@ -0,0 +1,32 @@ +import 'reflect-metadata'; +import { container } from 'tsyringe'; +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; +import { HashingService } from '../services/hashing.service'; + +describe('HashingService', () => { + let service: HashingService; + + beforeAll(() => { + service = container.resolve(HashingService); + }); + + afterAll(() => { + vi.resetAllMocks() + }); + + describe('Create Hash', () => { + it('should create a hash', async () => { + const hash = await service.hash('111'); + expect(hash).not.toBeUndefined(); + expect(hash).not.toBeNull(); + }); + }) + + describe('Verify Hash', () => { + it('should verify a hash', async () => { + const hash = await service.hash('111'); + const verifiable = await service.verify(hash, '111'); + expect(verifiable).toBeTruthy(); + }); + }) +}) \ No newline at end of file diff --git a/src/lib/server/api/tests/tokens.service.test.ts b/src/lib/server/api/tests/tokens.service.test.ts new file mode 100644 index 0000000..5c0e34e --- /dev/null +++ b/src/lib/server/api/tests/tokens.service.test.ts @@ -0,0 +1,49 @@ +import 'reflect-metadata'; +import { container } from 'tsyringe'; +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; +import { TokensService } from '../services/tokens.service'; +import { HashingService } from '../services/hashing.service'; +import { Argon2id } from 'oslo/password'; + +describe('TokensService', () => { + let service: TokensService; + const hashingService = vi.mocked(HashingService.prototype); + + beforeAll(() => { + service = container + .register(HashingService, { useValue: hashingService }) + .resolve(TokensService); + }); + + afterAll(() => { + vi.resetAllMocks() + }); + + describe('Generate Token', () => { + const hashedPassword = new Argon2id().hash('111'); + + hashingService.hash = vi.fn().mockResolvedValue(hashedPassword); + hashingService.verify = vi.fn().mockResolvedValue(true); + + const spy_hashingService_hash = vi.spyOn(hashingService, 'hash'); + const spy_hashingService_verify = vi.spyOn(hashingService, 'verify'); + + it('should resolve', async () => { + await expect(service.createHashedToken('111')).resolves.string + }) + it('should generate a token that is verifiable', async () => { + const token = await service.createHashedToken('111'); + expect(token).not.toBeUndefined(); + expect(token).not.toBeNull(); + const verifiable = await service.verifyHashedToken(token, '111'); + expect(verifiable).toBeTruthy(); + }); + + it('should generate a hashed token', async () => { + expect(spy_hashingService_hash).toHaveBeenCalledTimes(2); + }) + it('should verify a hashed token', async () => { + expect(spy_hashingService_verify).toHaveBeenCalledTimes(1); + }) + }); +}); \ No newline at end of file diff --git a/src/lib/server/api/tests/user_roles.service.test.ts b/src/lib/server/api/tests/user_roles.service.test.ts new file mode 100644 index 0000000..dfd47d2 --- /dev/null +++ b/src/lib/server/api/tests/user_roles.service.test.ts @@ -0,0 +1,62 @@ +import 'reflect-metadata'; +import { container } from 'tsyringe'; +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; +import { UserRolesService } from '../services/user_roles.service'; +import { UserRolesRepository } from '../repositories/user_roles.repository'; +import { RolesService } from '../services/roles.service'; + +describe('UserRolesService', () => { + let service: UserRolesService; + const userRolesRepository = vi.mocked(UserRolesRepository.prototype); + const rolesService = vi.mocked(RolesService.prototype); + + beforeAll(() => { + service = container + .register(UserRolesRepository, { useValue: userRolesRepository }) + .register(RolesService, { useValue: rolesService }) + .resolve(UserRolesService); + }); + + afterAll(() => { + vi.resetAllMocks() + }); + + describe('Create User Role', () => { + rolesService.findOneByNameOrThrow = vi.fn().mockResolvedValue({ + id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + cuid: 'ciglo1j8q0000t9j4xq8d6p5e', + name: 'user', + createdAt: new Date(), + updatedAt: new Date() + } satisfies Awaited>); + + userRolesRepository.create = vi.fn().mockResolvedValue({ + id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + cuid: 'ciglo1j8q0000t9j4xq8d6p5e', + user_id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8fff', + role_id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + primary: true, + createdAt: new Date(), + updatedAt: new Date() + } satisfies Awaited>); + + const spy_rolesService_findOneByNameOrThrow = vi.spyOn(rolesService, 'findOneByNameOrThrow'); + const spy_userRolesRepository_create = vi.spyOn(userRolesRepository, 'create'); + + it('should resolve', async () => { + await expect(service.addRoleToUser('3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8fff', 'user', true)).resolves.not.toThrowError(); + }) + it('should call rolesService.findOneByNameOrThrow', async () => { + expect(spy_rolesService_findOneByNameOrThrow).toBeCalledWith('user'); + expect(spy_rolesService_findOneByNameOrThrow).toBeCalledTimes(1); + }) + it('should call userRolesRepository.create', async () => { + expect(spy_userRolesRepository_create).toBeCalledWith({ + user_id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8fff', + role_id: '3e0e9f0f-0a0b-4f0b-8f0b-0a0b4f0b8f0b', + primary: true + }); + expect(spy_userRolesRepository_create).toBeCalledTimes(1); + }) + }) +}); \ No newline at end of file diff --git a/src/lib/server/api/tests/users.service.test.ts b/src/lib/server/api/tests/users.service.test.ts index 5fe24d3..fb40e5f 100644 --- a/src/lib/server/api/tests/users.service.test.ts +++ b/src/lib/server/api/tests/users.service.test.ts @@ -9,13 +9,6 @@ import { UsersRepository } from '../repositories/users.repository'; import { Argon2id } from 'oslo/password'; import { WishlistsService } from '../services/wishlists.service'; import { CollectionsService } from '../services/collections.service'; -// import { LoginRequestsService } from '../services/login-requests.service'; -// import { TokensService } from '../services/tokens.service'; -// import { MailerService } from '../services/mailer.service'; -// import { UsersRepository } from '../repositories/users.repository'; -// import { DatabaseProvider, LuciaProvider } from '../providers'; -// import { LoginRequestsRepository } from '../repositories/login-requests.repository'; -// import { PgDatabase } from 'drizzle-orm/pg-core'; describe('UsersService', () => { let service: UsersService;