Skip to content

Extended test case #1

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

Merged
merged 1 commit into from
Dec 10, 2024
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
43 changes: 39 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
# API test task
In order to run the API and the documentation execute
# Senior QA Engineer (API) - Test Task
You have done an awesome job in your first interview! We designed this case study to get to
know you and your way of working a little better.
Please take no more than 2h to solve the following questions. Try to focus on the main
important topics and if you struggle with one task try to continue with another one :-)

Important: we want to hire human intelligence, not artificial intelligence. Therefore do not use
AI-assisted tools like chatbots or AI coding assistants (e.g. ChatGPT or GitHub Copilot) to solve
this task. You are of course free to use any other tool you like such as IDEs, normal
autocomplete, libraries and so on. But keep in mind that the point of this task is not to present
the perfect solution under ideal conditions, but to show us how you work.
Note: please do not upload the task or your solution to GitHub or anywhere else. We want to
keep the experience of working on the task the same for all candidates.

docker compose up -d
## Run instructions
Clone this Git repository. You will need docker and docker compose installed.
After doing “docker compose up -d” in the root folder of the repo, the backend API as well as the swagger
documentation will be available. In order to access the swagger documentation, go to
your browser and visit http://localhost:8081. All the backend APIs will be available with
the host http://localhost:8080, you can use Postman or curl to test the API and inspect
requests.
Good luck and have fun! 💫

in the root of the folder
## Task description
The backend developer has finished implementing APIs that the frontend should use in
order to get campaigns, make a view and make a click. The backend developers have
also created swagger documentation describing the API.
A user is supposed to make a request to /campaign-distribution/campaigns in order to
get the list of campaigns. A campaign is always related to an app, which has a unique creative.
The frontend will later render this response. When a user
scrolls through the list of campaigns, a request to the ViewURL given in the list should be
executed once and this request will return an empty response. When the user clicks on
the campaign in the list, a request to the ClickURL should be executed and this request
will return in the response the store URL to which the user should then be redirected.

## Todo
When you are done, send us a zip file containing the test report with prioritization of the bugs,
as well as any additional material (for example screenshots or log files). If you wrote code or
scripts please include them as well.
Your task is to test the backend API and not any frontend. After your findings, write down a
list of test cases that should be done for regression testing. Suggestions and improvements to the process are also welcome.
31 changes: 26 additions & 5 deletions api_spec/api.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,31 @@
}
],
"paths": {
"/campaign-distribution/campaigns": {
"/campaign-distribution/android/campaigns": {
"get": {
"summary": "Get list of campaigns",
"description": "Get a list of campaigns",
"summary": "Get list of Android campaigns",
"description": "Get a list of Android campaigns",
"responses": {
"200": {
"description": "Successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CampaignList"
}
}
}
},
"400": {
"description": "Invalid request"
}
}
}
},
"/campaign-distribution/ios/campaigns": {
"get": {
"summary": "Get list of iOS campaigns",
"description": "Get a list of iOS campaigns",
"responses": {
"200": {
"description": "Successful operation",
Expand Down Expand Up @@ -81,7 +102,7 @@
"properties": {
"CreativeID": {
"type": "string",
"example": "123"
"example": "ed75c3d6-db84-4b2a-85c0-d5d26fb2fba9"
}
}
},
Expand Down Expand Up @@ -114,7 +135,7 @@
},
"CreativeID": {
"type": "string",
"example": 123
"example": "ed75c3d6-db84-4b2a-85c0-d5d26fb2fba9"
},
"ClickURL": {
"type": "string",
Expand Down
181 changes: 173 additions & 8 deletions wiremock/mappings/mocks.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
{
"request": {
"method": "GET",
"url": "/campaign-distribution/campaigns"
"url": "/campaign-distribution/android/campaigns"
},

"response": {
"status": 200,
"body": "{\"Length\":2,\"Campaigns\":[{\"AppID\":\"553834731\",\"AppName\":\"App1\",\"CreativeID\":\"one\",\"ClickURL\":\"/campaign-click/click/123\",\"ViewURL\":\"/campaign-view/view/123\"}]}",
"body": "{\"Length\":3,\"Campaigns\":[{\"AppID\":\"6458097001\",\"AppName\":\"Archery Clash\",\"CreativeID\":\"31f15623-57c6-450e-82eb-1fda52cade22\",\"ClickURL\":\"/campaign-click/click/123\",\"ViewURL\":\"/campaign-view/view/123\"},{\"AppID\":\"ball.sort.color.puz.game.puzzle\",\"AppName\":\"Ballsort\",\"CreativeID\":\"7f79cb7e-9285-442e-9e64-e861c9b1e60c\",\"ClickURL\":\"/campaign-click/click/321\",\"ViewURL\":\"/campaign-view/view/321\"}]}",
"headers": {
"Content-Type": "text/json"
},
Expand All @@ -19,17 +19,122 @@
}
}
},
{
"request": {
"method": "GET",
"url": "/campaign-distribution/ios/campaigns"
},
"response": {
"status": 200,
"body": "{\"Campaigns\":[{\"AppID\":\"6466648550\",\"AppName\":\"Warriors\",\"CreativeID\":\"356054a8-7129-474b-848f-4aa6e164c492\",\"ClickURL\":\"/campaign-click/click/456\",\"ViewURL\":\"/campaign-view/view/456\"},{\"AppID\":\"1494108691\",\"AppName\":\"Sort puzzle\",\"CreativeID\":\"356054a8-7129-474b-848f-4aa6e164c492\",\"ClickURL\":\"/campaign-click/click/567\",\"ViewURL\":\"/campaign-view/view/567\"}]}",
"headers": {
"Content-Type": "text/json"
}
}
},
{
"priority": 1,
"request": {
"method": "POST",
"url": "/campaign-click/click/321",
"bodyPatterns": [
{
"matchesJsonSchema": {
"type": "object",
"required": ["CreativeID"],
"properties": {
"CreativeID": {
"type": "string"
}
}
}
}
]
},
"response": {
"status": 200,
"body": "{\"StoreURL\":\"https://play.google.com/store/apps/details?id=ball.sort.color.puz.game.puzzle\"}",
"headers": {
"Content-Type": "text/json"
}
}
},
{
"priority": 1,
"request": {
"method": "POST",
"url": "/campaign-click/click/123",
"bodyPatterns": [{ "equalToJson": "{\"CreativeID\":\"one\"}" }]
"bodyPatterns": [
{
"matchesJsonSchema": {
"type": "object",
"required": ["CreativeID"],
"properties": {
"CreativeID": {
"type": "string"
}
}
}
}
]
},
"response": {
"status": 200,
"body": "{\"StoreURL\":\"https://apps.apple.com/us/app/id6458097001\"}",
"headers": {
"Content-Type": "text/json"
}
}
},
{
"priority": 1,
"request": {
"method": "POST",
"url": "/campaign-click/click/456",
"bodyPatterns": [
{
"matchesJsonSchema": {
"type": "object",
"required": ["CreativeID"],
"properties": {
"CreativeID": {
"type": "string"
}
}
}
}
]
},
"response": {
"status": 200,
"body": "{\"StoreURL\":\"https://apps.apple.com/us/app/id666648550\"}",
"headers": {
"Content-Type": "text/json"
}
}
},
{
"priority": 1,
"request": {
"method": "POST",
"url": "/campaign-click/click/567",
"bodyPatterns": [
{
"matchesJsonSchema": {
"type": "object",
"required": ["CreativeID"],
"properties": {
"CreativeID": {
"type": "string"
}
}
}
}
]
},

"response": {
"status": 200,
"body": "{\"StoreURL\":\"https://apps.apple.com/us/app/id553834731\"}",
"body": "{\"StoreURL\":\"https://apps.apple.com/us/app/id1494108691\"}",
"headers": {
"Content-Type": "text/json"
}
Expand Down Expand Up @@ -83,14 +188,74 @@
"url": "/campaign-view/view/123",
"bodyPatterns": [
{
"equalToJson": "{\"CreativeID\":\"one\"}"
"equalToJson": "{\"CreativeID\":\"31f15623-57c6-450e-82eb-1fda52cade22\"}"
}
]
},

"response": {
"status": 301,
"body": "{\"RedirectURL\":\"https://apps.apple.com/us/app/id6466648550\"}",
"headers": {
"Content-Type": "text/json"
}
}
},
{
"priority": 1,
"request": {
"method": "POST",
"url": "/campaign-view/view/321",
"bodyPatterns": [
{
"equalToJson": "{\"CreativeID\":\"7f79cb7e-9285-442e-9e64-e861c9b1e60c\"}"
}
]
},

"response": {
"status": 301,
"body": "{\"RedirectURL\":\"https://play.google.com/store/apps/details?id=ball.sort.color.puz.game.puzzle\"}",
"headers": {
"Content-Type": "text/json"
}
}
},
{
"priority": 1,
"request": {
"method": "POST",
"url": "/campaign-view/view/456",
"bodyPatterns": [
{
"equalToJson": "{\"CreativeID\":\"356054a8-7129-474b-848f-4aa6e164c492\"}"
}
]
},

"response": {
"status": 301,
"body": "{\"RedirectURL\":\"https://apps.apple.com/us/app/id553834731\"}",
"body": "{\"RedirectURL\":\"https://apps.apple.com/us/app/id6466648550\"}",
"headers": {
"Content-Type": "text/json"
}
}
},
{
"priority": 1,
"request": {
"method": "POST",
"url": "/campaign-view/view/567",
"bodyPatterns": [
{
"equalToJson": "{\"CreativeID\":\"356054a8-7129-474b-848f-4aa6e164c492\"}"
}
]
},

"response": {
"status": 301,
"body": "{\"RedirectURL\":\"https://apps.apple.com/us/app/id1494108691\"}",
"headers": {
"Content-Type": "text/json"
}
Expand All @@ -100,7 +265,7 @@
"priority": 2,
"request": {
"method": "POST",
"url": "/campaign-view/view/123",
"url": "/campaign-view/view/[0-9]*",
"bodyPatterns": [
{
"matchesJsonSchema": {
Expand Down