Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove special handling of non-FormData entries #6036

Merged
merged 1 commit into from
May 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions src/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ export function fromJSOrdered(js) {
const objWithHashedKeys = createObjWithHashedKeys(js)
Copy link
Member

@char0n char0n May 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic here is a little bit nonsensical for me here.

createObjWithHashedKeys is used in only one place in codebase, and that's here on line 86.

Then first thing the function does is validate it's input param again but with different predicate statement. This seems redundant and non-compatible with isFunction(js.entries) predicate statement checking if entries is a function instead checking if it's falsy. I recommend dropping following code from the function body.

 if (!fdObj.entries) {
    return fdObj // not a FormData object with iterable
  }

Another thing about createObjWithHashedKeys is that it's super crazy complicated. It's not apparent what is does by reading it. So I'd either put @example tag to functions existing jsdoc to document what is the expected output of this function for particular input (formdata) or create a unit tests for this function.

Copy link
Contributor Author

@tim-lai tim-lai May 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems redundant

Internal validation updated to match isFunction for consistency. Internal validation retained for robustness.

The original use of isFunction(js.entries) is a conditional, not a validation

put @example tag

Added a real example

unit tests

Not done for 'createObjWithHashedKeys'. Reason: would be new feature with additional dependencies for isomorphic-form-data for testing purposes. This is also the reason for validating fdObj.entries rather than validating instanceof FormData.

However, there exists a curlify test that tests rendering of the result, which is basis of the added @example tag mentioned above

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK everything clear except one thing.

We're trying to detect if the js is a FormData instance. Why are we not using instanceof FormData operator but rather asserting on the shape of the possible formData instance? swagger-client is integral part of swagger-ui and it makes sure that FormData symbol is always present as global symbol, both in browser and node.js so it's absolutely safe to do so without installing isomorphic-form-data explicitly.

Reason: would be new feature with additional dependencies for isomorphic-form-data for testing purposes

New feature? I'd rather say it's just a dev-dependency used only for tests. But anyway @examples in jsdoc should suffice if function is tested elsewhere in integration.

return Im.OrderedMap(objWithHashedKeys).map(fromJSOrdered)
}
if (js.entries && !isFunction(js.entries)) {
return Im.OrderedMap(js.entries).map(fromJSOrdered)
}
return Im.OrderedMap(js).map(fromJSOrdered)
}

Expand All @@ -97,11 +94,21 @@ export function fromJSOrdered(js) {
* Append a hashIdx and counter to the key name, if multiple exists
* if single, key name = <original>
* if multiple, key name = <original><hashIdx><count>
* @example <caption>single entry for vegetable</caption>
* fdObj.entries.vegtables: "carrot"
* // returns newObj.vegetables : "carrot"
* @example <caption>multiple entries for fruits[]</caption>
* fdObj.entries.fruits[]: "apple"
* // returns newObj.fruits[]_**[]1 : "apple"
* fdObj.entries.fruits[]: "banana"
* // returns newObj.fruits[]_**[]2 : "banana"
* fdObj.entries.fruits[]: "grape"
* // returns newObj.fruits[]_**[]3 : "grape"
* @param {FormData} fdObj - a FormData object
* @return {Object} - a plain object
*/
export function createObjWithHashedKeys (fdObj) {
if (!fdObj.entries) {
if (!isFunction(fdObj.entries)) {
return fdObj // not a FormData object with iterable
}
const newObj = {}
Expand Down
34 changes: 32 additions & 2 deletions test/e2e-cypress/tests/bugs/6016.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
describe("Entries should be valid property name", () => {
it("should render a OAS3.0 definition that uses 'entries' as a property name", () => {
it("should render a OAS3.0 definition that uses 'entries' as a 'components' property name", () => {
cy.visit("/?url=/documents/bugs/6016-oas3.yaml")
.get("#operations-tag-default")
.should("exist")
})
it("should render a OAS2.0 definition that uses 'entries' as a property name", () => {
it("should render expanded Operations of OAS3.0 definition that uses 'entries' as a 'components' property name", () => {
cy.visit("/?url=/documents/bugs/6016-oas3.yaml")
.get("#operations-default-test_test__get")
.click()
.get("#operations-default-test_test__get > div .opblock-body")
.should("exist")

})
it("should render expanded Models of OAS3.0 definition that uses 'entries' as a 'components' property name", () => {
cy.visit("/?url=/documents/bugs/6016-oas3.yaml")
.get("#model-Testmodel > span .model-box")
.click()
.get("div .model-box")
.should("exist")
})
it("should render a OAS2.0 definition that uses 'entries' as a 'definitions' property name", () => {
cy.visit("/?url=/documents/bugs/6016-oas2.yaml")
.get("#operations-default-post_pet")
.should("exist")
})
it("should render expanded Operations of OAS2.0 definition that uses 'entries' as a 'definitions' property name", () => {
cy.visit("/?url=/documents/bugs/6016-oas2.yaml")
.get("#operations-default-post_pet")
.click()
.get("#operations-default-post_pet > div .opblock-body")
.should("exist")

})
it("should render expanded Models of OAS2.0 definition that uses 'entries' as a 'defintions' property name", () => {
cy.visit("/?url=/documents/bugs/6016-oas2.yaml")
.get("#model-Pet > span .model-box")
.click()
.get("div .model-box")
.should("exist")
})
})