Skip to content

Commit

Permalink
fix(swagger): Fixed multiple Open API tags not being applied correctl…
Browse files Browse the repository at this point in the history
…y on First Class Entity and Nested First Class Entity (#996)
  • Loading branch information
ktutnik committed Jul 2, 2021
1 parent dc54af9 commit 65d1cfd
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 10 deletions.
14 changes: 7 additions & 7 deletions packages/generic-controller/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,22 +285,22 @@ function decorateCustomQuery(config: GenericControllerOptions) {

function decorateTagByClass(entity: Class, nameConversion: (x: string) => string) {
const meta = reflect(entity)
const tag = meta.decorators.find((x: ApiTagDecorator) => x.kind === "ApiTag")
if (!tag)
return api.tag(nameConversion(entity.name))
return decorateClass(tag)
const tags = meta.decorators.filter((x: ApiTagDecorator) => x.kind === "ApiTag")
if (tags.length === 0)
return [api.tag(nameConversion(entity.name))]
return tags.map(x => decorateClass(x))
}

function decorateTagByRelation(info: EntityRelationInfo, nameConversion: (x: string) => string) {
const meta = reflect(info.parent)
const relProp = meta.properties.find(x => x.name === info.parentProperty || x.name === info.childProperty)
if (relProp) {
const tag = relProp.decorators.find((x: ApiTagDecorator) => x.kind === "ApiTag")
if (tag) return decorateClass(tag)
const tags = relProp.decorators.filter((x: ApiTagDecorator) => x.kind === "ApiTag")
if (tags.length > 0) return tags.map(x => decorateClass(x))
}
const parent = nameConversion(info.parent.name)
const child = nameConversion(info.child.name)
return api.tag(`${parent} ${child}`)
return [api.tag(`${parent} ${child}`)]
}


Expand Down
4 changes: 2 additions & 2 deletions packages/generic-controller/src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function createGenericControllerType(entity: Class, opt: ControllerFactoryOption
], Controller)
if (!opt.skipTag) {
Reflect.decorate([
decorateTagByClass(entity, opt.nameConversion),
...decorateTagByClass(entity, opt.nameConversion),
], Controller)
}
return Controller
Expand Down Expand Up @@ -119,7 +119,7 @@ function createNestedGenericControllerType(type: EntityWithRelation, opt: Contro
], Controller)
if (!opt.skipTag) {
Reflect.decorate([
decorateTagByRelation(info, opt.nameConversion)
...decorateTagByRelation(info, opt.nameConversion)
], Controller)
}
return Controller
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,13 @@ Object {
}
`;

exports[`Open Api Generic Controller Should allow multiple tag decorators 1`] = `
Array [
"Animal Management",
"Animals",
]
`;

exports[`Open Api Generic Controller Should generate DELETE /animal/:id properly 1`] = `
Array [
Object {
Expand Down Expand Up @@ -1018,6 +1025,13 @@ Object {
}
`;

exports[`Open Api Generic One To Many Controller Should allow multiple tag decorators 1`] = `
Array [
"Tags Management",
"Tags",
]
`;

exports[`Open Api Generic One To Many Controller Should generate DELETE /animals/:id properly 1`] = `
Array [
Object {
Expand Down
46 changes: 46 additions & 0 deletions tests/behavior/generic-controller/generic-controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,24 @@ describe("Open Api", () => {
.expect(200)
expect(body.paths["/animal"].post.tags).toMatchSnapshot()
})
it("Should allow multiple tag decorators", async () => {
@genericController()
@api.tag("Animal Management")
@api.tag("Animals")
class Animal {
@entity.primaryId()
id: number
@reflect.noop()
name: string
}
const koa = await createApp({ controller: Animal }, { mode: "production" })
.set(new SwaggerFacility())
.initialize()
const { body } = await supertest(koa.callback())
.get("/swagger/swagger.json")
.expect(200)
expect(body.paths["/animal"].post.tags).toMatchSnapshot()
})
})

describe("Generic One To Many Controller", () => {
Expand Down Expand Up @@ -1675,6 +1693,34 @@ describe("Open Api", () => {
.expect(200)
expect(body.paths["/animal/{pid}/tags"].post.tags).toMatchSnapshot()
})
it("Should allow multiple tag decorators", async () => {
@genericController()
class Animal {
@entity.primaryId()
id: number
@reflect.noop()
name: string
@reflect.type(x => [Tag])
@entity.relation()
@genericController()
@api.tag("Tags Management")
@api.tag("Tags")
tags: Tag[]
}
class Tag {
@entity.primaryId()
id: number
@reflect.noop()
tag: string
}
const koa = await createApp({ controller: Animal }, { mode: "production" })
.set(new SwaggerFacility())
.initialize()
const { body } = await supertest(koa.callback())
.get("/swagger/swagger.json")
.expect(200)
expect(body.paths["/animal/{pid}/tags"].post.tags).toMatchSnapshot()
})
})

describe("Generic Many To One Controller", () => {
Expand Down
1 change: 0 additions & 1 deletion tests/behavior/mongoose/mongoose-generic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3487,7 +3487,6 @@ describe("Open API", () => {
.expect(200)
expect(body.paths["/users"].post.tags).toMatchSnapshot()
})

})
describe("Nested Generic Controller", () => {
it("Should generate tags properly", async () => {
Expand Down

0 comments on commit 65d1cfd

Please sign in to comment.