commit
cfa9c9b224
24 changed files with 8079 additions and 0 deletions
-
161.circleci/config.yml
-
24.eslintrc.js
-
37.gitignore
-
4.prettierrc
-
10Dockerfile
-
62README.md
-
6compodoc.server.json
-
9dev/pg.yml
-
7example.env
-
4nest-cli.json
-
79package.json
-
22src/app.controller.spec.ts
-
12src/app.controller.ts
-
28src/app.module.ts
-
8src/app.service.ts
-
9src/config/config.module.ts
-
102src/config/config.service.spec.ts
-
68src/config/config.service.ts
-
12src/main.ts
-
28test/app.e2e-spec.ts
-
9test/jest-e2e.json
-
4tsconfig.build.json
-
16tsconfig.json
-
7358yarn.lock
@ -0,0 +1,161 @@ |
|||
version: 2 |
|||
jobs: |
|||
build: &shared-config |
|||
docker: |
|||
- image: circleci/node:lts-fermium |
|||
working_directory: ~/repo |
|||
steps: |
|||
- checkout |
|||
- restore_cache: |
|||
keys: |
|||
- dependencies-{{ checksum "package.json" }}-v1 |
|||
# fallback to using the latest cache if no exact match is found |
|||
- dependencies- |
|||
- run: yarn install |
|||
- save_cache: |
|||
paths: |
|||
- node_modules |
|||
key: dependencies-{{ checksum "package.json" }}-v1 |
|||
lint: |
|||
<<: *shared-config |
|||
steps: |
|||
- checkout |
|||
- restore_cache: |
|||
key: dependencies-{{ checksum "package.json" }}-v1 |
|||
- run: yarn lint |
|||
- run: yarn format:check |
|||
server-doc-build: |
|||
<<: *shared-config |
|||
steps: |
|||
- checkout |
|||
- restore_cache: |
|||
key: dependencies-{{ checksum "package.json" }}-v1 |
|||
- run: yarn doc:build |
|||
- run: |
|||
name: Copy deployment artifacts to workspace |
|||
command: | |
|||
cp docs/ /tmp/server-doc -r |
|||
- store_artifacts: |
|||
path: /tmp/server-doc |
|||
- persist_to_workspace: |
|||
root: /tmp |
|||
paths: |
|||
- server-doc |
|||
server-doc-deploy: |
|||
<<: *shared-config |
|||
working_directory: ~/deploy-doc-server |
|||
steps: |
|||
- attach_workspace: |
|||
at: /tmp |
|||
- run: |
|||
name: Deploy app |
|||
command: echo todo && false |
|||
back-test-unit: |
|||
<<: *shared-config |
|||
steps: |
|||
- checkout |
|||
- restore_cache: |
|||
key: dependencies-{{ checksum "package.json" }}-v1 |
|||
- run: |
|||
command: yarn test |
|||
environment: |
|||
DATABASE_URL: postgres://psqluer:psqlpassword@localhost:5432/psqluer |
|||
back-test-e2e: |
|||
docker: |
|||
- image: circleci/node:lts-fermium |
|||
- image: circleci/postgres:9.6.5 |
|||
environment: |
|||
POSTGRES_DB: psqluer |
|||
POSTGRES_USER: psqluer |
|||
POSTGRES_PASSWORD: psqlpassword |
|||
working_directory: ~/repo |
|||
steps: |
|||
- checkout |
|||
- restore_cache: |
|||
key: dependencies-{{ checksum "package.json" }}-v1 |
|||
- run: |
|||
command: yarn test:e2e |
|||
environment: |
|||
DATABASE_URL: postgres://psqluer:psqlpassword@localhost:5432/psqluer |
|||
|
|||
docker-build-and-push: |
|||
working_directory: /dockerapp |
|||
docker: |
|||
- image: docker:17.05.0-ce-git |
|||
steps: |
|||
- checkout |
|||
- setup_remote_docker |
|||
- run: |
|||
name: Build application Docker image |
|||
command: | |
|||
# docker build --cache-from=app -t app . |
|||
echo true |
|||
- deploy: |
|||
name: Publish application to docker hub |
|||
command: | |
|||
# docker login -e $DOCKER_HUB_EMAIL -u $DOCKER_HUB_USER_ID -p $DOCKER_HUB_PWD |
|||
# docker tag app $DOCKER_HUB_USER_ID/my-awesome-ci-expr:$CIRCLE_BUILD_NUM |
|||
# docker tag app $DOCKER_HUB_USER_ID/my-awesome-ci-expr:latest |
|||
# docker push $DOCKER_HUB_USER_ID/my-awesome-ci-expr:$CIRCLE_BUILD_NUM |
|||
# docker push $DOCKER_HUB_USER_ID/my-awesome-ci-expr:latest |
|||
echo true |
|||
|
|||
back-deploy-heroku: |
|||
docker: |
|||
- image: buildpack-deps:trusty |
|||
steps: |
|||
- checkout |
|||
- run: |
|||
name: Heroku Deploy |
|||
command: echo todo && false |
|||
- run: |
|||
name: Smoke Test |
|||
command: echo todo && false |
|||
|
|||
workflows: |
|||
version: 2 |
|||
build-test-and-lint: |
|||
jobs: |
|||
- build |
|||
- back-test-unit: |
|||
requires: |
|||
- build |
|||
- back-test-e2e: |
|||
requires: |
|||
- build |
|||
- lint: |
|||
requires: |
|||
- build |
|||
- docker-build-and-push: |
|||
requires: |
|||
- build |
|||
- lint |
|||
- back-test-e2e |
|||
- back-test-unit |
|||
filters: |
|||
branches: |
|||
only: main |
|||
- back-deploy-heroku: |
|||
requires: |
|||
- build |
|||
- lint |
|||
- back-test-e2e |
|||
- back-test-unit |
|||
filters: |
|||
branches: |
|||
only: main |
|||
- server-doc-build: |
|||
requires: |
|||
- build |
|||
- lint |
|||
- back-test-e2e |
|||
- back-test-unit |
|||
filters: |
|||
branches: |
|||
only: main |
|||
- server-doc-deploy: |
|||
requires: |
|||
- server-doc-build |
|||
filters: |
|||
branches: |
|||
only: main |
|||
@ -0,0 +1,24 @@ |
|||
module.exports = { |
|||
parser: '@typescript-eslint/parser', |
|||
parserOptions: { |
|||
project: 'tsconfig.json', |
|||
sourceType: 'module', |
|||
}, |
|||
plugins: ['@typescript-eslint/eslint-plugin'], |
|||
extends: [ |
|||
'plugin:@typescript-eslint/recommended', |
|||
'plugin:prettier/recommended', |
|||
], |
|||
root: true, |
|||
env: { |
|||
node: true, |
|||
jest: true, |
|||
}, |
|||
ignorePatterns: ['.eslintrc.js'], |
|||
rules: { |
|||
'@typescript-eslint/interface-name-prefix': 'off', |
|||
'@typescript-eslint/explicit-function-return-type': 'off', |
|||
'@typescript-eslint/explicit-module-boundary-types': 'off', |
|||
'@typescript-eslint/no-explicit-any': 'off', |
|||
}, |
|||
}; |
|||
@ -0,0 +1,37 @@ |
|||
# compiled output |
|||
/dist |
|||
/node_modules |
|||
|
|||
# Logs |
|||
logs |
|||
*.log |
|||
npm-debug.log* |
|||
pnpm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
lerna-debug.log* |
|||
|
|||
# OS |
|||
.DS_Store |
|||
|
|||
# Tests |
|||
/coverage |
|||
/.nyc_output |
|||
|
|||
# IDEs and editors |
|||
/.idea |
|||
.project |
|||
.classpath |
|||
.c9/ |
|||
*.launch |
|||
.settings/ |
|||
*.sublime-workspace |
|||
|
|||
# IDE - VSCode |
|||
.vscode/* |
|||
!.vscode/settings.json |
|||
!.vscode/tasks.json |
|||
!.vscode/launch.json |
|||
!.vscode/extensions.json |
|||
.env |
|||
docs/ |
|||
@ -0,0 +1,4 @@ |
|||
{ |
|||
"singleQuote": true, |
|||
"trailingComma": "all" |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
FROM node:lts-fermium |
|||
|
|||
WORKDIR /nest-server |
|||
|
|||
COPY . . |
|||
|
|||
RUN yarn install |
|||
|
|||
|
|||
CMD ["yarn", "start"] |
|||
@ -0,0 +1,62 @@ |
|||
<h1 align="center">Welcome to TP on CD and CircleCI 👋</h1> |
|||
|
|||
|
|||
You can find the codelabs here on iCampus. |
|||
|
|||
## Installation |
|||
|
|||
```bash |
|||
$ yarn install |
|||
``` |
|||
|
|||
## Running the app |
|||
|
|||
```bash |
|||
# development |
|||
yarn start |
|||
|
|||
# watch mode |
|||
yarn start:dev |
|||
|
|||
# production mode |
|||
$ yarn start:prod |
|||
``` |
|||
|
|||
## Test |
|||
|
|||
```bash |
|||
# unit tests |
|||
$ yarn test |
|||
|
|||
# e2e tests |
|||
$ yarn test:e2e |
|||
``` |
|||
|
|||
## Lints |
|||
|
|||
```bash |
|||
# Check |
|||
$ yarn format:check |
|||
|
|||
# Format code |
|||
$ yarn format:check |
|||
|
|||
$ yarn lint |
|||
``` |
|||
|
|||
## Documentation |
|||
|
|||
```bash |
|||
# Run it locally |
|||
$ yarn doc |
|||
|
|||
# Build it |
|||
$ yarn doc:build |
|||
``` |
|||
|
|||
## Author |
|||
|
|||
👤 **Nicolas Beaussart <nic.beaussart@gmail.com>** |
|||
|
|||
- Twitter: [@beaussan](https://twitter.com/beaussan) |
|||
- Github: [@beaussan](https://github.com/beaussan) |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"port": 9911, |
|||
"name": "TP_CI SERVER", |
|||
"output": "docs", |
|||
"tsconfig": "./tsconfig.json" |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
version: '2' |
|||
services: |
|||
ognion-boilerplate-postgresql: |
|||
image: postgres:9.6.5 |
|||
environment: |
|||
- POSTGRES_USER=tpCi |
|||
- POSTGRES_PASSWORD=someNotSecurePassword |
|||
ports: |
|||
- 5432:5432 |
|||
@ -0,0 +1,7 @@ |
|||
## LOGGER |
|||
LOG_LEVEL=debug |
|||
LOG_SQL_REQUEST=false |
|||
PORT=3000 |
|||
|
|||
## DB [TypeORM] |
|||
DATABASE_URL=postgres://tpCi:someNotSecurePassword@localhost:5432/tpCi |
|||
@ -0,0 +1,4 @@ |
|||
{ |
|||
"collection": "@nestjs/schematics", |
|||
"sourceRoot": "src" |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
{ |
|||
"name": "2021-2022-devops-03-ci-tp", |
|||
"version": "0.0.1", |
|||
"description": "", |
|||
"author": "", |
|||
"private": true, |
|||
"license": "UNLICENSED", |
|||
"scripts": { |
|||
"prebuild": "rimraf dist", |
|||
"build": "nest build", |
|||
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", |
|||
"format:check": "prettier --list-different \"src/**/*.ts\" \"test/**/*.ts\"", |
|||
"start": "nest start", |
|||
"start:dev": "nest start --watch", |
|||
"start:debug": "nest start --debug --watch", |
|||
"start:prod": "node dist/main", |
|||
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", |
|||
"doc:build": "compodoc -c compodoc.server.json", |
|||
"doc": "compodoc -c compodoc.server.json -s -o -w", |
|||
"test": "jest", |
|||
"test:watch": "jest --watch", |
|||
"test:cov": "jest --coverage", |
|||
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", |
|||
"test:e2e": "jest --config ./test/jest-e2e.json" |
|||
}, |
|||
"dependencies": { |
|||
"@nestjs/common": "^8.0.0", |
|||
"@nestjs/core": "^8.0.0", |
|||
"@nestjs/platform-express": "^8.0.0", |
|||
"@nestjs/typeorm": "8.0.2", |
|||
"dotenv": "10.0.0", |
|||
"pg": "8.7.1", |
|||
"reflect-metadata": "^0.1.13", |
|||
"rimraf": "^3.0.2", |
|||
"rxjs": "^7.2.0", |
|||
"typeorm": "0.2.38", |
|||
"zod": "3.9.8" |
|||
}, |
|||
"devDependencies": { |
|||
"@compodoc/compodoc": "1.1.15", |
|||
"@nestjs/cli": "^8.0.0", |
|||
"@nestjs/schematics": "^8.0.0", |
|||
"@nestjs/testing": "^8.0.0", |
|||
"@types/express": "^4.17.13", |
|||
"@types/jest": "^26.0.24", |
|||
"@types/node": "^16.0.0", |
|||
"@types/supertest": "^2.0.11", |
|||
"@typescript-eslint/eslint-plugin": "^4.28.2", |
|||
"@typescript-eslint/parser": "^4.28.2", |
|||
"eslint": "^7.30.0", |
|||
"eslint-config-prettier": "^8.3.0", |
|||
"eslint-plugin-prettier": "^3.4.0", |
|||
"jest": "27.0.6", |
|||
"prettier": "^2.3.2", |
|||
"supertest": "^6.1.3", |
|||
"ts-jest": "^27.0.3", |
|||
"ts-loader": "^9.2.3", |
|||
"ts-node": "^10.0.0", |
|||
"tsconfig-paths": "^3.10.1", |
|||
"typescript": "^4.3.5" |
|||
}, |
|||
"jest": { |
|||
"moduleFileExtensions": [ |
|||
"js", |
|||
"json", |
|||
"ts" |
|||
], |
|||
"rootDir": "src", |
|||
"testRegex": ".*\\.spec\\.ts$", |
|||
"transform": { |
|||
"^.+\\.(t|j)s$": "ts-jest" |
|||
}, |
|||
"collectCoverageFrom": [ |
|||
"**/*.(t|j)s" |
|||
], |
|||
"coverageDirectory": "../coverage", |
|||
"testEnvironment": "node" |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
import { Test, TestingModule } from '@nestjs/testing'; |
|||
import { AppController } from './app.controller'; |
|||
import { AppService } from './app.service'; |
|||
|
|||
describe('AppController', () => { |
|||
let appController: AppController; |
|||
|
|||
beforeEach(async () => { |
|||
const app: TestingModule = await Test.createTestingModule({ |
|||
controllers: [AppController], |
|||
providers: [AppService], |
|||
}).compile(); |
|||
|
|||
appController = app.get<AppController>(AppController); |
|||
}); |
|||
|
|||
describe('root', () => { |
|||
it('should return "Hello World!"', () => { |
|||
expect(appController.getHello()).toBe('Hello World!'); |
|||
}); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,12 @@ |
|||
import { Controller, Get } from '@nestjs/common'; |
|||
import { AppService } from './app.service'; |
|||
|
|||
@Controller() |
|||
export class AppController { |
|||
constructor(private readonly appService: AppService) {} |
|||
|
|||
@Get() |
|||
getHello(): string { |
|||
return this.appService.getHello(); |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
import { Module } from '@nestjs/common'; |
|||
import { AppController } from './app.controller'; |
|||
import { AppService } from './app.service'; |
|||
import { ConfigModule } from './config/config.module'; |
|||
import { ConfigService } from './config/config.service'; |
|||
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm'; |
|||
|
|||
@Module({ |
|||
imports: [ |
|||
ConfigModule, |
|||
TypeOrmModule.forRootAsync({ |
|||
imports: [ConfigModule], |
|||
useFactory: async ( |
|||
configService: ConfigService, |
|||
): Promise<TypeOrmModuleOptions> => ({ |
|||
type: 'postgres', |
|||
url: configService.databaseUrl, |
|||
entities: [__dirname + '/**/*.entity{.ts,.js}'], |
|||
synchronize: true, |
|||
logging: configService.isLoggingDb ? 'all' : false, |
|||
}), |
|||
inject: [ConfigService], |
|||
}), |
|||
], |
|||
controllers: [AppController], |
|||
providers: [AppService], |
|||
}) |
|||
export class AppModule {} |
|||
@ -0,0 +1,8 @@ |
|||
import { Injectable } from '@nestjs/common'; |
|||
|
|||
@Injectable() |
|||
export class AppService { |
|||
getHello(): string { |
|||
return 'Hello World!'; |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
import { Global, Module } from '@nestjs/common'; |
|||
import { ConfigService } from './config.service'; |
|||
|
|||
@Global() |
|||
@Module({ |
|||
providers: [ConfigService], |
|||
exports: [ConfigService], |
|||
}) |
|||
export class ConfigModule {} |
|||
@ -0,0 +1,102 @@ |
|||
import { Test, TestingModule } from '@nestjs/testing'; |
|||
import { ConfigService } from './config.service'; |
|||
import { expand } from 'rxjs/operators'; |
|||
|
|||
describe('ConfigService', () => { |
|||
const OLD_ENV = process.env; |
|||
|
|||
beforeEach(() => { |
|||
jest.resetModules(); // this is important - it clears the cache
|
|||
process.env = { ...OLD_ENV }; |
|||
delete process.env.NODE_ENV; |
|||
}); |
|||
|
|||
afterEach(() => { |
|||
process.env = OLD_ENV; |
|||
}); |
|||
|
|||
const loadService = async (): Promise<ConfigService> => { |
|||
const module: TestingModule = await Test.createTestingModule({ |
|||
providers: [ConfigService], |
|||
}).compile(); |
|||
|
|||
return module.get<ConfigService>(ConfigService); |
|||
}; |
|||
|
|||
it('should have default values', async () => { |
|||
const dbUrl = 'gotodb please'; |
|||
const jwtSecrets = 'shhhh, secret'; |
|||
|
|||
// set the variables
|
|||
process.env.NODE_ENV = undefined; |
|||
process.env.API_PORT = undefined; |
|||
process.env.API_PROTOCOL = undefined; |
|||
process.env.LOG_LEVEL = undefined; |
|||
process.env.LOG_SQL_REQUEST = undefined; |
|||
process.env.DATABASE_URL = dbUrl; |
|||
process.env.JWT_SECRET = jwtSecrets; |
|||
|
|||
const configService = await loadService(); |
|||
|
|||
expect(configService.nodeEnv).toEqual('development'); |
|||
expect(configService.loggerLevel).toEqual('debug'); |
|||
expect(configService.databaseUrl).toEqual(dbUrl); |
|||
expect(configService.isLoggingDb).toEqual(false); |
|||
}); |
|||
|
|||
it('should error when no db url set', async () => { |
|||
const jwtSecrets = 'shhhh, secret'; |
|||
|
|||
// set the variables
|
|||
process.env.NODE_ENV = undefined; |
|||
process.env.API_PORT = undefined; |
|||
process.env.API_PROTOCOL = undefined; |
|||
process.env.LOG_LEVEL = undefined; |
|||
process.env.LOG_SQL_REQUEST = undefined; |
|||
process.env.DATABASE_URL = undefined; |
|||
process.env.JWT_SECRET = jwtSecrets; |
|||
|
|||
try { |
|||
const configService = await loadService(); |
|||
fail(); |
|||
} catch (e) { |
|||
expect(e.message).toMatchInlineSnapshot(`
|
|||
"Config validation error: [ |
|||
{ |
|||
\\"code\\": \\"invalid_type\\", |
|||
\\"expected\\": \\"string\\", |
|||
\\"received\\": \\"undefined\\", |
|||
\\"path\\": [ |
|||
\\"DATABASE_URL\\" |
|||
], |
|||
\\"message\\": \\"Required\\" |
|||
} |
|||
]" |
|||
`);
|
|||
} |
|||
}); |
|||
|
|||
it('should set correct values', async () => { |
|||
const dbUrl = 'gotodb please'; |
|||
const jwtSecrets = 'shhhh, secret'; |
|||
const nodeEnv = 'test'; |
|||
const apiPort = 2020; |
|||
const logLevel = 'silly'; |
|||
const logSqlRequest = true; |
|||
|
|||
// set the variables
|
|||
process.env.NODE_ENV = nodeEnv; |
|||
process.env.API_PORT = `${apiPort}`; |
|||
process.env.LOG_LEVEL = logLevel; |
|||
process.env.LOG_SQL_REQUEST = `${logSqlRequest}`; |
|||
process.env.DATABASE_URL = dbUrl; |
|||
process.env.JWT_SECRET = jwtSecrets; |
|||
|
|||
const configService = await loadService(); |
|||
|
|||
expect(configService.nodeEnv).toEqual(nodeEnv); |
|||
expect(configService.loggerLevel).toEqual(logLevel); |
|||
expect(configService.databaseUrl).toEqual(dbUrl); |
|||
expect(configService.isLoggingDb).toEqual(logSqlRequest); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,68 @@ |
|||
import { Injectable } from '@nestjs/common'; |
|||
import * as z from 'zod'; |
|||
import { config as parseConfig } from 'dotenv'; |
|||
|
|||
const schema = z.object({ |
|||
NODE_ENV: z |
|||
.enum(['development', 'production', 'test']) |
|||
.default('development'), |
|||
LOG_LEVEL: z |
|||
.enum(['error', 'warning', 'info', 'debug', 'silly']) |
|||
.default('debug'), |
|||
DATABASE_URL: z.string().nonempty(), |
|||
LOG_SQL_REQUEST: z |
|||
.string() |
|||
.transform((value) => value === 'true') |
|||
.default('false'), |
|||
PORT: z.string() |
|||
.transform(value => parseInt(value)) |
|||
.default('3000'), |
|||
}); |
|||
|
|||
type EnvConfig = z.infer<typeof schema>; |
|||
|
|||
@Injectable() |
|||
export class ConfigService { |
|||
private readonly envConfig: EnvConfig; |
|||
|
|||
constructor() { |
|||
try { |
|||
parseConfig(); |
|||
} catch (e) {} |
|||
|
|||
this.envConfig = this.validateInput(process.env); |
|||
} |
|||
|
|||
/** |
|||
* Ensures all needed variables are set, and returns the validated JavaScript object |
|||
* including the applied default values. |
|||
*/ |
|||
private validateInput(envConfig: any): EnvConfig { |
|||
const result = schema.safeParse(envConfig); |
|||
|
|||
if (result.success === false) { |
|||
throw new Error(`Config validation error: ${result.error.toString()}`); |
|||
} |
|||
return result.data; |
|||
} |
|||
|
|||
get nodeEnv(): string { |
|||
return this.envConfig.NODE_ENV; |
|||
} |
|||
|
|||
get databaseUrl(): string { |
|||
return this.envConfig.DATABASE_URL; |
|||
} |
|||
|
|||
get isLoggingDb(): boolean { |
|||
return this.envConfig.LOG_SQL_REQUEST; |
|||
} |
|||
|
|||
get loggerLevel(): string { |
|||
return this.envConfig.LOG_LEVEL; |
|||
} |
|||
|
|||
get port(): number { |
|||
return this.envConfig.PORT; |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
import { NestFactory } from '@nestjs/core'; |
|||
import { AppModule } from './app.module'; |
|||
import { ConfigModule } from './config/config.module'; |
|||
import { ConfigService } from './config/config.service'; |
|||
|
|||
async function bootstrap() { |
|||
const app = await NestFactory.create(AppModule); |
|||
const connfigService = app.select(ConfigModule).get(ConfigService); |
|||
await app.listen(connfigService.port); |
|||
console.log(`Application is listening on port ${connfigService.port}.`) |
|||
} |
|||
bootstrap(); |
|||
@ -0,0 +1,28 @@ |
|||
import { Test, TestingModule } from '@nestjs/testing'; |
|||
import { INestApplication } from '@nestjs/common'; |
|||
import * as request from 'supertest'; |
|||
import { AppModule } from './../src/app.module'; |
|||
|
|||
describe('AppController (e2e)', () => { |
|||
let app: INestApplication; |
|||
|
|||
beforeEach(async () => { |
|||
const moduleFixture: TestingModule = await Test.createTestingModule({ |
|||
imports: [AppModule], |
|||
}).compile(); |
|||
|
|||
app = moduleFixture.createNestApplication(); |
|||
await app.init(); |
|||
}); |
|||
|
|||
afterEach(async () => { |
|||
await app.close(); |
|||
}); |
|||
|
|||
it('/ (GET)', () => { |
|||
return request(app.getHttpServer()) |
|||
.get('/') |
|||
.expect(200) |
|||
.expect('Hello World!'); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,9 @@ |
|||
{ |
|||
"moduleFileExtensions": ["js", "json", "ts"], |
|||
"rootDir": ".", |
|||
"testEnvironment": "node", |
|||
"testRegex": ".e2e-spec.ts$", |
|||
"transform": { |
|||
"^.+\\.(t|j)s$": "ts-jest" |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
{ |
|||
"extends": "./tsconfig.json", |
|||
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"] |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"module": "commonjs", |
|||
"declaration": true, |
|||
"removeComments": true, |
|||
"emitDecoratorMetadata": true, |
|||
"experimentalDecorators": true, |
|||
"allowSyntheticDefaultImports": true, |
|||
"target": "es2017", |
|||
"sourceMap": true, |
|||
"outDir": "./dist", |
|||
"baseUrl": "./", |
|||
"incremental": true, |
|||
"skipLibCheck": true |
|||
} |
|||
} |
|||
7358
yarn.lock
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue