From a72d72d8d4f52d68ea0d686f382d3ab20d5b6870 Mon Sep 17 00:00:00 2001 From: Michael Feher Date: Fri, 26 Apr 2024 22:27:28 -0400 Subject: [PATCH] test: increase coverage for auth service --- services/liquid-auth-api-js/package.json | 1 + .../src/__mocks__/assertion.service.mock.ts | 6 - .../src/auth/auth.guard.spec.ts | 27 ++++ .../src/auth/auth.service.spec.ts | 130 ++++++++++++++++++ .../src/auth/auth.service.ts | 4 - 5 files changed, 158 insertions(+), 10 deletions(-) delete mode 100644 services/liquid-auth-api-js/src/__mocks__/assertion.service.mock.ts create mode 100644 services/liquid-auth-api-js/src/auth/auth.guard.spec.ts create mode 100644 services/liquid-auth-api-js/src/auth/auth.service.spec.ts diff --git a/services/liquid-auth-api-js/package.json b/services/liquid-auth-api-js/package.json index abe7065..8b5f5bd 100644 --- a/services/liquid-auth-api-js/package.json +++ b/services/liquid-auth-api-js/package.json @@ -86,6 +86,7 @@ "node": ">=18.0.0 <21.0.0" }, "jest": { + "testTimeout": 10000, "extensionsToTreatAsEsm": [ ".ts" ], diff --git a/services/liquid-auth-api-js/src/__mocks__/assertion.service.mock.ts b/services/liquid-auth-api-js/src/__mocks__/assertion.service.mock.ts deleted file mode 100644 index d59ef3e..0000000 --- a/services/liquid-auth-api-js/src/__mocks__/assertion.service.mock.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { dummyUsers, dummyOptions } from '../../tests/constants.js'; - -export const mockAssertionService = { - request: jest.fn().mockReturnValue(dummyOptions), - response: jest.fn().mockReturnValue(dummyUsers[0]), -}; diff --git a/services/liquid-auth-api-js/src/auth/auth.guard.spec.ts b/services/liquid-auth-api-js/src/auth/auth.guard.spec.ts new file mode 100644 index 0000000..e788a68 --- /dev/null +++ b/services/liquid-auth-api-js/src/auth/auth.guard.spec.ts @@ -0,0 +1,27 @@ +import { AuthGuard } from './auth.guard.js'; +import { ExecutionContext } from '@nestjs/common'; +import sessionFixtures from '../__fixtures__/session.fixtures.json'; +describe('AuthGuard', () => { + const mockExecutionContext: Partial< + Record< + jest.FunctionPropertyNames, + jest.MockedFunction + > + > = { + switchToHttp: jest.fn().mockReturnValue({ + getRequest: jest + .fn() + .mockReturnValue({ session: sessionFixtures.authorized }), + getResponse: jest.fn().mockReturnThis(), + }), + }; + it('should be defined', () => { + expect(new AuthGuard()).toBeDefined(); + }); + it('should guard a route', () => { + const guard = new AuthGuard(); + expect(guard.canActivate(mockExecutionContext as ExecutionContext)).toBe( + true, + ); + }); +}); diff --git a/services/liquid-auth-api-js/src/auth/auth.service.spec.ts b/services/liquid-auth-api-js/src/auth/auth.service.spec.ts new file mode 100644 index 0000000..24790c1 --- /dev/null +++ b/services/liquid-auth-api-js/src/auth/auth.service.spec.ts @@ -0,0 +1,130 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { getModelToken } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { AuthService } from './auth.service.js'; +import { User } from './auth.schema.js'; +import { Session } from './session.schema.js'; + +describe('AuthService', () => { + const mockUser = { + wallet: '2SPDE6XLJNXFTOO7OIGNRNKSEDOHJWVD3HBSEAPHONZQ4IQEYOGYTP6LXA', + credentials: [], + }; + const mockCredential = { + device: 'Pixel 8 Pro', + publicKey: + 'pQECAyYgASFYIB2dcp3wanhReRhgRIpJCUfRSwkCvyE9OdvEL_NlncSJIlggkSIz7h7O5nrAXGJrkCOmeolChSc09eHzniCFLFxaKH0', + credId: + 'AYMPi2Rbhcnu2gSHOO1TNvzDJ38iU00rrlCqyH874XCIEoIotRc7eVRFpx0TvsQurg7BAnXy5KnWdKC8LeWs0k0', + prevCounter: 0, + }; + const mockSession = { + _id: '60b3b3b3b3b3b3b3b3b3b3b3', + expires: new Date(), + session: JSON.stringify({ wallet: mockUser.wallet }), + }; + let service: AuthService; + let userModel; + let mockUserModel; + let mockSessionModel; + beforeEach(async () => { + mockUserModel = jest.fn(() => ({ + save: jest.fn().mockResolvedValue(mockUser), + toObject: jest.fn().mockReturnValue({}), + })) as unknown as Model; + mockUserModel.findOne = jest.fn().mockReturnValue({ + exec: jest.fn().mockResolvedValue(mockUser), + }); + mockUserModel.findOneAndUpdate = jest.fn().mockReturnValue({ + exec: jest.fn().mockResolvedValue(mockUser), + }); + mockSessionModel = jest.fn(() => ({ + save: jest.fn().mockResolvedValue(mockSession), + toObject: jest.fn().mockReturnValue({}), + })) as unknown as Model; + mockSessionModel.findOne = jest.fn().mockReturnValue({ + exec: jest.fn().mockResolvedValue(mockSession), + }); + mockSessionModel.findOneAndUpdate = jest.fn().mockReturnValue({ + exec: jest.fn().mockResolvedValue(mockSession), + }); + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: getModelToken(User.name), + useValue: mockUserModel, + }, + { + provide: getModelToken(Session.name), + useValue: mockSessionModel, + }, + AuthService, + ], + }).compile(); + userModel = module.get>(getModelToken(User.name)); + service = module.get(AuthService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); + it('should initialize a new user', async () => { + userModel.findOne = jest.fn().mockReturnValue({ + exec: jest.fn().mockResolvedValue(null), + }); + const user = await service.init(mockUser.wallet); + expect(user).toEqual(mockUser); + }); + it('should fail to create invalid user', async () => { + await expect(service.init('&$@#%')).rejects.toThrow(TypeError); + }); + it('should search for a user', async () => { + const user = await service.search({ wallet: mockUser.wallet }); + expect(user).toEqual(mockUser); + }); + it('should update a user', async () => { + const user = await service.update(mockUser as User); + expect(user).toEqual(mockUser); + }); + it('should find a credential', async () => { + userModel.findOne = jest.fn().mockReturnValue({ + exec: jest + .fn() + .mockResolvedValue({ ...mockUser, credentials: [mockCredential] }), + }); + const credential = await service.findCredential(mockCredential.credId); + expect(credential).toEqual(mockCredential); + }); + it('should add a credential to a user', async () => { + const user = await service.addCredential(mockUser.wallet, mockCredential); + expect(user).toEqual({ ...mockUser, credentials: [mockCredential] }); + }); + it('should not add duplicate credentials', async () => { + userModel.findOne = jest.fn().mockReturnValue({ + exec: jest + .fn() + .mockResolvedValue({ ...mockUser, credentials: [mockCredential] }), + }); + const user = await service.addCredential(mockUser.wallet, mockCredential); + expect(user).toEqual({ ...mockUser, credentials: [mockCredential] }); + }); + it('should remove a credential from a user', async () => { + const user = await service.removeCredential( + { ...mockUser, credentials: [mockCredential] } as User, + mockCredential.credId, + ); + expect(user).toEqual(mockUser); + }); + + it('should find a session', async () => { + const session = await service.findSession(mockSession._id); + expect(session).toEqual(mockSession); + }); + it('should update a session', async () => { + const session = await service.updateSessionWallet( + mockSession, + mockUser.wallet, + ); + expect(session).toEqual(mockSession); + }); +}); diff --git a/services/liquid-auth-api-js/src/auth/auth.service.ts b/services/liquid-auth-api-js/src/auth/auth.service.ts index fafccad..2113e9f 100644 --- a/services/liquid-auth-api-js/src/auth/auth.service.ts +++ b/services/liquid-auth-api-js/src/auth/auth.service.ts @@ -95,10 +95,6 @@ export class AuthService { return this.update(user); } - async all() { - return this.userModel.find({}).exec(); - } - /** * Find a Session by ID *