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

chore: improve test coverage #154

Closed
wants to merge 2 commits into from
Closed
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
14 changes: 5 additions & 9 deletions jest.config.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
{
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"moduleFileExtensions": ["js", "json", "ts"],
"globals": {
"ts-jest": {
"tsconfig": "tsconfig.jest.json"
Expand All @@ -18,10 +14,7 @@
}
},
"testRegex": ".*\\.spec\\.ts$",
"testPathIgnorePatterns": [
"/node_modules/",
"/dist/"
],
"testPathIgnorePatterns": ["/node_modules/", "/dist/"],
"transform": {
"^.+\\.ts$": "ts-jest"
},
Expand All @@ -30,6 +23,9 @@
"!packages/**/*.d.ts",
"!packages/**/*.interface.ts",
"!packages/**/*.e2e-spec.ts",
"!packages/**/*.factory.ts",
"!packages/**/*.seeder.ts",
"!packages/**/*.seeding.ts",
"!packages/nestjs-samples/src/**/main.ts",
"!**/node_modules/**",
"!**/__mocks__/**",
Expand Down
25 changes: 25 additions & 0 deletions packages/nestjs-auth-jwt/src/auth-jwt.module-definition.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { FactoryProvider } from '@nestjs/common';
import {
AuthJwtOptions,
createAuthJwtAppGuardProvider,
} from './auth-jwt.module-definition';
import { AuthJwtGuard } from './auth-jwt.guard';
import { mock } from 'jest-mock-extended';

describe(createAuthJwtAppGuardProvider.name, () => {
const guard = mock<AuthJwtGuard>();

it('should return null if appGuard is explicitly false', async () => {
const options: Pick<AuthJwtOptions, 'appGuard'> = { appGuard: false };
const provider = createAuthJwtAppGuardProvider(options) as FactoryProvider;
const result = await provider.useFactory(options, guard);
expect(result).toBeNull();
});

it('should return appGuard if set, or fall back to default', async () => {
const options = { appGuard: guard };
const provider = createAuthJwtAppGuardProvider(options) as FactoryProvider;
const result = await provider.useFactory(options, guard);
expect(result).toBe(options.appGuard);
});
});
12 changes: 6 additions & 6 deletions packages/nestjs-auth-jwt/src/auth-jwt.module-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,13 @@ export function createAuthJwtOptionsProvider(
}

export function createAuthJwtVerifyTokenServiceProvider(
optionsOverrides?: AuthJwtOptions,
optionsOverrides?: Pick<AuthJwtOptions, 'verifyTokenService'>,
): Provider {
return {
provide: AUTH_JWT_MODULE_VERIFY_TOKEN_SERVICE_TOKEN,
inject: [RAW_OPTIONS_TOKEN, VerifyTokenService],
useFactory: async (
options: AuthJwtOptionsInterface,
options: Pick<AuthJwtOptions, 'verifyTokenService'>,
defaultService: VerifyTokenServiceInterface,
) =>
optionsOverrides?.verifyTokenService ??
Expand All @@ -123,24 +123,24 @@ export function createAuthJwtVerifyTokenServiceProvider(
}

export function createAuthJwtUserLookupServiceProvider(
optionsOverrides?: AuthJwtOptions,
optionsOverrides?: Pick<AuthJwtOptions, 'userLookupService'>,
): Provider {
return {
provide: AUTH_JWT_MODULE_USER_LOOKUP_SERVICE_TOKEN,
inject: [RAW_OPTIONS_TOKEN],
useFactory: async (options: AuthJwtOptionsInterface) =>
useFactory: async (options: Pick<AuthJwtOptions, 'userLookupService'>) =>
optionsOverrides?.userLookupService ?? options.userLookupService,
};
}

export function createAuthJwtAppGuardProvider(
optionsOverrides?: AuthJwtOptions,
optionsOverrides?: Pick<AuthJwtOptions, 'appGuard'>,
): Provider {
return {
provide: APP_GUARD,
inject: [RAW_OPTIONS_TOKEN, AuthJwtGuard],
useFactory: async (
options: AuthJwtOptionsInterface,
options: Pick<AuthJwtOptions, 'appGuard'>,
defaultGuard: AuthJwtGuard,
) => {
// get app guard from the options
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as common from '@nestjs/common';
import { SetMetadata } from '@nestjs/common';
import { AUTHENTICATION_MODULE_DISABLE_GUARDS_TOKEN } from '../authentication.constants';
import { AuthPublic } from './auth-public.decorator';

Expand All @@ -12,7 +12,7 @@ describe(AuthPublic.name, () => {
it('should set metadata to disable guards', () => {
AuthPublic();
// Assert that SetMetadata was called with specific arguments
expect(common.SetMetadata).toHaveBeenCalledWith(
expect(SetMetadata).toHaveBeenCalledWith(
AUTHENTICATION_MODULE_DISABLE_GUARDS_TOKEN,
true,
);
Expand Down
27 changes: 27 additions & 0 deletions packages/nestjs-authentication/src/guards/auth.guard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,31 @@ describe(AuthGuard.name, () => {
const guardInstance = new Guard(mockSettings, reflector);
expect(guardInstance.canActivate(mockContext)).toBeTruthy();
});

it('should respect enable guard and disabled from reflector callback', () => {
const mockContext = {
getHandler: jest.fn(),
getClass: jest.fn(),
} as unknown as ExecutionContext;

const mockSettings = { enableGuards: true };
jest.spyOn(reflector, 'getAllAndOverride').mockReturnValue(true);
const Guard = AuthGuard('local', { canDisable: true });
const guardInstance = new Guard(mockSettings, reflector);
expect(guardInstance.canActivate(mockContext)).toBeTruthy();
});

it('should respect disableGuard callback', () => {
const mockContext = {
getHandler: jest.fn(),
getClass: jest.fn(),
} as unknown as ExecutionContext;

const mockSettings = { enableGuards: true, disableGuard: () => true };
jest.spyOn(reflector, 'getAllAndOverride').mockReturnValue(false);
const Guard = AuthGuard('local', { canDisable: true });
const guardInstance = new Guard(mockSettings, reflector);
expect(guardInstance.canActivate(mockContext)).toBeTruthy();
});

});
35 changes: 35 additions & 0 deletions packages/nestjs-authentication/src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
AuthUser,
AuthPublic,
AuthenticationJwtResponseDto,
IssueTokenService,
VerifyTokenService,
ValidateUserService,
} from './index';

describe('Authentication Module Exports', () => {
it('AuthUser should be a function', () => {
expect(AuthUser).toBeInstanceOf(Function);
});

it('AuthPublic should be a function', () => {
expect(AuthPublic).toBeInstanceOf(Function);
});

it('AuthenticationJwtResponseDto should be a function', () => {
expect(AuthenticationJwtResponseDto).toBeInstanceOf(Function);
});

it('IssueTokenService should be a class', () => {
expect(IssueTokenService).toBeInstanceOf(Function);
});

it('VerifyTokenService should be a class', () => {
expect(VerifyTokenService).toBeInstanceOf(Function);
});

it('ValidateUserService should be a class', () => {
expect(ValidateUserService).toBeInstanceOf(Function);
});
});

54 changes: 54 additions & 0 deletions packages/nestjs-cache/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Rockets NestJS Cache

Check notice on line 1 in packages/nestjs-cache/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

packages/nestjs-cache/README.md#L1

Expected: [None]; Actual: # Rockets NestJS Cache

A module for managing a basic Cache entity, including controller with full CRUD, DTOs, sample data factory and seeder.

Check notice on line 3 in packages/nestjs-cache/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

packages/nestjs-cache/README.md#L3

Expected: 80; Actual: 118

## Project

[![NPM Latest](https://img.shields.io/npm/v/@concepta/nestjs-user)](https://www.npmjs.com/package/@concepta/nestjs-user)
[![NPM Downloads](https://img.shields.io/npm/dw/@conceptadev/nestjs-user)](https://www.npmjs.com/package/@concepta/nestjs-user)
[![GH Last Commit](https://img.shields.io/github/last-commit/conceptadev/rockets?logo=github)](https://github.com/conceptadev/rockets)
[![GH Contrib](https://img.shields.io/github/contributors/conceptadev/rockets?logo=github)](https://github.com/conceptadev/rockets/graphs/contributors)
[![NestJS Dep](https://img.shields.io/github/package-json/dependency-version/conceptadev/rockets/@nestjs/common?label=NestJS&logo=nestjs&filename=packages%2Fnestjs-core%2Fpackage.json)](https://www.npmjs.com/package/@nestjs/common)

## Installation

`yarn add @concepta/nestjs-cache`

## Usage

```ts
// ...
import { TypeOrmExtModule } from '@concepta/nestjs-typeorm-ext';
import { CacheModule } from '@concepta/nestjs-user';
import { CrudModule } from '@concepta/nestjs-crud';

@Module({
imports: [
TypeOrmExtModule.forRoot({
type: 'postgres',
url: 'postgres://user:pass@localhost:5432/postgres',
}),
CrudModule.forRoot({}),
CacheModule.forRoot({}),
],
})
export class AppModule {}
```

## Configuration

- [Seeding](#seeding)
- [ENV](#env)

### Seeding

Configurations specific to (optional) database seeding.

#### ENV

Configurations available via environment.

| Variable | Type | Default | |

Check notice on line 51 in packages/nestjs-cache/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

packages/nestjs-cache/README.md#L51

Expected: 80; Actual: 92
| -------------------------- | ---------- | ------- | ------------------------------------ |

Check notice on line 52 in packages/nestjs-cache/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

packages/nestjs-cache/README.md#L52

Expected: 80; Actual: 92
| `CACHE_MODULE_SEEDER_AMOUNT` | `<number>` | `50` | number of additional users to create |

Check notice on line 53 in packages/nestjs-cache/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

packages/nestjs-cache/README.md#L53

Expected: 80; Actual: 94
| `CACHE_EXPIRE_IN` | `<string>` | `1d` | string for the amount of time to expire the cache |

Check notice on line 54 in packages/nestjs-cache/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

packages/nestjs-cache/README.md#L54

Expected: 80; Actual: 96
43 changes: 43 additions & 0 deletions packages/nestjs-cache/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "@concepta/nestjs-cache",
"version": "4.0.0-alpha.42",
"description": "Rockets NestJS User",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "BSD-3-Clause",
"publishConfig": {
"access": "public"
},
"files": [
"dist/**/!(*.spec|*.e2e-spec|*.fixture).{js,d.ts}"
],
"dependencies": {
"@concepta/nestjs-access-control": "^4.0.0-alpha.42",
"@concepta/nestjs-common": "^4.0.0-alpha.42",
"@concepta/nestjs-core": "^4.0.0-alpha.42",
"@concepta/nestjs-crud": "^4.0.0-alpha.42",
"@concepta/nestjs-typeorm-ext": "^4.0.0-alpha.42",
"@concepta/ts-common": "^4.0.0-alpha.42",
"@concepta/ts-core": "^4.0.0-alpha.42",
"@concepta/typeorm-common": "^4.0.0-alpha.42",
"@nestjs/common": "^9.0.0",
"@nestjs/config": "^2.2.0",
"@nestjs/swagger": "^6.0.0",
"ms": "^2.1.3"
},
"devDependencies": {
"@concepta/typeorm-seeding": "^4.0.0-beta.0",
"@faker-js/faker": "^6.0.0-alpha.6",
"@nestjs/testing": "^9.0.0",
"@nestjs/typeorm": "^9.0.0",
"@types/ms": "^0.7.31",
"@types/supertest": "^2.0.11",
"jest-mock-extended": "^2.0.4",
"supertest": "^6.1.3"
},
"peerDependencies": {
"class-transformer": "*",
"class-validator": "*",
"typeorm": "^0.3.0"
}
}
33 changes: 33 additions & 0 deletions packages/nestjs-cache/src/__fixtures__/app.module.fixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { TypeOrmExtModule } from '@concepta/nestjs-typeorm-ext';
import { Module } from '@nestjs/common';

import { CacheModule } from '../cache.module';
import { UserEntityFixture } from './entities/user-entity.fixture';
import { UserCacheEntityFixture } from './entities/user-cache-entity.fixture';
import { CrudModule } from '@concepta/nestjs-crud';

@Module({
imports: [
TypeOrmExtModule.forRoot({
type: 'sqlite',
database: ':memory:',
synchronize: true,
entities: [UserEntityFixture, UserCacheEntityFixture],
}),
CacheModule.register({
settings: {
assignments: {
user: { entityKey: 'userCache' },
},
},
entities: {
userCache: {
entity: UserCacheEntityFixture,
},
},
}),
CrudModule.forRoot({}),
],
})
export class AppModuleFixture { }

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Entity, ManyToOne } from 'typeorm';
import { ReferenceIdInterface } from '@concepta/ts-core';
import { UserEntityFixture } from './user-entity.fixture';
import { CacheSqliteEntity } from '../../entities/cache-sqlite.entity';

/**
* Cache Entity Fixture
*/
@Entity()
export class UserCacheEntityFixture extends CacheSqliteEntity {
@ManyToOne(() => UserEntityFixture, (user) => user.userCaches)
assignee!: ReferenceIdInterface;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { ReferenceIdInterface } from '@concepta/ts-core';
import { UserCacheEntityFixture } from './user-cache-entity.fixture';

/**
* User Entity Fixture
*/
@Entity()
export class UserEntityFixture implements ReferenceIdInterface {
@PrimaryGeneratedColumn('uuid')
id!: string;

@Column({ default: false })
isActive!: boolean;

@OneToMany(() => UserCacheEntityFixture, (userCache) => userCache.assignee)
userCaches!: UserCacheEntityFixture[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

import { Factory } from '@concepta/typeorm-seeding';
import { UserCacheEntityFixture } from '../entities/user-cache-entity.fixture';
import Faker from '@faker-js/faker';

export class UserCacheFactoryFixture extends Factory<UserCacheEntityFixture> {
protected options = {
entity: UserCacheEntityFixture,
};

protected async entity(
userCache: UserCacheEntityFixture,
): Promise<UserCacheEntityFixture> {
userCache.key = Faker.name.jobArea();
userCache.type = 'filter';
userCache.data = JSON.stringify({ sortBy: 'name' });
userCache.expirationDate = new Date();

return userCache;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Factory } from '@concepta/typeorm-seeding';
import { UserEntityFixture } from '../entities/user-entity.fixture';

export class UserFactoryFixture extends Factory<UserEntityFixture> {
options = {
entity: UserEntityFixture,
};
}
8 changes: 8 additions & 0 deletions packages/nestjs-cache/src/cache.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const CACHE_MODULE_SETTINGS_TOKEN = 'CACHE_MODULE_SETTINGS_TOKEN';
export const CACHE_MODULE_REPOSITORIES_TOKEN =
'CACHE_MODULE_REPOSITORIES_TOKEN';
export const CACHE_MODULE_CRUD_SERVICES_TOKEN =
'CACHE_MODULE_CRUD_SERVICES_TOKEN';
export const CACHE_MODULE_DEFAULT_SETTINGS_TOKEN =
'CACHE_MODULE_DEFAULT_SETTINGS_TOKEN';
export const CACHE_MODULE_CACHE_ENTITY_KEY = 'cache';
Loading
Loading