Skip to content

Commit

Permalink
Dockerize (#601)
Browse files Browse the repository at this point in the history
* chore: moves to eslint and starts dockerization

* fix(websocket): fix jest not exiting properly

Because I was using `io.connect()` without a properport, socketIo was not properly disconnecting
after the test. Now that I am useing `io.connect(await app.getUrl())` everything works just fine

fix #14

* ci: starts dockerizing the e2e testing process

I'm tired of seeing CRON failures so I'm also adding in the necessary service to the cron.yml for
the moment. I'll get it all fixed in the future

* test(typeorm): fixes up typeorm e2e tests with docker-compose

* feat: removes typeorm-graphql-sample

The TypeOrm-GraphQL-Sample project is removed as there is no need for two sample projects to use
TypeORM. The point of the repository is to show how testing can be done with NestJS. As there is a
fully working typeorm-sample project and a graphql-sample project, there is no need to combine the
two.

BREAKING CHANGE: removal of the typeorm-graphql-sample

* feat(e2e): adds docker-compose for e2e tests

There's still some bugs with how the microservices tests were implemented, I'll need to spend more
time on that, but now the TypeORM test has an actual database to query and use. Mongo is next, but I
want to get rid of the failing CRON test for now.

* fix: fixes microservice tests
  • Loading branch information
jmcdo29 committed May 25, 2020
1 parent e4b8820 commit fa73e57
Show file tree
Hide file tree
Showing 84 changed files with 3,419 additions and 3,821 deletions.
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
node_modules/
.git/
dist/
coverage/
.vscode/
.github/
docker-compose*
LICENSE
*.md
.sonarcloud*
.editorconfig
commitlint*
*.gql
38 changes: 38 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
],
plugins: ['@typescript-eslint'],
parserOptions: {
source: 'module',
ecmaVersion: 2018,
},
root: true,
env: {
node: true,
jest: true,
},
rules: {
'no-control-regex': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'no-dupe-class-members': 'off',
'sort-imports': [
'error',
{ ignoreDeclarationSort: true, ignoreCase: true },
],
'prettier/prettier': 'warn',
},
ignorePatterns: ['*.d.ts', 'dist/*', '**/node_modules/*', 'lib/*', '*.js'],
globals: {
WeakSet: 'readonly',
Promise: 'readonly',
Reflect: 'readonly',
Symbol: 'readonly',
},
};
27 changes: 23 additions & 4 deletions .github/workflows/cron.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ jobs:
complex-sample,
mongo-sample,
typeorm-sample,
typeorm-graphql-sample,
websocket-sample,
rxjs-sample,
render-sample,
/graphql-sample,
graphql-sample,
microservice-sample,
]

Expand All @@ -35,5 +34,25 @@ jobs:
run: npm ci
- name: npm test
run: npm run test:cov -- ${{ matrix.app-name }}
env:
CI: true

e2e:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [10.x, 12.x]

steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Start Docker-Compose
run: docker-compose up -d
- name: npm install
run: npm ci
- name: Run tests
run: ./scripts/full-e2e
- name: Stop Docker-Compose
run: docker-compose down
16 changes: 0 additions & 16 deletions .github/workflows/e2e.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/microservice.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ jobs:
env:
CI: true
- name: npm test:e2e
run: npm run test:cov -- --config ./apps/microservice-sample/jest-e2e.json --runInBand
run: npm run test:cov -- --config ./apps/microservice-sample/test/jest-e2e.json --runInBand
env:
CI: true
28 changes: 0 additions & 28 deletions .github/workflows/typeorm-graphql.yml

This file was deleted.

22 changes: 0 additions & 22 deletions .github/workflows/typeorm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,6 @@ jobs:
matrix:
node-version: [10.x, 12.x]

services:
postgres:
image: postgres
env:
POSTGRES_USER: rm
POSTGRES_PASSWORD: root
POSTGRES_DB: cat_test_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
Expand All @@ -38,10 +23,3 @@ jobs:
run: npm ci
- name: npm test
run: npm run test:cov -- typeorm-sample
env:
CI: true
POSTGRES_USER: rm
POSTGRES_PASSWORD: root
POSTGRES_DB: cat_test_db
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
Empty file removed .sonarcloud.properties
Empty file.
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM node:12 as BASE
WORKDIR /app
COPY package*.json \
nest-cli.json \
tsconfig*.json \
./
RUN npm i
# allow ability to pass in an arg for build time changes
ARG APP_NAME="complex-sample"
COPY apps/$APP_NAME/ ./apps/$APP_NAME/
# assign passed are to env for runtime effects
ENV APP_NAME ${APP_NAME}
# use env var at runtime
CMD ["npm", "run", "test", "--", "--config", "apps/$APP_NAME/test/jest-e2e.json"]
16 changes: 7 additions & 9 deletions apps/complex-sample/src/cat/cat.pipe.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { CatPipe } from './cat.pipe';
import { CatDTO } from './dto/cats.dto';
import { BadRequestException } from '@nestjs/common';

const metadata = {} as any;
const testBreed = 'Test Breed';
const badRequest = 'Bad Request';
const failString = 'should throw an error for incorrect type';

