Skip to content

Commit 82a33cc

Browse files
pnoebauerdhmlau
authored andcommitted
fix: adding tests and comments illustrating the discriminator bug issue
Signed-off-by: Philip Noebauer <[email protected]>
1 parent 9fa3593 commit 82a33cc

File tree

4 files changed

+92
-21
lines changed

4 files changed

+92
-21
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright IBM Corp. and LoopBack contributors 2020. All Rights Reserved.
2+
// Node module: @loopback/example-validation-app
3+
// This file is licensed under the MIT License.
4+
// License text available at https://opensource.org/licenses/MIT
5+
6+
import {Client, expect} from '@loopback/testlab';
7+
import {ValidationApplication} from '../..';
8+
import {setupApplication} from './test-helper';
9+
10+
const validCat = {
11+
name: 'Kitty',
12+
weight: 5,
13+
kind: 'Cat',
14+
animalProperties: {
15+
color: 'grey',
16+
whiskerLength: 2,
17+
},
18+
};
19+
20+
const validDog = {
21+
name: 'Rex',
22+
weight: 5,
23+
kind: 'Dog',
24+
animalProperties: {
25+
breed: 'poodle',
26+
barkVolume: 5,
27+
},
28+
};
29+
30+
describe('validate properties', () => {
31+
let client: Client;
32+
let app: ValidationApplication;
33+
34+
before(givenAClient);
35+
36+
after(async () => {
37+
await app.stop();
38+
});
39+
40+
async function givenAClient() {
41+
({app, client} = await setupApplication());
42+
}
43+
44+
it('should pass with valid cat properties', async () => {
45+
await client.post('/pets').send(validCat).expect(200);
46+
});
47+
48+
it('should pass with valid dog properties', async () => {
49+
await client.post('/pets').send(validDog).expect(200);
50+
});
51+
52+
it('should fail with error indicating the invalid barkVolume', async () => {
53+
const invalidDog = {...validDog};
54+
invalidDog.animalProperties.barkVolume = 'loud' as unknown as number;
55+
const response = await client.post('/pets').send(invalidDog).expect(422);
56+
57+
/*
58+
below expect statements pass after fixing the bug in function convertToJsonSchema()
59+
loopback-next/packages/rest/src/validation/request-body.validator.ts#lines-87:99
60+
a possible solution is indicated under //NOTE
61+
*/
62+
expect(response.body.error.details.length).to.equal(1);
63+
expect(response.body.error.details[0].message).to.equal('must be number');
64+
expect(response.body.error.details).to.deepEqual([
65+
{
66+
code: 'type',
67+
info: {
68+
type: 'number',
69+
},
70+
message: 'must be number',
71+
path: '/animalProperties/barkVolume',
72+
},
73+
]);
74+
});
75+
});

examples/validation-app/src/controllers/pet.controller.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,12 @@ import {Cat, Dog, Pet} from '../models';
99
export class PetController {
1010
constructor() {}
1111

12-
@post('/pets', {
13-
responses: {
14-
'200': {
15-
description: 'Pet model instance',
16-
content: {
17-
'application/json': {
18-
schema: {'x-ts-type': Pet},
19-
},
20-
},
21-
},
22-
},
23-
})
12+
@post('/pets')
2413
async create(
2514
@requestBody({
2615
content: {
2716
'application/json': {
2817
schema: {
29-
required: ['kind'],
3018
discriminator: {
3119
propertyName: 'kind',
3220
},

examples/validation-app/src/models/pet.model.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ export class CatProperties extends Model {
1010

1111
@property({
1212
type: Number,
13-
required: false,
13+
required: true,
1414
})
15-
whiskerLength?: number;
15+
whiskerLength: number;
1616
}
1717

1818
@model()
@@ -25,9 +25,9 @@ export class DogProperties extends Model {
2525

2626
@property({
2727
type: Number,
28-
required: false,
28+
required: true,
2929
})
30-
barkVolume?: number;
30+
barkVolume: number;
3131
}
3232

3333
@model()

packages/rest/src/validation/request-body.validator.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,18 @@ export async function validateRequestBody(
8484
* @param openapiSchema - The OpenAPI schema to convert.
8585
*/
8686
function convertToJsonSchema(openapiSchema: SchemaObject) {
87-
// const jsonSchema = toJsonSchema(openapiSchema);
88-
const jsonSchema = toJsonSchema(openapiSchema, {
89-
keepNotSupported: ['discriminator'],
90-
});
87+
/*
88+
loopback does not pass the options arg to function toJsonSchema(schema, options?),
89+
which is part of the openapi-schema-to-json-schema library;
90+
by default toJsonSchema() removes discriminators, which is why they do not work
91+
in loopback
92+
*/
93+
// TODO: fix below bug; toJsonSchema requires the options object to enable discriminators
94+
const jsonSchema = toJsonSchema(openapiSchema);
95+
// NOTE: replacing above line with below fixes discriminators not working in loopback and all tests pass
96+
// const jsonSchema = toJsonSchema(openapiSchema, {
97+
// keepNotSupported: ['discriminator'],
98+
// });
9199

92100
delete jsonSchema['$schema'];
93101
/* istanbul ignore if */

0 commit comments

Comments
 (0)