Skip to content

Commit 11a7da1

Browse files
committed
feat: extras
1 parent e5bc949 commit 11a7da1

File tree

8 files changed

+83
-5
lines changed

8 files changed

+83
-5
lines changed

funpets-server/main/function.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"bindings": [
33
{
4-
"authLevel": "anonymous",
4+
"authLevel": "function",
55
"type": "httpTrigger",
66
"direction": "in",
77
"name": "req",

funpets-server/package-lock.json

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

funpets-server/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
"@azure/functions": "^1.0.3",
2525
"@nestjs/azure-database": "^1.0.0",
2626
"@nestjs/azure-func-http": "^0.4.1",
27-
"@nestjs/azure-storage": "^2.1.0",
27+
"@nestjs/azure-storage": "^2.1.1",
2828
"@nestjs/common": "^6.10.14",
2929
"@nestjs/core": "^6.10.14",
3030
"@nestjs/platform-express": "^6.10.14",
3131
"@nestjs/typeorm": "^6.3.4",
3232
"mongodb": "^3.5.5",
33+
"class-transformer": "^0.2.3",
34+
"class-validator": "^0.11.0",
3335
"reflect-metadata": "^0.1.13",
3436
"rimraf": "^3.0.2",
3537
"rxjs": "^6.5.4",

funpets-server/src/main.azure.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { INestApplication } from '@nestjs/common';
1+
import { INestApplication, ValidationPipe } from '@nestjs/common';
22
import { NestFactory } from '@nestjs/core';
33
import { AppModule } from './app.module';
44

55
export async function createApp(): Promise<INestApplication> {
66
const app = await NestFactory.create(AppModule);
77
app.setGlobalPrefix('api');
8-
8+
app.useGlobalPipes(new ValidationPipe());
9+
910
await app.init();
1011
return app;
1112
}

funpets-server/src/main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import { ValidationPipe } from '@nestjs/common';
12
import { NestFactory } from '@nestjs/core';
23
import { AppModule } from './app.module';
34

45
async function bootstrap() {
56
const app = await NestFactory.create(AppModule);
67
app.setGlobalPrefix('api');
8+
app.useGlobalPipes(new ValidationPipe());
9+
710
await app.listen(3000);
811
}
912
bootstrap();

funpets-server/src/stories/stories.controller.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,31 @@
11
import { Test, TestingModule } from '@nestjs/testing';
22
import { StoriesController } from './stories.controller';
3+
import { AzureStorageService } from '@nestjs/azure-storage';
4+
import { getRepositoryToken } from '@nestjs/typeorm';
5+
import { Story } from './story.entity';
6+
7+
jest.mock('@nestjs/azure-storage', () => ({
8+
// Use Jest automatic mock generation
9+
...jest.genMockFromModule('@nestjs/azure-storage'),
10+
11+
// Interceptor mock needs to be done manually
12+
AzureStorageFileInterceptor: jest.fn(() => ({
13+
intercept: (context, next) => next.handle(),
14+
})),
15+
}));
16+
17+
const mockRepository = jest.genMockFromModule<any>('typeorm').MongoRepository;
318

419
describe('Stories Controller', () => {
520
let controller: StoriesController;
621

722
beforeEach(async () => {
823
const module: TestingModule = await Test.createTestingModule({
924
controllers: [StoriesController],
25+
providers: [
26+
AzureStorageService,
27+
{ provide: getRepositoryToken(Story), useValue: mockRepository },
28+
],
1029
}).compile();
1130

1231
controller = module.get<StoriesController>(StoriesController);

funpets-server/src/stories/stories.controller.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Body,
1010
UploadedFile,
1111
UnsupportedMediaTypeException,
12+
BadRequestException,
1213
} from '@nestjs/common';
1314
import {
1415
AzureStorageFileInterceptor,
@@ -17,7 +18,9 @@ import {
1718
import { InjectRepository } from '@nestjs/typeorm';
1819
import { MongoRepository } from 'typeorm';
1920
import { ObjectID } from 'mongodb';
21+
import { Validator } from 'class-validator';
2022
import { Story } from './story.entity';
23+
import { StoryDto } from './story.dto';
2124

2225
// Some cat facts, courtesy of https://catfact.ninja
2326
const funFacts = [
@@ -89,7 +92,7 @@ export class StoriesController {
8992
@UseInterceptors(AzureStorageFileInterceptor('file', fileUploadOptions))
9093
async createStory(
9194
@Body()
92-
data: Partial<Story>,
95+
data: StoryDto,
9396
@UploadedFile()
9497
file: UploadedFileMetadata,
9598
): Promise<Story> {
@@ -100,6 +103,10 @@ export class StoriesController {
100103
if (file) {
101104
story.imageUrl = file.storageUrl || null;
102105
}
106+
const validator = new Validator();
107+
if (validator.isEmpty(story.description) && validator.isEmpty(story.imageUrl)) {
108+
throw new BadRequestException('Either description or image file must be provided');
109+
}
103110
return await this.storiesRepository.save(story);
104111
}
105112
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { IsNotEmpty, IsOptional, IsDate, MaxLength } from 'class-validator';
2+
3+
export class StoryDto {
4+
@IsNotEmpty()
5+
animal: string;
6+
7+
@IsOptional()
8+
@MaxLength(240)
9+
description: string;
10+
11+
@IsOptional()
12+
@IsDate()
13+
createdAt: Date;
14+
}

0 commit comments

Comments
 (0)