diff --git a/cli/src/test-utils/test-runner-examples/object-query-param.ts b/cli/src/test-utils/test-runner-examples/object-query-param.ts new file mode 100644 index 000000000..cffa9cd1a --- /dev/null +++ b/cli/src/test-utils/test-runner-examples/object-query-param.ts @@ -0,0 +1,48 @@ +import { + api, + body, + endpoint, + Integer, + queryParams, + request, + response, + String, + test +} from "@airtasker/spot"; + +@api({ name: "company-api" }) +class CompanyApi {} + +@endpoint({ + method: "GET", + path: "/companies" +}) +class GetCompanies { + @request + request(@queryParams + queryParam: { + profile?: { name: String }; + }) {} + + @response({ status: 200 }) + successResponse(@body body: CompanyBody[]) {} + + @test({ + request: { + queryParams: { + profile: { + name: "testname" + } + } + }, + response: { + status: 200 + } + }) + successResponseTest() {} +} + +interface CompanyBody { + name: String; + employeeCount: Integer; +} diff --git a/cli/src/test-utils/test-runner.spec.ts b/cli/src/test-utils/test-runner.spec.ts index 661c5edcd..a228ec48a 100644 --- a/cli/src/test-utils/test-runner.spec.ts +++ b/cli/src/test-utils/test-runner.spec.ts @@ -371,6 +371,31 @@ describe("test runner", () => { expect(scope.isDone()).toBe(true); expect(result).toBe(true); }); + + test("request serializes query string objects using the deepObject strategy", async () => { + const contract = parseAndCleanse( + "./cli/src/test-utils/test-runner-examples/object-query-param.ts" + ); + + const scope = nock(baseUrl) + .post("/state") + .query({ action: "initialize" }) + .reply(200) + .get("/companies?profile%5Bname%5D=testname") + .reply(200, [ + { + name: "testname", + employeeCount: 15 + } + ]) + .post("/state") + .query({ action: "teardown" }) + .reply(200); + + const result = await runTest(contract, stateUrl, baseUrl); + expect(scope.isDone()).toBe(true); + expect(result).toBe(true); + }); }); function parseAndCleanse(path: string): ContractDefinition { diff --git a/cli/src/test-utils/test-runner.ts b/cli/src/test-utils/test-runner.ts index 4d150a8b3..779a5ad5b 100644 --- a/cli/src/test-utils/test-runner.ts +++ b/cli/src/test-utils/test-runner.ts @@ -1,5 +1,6 @@ import JsonSchemaValidator from "ajv"; import axios, { AxiosRequestConfig, AxiosResponse } from "axios"; +import { stringify as qsStringify } from "qs"; import { JsonSchemaType, jsonTypeSchema @@ -190,6 +191,10 @@ function generateAxiosConfig( {} ); + config.paramsSerializer = params => { + return qsStringify(params); + }; + if (test.request.body) { config.data = valueFromDataExpression(test.request.body); } diff --git a/package.json b/package.json index 9c36c3e41..e8c4475a8 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@oclif/plugin-help": "^2", "@types/cors": "^2.8.4", "@types/express": "^4.16.0", + "@types/qs": "^6.5.3", "@types/ramda": "^0.26.6", "@types/randomstring": "^1.1.6", "ajv": "^6.10.0", @@ -24,6 +25,7 @@ "inquirer": "^6.2.0", "js-yaml": "^3.13.1", "lodash": "^4.17.11", + "qs": "^6.7.0", "ramda": "^0.26.1", "randomstring": "^1.1.5", "ts-morph": "^1.3.3", diff --git a/yarn.lock b/yarn.lock index 1a24bdd69..d789a8cc2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -551,6 +551,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.2.tgz#dc85dde46aa8740bb4aed54b8104250f8f849503" integrity sha512-HOtU5KqROKT7qX/itKHuTtt5fV0iXbheQvrgbLNXFJQBY/eh+VS5vmmTAVlo3qIGMsypm0G4N1t2AXjy1ZicaQ== +"@types/qs@^6.5.3": + version "6.5.3" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.5.3.tgz#1c3b71b091eaeaf5924538006b7f70603ce63d38" + integrity sha512-Jugo5V/1bS0fRhy2z8+cUAHEyWOATaz4rbyLVvcFs7+dXp5HfwpEwzF1Q11bB10ApUqHf+yTauxI0UXQDwGrbA== + "@types/ramda@^0.26.6": version "0.26.6" resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.26.6.tgz#1aaf5060da8ebb99529420b6eb997c50f74c218e" @@ -3988,6 +3993,11 @@ qs@^6.5.1: resolved "https://registry.yarnpkg.com/qs/-/qs-6.6.0.tgz#a99c0f69a8d26bf7ef012f871cdabb0aee4424c2" integrity sha512-KIJqT9jQJDQx5h5uAVPimw6yVg2SekOKu959OCtktD3FjzbpvaPr8i4zzg07DOMz+igA4W/aNM7OV8H37pFYfA== +qs@^6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + ramda@^0.26.1: version "0.26.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06"