Skip to content

Commit

Permalink
Merge pull request #1586 from jackey8616/fix/1585_optional_uploaded_file
Browse files Browse the repository at this point in the history
Fix/can't use optional at UploadedFile decorator
  • Loading branch information
WoH committed Mar 17, 2024
2 parents 935af8e + 41b1e48 commit 75f9482
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ export class ExpressTemplateService extends TemplateService<ExpressApiHandlerPar
const files = Object.values(args).filter(param => param.dataType === 'file');
if (param.dataType === 'file' && files.length > 0) {
const requestFiles = request.files as { [fileName: string]: Express.Multer.File[] };
if (requestFiles[name] === undefined) {
return undefined;
}

const fileArgs = this.validationService.ValidateParam(param, requestFiles[name], name, fieldErrors, undefined, this.minimalSwaggerConfig);
return fileArgs.length === 1 ? fileArgs[0] : fileArgs;
} else if (param.dataType === 'array' && param.array && param.array.dataType === 'file') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ export class KoaTemplateService extends TemplateService<KoaApiHandlerParameters,
const files = Object.values(args).filter(param => param.dataType === 'file');
const contextRequest = context.request as any;
if (param.dataType === 'file' && files.length > 0) {
if (contextRequest.files[name] === undefined) {
return undefined;
}

const fileArgs = this.validationService.ValidateParam(param, contextRequest.files[name], name, errorFields, undefined, this.minimalSwaggerConfig);
return fileArgs.length === 1 ? fileArgs[0] : fileArgs;
} else if (param.dataType === 'array' && param.array && param.array.dataType === 'file') {
Expand Down
7 changes: 4 additions & 3 deletions tests/fixtures/controllers/postController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@ export class PostTestController {
return [fileA, fileB];
}

@Post('MixedFormDataWithFile')
@Post('MixedFormDataWithFilesContainsOptionalFile')
public async mixedFormDataWithFile(
@FormField('username') username: string,
@UploadedFile('avatar') avatar: File,
): Promise<{ username: string; avatar: File; }> {
return { username, avatar };
@UploadedFile('optionalAvatar') optionalAvatar?: File,
): Promise<{ username: string; avatar: File; optionalAvatar?: File; }> {
return { username, avatar, optionalAvatar };
}

/**
Expand Down
27 changes: 25 additions & 2 deletions tests/integration/express-server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1560,16 +1560,17 @@ describe('Express Server', () => {
});
});

it('can post mixed form data content with file', () => {
it('can post mixed form data content with file and not providing optional file', () => {
const formData = {
username: 'test',
avatar: '@../tsconfig.json',
};
return verifyFileUploadRequest(`${basePath}/PostTest/MixedFormDataWithFile`, formData, (_err, res) => {
return verifyFileUploadRequest(`${basePath}/PostTest/MixedFormDataWithFilesContainsOptionalFile`, formData, (_err, res) => {
const file = res.body.avatar;
const packageJsonBuffer = readFileSync(resolve(__dirname, `../${file.originalname}`));
const returnedBuffer = Buffer.from(file.buffer);
expect(res.body.username).to.equal(formData.username);
expect(res.body.optionalAvatar).to.undefined;
expect(file).to.not.be.undefined;
expect(file.fieldname).to.be.not.undefined;
expect(file.originalname).to.be.not.undefined;
Expand All @@ -1579,6 +1580,28 @@ describe('Express Server', () => {
});
});

it('can post mixed form data content with file and provides optional file', () => {
const formData = {
username: 'test',
avatar: '@../tsconfig.json',
optionalAvatar: '@../package.json',
};
return verifyFileUploadRequest(`${basePath}/PostTest/MixedFormDataWithFilesContainsOptionalFile`, formData, (_err, res) => {
expect(res.body.username).to.equal(formData.username);
for (const fieldName of ['avatar', 'optionalAvatar']) {
const file = res.body[fieldName];
const packageJsonBuffer = readFileSync(resolve(__dirname, `../${file.originalname}`));
const returnedBuffer = Buffer.from(file.buffer);
expect(file).to.not.be.undefined;
expect(file.fieldname).to.be.not.undefined;
expect(file.originalname).to.be.not.undefined;
expect(file.encoding).to.be.not.undefined;
expect(file.mimetype).to.equal('application/json');
expect(Buffer.compare(returnedBuffer, packageJsonBuffer)).to.equal(0);
}
});
});

function verifyFileUploadRequest(
path: string,
formData: any,
Expand Down
27 changes: 25 additions & 2 deletions tests/integration/hapi-server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1443,16 +1443,17 @@ describe('Hapi Server', () => {
});
});

it('can post mixed form data content with file', () => {
it('can post mixed form data content with file and not providing optional file', () => {
const formData = {
username: 'test',
avatar: '@../tsconfig.json',
};
return verifyFileUploadRequest(`${basePath}/PostTest/MixedFormDataWithFile`, formData, (_err, res) => {
return verifyFileUploadRequest(`${basePath}/PostTest/MixedFormDataWithFilesContainsOptionalFile`, formData, (_err, res) => {
const file = res.body.avatar;
const packageJsonBuffer = readFileSync(resolve(__dirname, `../${file.originalname}`));
const returnedBuffer = Buffer.from(file.buffer);
expect(res.body.username).to.equal(formData.username);
expect(res.body.optionalAvatar).to.undefined;
expect(file).to.not.be.undefined;
expect(file.fieldname).to.be.not.undefined;
expect(file.originalname).to.be.not.undefined;
Expand All @@ -1462,6 +1463,28 @@ describe('Hapi Server', () => {
});
});

it('can post mixed form data content with file and provides optional file', () => {
const formData = {
username: 'test',
avatar: '@../tsconfig.json',
optionalAvatar: '@../package.json',
};
return verifyFileUploadRequest(`${basePath}/PostTest/MixedFormDataWithFilesContainsOptionalFile`, formData, (_err, res) => {
expect(res.body.username).to.equal(formData.username);
for (const fieldName of ['avatar', 'optionalAvatar']) {
const file = res.body[fieldName];
const packageJsonBuffer = readFileSync(resolve(__dirname, `../${file.originalname}`));
const returnedBuffer = Buffer.from(file.buffer);
expect(file).to.not.be.undefined;
expect(file.fieldname).to.be.not.undefined;
expect(file.originalname).to.be.not.undefined;
expect(file.encoding).to.be.not.undefined;
expect(file.mimetype).to.equal('application/json');
expect(Buffer.compare(returnedBuffer, packageJsonBuffer)).to.equal(0);
}
});
});

function verifyFileUploadRequest(
path: string,
formData: any,
Expand Down
27 changes: 25 additions & 2 deletions tests/integration/koa-server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1423,16 +1423,17 @@ describe('Koa Server', () => {
});
});

it('can post mixed form data content with file', () => {
it('can post mixed form data content with file and not providing optional file', () => {
const formData = {
username: 'test',
avatar: '@../tsconfig.json',
};
return verifyFileUploadRequest(`${basePath}/PostTest/MixedFormDataWithFile`, formData, (_err, res) => {
return verifyFileUploadRequest(`${basePath}/PostTest/MixedFormDataWithFilesContainsOptionalFile`, formData, (_err, res) => {
const file = res.body.avatar;
const packageJsonBuffer = readFileSync(resolve(__dirname, `../${file.originalname}`));
const returnedBuffer = Buffer.from(file.buffer);
expect(res.body.username).to.equal(formData.username);
expect(res.body.optionalAvatar).to.undefined;
expect(file).to.not.be.undefined;
expect(file.fieldname).to.be.not.undefined;
expect(file.originalname).to.be.not.undefined;
Expand All @@ -1442,6 +1443,28 @@ describe('Koa Server', () => {
});
});

it('can post mixed form data content with file and provides optional file', () => {
const formData = {
username: 'test',
avatar: '@../tsconfig.json',
optionalAvatar: '@../package.json',
};
return verifyFileUploadRequest(`${basePath}/PostTest/MixedFormDataWithFilesContainsOptionalFile`, formData, (_err, res) => {
expect(res.body.username).to.equal(formData.username);
for (const fieldName of ['avatar', 'optionalAvatar']) {
const file = res.body[fieldName];
const packageJsonBuffer = readFileSync(resolve(__dirname, `../${file.originalname}`));
const returnedBuffer = Buffer.from(file.buffer);
expect(file).to.not.be.undefined;
expect(file.fieldname).to.be.not.undefined;
expect(file.originalname).to.be.not.undefined;
expect(file.encoding).to.be.not.undefined;
expect(file.mimetype).to.equal('application/json');
expect(Buffer.compare(returnedBuffer, packageJsonBuffer)).to.equal(0);
}
});
});

function verifyFileUploadRequest(
path: string,
formData: any,
Expand Down

0 comments on commit 75f9482

Please sign in to comment.