osr-root-router/test/unit/auth/auth.service.spec.ts
2024-05-25 10:36:47 +02:00

693 lines
22 KiB
TypeScript

import { Test } from '@nestjs/testing';
import { faker } from '@faker-js/faker';
import { AuthService } from 'src/common/auth/services/auth.service';
import { ENUM_AUTH_ACCESS_FOR } from 'src/common/auth/constants/auth.enum.constant';
import configs from 'src/configs';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { HelperModule } from 'src/common/helper/helper.module';
import { IAuthPassword } from 'src/common/auth/interfaces/auth.interface';
import { HelperDateService } from 'src/common/helper/services/helper.date.service';
import { AuthModule } from 'src/common/auth/auth.module';
describe('AuthService', () => {
let authService: AuthService;
let configService: ConfigService;
let helperDateService: HelperDateService;
let encryptedAccessToken: string;
let accessToken: string;
let encryptedRefreshToken: string;
let refreshToken: string;
let encryptedPermissionToken: string;
let permissionToken: string;
let prefixAuthorization: string;
let accessTokenExpirationTime: number;
let refreshTokenExpirationTime: number;
let refreshTokenExpirationTimeRememberMe: number;
let issuer: string;
let audience: string;
let subject: string;
let payloadEncryption: boolean;
let permissionTokenExpirationTime: number;
// cSpell:ignore ZfqgaDMPpWQ3lJEGQ8Ueu stnk
const user: Record<string, any> = {
_id: '623cb7fd37a861a10bac2c91',
isActive: true,
salt: '$2b$08$GZfqgaDMPpWQ3lJEGQ8Ueu',
passwordExpired: new Date('2023-03-24T18:27:09.500Z'),
password:
'$2b$08$GZfqgaDMPpWQ3lJEGQ8Ueu1vJ3C6G3stnkS/5e61bK/4f1.Fuw2Eq',
role: {
_id: '623cb7f7965a74bf7a0e9e53',
accessFor: ENUM_AUTH_ACCESS_FOR.SUPER_ADMIN,
isActive: true,
permissions: [],
name: 'admin',
},
email: 'admin@mail.com',
mobileNumber: '08111111111',
lastName: 'test',
firstName: 'admin@mail.com',
};
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
imports: [
ConfigModule.forRoot({
load: configs,
isGlobal: true,
cache: true,
envFilePath: ['.env'],
expandVariables: true,
}),
HelperModule,
AuthModule,
],
}).compile();
authService = moduleRef.get<AuthService>(AuthService);
configService = moduleRef.get<ConfigService>(ConfigService);
helperDateService = moduleRef.get<HelperDateService>(HelperDateService);
user.passwordExpired = helperDateService.forwardInDays(30);
accessToken = await authService.createAccessToken(user);
encryptedAccessToken = await authService.encryptAccessToken(user);
refreshToken = await authService.createRefreshToken(user, {
notBeforeExpirationTime: 0,
});
encryptedRefreshToken = await authService.encryptRefreshToken(user);
permissionToken = await authService.createPermissionToken(user);
encryptedPermissionToken = await authService.encryptPermissionToken(
user
);
prefixAuthorization = configService.get<string>(
'auth.prefixAuthorization'
);
accessTokenExpirationTime = configService.get<number>(
'auth.accessToken.expirationTime'
);
refreshTokenExpirationTime = configService.get<number>(
'auth.refreshToken.expirationTime'
);
refreshTokenExpirationTimeRememberMe = configService.get<number>(
'auth.refreshToken.expirationTimeRememberMe'
);
issuer = configService.get<string>('auth.issuer');
audience = configService.get<string>('auth.audience');
subject = configService.get<string>('auth.subject');
payloadEncryption = configService.get<boolean>(
'auth.payloadEncryption'
);
permissionTokenExpirationTime = configService.get<number>(
'auth.permissionToken.expirationTime'
);
});
afterEach(async () => {
jest.clearAllMocks();
});
it('should be defined', async () => {
expect(authService).toBeDefined();
});
describe('encryptAccessToken', () => {
it('should be return a hashed string', async () => {
const result: string = await authService.encryptAccessToken(user);
jest.spyOn(authService, 'encryptAccessToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
});
});
describe('decryptAccessToken', () => {
it('should be return payload data', async () => {
const result: Record<string, any> =
await authService.decryptAccessToken({
data: encryptedAccessToken,
});
jest.spyOn(authService, 'decryptAccessToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result._id).toBe(user._id);
});
});
describe('createAccessToken', () => {
it('should be create access token in string, from object', async () => {
const result: string = await authService.createAccessToken(user);
jest.spyOn(authService, 'createAccessToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
});
it('should be create access token in string, from string', async () => {
const result: string = await authService.createAccessToken('');
jest.spyOn(authService, 'createAccessToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
});
});
describe('validateAccessToken', () => {
it('should be verified', async () => {
const result: boolean = await authService.validateAccessToken(
accessToken
);
jest.spyOn(authService, 'validateAccessToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result).toBe(true);
});
it('should be failed', async () => {
const result: boolean = await authService.validateAccessToken(
faker.random.alphaNumeric(20)
);
jest.spyOn(authService, 'validateAccessToken').mockReturnValueOnce(
result as any
);
expect(result).toBeFalsy();
expect(result).toBe(false);
});
});
describe('payloadAccessToken', () => {
it('should given a payload of token', async () => {
const result: Record<string, any> =
await authService.payloadAccessToken(accessToken);
jest.spyOn(authService, 'payloadAccessToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result.data._id).toBe(user._id);
});
});
describe('encryptRefreshToken', () => {
it('should be return a hashed string', async () => {
const result: string = await authService.encryptRefreshToken(user);
jest.spyOn(authService, 'encryptRefreshToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
});
});
describe('decryptRefreshToken', () => {
it('should be return payload data', async () => {
const result: Record<string, any> =
await authService.decryptRefreshToken({
data: encryptedRefreshToken,
});
jest.spyOn(authService, 'decryptRefreshToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result._id).toBe(user._id);
});
});
describe('createRefreshToken', () => {
it('should be create refresh token in string, from object', async () => {
const result: string = await authService.createRefreshToken(user);
jest.spyOn(authService, 'createRefreshToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
});
it('should be create refresh token in string, from string', async () => {
const result: string = await authService.createRefreshToken('');
jest.spyOn(authService, 'createRefreshToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
});
it('should be create refresh token in string with options rememberMe, from string', async () => {
const result: string = await authService.createRefreshToken(user, {
rememberMe: true,
});
jest.spyOn(authService, 'createRefreshToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
});
});
describe('validateRefreshToken', () => {
it('should be verified', async () => {
const result: boolean = await authService.validateRefreshToken(
refreshToken
);
jest.spyOn(authService, 'validateRefreshToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result).toBe(true);
});
it('should be failed', async () => {
const result: boolean = await authService.validateRefreshToken(
faker.random.alphaNumeric(20)
);
jest.spyOn(authService, 'validateRefreshToken').mockReturnValueOnce(
result as any
);
expect(result).toBeFalsy();
expect(result).toBe(false);
});
});
describe('payloadRefreshToken', () => {
it('should given a payload of token', async () => {
const result: Record<string, any> =
await authService.payloadRefreshToken(refreshToken);
jest.spyOn(authService, 'payloadRefreshToken').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result.data._id).toBe(user._id);
});
});
describe('encryptPermissionToken', () => {
it('should be success', async () => {
const payloadHashedPermissionToken =
await authService.encryptPermissionToken(user);
jest.spyOn(
authService,
'encryptPermissionToken'
).mockImplementation(async () => payloadHashedPermissionToken);
expect(await authService.encryptPermissionToken(user)).toBe(
payloadHashedPermissionToken
);
});
});
describe('decryptPermissionToken', () => {
it('should be return payload data', async () => {
const result: Record<string, any> =
await authService.decryptPermissionToken({
data: encryptedPermissionToken,
});
jest.spyOn(
authService,
'decryptPermissionToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result._id).toBe(user._id);
});
});
describe('createPermissionToken', () => {
it('should be create refresh token in string, from object', async () => {
const result: string = await authService.createPermissionToken(
user
);
jest.spyOn(
authService,
'createPermissionToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
});
it('should be create refresh token in string, from string', async () => {
const result: string = await authService.createPermissionToken('');
jest.spyOn(
authService,
'createPermissionToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
});
});
describe('validatePermissionToken', () => {
it('should be verified', async () => {
const result: boolean = await authService.validatePermissionToken(
permissionToken
);
jest.spyOn(
authService,
'validatePermissionToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result).toBe(true);
});
it('should be failed', async () => {
const result: boolean = await authService.validatePermissionToken(
faker.random.alphaNumeric(20)
);
jest.spyOn(
authService,
'validatePermissionToken'
).mockReturnValueOnce(result as any);
expect(result).toBeFalsy();
expect(result).toBe(false);
});
});
describe('payloadPermissionToken', () => {
it('should given a payload of token', async () => {
const result: Record<string, any> =
await authService.payloadPermissionToken(permissionToken);
jest.spyOn(
authService,
'payloadPermissionToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result.data._id).toBe(user._id);
});
});
describe('validateUser', () => {
it('should be a valid user', async () => {
const password = faker.internet.password(20, true, /[A-Za-z0-9]/);
const passwordHash = await authService.createPassword(password);
const result: boolean = await authService.validateUser(
password,
passwordHash.passwordHash
);
jest.spyOn(authService, 'validateUser').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result).toBe(true);
});
it('should be not valid user', async () => {
const password = faker.internet.password(20, true, /[A-Za-z0-9]/);
const passwordHash = await authService.createPassword(password);
const result: boolean = await authService.validateUser(
'aasdasd12312',
passwordHash.passwordHash
);
jest.spyOn(authService, 'validateUser').mockReturnValueOnce(
result as any
);
expect(result).toBeFalsy();
expect(result).toBe(false);
});
});
describe('createPayloadAccessToken', () => {
it('should be mapped', async () => {
const result: Record<string, any> =
await authService.createPayloadAccessToken(user, false);
jest.spyOn(
authService,
'createPayloadAccessToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result._id).toBe(user._id);
});
it('payload with login date options', async () => {
const result: Record<string, any> =
await authService.createPayloadAccessToken(user, false, {
loginDate: new Date(),
});
jest.spyOn(
authService,
'createPayloadAccessToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result._id).toBe(user._id);
expect(result.loginDate).toBeDefined();
});
});
describe('createPayloadRefreshToken', () => {
it('should be mapped', async () => {
const result: Record<string, any> =
await authService.createPayloadRefreshToken(user._id, false);
jest.spyOn(
authService,
'createPayloadRefreshToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result._id).toBe(user._id);
});
it('payload with login date options', async () => {
const result: Record<string, any> =
await authService.createPayloadRefreshToken(user._id, false, {
loginDate: new Date(),
});
jest.spyOn(
authService,
'createPayloadRefreshToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result._id).toBe(user._id);
expect(result.loginDate).toBeDefined();
});
});
describe('createPayloadPermissionToken', () => {
it('should be mapped', async () => {
const result: Record<string, any> =
await authService.createPayloadPermissionToken(user);
jest.spyOn(
authService,
'createPayloadPermissionToken'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result).toEqual(user);
});
});
describe('createPassword', () => {
it('should be success', async () => {
const password = faker.internet.password(20, true, /[A-Za-z0-9]/);
const result: IAuthPassword = await authService.createPassword(
password
);
jest.spyOn(authService, 'createPassword').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
});
});
describe('checkPasswordExpired', () => {
it('should be not expired', async () => {
const result: boolean = await authService.checkPasswordExpired(
user.passwordExpired
);
jest.spyOn(authService, 'checkPasswordExpired').mockReturnValueOnce(
result as any
);
expect(result).toBeFalsy();
expect(result).toBe(false);
});
it('should be expired', async () => {
const expiredDate = new Date('1999-01-01');
const result: boolean = await authService.checkPasswordExpired(
expiredDate
);
jest.spyOn(authService, 'checkPasswordExpired').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result).toBe(true);
});
});
describe('getTokenType', () => {
it('should be success', async () => {
const result: string = await authService.getTokenType();
jest.spyOn(authService, 'getTokenType').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result).toBe(prefixAuthorization);
});
});
describe('getAccessTokenExpirationTime', () => {
it('should be give number in days for access token expiration', async () => {
const result: number =
await authService.getAccessTokenExpirationTime();
jest.spyOn(
authService,
'getAccessTokenExpirationTime'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result).toBe(accessTokenExpirationTime);
});
});
describe('getRefreshTokenExpirationTime', () => {
it('should be give number in days for refresh token expiration', async () => {
const result: number =
await authService.getRefreshTokenExpirationTime();
jest.spyOn(
authService,
'getRefreshTokenExpirationTime'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result).toBe(refreshTokenExpirationTime);
});
it('should be give number in days for refresh token expiration with long period', async () => {
const result: number =
await authService.getRefreshTokenExpirationTime(true);
jest.spyOn(
authService,
'getRefreshTokenExpirationTime'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result).toBe(refreshTokenExpirationTimeRememberMe);
});
});
describe('getIssuer', () => {
it('should be success', async () => {
const result: string = await authService.getIssuer();
jest.spyOn(authService, 'getIssuer').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result).toBe(issuer);
});
});
describe('getAudience', () => {
it('should be success', async () => {
const result: string = await authService.getAudience();
jest.spyOn(authService, 'getAudience').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result).toBe(audience);
});
});
describe('getSubject', () => {
it('should be success', async () => {
const result: string = await authService.getSubject();
jest.spyOn(authService, 'getSubject').mockReturnValueOnce(
result as any
);
expect(result).toBeTruthy();
expect(result).toBe(subject);
});
});
describe('getPayloadEncryption', () => {
it('should be success', async () => {
const result: boolean = await authService.getPayloadEncryption();
jest.spyOn(authService, 'getPayloadEncryption').mockReturnValueOnce(
result as any
);
expect(result).toBeDefined();
expect(result).toBe(payloadEncryption);
});
});
describe('getPermissionTokenExpirationTime', () => {
it('should be success', async () => {
const result: number =
await authService.getPermissionTokenExpirationTime();
jest.spyOn(
authService,
'getPermissionTokenExpirationTime'
).mockReturnValueOnce(result as any);
expect(result).toBeTruthy();
expect(result).toBe(permissionTokenExpirationTime);
});
});
});