Skip to content

Commit

Permalink
Merge pull request #153 from conceptadev/tnramalho-feature/improve-te…
Browse files Browse the repository at this point in the history
…st-coverage

Tnramalho feature/improve test coverage
  • Loading branch information
MrMaz authored Apr 29, 2024
2 parents 2003d38 + 22af759 commit b44e3cc
Show file tree
Hide file tree
Showing 22 changed files with 1,105 additions and 39 deletions.
4 changes: 2 additions & 2 deletions packages/nestjs-auth-jwt/src/auth-jwt.module-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ function definitionTransform(
definition: DynamicModule,
extras: AuthJwtOptionsExtrasInterface,
): DynamicModule {
const { providers = [] } = definition;
const { global = false } = extras;
const { providers } = definition;
const { global } = extras;

return {
...definition,
Expand Down
24 changes: 24 additions & 0 deletions packages/nestjs-auth-jwt/src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
AuthJwtModule,
AuthJwtStrategy,
AuthJwtGuard,
JwtAuthGuard,
} from './index';

describe('Index', () => {
it('AuthJwtModule should be imported', () => {
expect(AuthJwtModule).toBeInstanceOf(Function);
});

it('AuthJwtStrategy should be imported', () => {
expect(AuthJwtStrategy).toBeInstanceOf(Function);
});

it('AuthJwtGuard should be imported', () => {
expect(AuthJwtGuard).toBeInstanceOf(Function);
});

it('JwtAuthGuard should be imported', () => {
expect(JwtAuthGuard).toBeInstanceOf(Function);
});
});
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { ReferenceIdInterface } from '@concepta/ts-core';
import { AuthLocalCredentialsInterface } from '../../interfaces/auth-local-credentials.interface';

export class UserFixture
implements ReferenceIdInterface, AuthLocalCredentialsInterface
{
id!: string;

username!: string;

active!: boolean;

password!: string;

passwordHash!: string | null;

passwordSalt!: string | null;
}
235 changes: 235 additions & 0 deletions packages/nestjs-auth-local/src/auth-local.module-definition.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
import { IssueTokenService } from '@concepta/nestjs-authentication';
import { PasswordValidationService } from '@concepta/nestjs-password';
import { FactoryProvider } from '@nestjs/common';
import { mock } from 'jest-mock-extended';
import { UserLookupServiceFixture } from './__fixtures__/user/user-lookup.service.fixture';
import {
AUTH_LOCAL_MODULE_ISSUE_TOKEN_SERVICE_TOKEN,
AUTH_LOCAL_MODULE_PASSWORD_VALIDATION_SERVICE_TOKEN,
AUTH_LOCAL_MODULE_SETTINGS_TOKEN,
AUTH_LOCAL_MODULE_USER_LOOKUP_SERVICE_TOKEN,
AUTH_LOCAL_MODULE_VALIDATE_USER_SERVICE_TOKEN,
} from './auth-local.constants';
import { AuthLocalController } from './auth-local.controller';
import {
createAuthLocalControllers,
createAuthLocalExports,
createAuthLocalIssueTokenServiceProvider,
createAuthLocalPasswordValidationServiceProvider,
createAuthLocalUserLookupServiceProvider,
createAuthLocalValidateUserServiceProvider,
} from './auth-local.module-definition';
import { AuthLocalValidateUserService } from './services/auth-local-validate-user.service';
import { JwtIssueService } from '@concepta/nestjs-jwt';

describe('Auth-local.module-definition', () => {
describe(createAuthLocalExports.name, () => {
it('should return an array with the expected tokens', () => {
const result = createAuthLocalExports();
expect(result).toEqual([
AUTH_LOCAL_MODULE_SETTINGS_TOKEN,
AUTH_LOCAL_MODULE_USER_LOOKUP_SERVICE_TOKEN,
AUTH_LOCAL_MODULE_ISSUE_TOKEN_SERVICE_TOKEN,
AUTH_LOCAL_MODULE_VALIDATE_USER_SERVICE_TOKEN,
AUTH_LOCAL_MODULE_PASSWORD_VALIDATION_SERVICE_TOKEN,
]);
});
});

describe(createAuthLocalControllers.name, () => {
it('should return a default AuthLocalController', () => {
const result = createAuthLocalControllers();
expect(result).toEqual([AuthLocalController]);
});

it('should return a default AuthLocalController', () => {
const result = createAuthLocalControllers({});
expect(result).toEqual([AuthLocalController]);
});

it('should return a default AuthLocalController', () => {
const result = createAuthLocalControllers({ controllers: undefined });
expect(result).toEqual([AuthLocalController]);
});

it('should return the provided controllers', () => {
const customController = class CustomController {};
const result = createAuthLocalControllers({
controllers: [customController],
});
expect(result).toEqual([customController]);
});

it('should return an empty array if the controllers option is an empty array', () => {
const result = createAuthLocalControllers({ controllers: [] });
expect(result).toEqual([]);
});

it('should return an array with AuthLocalController if the controllers option includes AuthLocalController', () => {
const result = createAuthLocalControllers({
controllers: [AuthLocalController],
});
expect(result).toEqual([AuthLocalController]);
});

it('should return an array with AuthLocalController and the provided controllers if the controllers option includes AuthLocalController and other controllers', () => {
const customController = class CustomController {};
const result = createAuthLocalControllers({
controllers: [AuthLocalController, customController],
});
expect(result).toEqual([AuthLocalController, customController]);
});
});

describe(createAuthLocalValidateUserServiceProvider.name, () => {
class TestUserLookupService extends UserLookupServiceFixture {}
class TestPasswordValidationService extends PasswordValidationService {}
class TestAuthLocalValidateUserService extends AuthLocalValidateUserService {}

const testUserLookupService = mock<TestUserLookupService>();
const testPasswordValidationService = mock<TestPasswordValidationService>();
const testAuthLocalValidateUserService =
new TestAuthLocalValidateUserService(
testUserLookupService,
testPasswordValidationService,
);

it('should return a default validateUserService', async () => {
const provider =
createAuthLocalValidateUserServiceProvider() as FactoryProvider;

const useFactoryResult = await provider.useFactory({});

expect(useFactoryResult).toBeInstanceOf(AuthLocalValidateUserService);
});

it('should return a validateUserService from initialization', async () => {
const provider =
createAuthLocalValidateUserServiceProvider() as FactoryProvider;

const useFactoryResult = await provider.useFactory({
validateUserService: testAuthLocalValidateUserService,
});

expect(useFactoryResult).toBeInstanceOf(TestAuthLocalValidateUserService);
});

it('should return a override validateUserService', async () => {
const provider = createAuthLocalValidateUserServiceProvider({
validateUserService: testAuthLocalValidateUserService,
}) as FactoryProvider;

const useFactoryResult = await provider.useFactory({});

expect(useFactoryResult).toBeInstanceOf(TestAuthLocalValidateUserService);
});
});

describe(createAuthLocalIssueTokenServiceProvider.name, () => {
class TestIssueTokenService extends IssueTokenService {}

const jwtIssuer = mock<JwtIssueService>();
const testIssueTokenService = new TestIssueTokenService(jwtIssuer);

it('should return an issueTokenService', async () => {
const provider =
createAuthLocalIssueTokenServiceProvider() as FactoryProvider;

const useFactoryResult = await provider.useFactory(
{},
testIssueTokenService,
);

expect(useFactoryResult).toBeInstanceOf(TestIssueTokenService);
});

it('should return an issueTokenService from initialization', async () => {
const provider =
createAuthLocalIssueTokenServiceProvider() as FactoryProvider;

const useFactoryResult = await provider.useFactory({
issueTokenService: testIssueTokenService,
});

expect(useFactoryResult).toBeInstanceOf(TestIssueTokenService);
});

it('should return an overridden issueTokenService', async () => {
const provider = createAuthLocalIssueTokenServiceProvider({
issueTokenService: testIssueTokenService,
}) as FactoryProvider;

const useFactoryResult = await provider.useFactory({});

expect(useFactoryResult).toBeInstanceOf(TestIssueTokenService);
});
});

describe(createAuthLocalUserLookupServiceProvider.name, () => {
class LookupService extends UserLookupServiceFixture {}
class OverrideLookupService extends UserLookupServiceFixture {}

it('should return a default userLookupService', async () => {
const provider: FactoryProvider =
createAuthLocalUserLookupServiceProvider({
userLookupService: new OverrideLookupService(),
}) as FactoryProvider;

// useFactory is for when class was initially defined
const useFactoryResult = await provider.useFactory({
userLookupService: new LookupService(),
});
expect(useFactoryResult).toBeInstanceOf(OverrideLookupService);
});

it('should return a userLookupService from initialization', async () => {
const provider: FactoryProvider =
createAuthLocalUserLookupServiceProvider() as FactoryProvider;

// useFactory is for when class was initially defined
const useFactoryResult = await provider.useFactory({
userLookupService: new LookupService(),
});
expect(useFactoryResult).toBeInstanceOf(LookupService);
});
});

describe(createAuthLocalPasswordValidationServiceProvider.name, () => {
class TestPasswordValidationService extends PasswordValidationService {}

const testPasswordValidationService = new TestPasswordValidationService();

it('should return an issueTokenService', async () => {
const provider =
createAuthLocalPasswordValidationServiceProvider() as FactoryProvider;

const useFactoryResult = await provider.useFactory(
{},
testPasswordValidationService,
);

expect(useFactoryResult).toBeInstanceOf(TestPasswordValidationService);
});

it('should return an issueTokenService from initialization', async () => {
const provider =
createAuthLocalPasswordValidationServiceProvider() as FactoryProvider;

const useFactoryResult = await provider.useFactory({
passwordValidationService: testPasswordValidationService,
});

expect(useFactoryResult).toBeInstanceOf(TestPasswordValidationService);
});

it('should return an overridden issueTokenService', async () => {
const provider = createAuthLocalPasswordValidationServiceProvider({
passwordValidationService: testPasswordValidationService,
}) as FactoryProvider;

const useFactoryResult = await provider.useFactory({});

expect(useFactoryResult).toBeInstanceOf(TestPasswordValidationService);
});
});
});
20 changes: 10 additions & 10 deletions packages/nestjs-auth-local/src/auth-local.module-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ function definitionTransform(
definition: DynamicModule,
extras: AuthLocalOptionsExtrasInterface,
): DynamicModule {
const { providers = [] } = definition;
const { controllers, global = false } = extras;
const { providers } = definition;
const { controllers, global } = extras;

return {
...definition,
Expand Down Expand Up @@ -104,7 +104,7 @@ export function createAuthLocalProviders(options: {
}

export function createAuthLocalControllers(
overrides: Pick<AuthLocalOptions, 'controllers'> = {},
overrides?: Pick<AuthLocalOptions, 'controllers'>,
): DynamicModule['controllers'] {
return overrides?.controllers !== undefined
? overrides.controllers
Expand All @@ -126,7 +126,7 @@ export function createAuthLocalOptionsProvider(
}

export function createAuthLocalValidateUserServiceProvider(
optionsOverrides?: AuthLocalOptions,
optionsOverrides?: Pick<AuthLocalOptions, 'validateUserService'>,
): Provider {
return {
provide: AUTH_LOCAL_MODULE_VALIDATE_USER_SERVICE_TOKEN,
Expand All @@ -136,7 +136,7 @@ export function createAuthLocalValidateUserServiceProvider(
AUTH_LOCAL_MODULE_PASSWORD_VALIDATION_SERVICE_TOKEN,
],
useFactory: async (
options: AuthLocalOptionsInterface,
options: Pick<AuthLocalOptions, 'validateUserService'>,
userLookupService: AuthLocalUserLookupServiceInterface,
passwordValidationService: PasswordValidationServiceInterface,
) =>
Expand All @@ -150,13 +150,13 @@ export function createAuthLocalValidateUserServiceProvider(
}

export function createAuthLocalIssueTokenServiceProvider(
optionsOverrides?: AuthLocalOptions,
optionsOverrides?: Pick<AuthLocalOptions, 'issueTokenService'>,
): Provider {
return {
provide: AUTH_LOCAL_MODULE_ISSUE_TOKEN_SERVICE_TOKEN,
inject: [RAW_OPTIONS_TOKEN, IssueTokenService],
useFactory: async (
options: AuthLocalOptionsInterface,
options: Pick<AuthLocalOptions, 'issueTokenService'>,
defaultService: IssueTokenServiceInterface,
) =>
optionsOverrides?.issueTokenService ??
Expand All @@ -166,13 +166,13 @@ export function createAuthLocalIssueTokenServiceProvider(
}

export function createAuthLocalPasswordValidationServiceProvider(
optionsOverrides?: AuthLocalOptions,
optionsOverrides?: Pick<AuthLocalOptions, 'passwordValidationService'>,
): Provider {
return {
provide: AUTH_LOCAL_MODULE_PASSWORD_VALIDATION_SERVICE_TOKEN,
inject: [RAW_OPTIONS_TOKEN, PasswordValidationService],
useFactory: async (
options: AuthLocalOptionsInterface,
options: Pick<AuthLocalOptions, 'passwordValidationService'>,
defaultService: PasswordValidationServiceInterface,
) =>
optionsOverrides?.passwordValidationService ??
Expand All @@ -182,7 +182,7 @@ export function createAuthLocalPasswordValidationServiceProvider(
}

export function createAuthLocalUserLookupServiceProvider(
optionsOverrides?: AuthLocalOptions,
optionsOverrides?: Pick<AuthLocalOptions, 'userLookupService'>,
): Provider {
return {
provide: AUTH_LOCAL_MODULE_USER_LOOKUP_SERVICE_TOKEN,
Expand Down
Loading

0 comments on commit b44e3cc

Please sign in to comment.