describe('CatPipe', () => {
Expand All @@ -19,7 +17,7 @@ describe('CatPipe', () => {
describe('successful calls', () => {
it('should let the cat DTO go on through', () => {
const catDTO = { name: 'Test Name', breed: testBreed, age: 4 };
expect(pipe.transform(catDTO, metadata)).toEqual(catDTO);
expect(pipe.transform(catDTO)).toEqual(catDTO);
});
});
/**
Expand All @@ -35,15 +33,15 @@ describe('CatPipe', () => {
breed: testBreed,
} as any;
it('should throw an error for missing age', () => {
const errorPipe = () => pipe.transform(badAgeCat as any, metadata);
const errorPipe = () => pipe.transform(badAgeCat as any);
expect(errorPipe).toThrowError(BadRequestException);
expect(errorPipe).toThrowError(
'Incoming cat is not formatted correctly. Age must be a number.',
);
});
it(failString, () => {
badAgeCat.age = '5' as any;
const errorPipe = () => pipe.transform(badAgeCat, metadata);
const errorPipe = () => pipe.transform(badAgeCat);
expect(errorPipe).toThrowError(BadRequestException);
expect(errorPipe).toThrowError(
'Incoming cat is not formatted correctly. Age must be a number.',
Expand All @@ -56,15 +54,15 @@ describe('CatPipe', () => {
breed: testBreed,
} as any;
it('should throw an error for missing name', () => {
const errorPipe = () => pipe.transform(badNameCat as any, metadata);
const errorPipe = () => pipe.transform(badNameCat as any);
expect(errorPipe).toThrowError(BadRequestException);
expect(errorPipe).toThrowError(
'Incoming cat is not formatted correctly. Name must be a string.',
);
});
it(failString, () => {
badNameCat.name = true as any;
const errorPipe = () => pipe.transform(badNameCat, metadata);
const errorPipe = () => pipe.transform(badNameCat);
expect(errorPipe).toThrowError(BadRequestException);
expect(errorPipe).toThrowError(
'Incoming cat is not formatted correctly. Name must be a string.',
Expand All @@ -77,15 +75,15 @@ describe('CatPipe', () => {
name: 'Test Name',
} as any;
it('should throw an error for missing breed', () => {
const errorPipe = () => pipe.transform(badBreedCat as any, metadata);
const errorPipe = () => pipe.transform(badBreedCat as any);
expect(errorPipe).toThrowError(BadRequestException);
expect(errorPipe).toThrowError(
'Incoming cat is not formatted correctly. Breed must be a string.',
);
});
it(failString, () => {
badBreedCat.breed = true as any;
const errorPipe = () => pipe.transform(badBreedCat, metadata);
const errorPipe = () => pipe.transform(badBreedCat);
expect(errorPipe).toThrowError(BadRequestException);
expect(errorPipe).toThrowError(
'Incoming cat is not formatted correctly. Breed must be a string.',
Expand Down
9 changes: 2 additions & 7 deletions apps/complex-sample/src/cat/cat.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import {
ArgumentMetadata,
BadRequestException,
Injectable,
PipeTransform,
} from '@nestjs/common';
import { BadRequestException, Injectable, PipeTransform } from '@nestjs/common';
import { CatDTO } from './dto/cats.dto';

@Injectable()
export class CatPipe implements PipeTransform<CatDTO, CatDTO> {
private errorString = 'Incoming cat is not formatted correctly. ';

transform(value: CatDTO, metadata: ArgumentMetadata) {
transform(value: CatDTO): CatDTO {
if (!value.age || typeof value.age !== 'number') {
throw new BadRequestException(this.errorString + 'Age must be a number.');
}
Expand Down
10 changes: 3 additions & 7 deletions apps/complex-sample/src/parse-int.pipe.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,14 @@ describe('ParseIntPipe', () => {
for (let i = 0; i < 10; i++) {
it('should return a random number (just for the sake of being thorough)', () => {
const randomNumber = Math.floor(Math.random() * 1000) % 1000;
expect(pipe.transform(randomNumber.toString(), {} as any)).toBe(
randomNumber,
);
expect(pipe.transform(randomNumber.toString())).toBe(randomNumber);
});
}
});
describe('unsuccessful calls', () => {
it('should throw an error if given a non-number string', () => {
expect(() => pipe.transform('true', {} as any)).toThrowError(
BadRequestException,
);
expect(() => pipe.transform('true', {} as any)).toThrowError(
expect(() => pipe.transform('true')).toThrowError(BadRequestException);
expect(() => pipe.transform('true')).toThrowError(
'Id parameter should be a number.',
);
});
Expand Down
9 changes: 2 additions & 7 deletions apps/complex-sample/src/parse-int.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import {
ArgumentMetadata,
BadRequestException,
Injectable,
PipeTransform,
} from '@nestjs/common';
import { BadRequestException, Injectable, PipeTransform } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform {
transform(value: string, metadata: ArgumentMetadata) {
transform(value: string): number {
if (!/^\d+$/.test(value)) {
throw new BadRequestException('Id parameter should be a number.');
}
Expand Down
Loading

0 comments on commit fa73e57

Please sign in to comment.