diff --git a/.postman/api b/.postman/api new file mode 100644 index 0000000..69016d7 --- /dev/null +++ b/.postman/api @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY +apis[] = {"apiId":"5a04480e-281f-45b0-af8f-468d33554fd4"} +configVersion = 1.0.0 +type = api diff --git a/.postman/api_5a04480e-281f-45b0-af8f-468d33554fd4 b/.postman/api_5a04480e-281f-45b0-af8f-468d33554fd4 new file mode 100644 index 0000000..2b80c91 --- /dev/null +++ b/.postman/api_5a04480e-281f-45b0-af8f-468d33554fd4 @@ -0,0 +1,22 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY +configVersion = 1.0.0 +type = apiEntityData + +[config] +id = 5a04480e-281f-45b0-af8f-468d33554fd4 + +[config.relations] + +[config.relations.collections] +rootDirectory = postman/collections +files[] = {"id":"23245044-ee57b305-6748-43ca-8fa6-5a29a3956d42","path":"Customers CHALLENGE.json","metaData":{}} + +[config.relations.collections.metaData] + +[config.relations.apiDefinition] +rootDirectory = postman/schemas +files[] = {"path":"index.yaml","metaData":{}} + +[config.relations.apiDefinition.metaData] +type = openapi:3 +rootFiles[] = index.yaml diff --git a/postman/collections/Customers CHALLENGE.json b/postman/collections/Customers CHALLENGE.json new file mode 100644 index 0000000..36fe640 --- /dev/null +++ b/postman/collections/Customers CHALLENGE.json @@ -0,0 +1,604 @@ +{ + "info": { + "_postman_id": "ee57b305-6748-43ca-8fa6-5a29a3956d42", + "name": "Customers CHALLENGE", + "description": "# Customers CHALLENGE Collection\n\n## Summary\n\nThis collection was designed to test and validate responses from the example [**Customers API**](https://cs-demo.postman.co/workspace/c06eaed9-1cdc-4b3e-934b-3985817a71fc/api/cfd9425f-2989-4f81-87e0-bea133996be4?branch=main), which reads and updates customer-specific data within the Acme Co database.\n\nThis collection does not have any test scripts in any Tests tabs included herein. Users will need to add tests based on the directions provided in the _**Test Automation Success Sprint**_.\n\nOutside of the steps from the Success Sprint, feel free to add any other tests, pre-request scripts, etc. That said, we recommend keeping your workspace in a manageable state so you can continue to easily use it for future reference.\n\n## How to use this collection\n\nThis collection is meant to run demonstrate how test assertions can be used in automated tests in Postman. For demonstrative purposes, our work will be in conjunction with the [Customers API](https://cs-demo.postman.co/workspace/c06eaed9-1cdc-4b3e-934b-3985817a71fc/api/cfd9425f-2989-4f81-87e0-bea133996be4?branch=main) example, which is also available in the _**Test Automation Success Sprint**_ workspace (under APIs > Customers).\n\nYou will notice it is possible to add _Collection-level_ scripts, along with _Request-specific_ **Tests** and **Pre-request Scripts**.\n\nThese scripts are meant to either support or validate required behavior in this API during **manual collection** runs (Postman UI or CLI), **scheduled** **collection** runs, **monitor** runs, and **CI/CD pipeline** runs.\n\n## Scoping\n\nThe collections, folders, and requests in this workspace all have their own scopes, contained within the scope of the workspace itself.\n\nYou can view more information on leveraging scopes within Postman scripts in our [Learning Center documentation](https://learning.postman.com/docs/sending-requests/variables/#variable-scopes).\n\nA quick diagram on how variable scoping is leveraged in Postman can be seen here:\n\n", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_uid": "23245044-ee57b305-6748-43ca-8fa6-5a29a3956d42" + }, + "item": [ + { + "name": "CRUD Challenge", + "item": [ + { + "name": "Create customer", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "// SET A RANDOMIZED INTEGER AND ", + "// SET IT AS A NEW VARIABLE", + "let spendLevel = Math.floor(Math.random()*100);", + "pm.collectionVariables.set('spendLevel', JSON.parse(parseInt(spendLevel)));", + "", + "// CREATE A REQUEST TO ", + "// CALL RANDOM USER INFO", + "const userRequest = {", + " url: 'https://randomuser.me/api',", + " method: 'GET'", + "}", + "", + "// SEND THE REQUEST DEFINED ABOVE AND SET ", + "// COLLECTION-LEVEL VARIABLES BASED ON THE RESPONSE", + "pm.sendRequest(userRequest, (error, response) => {", + " let res = response.json().results[0];", + " console.log(error ? error: res); // RETURNS ERROR OR RESPONSE DEPENDING ON RESULTS", + " let firstName = res.name.first;", + " let lastName = res.name.last;", + " let email = res.email;", + " let dob = res.dob.date;", + " let age = res.dob.age;", + " let cell = res.cell;", + " let nationality = res.nat;", + " pm.collectionVariables.set('firstName', firstName);", + " pm.collectionVariables.set('lastName', lastName);", + " pm.collectionVariables.set('email', email);", + " pm.collectionVariables.set('dob', dob);", + " pm.collectionVariables.set('age', age);", + " pm.collectionVariables.set('cell', cell);", + " pm.collectionVariables.set('nationality', nationality);", + "});" + ], + "type": "text/javascript", + "id": "1d5a278c-299b-4170-8e62-d6f96d8f92a7" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "id": "1898d57a-46de-43f2-b2ab-6f40de7d0028" + } + } + ], + "id": "705a64e1-e8af-4a37-b3bc-5ba5f3f58bde", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"firstName\": \"{{firstName}}\",\n \"lastName\": \"{{lastName}}\",\n \"spendLevel\": {{spendLevel}},\n \"preferredCurrency\": \"{{$randomCurrencyCode}}\",\n \"nationality\": \"{{nationality}}\",\n \"email\": \"{{email}}\",\n \"dob\": \"{{dob}}\",\n \"age\": \"{{age}}\",\n \"cell\": \"{{cell}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/customers", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "customers" + ] + } + }, + "response": [ + { + "id": "efd6e78d-18a4-4fae-bddd-d7c5846d5767", + "name": "Create customer", + "originalRequest": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/customers", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "customers" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "name": "Content-Type", + "description": "", + "type": "text" + } + ], + "cookie": [], + "body": "{\n \"customerId\": \"{{$randomUUID}}\",\n \"firstName\": \"{{$body 'firstName'}}\",\n \"lastName\": \"{{$body 'lastName'}}\",\n \"spendLevel\": {{$body 'spendLevel'}},\n \"currency\": \"{{$body 'preferredCurrency'}}\",\n \"preferredCurrency\": \"{{$body 'preferredCurrency'}}\",\n \"country\": \"{{$body 'nationality'}}\"\n}" + } + ] + }, + { + "name": "Read a customer", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "console.log(`Starting request to random user API`);", + "", + "// CREATE A REQUEST TO CALL RANDOM USER INFO", + "// LOG ERROR IF REQUEST FAILS OR SET VARIABLE WHEN REQUEST IS SUCCESSFUL", + "pm.sendRequest('https://randomuser.me/api', (error, response) => {", + " if(error){", + " console.log(`An error occurred!\\n ${error}`);", + " } else {", + " let userId = response.json().results[0].login.uuid;", + " pm.collectionVariables.set('userId', userId);", + " pm.collectionVariables.set('randomUserData', JSON.stringify(response.json()));", + " }", + "});" + ], + "type": "text/javascript", + "id": "73cd29eb-e061-4073-9096-2703914ae7b0" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "id": "2fb26db5-2b27-4cc8-acb4-19c2515ffa17" + } + } + ], + "id": "f3f50f7e-7bfe-4985-901b-54bf34c534b7", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [ + { + "key": "x-mock-response-id", + "value": "23503262-3fc6b833-dcfd-4b68-b556-9c3825c5f0bd", + "type": "text" + } + ], + "url": { + "raw": "{{baseUrl}}/customers/{{userId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "customers", + "{{userId}}" + ] + } + }, + "response": [ + { + "id": "f162b4dd-27f5-4e44-8176-81fd5fd13487", + "name": "Customer data", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/customers/{{userId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "customers", + "{{userId}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Fri, 07 Jul 2023 21:16:40 GMT" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Content-Length", + "value": "173" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "x-srv-trace", + "value": "v=1;t=a534e8dbefcea89f" + }, + { + "key": "x-srv-span", + "value": "v=1;s=2b7316bc39484fcb" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "X-RateLimit-Limit", + "value": "120" + }, + { + "key": "X-RateLimit-Remaining", + "value": "117" + }, + { + "key": "X-RateLimit-Reset", + "value": "1688764652" + }, + { + "key": "ETag", + "value": "W/\"ad-k3B5ZZ8PoRYytMTuF/O90YrShDA\"" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + } + ], + "cookie": [], + "body": "{\n \"customerId\": \"{{$pathSegments '1'}}\",\n \"firstName\": \"{{$randomFirstName}}\",\n \"lastName\": \"{{$randomLastName}}\",\n \"spendLevel\": \"${{$randomInt}}.00\",\n \"preferredCurrency\": \"{{$randomCurrencyCode}}\",\n \"country\": \"{{$randomCountry}}\"\n}" + } + ] + }, + { + "name": "Update customer", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "// SET A RANDOMIZED INTEGER AND ", + "// SET IT AS A NEW VARIABLE", + "let spendLevel = Math.floor(Math.random()*100);", + "pm.collectionVariables.set('spendLevel', JSON.parse(parseInt(spendLevel)));", + "", + "// CREATE A REQUEST TO ", + "// CALL RANDOM USER INFO", + "const userRequest = {", + " url: 'https://randomuser.me/api',", + " method: 'GET'", + "}", + "", + "// SEND THE REQUEST DEFINED ABOVE AND SET ", + "// COLLECTION-LEVEL VARIABLES BASED ON THE RESPONSE", + "pm.sendRequest(userRequest, (error, response) => {", + " let res = response.json().results[0];", + " // console.log(error ? error: res);", + " let firstName = res.name.first;", + " let lastName = res.name.last;", + " let email = res.email;", + " let dob = res.dob.date;", + " let age = res.dob.age;", + " let cell = res.cell;", + " let nationality = res.nat;", + " pm.collectionVariables.set('firstName', firstName);", + " pm.collectionVariables.set('lastName', lastName);", + " pm.collectionVariables.set('email', email);", + " pm.collectionVariables.set('dob', dob);", + " pm.collectionVariables.set('age', age);", + " pm.collectionVariables.set('cell', cell);", + " pm.collectionVariables.set('nationality', nationality);", + "});" + ], + "type": "text/javascript", + "id": "3853df25-832a-47f7-949c-9ae23ecc1394" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "id": "b8f6648a-da60-40b1-8705-87f3c05760e9" + } + } + ], + "id": "2f1fc7e8-6657-4ada-8951-8295d902a59a", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"firstName\": \"{{firstName}}\",\n \"lastName\": \"{{lastName}}\",\n \"spendLevel\": {{spendLevel}},\n \"preferredCurrency\": \"{{$randomCurrencyCode}}\",\n \"nationality\": \"{{nationality}}\",\n \"email\": \"{{email}}\",\n \"dob\": \"{{dob}}\",\n \"age\": \"{{age}}\",\n \"cell\": \"{{cell}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/customers/{{userId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "customers", + "{{userId}}" + ] + } + }, + "response": [ + { + "id": "683a0064-3cc2-4a32-97f3-874fd99d0765", + "name": "Update customer", + "originalRequest": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/customers/{{userId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "customers", + "{{userId}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "name": "Content-Type", + "description": "", + "type": "text" + } + ], + "cookie": [], + "body": "{\n \"customerId\": \"{{$randomUUID}}\",\n \"firstName\": \"{{$body 'firstName'}}\",\n \"lastName\": \"{{$body 'lastName'}}\",\n \"spendLevel\": {{$body 'spendLevel'}},\n \"currency\": \"{{$body 'preferredCurrency'}}\",\n \"preferredCurrency\": \"{{$body 'preferredCurrency'}}\",\n \"country\": \"{{$body 'nationality'}}\"\n}" + } + ] + }, + { + "name": "Delete customer", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "// CREATE A REQUEST TO ", + "// CALL RANDOM USER INFO", + "const userRequest = {", + " url: 'https://randomuser.me/api',", + " method: 'GET'", + "}", + "", + "// SEND THE REQUEST DEFINED ABOVE AND SET ", + "// COLLECTION-LEVEL VARIABLES BASED ON THE RESPONSE", + "pm.sendRequest(userRequest, (error, response) => {", + " let userId = error ? error: response.json().results[0].login.uuid;", + " pm.collectionVariables.set('userId', userId);", + "});" + ], + "type": "text/javascript", + "id": "0bf37195-796f-4dfd-a805-f0f4bab91fcc" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript", + "id": "5195ad69-e5b7-4b2d-abea-efcdd6ca02da" + } + } + ], + "id": "5ad28a52-05dd-4fc0-925f-3040bed89af7", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "DELETE", + "header": [ + { + "key": "x-delete-customer-bool", + "value": "true", + "type": "text" + } + ], + "url": { + "raw": "{{baseUrl}}/customers/{{userId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "customers", + "{{userId}}" + ] + } + }, + "response": [ + { + "id": "f8b7430b-fe9d-4f4f-9290-6312126b2d44", + "name": "Delete customer", + "originalRequest": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{baseUrl}}/customers/{{userId}}?x-delete-customer-bool=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "customers", + "{{userId}}" + ], + "query": [ + { + "key": "x-delete-customer-bool", + "value": "true" + } + ] + } + }, + "status": "No Content", + "code": 204, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "name": "Content-Type", + "description": "", + "type": "text" + } + ], + "cookie": [], + "body": "" + } + ] + } + ], + "id": "0d257b40-e7cf-42db-b38a-e2a22dfd6135", + "description": "## Collection setup & runner\n\nYou should have already [forked](https://learning.postman.com/docs/collaborating-in-postman/using-version-control/forking-entities/) the **Customers CHALLENGE** collection to a workspace of your own\n\n### **Notes**\n\n- This collection leverages a [Mock server](https://learning.postman.com/docs/designing-and-developing-your-api/mocking-data/setting-up-mock/)\n- These collections use pre-defined example responses that the Mock Server is serving\n \n\n### **Next steps**\n\n1. Send each request from the **CRUD Challenge** folder at least once\n 1. Review the example responses for each request\n 2. Confirm you receive expected responses based on pre-defined example responses\n2. In the Tests tab, add each of the following [test snippets](https://learning.postman.com/docs/writing-scripts/test-scripts/#using-snippets)\\* to each request in the CRUD Challenge folder and save\n 1. `Status Code: Code is 200`\n 2. `Status code name has string`\n 3. `Response time is less than 200ms`\n 4. `Response headers: Content-Type is present`\n3. Send each request and validate responses\n4. Part of this challenge is to update the tests to correctly validate expected responses\n 1. Ex: For a successful POST request, users would expect a `201 Created` HTTP response, as opposed to `200 OK`.\n5. When tests are passing, run your collection\n6. Go to Runs tab and review run data\n \n\n### Expected results\n\n- All tests should indicate a “Success”\n - POST calls should have 201\n - GET/PUT calls should have 200\n - DELETE calls should have 204\n- Collection runner runs without any errors and all tests pass" + } + ], + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "key", + "value": "X-Api-Key", + "type": "string" + }, + { + "key": "value", + "value": "{{apiKey}}", + "type": "string" + }, + { + "key": "in", + "value": "header", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ], + "id": "8797e03a-5122-4f41-afc7-03feaddaa128" + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ], + "id": "91e32e75-a642-4a74-ab11-a6546416b939" + } + } + ], + "variable": [ + { + "id": "70c43352-e6a7-4685-9406-fbec0113faf5", + "key": "baseUrl", + "value": "https://ef10ec23-f5c6-4db6-9673-3056fefd5ccb.mock.pstmn.io" + }, + { + "id": "9d50a026-eef0-41c3-9377-861907b44041", + "key": "randomUserData", + "value": "" + }, + { + "id": "f0f21838-27ff-4458-a57e-f06806836b65", + "key": "userId", + "value": "" + }, + { + "id": "51e14e5c-197e-4d91-b377-3951f8b4cdbd", + "key": "firstName", + "value": "" + }, + { + "id": "225a6368-bcfb-4655-ac1f-90238c7b5d10", + "key": "lastName", + "value": "" + }, + { + "id": "06c49da4-9091-47e7-90a3-88088b8892a6", + "key": "email", + "value": "" + }, + { + "id": "4a987290-936e-4200-a636-085ae5fc89ea", + "key": "dob", + "value": "" + }, + { + "id": "918a0ecc-e5df-4dd4-a44c-1da7ef974b36", + "key": "age", + "value": "" + }, + { + "id": "c997bd62-9467-49b5-85a9-0d866d40911c", + "key": "cell", + "value": "" + }, + { + "id": "ff429ac6-0ad4-4e2e-9f04-058f242a9f74", + "key": "nationality", + "value": "" + }, + { + "id": "dbf08cd0-2880-48ec-98be-342c1a0a43ed", + "key": "spendLevel", + "value": "" + } + ] +} \ No newline at end of file diff --git a/postman/schemas/index.yaml b/postman/schemas/index.yaml index a44c725..c8fc3ec 100644 --- a/postman/schemas/index.yaml +++ b/postman/schemas/index.yaml @@ -1,7 +1,7 @@ openapi: '3.0.0' info: - version: '1.0.3' - title: 'Customers' + version: '1.0.4' + title: 'Customers Service' description: Create or check status of customer(s) servers: @@ -14,14 +14,40 @@ paths: responses: '200': description: The current list of customers using pagination + content: + application/json: + schema: + $ref: '#/components/schemas/Customer' '400': description: Malformed request body + content: + application/json: + schema: + $ref: '#/components/schemas/Error' '401': description: Invalid credentials + content: + application/json: + schema: + $ref: '#/components/schemas/Error' '403': description: Unauthorized access + content: + application/json: + schema: + $ref: '#/components/schemas/Error' '500': description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '503': + description: General error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' /customers/{customerId}: parameters: