From f869b748a4dd5b15dc78c790f5958fd55bbc9f79 Mon Sep 17 00:00:00 2001 From: Lisa Perrett Date: Mon, 17 Jul 2023 15:19:42 +0100 Subject: [PATCH] Lisa/Paul - added Postman collection so users can import it into Postman and updated the readme. --- README.md | 50 +- test/postman/postmanCollection.json | 685 ++++++++++++++++++++++++++++ 2 files changed, 715 insertions(+), 20 deletions(-) create mode 100644 test/postman/postmanCollection.json diff --git a/README.md b/README.md index 30a7130..89e0a8e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The aim of this experiment is to gain an understanding of the productivity gains ## Developers -The development task is to implement a web service that provides endpoints to manage a to do list. The choice of implementation language is at your discretion. Skeleton implementations have been provided in C#, Java and JavaScript on the ```start-here``` branch. It is also valid to start completely from scratch if you wish. +The development task is to implement a web service that provides endpoints to manage a to do list. The choice of implementation language is at your discretion. Skeleton implementations have been provided in C#, Java and JavaScript on the `start-here` branch. It is also valid to start completely from scratch if you wish. No guidance is provided as to the use of generative AI tools in completing the implementation of the web server. It is valid to implement a solution using generative AI and consider the experience and productivity gain as a standalone activity. It is also valid to implement a solution without using generative AI and then revert to the skeleton code and re-implement a solution using generative AI to compare the experience and the time taken for each implementation. @@ -45,7 +45,7 @@ The server data will be initialised with a list containing three tasks: The intial GET endpoint returns the list of tasks held by the server. If you are starting from scratch you need to implement this endpoint before continuing. -The data above is stored in the file ```src/static_data/ToDoList.json``` within the project. Feel free to copy and paste it into the implementation, or load the data from the file. +The data above is stored in the file `src/static_data/ToDoList.json` within the project. Feel free to copy and paste it into the implementation, or load the data from the file. ## Changes required @@ -58,11 +58,11 @@ http://localhost:8080/todo{?complete=true} A GET endpoint that takes an optional boolean parameter “complete”. If the parameter is given then the endpoint returns a list of tasks that have been filtered based on the value supplied for the parameter: -| URI | Required behaviour | -|-------------------------------------------|--------------------------------------------------| -| http://localhost:8080/todo | Return a list of all tasks with HTTP status 200. | -| http://localhost:8080/todo?complete=true | Return a list only containing completed tasks with HTTP status 200. | -| http://localhost:8080/todo?complete=false | Return a list only containing incomplete tasks with HTTP status 200. | +| URI | Required behaviour | +| ----------------------------------------- | -------------------------------------------------------------------- | +| http://localhost:8080/todo | Return a list of all tasks with HTTP status 200. | +| http://localhost:8080/todo?complete=true | Return a list only containing completed tasks with HTTP status 200. | +| http://localhost:8080/todo?complete=false | Return a list only containing incomplete tasks with HTTP status 200. | ### Add a new GET endpoint to obtain a task by uuid. @@ -72,9 +72,9 @@ http://localhost:8080/todo/{uuid} A GET endpoint that uses a uuid as a path parameter to return the task with the supplied uuid from the list of tasks. The endpoint returns the task with the given uuid if it exists, otherwise a fixed UNKNOWN_TASK is returned. If an invalid uuid is supplied the endpoint will return a bad request error. -| URI | Required behaviour | -|-------------------------------------------|--------------------------------------------------| -| http://localhost:8080/todo/{uuid} | Return the task with supplied uuid with HTTP status 200. | +| URI | Required behaviour | +| --------------------------------- | -------------------------------------------------------- | +| http://localhost:8080/todo/{uuid} | Return the task with supplied uuid with HTTP status 200. | Given the static data data above: @@ -90,6 +90,7 @@ http://localhost:8080/todo/5c3ec8bc-6099-4cd5-b6da-8e2956db3a34 returns "complete": false } ``` + with HTTP status 200. http://localhost:8080/todo/5c3ec8bc-6099-1a2b-b6da-8e2956db3a34 returns @@ -104,6 +105,7 @@ http://localhost:8080/todo/5c3ec8bc-6099-1a2b-b6da-8e2956db3a34 returns "complete": false } ``` + with HTTP status 200. http://localhost:8080/todo/invalid-uuid returns @@ -116,6 +118,7 @@ http://localhost:8080/todo/invalid-uuid returns "path": "/todo/invalid-uuid" } ``` + with HTTP status 400. ### Add a new PUT endpoint to mark a task as complete. @@ -129,11 +132,11 @@ Add a new PUT endpoint that uses a uuid as a path parameter to mark a specific t } ``` - If the task is already marked as completed, or the task is not found, then no change is made and the problem should be indicated in the response. If an invalid uuid is supplied the endpoint will return a bad request error. +If the task is already marked as completed, or the task is not found, then no change is made and the problem should be indicated in the response. If an invalid uuid is supplied the endpoint will return a bad request error. -| URI | Required behaviour | -|-----------------------------------------------------|--------------------------------------------------| -| http://localhost:8080/todo/completed/{uuid} | Mark the task with supplied uuid as complete and return a meaningful response with HTTP status 200. To mark a task as complete the “completed” fields should be set to the current time and the “complete” boolean value should be set to true.| +| URI | Required behaviour | +| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| http://localhost:8080/todo/completed/{uuid} | Mark the task with supplied uuid as complete and return a meaningful response with HTTP status 200. To mark a task as complete the “completed” fields should be set to the current time and the “complete” boolean value should be set to true. | Given the static data above: @@ -145,6 +148,7 @@ http://localhost:8080/todo/5c3ec8bc-6099-4cd5-b6da-8e2956db3a34 returns "message": "This task has now been completed." } ``` + with HTTP status 200. A further call to http://localhost:8080/todo/5c3ec8bc-6099-4cd5-b6da-8e2956db3a34 returns @@ -155,6 +159,7 @@ A further call to http://localhost:8080/todo/5c3ec8bc-6099-4cd5-b6da-8e2956db3a3 "message": "Task already marked complete." } ``` + with HTTP status 200. http://localhost:8080/todo/5c3ec8bc-6099-1a2b-b6da-8e2956db3a34 returns @@ -165,6 +170,7 @@ http://localhost:8080/todo/5c3ec8bc-6099-1a2b-b6da-8e2956db3a34 returns "message": "Task not found." } ``` + with HTTP status 200. http://localhost:8080/todo/completed/invalid-uuid returns @@ -177,6 +183,7 @@ http://localhost:8080/todo/completed/invalid-uuid returns "path": "/todo/completed/invalid-uuid" } ``` + with HTTP status 400. ### Add a new POST endpoint to create a new task and add it to the list of tasks. @@ -190,12 +197,11 @@ Add a new POST endpoint that takes two parameters, task name and task descriptio } ``` - The status of the response should be 201 (CREATED) for a successful operation. If both name and description parameters are not supplied the endpoint will return a bad request error. - +The status of the response should be 201 (CREATED) for a successful operation. If both name and description parameters are not supplied the endpoint will return a bad request error. -| URI | Required behaviour | -|------------------------------------------------------------------------------------------|--------------------------------------------------| -| http://localhost:8080/todo/addTask{?name=Name&description=Description} | Create a new task with the given name and description, add it to the list of tasks and return HTTP status 201.| +| URI | Required behaviour | +| ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| http://localhost:8080/todo/addTask{?name=Name&description=Description} | Create a new task with the given name and description, add it to the list of tasks and return HTTP status 201. | http://localhost:8080/todo/addTask?name=Name&description=Description returns: @@ -240,4 +246,8 @@ The tests found in `test/cypress/e2e` will appear. To run, click on your test su You can add tests to this file, or create a new test suite. -You can also run tests headlessly using `npx cypress run` \ No newline at end of file +You can also run tests headlessly using `npx cypress run` + +## Using Postman + +There is a Postman collection under the test folder. This can be imported into Postman, which can be used to aid development and testing. diff --git a/test/postman/postmanCollection.json b/test/postman/postmanCollection.json new file mode 100644 index 0000000..ac3bc97 --- /dev/null +++ b/test/postman/postmanCollection.json @@ -0,0 +1,685 @@ +{ + "info": { + "_postman_id": "162fd908-a5da-4134-bc2b-efe33ad6a8ce", + "name": "localhost:8080/", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "28135579", + "_collection_link": "https://quantifying-ai-sl.postman.co/workspace/Gen-AI-Team-Workspace~b724e7f4-2c07-4717-8e36-cf26a1c46c79/collection/28188874-162fd908-a5da-4134-bc2b-efe33ad6a8ce?action=share&creator=28135579&source=collection_link" + }, + "item": [ + { + "name": "ToDoTask - List All Tasks", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "var jsonData = pm.response.json()\r", + " pm.test(\"The length of the array is: \" + (jsonData.length));\r", + "\r", + "\r", + "\r", + "\r", + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disabledSystemHeaders": {}, + "disableUrlEncoding": false + }, + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/todo", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo" + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Completed List", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "\r", + " var jsonData = pm.response.json();\r", + "\r", + " if(jsonData.length == 0){\r", + " pm.test(\"The array is empty\");\r", + " } else {\r", + " pm.test(\"The length of the array is: \" + (jsonData.length));\r", + " }\r", + "}) \r", + "\r", + "\r", + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disabledSystemHeaders": {}, + "disableUrlEncoding": false + }, + "request": { + "auth": { + "type": "noauth" + }, + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/todo?complete=true", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo" + ], + "query": [ + { + "key": "complete", + "value": "true" + } + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Not Completed List", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "\r", + " var jsonData = pm.response.json();\r", + "\r", + " if(jsonData.length == 0){\r", + " pm.test(\"The array is empty\");\r", + " } else {\r", + " pm.test(\"The length of the array is: \" + (jsonData.length));\r", + " }\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/todo?complete=false", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo" + ], + "query": [ + { + "key": "complete", + "value": "false" + } + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Task Three", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test(\"Data Comparison for GET Task Three\", function () {\r", + " var expected = {\r", + " uuid: \"5c3ec8bc-6099-4cd5-b6da-8e2956db3a34\",\r", + " name: \"Test generative AI\",\r", + " description: \"Use generative AI technology to write a simple web service\",\r", + " created: \"2023-06-23T09:00:00Z\",\r", + " completed: null,\r", + " complete: false\r", + " }\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData.uuid).to.eql(expected.uuid);\r", + " pm.expect(jsonData.name).to.eql(expected.name);\r", + " pm.expect(jsonData.description).to.eql(expected.description);\r", + " pm.expect(new Date(jsonData.created).getTime()).to.eql(new Date(expected.created).getTime());\r", + " pm.expect(jsonData.completed).to.eql(expected.completed);\r", + " pm.expect(jsonData.complete).to.eql(expected.complete);\r", + "});\r", + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disabledSystemHeaders": {} + }, + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/todo/5c3ec8bc-6099-4cd5-b6da-8e2956db3a34", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "5c3ec8bc-6099-4cd5-b6da-8e2956db3a34" + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Task Not Found", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test(\"Data Comparison for GET task not found\", function () {\r", + " var expected = {\r", + " uuid: \"00000000-0000-0000-0000-000000000000\",\r", + " name: \"Unknown Task\",\r", + " description: \"Unknown Task\",\r", + " created: \"1970-01-01T00:00:00Z\",\r", + " completed: null,\r", + " complete: false\r", + " }\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData.uuid).to.eql(expected.uuid);\r", + " pm.expect(jsonData.name).to.eql(expected.name);\r", + " pm.expect(jsonData.description).to.eql(expected.description);\r", + " pm.expect(new Date(jsonData.created).getTime()).to.eql(new Date(expected.created).getTime());\r", + " pm.expect(jsonData.completed).to.eql(expected.completed);\r", + " pm.expect(jsonData.complete).to.eql(expected.complete);\r", + "});\r", + "" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disabledSystemHeaders": {} + }, + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/todo/5c3ec8bc-6099-1a2b-b6da-8e2956db3a34", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "5c3ec8bc-6099-1a2b-b6da-8e2956db3a34" + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Invalid UUID", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.response.to.have.status(400);\r", + "});\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "var moment = require('moment');\r", + "pm.globals.set(\"CurrentDateTime\", moment());" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disabledSystemHeaders": {} + }, + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/todo/invalid-uuid", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "invalid-uuid" + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Complete Task Two", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + " \r", + "pm.test(\"Data Comparison for PUT task completion\", function () {\r", + " var expectedOutcome = {\r", + " success: true,\r", + " message: \"This task has now been completed.\",\r", + " }\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.eql(expectedOutcome);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [], + "url": { + "raw": "http://localhost:8080/todo/completed/fd5ff9df-f194-4c6e-966a-71b38f95e14f", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "completed", + "fd5ff9df-f194-4c6e-966a-71b38f95e14f" + ], + "query": [ + { + "key": "", + "value": "", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Complete Task Two (Already Complete)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test(\"PUT Data Comparison for PUT task already completed\", function () {\r", + " var expectedOutcome = {\r", + " success: false,\r", + " message: \"Task already marked complete.\",\r", + " }\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.eql(expectedOutcome);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [], + "url": { + "raw": "http://localhost:8080/todo/completed/fd5ff9df-f194-4c6e-966a-71b38f95e14f", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "completed", + "fd5ff9df-f194-4c6e-966a-71b38f95e14f" + ], + "query": [ + { + "key": "", + "value": "", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Task Not Found", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test(\"PUT Data Comparison for PUT task not found\", function () {\r", + " var expected = {\r", + " success: false,\r", + " message: \"Task not found.\"\r", + " }\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.eql(expected);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [], + "url": { + "raw": "http://localhost:8080/todo/completed/fd5ff9df-f194-1a3b-966a-71b38f95e14f", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "completed", + "fd5ff9df-f194-1a3b-966a-71b38f95e14f" + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Invalid UUID", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.response.to.have.status(400);\r", + "});\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [], + "url": { + "raw": "http://localhost:8080/todo/completed/invalid-uuid", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "completed", + "invalid-uuid" + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Add Task Four", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 201\", function () {\r", + " pm.response.to.have.status(201);\r", + "});\r", + "\r", + "pm.test(\"Data Comparison for ADD Task 4\", function () {\r", + " var expected = {\r", + " message: \"Task Task Four added successfully.\"\r", + " }\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData.message).to.eql(expected.message);\r", + "})" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/todo/addTask?name=Task Four&description=Description Four", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "addTask" + ], + "query": [ + { + "key": "name", + "value": "Task Four" + }, + { + "key": "description", + "value": "Description Four" + } + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Add Task Missing Description and Name values", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/todo/addTask?name=&description=", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "addTask" + ], + "query": [ + { + "key": "name", + "value": "" + }, + { + "key": "description", + "value": "" + } + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Add Task Missing Description", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "http://localhost:8080/todo/addTask?name=Missing Description", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "addTask" + ], + "query": [ + { + "key": "name", + "value": "Missing Description" + } + ] + } + }, + "response": [] + }, + { + "name": "ToDoTask - Add Task Missing Name", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.response.to.have.status(400);\r", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "url": { + "raw": "http://localhost:8080/todo/addTask?description=Missing Name", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "todo", + "addTask" + ], + "query": [ + { + "key": "description", + "value": "Missing Name" + } + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file