Skip to content
This repository has been archived by the owner on Apr 23, 2024. It is now read-only.

Commit

Permalink
feat: add initial swagger docs
Browse files Browse the repository at this point in the history
  • Loading branch information
André Scheibel de Almada committed Jul 13, 2023
1 parent a0455c4 commit c65b41b
Show file tree
Hide file tree
Showing 15 changed files with 1,341 additions and 169 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@nestjs/core": "^10.0.0",
"@nestjs/mongoose": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/swagger": "7.1.1",
"csv-parse": "5.4.0",
"mongoose": "^7.3.1",
"reflect-metadata": "^0.1.13",
Expand All @@ -44,6 +45,7 @@
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.5.0",
"mongodb-memory-server": "8.13.0",
"prettier": "^2.8.8",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
Expand Down
22 changes: 0 additions & 22 deletions src/app.controller.spec.ts

This file was deleted.

12 changes: 0 additions & 12 deletions src/app.controller.ts

This file was deleted.

7 changes: 2 additions & 5 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import { MongooseModule } from '@nestjs/mongoose';

import { FishesModule } from './fishes/fishes.module';

import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
imports: [
ConfigModule.forRoot(),
Expand All @@ -16,7 +13,7 @@ import { AppService } from './app.service';
),
FishesModule,
],
controllers: [AppController],
providers: [AppService],
controllers: [],
providers: [],
})
export class AppModule {}
8 changes: 0 additions & 8 deletions src/app.service.ts

This file was deleted.

97 changes: 97 additions & 0 deletions src/fishes/dto/fish.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { ApiProperty } from '@nestjs/swagger';
import { IFishLocation } from '../interfaces/fish.interface';

const monthProperty = {
oneOf: [
{
type: 'array',
items: {
type: 'string',
enum: [
'All day',
'9 AM - 4 PM',
'4 PM - 9 AM',
'9 PM - 4 AM',
'4 AM - 9 PM',
],
},
},
{ type: 'undefined' },
],
};
const availabilityProperties = {
january: monthProperty,
february: monthProperty,
march: monthProperty,
april: monthProperty,
may: monthProperty,
june: monthProperty,
july: monthProperty,
august: monthProperty,
september: monthProperty,
october: monthProperty,
november: monthProperty,
december: monthProperty,
};

class Availability {
@ApiProperty({
type: 'object',
properties: availabilityProperties,
})
northern_hemisphere: Object;

@ApiProperty({
type: 'object',
properties: availabilityProperties,
})
southern_hemisphere: Object;
}

export class FishDto {
@ApiProperty()
name: string;

@ApiProperty()
icon_image: string;

@ApiProperty()
critterpedia_image: string;

@ApiProperty()
furniture_image: string;

@ApiProperty()
minimum_catches_to_spawn: number;

@ApiProperty()
sale_price: number;

@ApiProperty()
spawn_frequency: string;

@ApiProperty({
enum: [
'River',
'Pond',
'River (clifftop)',
'River (mouth)',
'Sea',
'Pier',
'Sea (rainy days)',
],
})
location: IFishLocation;

@ApiProperty()
shadow_size: string;

@ApiProperty()
blathers_description: string;

@ApiProperty()
catch_phrase: string;

@ApiProperty()
availability: Availability;
}
53 changes: 53 additions & 0 deletions src/fishes/fishes.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Test, TestingModule } from '@nestjs/testing';
import { getModelToken } from '@nestjs/mongoose';
import { MongoMemoryServer } from 'mongodb-memory-server';
import { Connection, connect, Model } from 'mongoose';

import { FishesController } from './fishes.controller';
import { FishesService } from './fishes.service';
import { Fish, FishSchema } from './schemas/fish.schema';
import { FishDtoStub } from '../../test/stubs/fish.dto.stub';

describe('FishesController', () => {
let fishesController: FishesController;
let mongodb: MongoMemoryServer;
let mongoConnection: Connection;
let fishModel: Model<Fish>;

beforeAll(async () => {
mongodb = await MongoMemoryServer.create();
const uri = mongodb.getUri();
mongoConnection = (await connect(uri)).connection;
fishModel = mongoConnection.model('Fish', FishSchema);
const app: TestingModule = await Test.createTestingModule({
controllers: [FishesController],
providers: [
FishesService,
{ provide: getModelToken('Fish'), useValue: fishModel },
],
}).compile();
fishesController = app.get<FishesController>(FishesController);
});

afterAll(async () => {
await mongoConnection.dropDatabase();
await mongoConnection.close();
await mongodb.stop();
});

afterEach(async () => {
const collections = mongoConnection.collections;
for (const key in collections) {
const collection = collections[key];
await collection.deleteMany({});
}
});

describe('getFishes', () => {
it('should return all fishes in database', async () => {
await new fishModel(FishDtoStub()).save();
const fishes = await fishesController.getFishes({});
expect(fishes).toHaveLength(1);
});
});
});
130 changes: 87 additions & 43 deletions src/fishes/fishes.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,68 +6,107 @@ import {
HttpException,
HttpStatus,
} from '@nestjs/common';
import {
ApiOperation,
ApiTags,
ApiOkResponse,
ApiQuery,
ApiBadRequestResponse,
} from '@nestjs/swagger';

import { FishesService } from './fishes.service';
import { Fish, IMonth } from './schemas/fish.schema';
import { IQueryParams } from './interfaces/fish.interface';

import { Fish } from './schemas/fish.schema';
import { IQueryParams, IMonth } from './interfaces/fish.interface';
import { FishDto } from './dto/fish.dto';

const hemispheres = ['northern_hemisphere', 'southern_hemisphere'];
const months = [
'january',
'february',
'march',
'april',
'may',
'june',
'july',
'august',
'september',
'october',
'november',
'december',
];
const times = [
'12 AM',
'1 AM',
'2 AM',
'3 AM',
'4 AM',
'5 AM',
'6 AM',
'7 AM',
'8 AM',
'9 AM',
'10 AM',
'11 AM',
'12 PM',
'1 PM',
'2 PM',
'3 PM',
'4 PM',
'5 PM',
'6 PM',
'7 PM',
'8 PM',
'9 PM',
'10 PM',
'11 PM',
];

@ApiTags('Fishes')
@Controller('fishes')
export class FishesController {
constructor(private fishesService: FishesService) {}

// Query params verifiers
private isOfTypeIMonth(month: string): month is IMonth {
return [
'january',
'february',
'march',
'april',
'may',
'june',
'july',
'august',
'september',
'october',
'november',
'december',
].includes(month);
return months.includes(month);
}

private isValidHemisphere(hemisphere: string): boolean {
return ['northern_hemisphere', 'southern_hemisphere'].includes(hemisphere);
return hemispheres.includes(hemisphere);
}

private isValidTime(time: string): boolean {
return [
'12 AM',
'1 AM',
'2 AM',
'3 AM',
'4 AM',
'5 AM',
'6 AM',
'7 AM',
'8 AM',
'9 AM',
'10 AM',
'11 AM',
'12 PM',
'1 PM',
'2 PM',
'3 PM',
'4 PM',
'5 PM',
'6 PM',
'7 PM',
'8 PM',
'9 PM',
'10 PM',
'11 PM',
].includes(time);
return times.includes(time);
}

// Routes
@Get()
@ApiOperation({ summary: 'Obtain all fishes' })
@ApiQuery({
name: 'hemisphere',
enum: hemispheres,
required: false,
})
@ApiQuery({
name: 'month',
enum: months,
required: false,
})
@ApiQuery({
name: 'time',
enum: times,
required: false,
})
@ApiOkResponse({
description: "The found fish records by request's criteria",
type: FishDto,
isArray: true,
})
@ApiBadRequestResponse({
description:
'Invalid query param informed or searching by active hours without informing a month',
})
public getFishes(@Query() query: IQueryParams): Promise<Fish[]> {
if (query.month && !this.isOfTypeIMonth(query.month))
throw new HttpException(
Expand Down Expand Up @@ -97,6 +136,11 @@ export class FishesController {
}

@Get(':name')
@ApiOkResponse({
description: 'The found fish record, or null, if not found',
type: FishDto,
})
@ApiOperation({ summary: 'Obtain all information from a specific fish' })
public getFish(@Param('name') name: string): Promise<Fish | null> {
return this.fishesService.findOne(name);
}
Expand Down
Loading

0 comments on commit c65b41b

Please sign in to comment.