-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add comprehensive API tests for coin change calculation
This update introduces a set of API tests to ensure the correct functioning of the application's coin change calculation feature. Various edge cases are considered such as multiple cash denominations, large target values, the absence of unit coins, the target being smaller than the smallest coin, and negative cash value. It also includes a workflow for GitHub Actions to automate these test checks.
- Loading branch information
Jegors Čemisovs
committed
Apr 16, 2024
0 parents
commit b4906f8
Showing
16 changed files
with
386 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# This workflow runs the API tests for the bruno application on the latest version of Ubuntu | ||
|
||
name: API Tests - Change | ||
|
||
on: | ||
workflow_dispatch: | ||
permissions: | ||
contents: read | ||
actions: read | ||
checks: write | ||
jobs: | ||
run_change_api_test: | ||
name: API Tests - Change | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Download ijhttp | ||
run: curl -f -s -L -o ijhttp.zip https://jb.gg/ijhttp/latest | ||
- name: Unpack ijhttp | ||
run: unzip -nq ijhttp.zip | ||
- name: Remove ijhttp.zip | ||
run: rm ijhttp.zip | ||
- name: Run API tests | ||
run: ijhttp/ijhttp --env azure --env-file http-client.env.json change/*.http --report | ||
|
||
- name: Publish Test Report | ||
uses: dorny/test-reporter@v1 | ||
if: success() || failure() # run this step even if previous step failed | ||
with: | ||
name: Change API Tests # Name of the check run which will be created | ||
path: reports/report.xml # Path to test results | ||
reporter: java-junit # Format of test results |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
ISC License | ||
|
||
Copyright 2024 Jegors Čemisovs | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without | ||
fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE | ||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE | ||
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | ||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
### A greedy approach is not optimal | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 20 cents. | ||
# The available coins are 1, 10, and 11 cents. The expected result is two 10 cent coins. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
1, | ||
10, | ||
11 | ||
], | ||
"target": 20 | ||
} | ||
|
||
> {% | ||
client.test("A greedy approach is not optimal", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 2, "Number of coins is not 2"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 10).length === 2, "The coins do not include two 10 cent coins"); | ||
}) | ||
%} |
25 changes: 25 additions & 0 deletions
25
change/Another possible change without unit coins available.http
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
### Another possible change without unit coins available | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 27 cents. | ||
# The available coins are 4 and 5 cents. The expected result is three 4 cent coins and three 5 cent coins. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
4, | ||
5 | ||
], | ||
"target": 27 | ||
} | ||
|
||
> {% | ||
client.test("Another possible change without unit coins available", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 6, "Number of coins is not 6"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 4).length === 3, "The coins do not include three 4 cent coins"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 5).length === 3, "The coins do not include three 5 cent coins"); | ||
}) | ||
%} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
### Cannot find negative change values | ||
# This test case checks if the API correctly returns an error when the target is a negative value. | ||
# The available coins are 1, 2, and 5 cents. The target is -5 cents. The expected result is an error message. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
1, | ||
2, | ||
5 | ||
], | ||
"target": -5 | ||
} | ||
|
||
> {% | ||
client.test("Cannot find negative change values", function () { | ||
client.assert(response.status === 400, "Response status is not 400"); | ||
let body = response.body; | ||
client.assert(body.error === "Negative change not allowed", "Error message is incorrect"); | ||
}) | ||
%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
### Change for 1 cent | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 1 cent. | ||
# The available coins are 1, 5, 10, and 25 cents. The expected result is a single 1 cent coin. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
1, | ||
5, | ||
10, | ||
25 | ||
], | ||
"target": 1 | ||
} | ||
|
||
> {% | ||
client.test("Change for 1 cent", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
const type = response.contentType.mimeType; | ||
client.assert(type === "application/json", `Expected 'application/json' but received '${type}'`); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 1, "Number of coins is not 1"); | ||
client.assert(body.fewestCoins[0] === 1, "The coin is not 1 cent"); | ||
}) | ||
%} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
### Change with Lilliputian Coins | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 23 cents. | ||
# The available coins are 1, 4, 15, 20, and 50 cents. The expected result is two 4 cent coins and one 15 cent coin. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
1, | ||
4, | ||
15, | ||
20, | ||
50 | ||
], | ||
"target": 23 | ||
} | ||
|
||
> {% | ||
client.test("Change with Lilliputian Coins", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 3, "Number of coins is not 3"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 4).length === 2, "The coins do not include two 4 cent coins"); | ||
client.assert(body.fewestCoins.includes(15), "The coins do not include a 15 cent coin"); | ||
}) | ||
%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
### Change with Lower Elbonia Coins | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 63 cents. | ||
# The available coins are 1, 5, 10, 21, and 25 cents. The expected result is three 21 cent coins. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
1, | ||
5, | ||
10, | ||
21, | ||
25 | ||
], | ||
"target": 63 | ||
} | ||
|
||
> {% | ||
client.test("Change with Lower Elbonia Coins", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 3, "Number of coins is not 3"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 21).length === 3, "The coins do not include three 21 cent coins"); | ||
}) | ||
%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
### Error if no combination can add up to target | ||
# This test case checks if the API correctly returns an error when no combination of available coins can add up to the target. | ||
# The available coins are 5 and 10 cents. The target is 94 cents. The expected result is an error message. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
5, | ||
10 | ||
], | ||
"target": 94 | ||
} | ||
|
||
> {% | ||
client.test("Error if no combination can add up to target", function () { | ||
client.assert(response.status === 400, "Response status is not 400"); | ||
let body = response.body; | ||
client.assert(body.error === "can't make target with given coins", "Error message is incorrect"); | ||
}) | ||
%} |
22 changes: 22 additions & 0 deletions
22
change/Error testing for change smaller than the smallest of coins.http
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
### Error testing for change smaller than the smallest of coins | ||
# This test case checks if the API correctly returns an error when the target is smaller than the smallest available coin. | ||
# The available coins are 5 and 10 cents. The target is 3 cents. The expected result is an error message. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
5, | ||
10 | ||
], | ||
"target": 3 | ||
} | ||
|
||
> {% | ||
client.test("Error testing for change smaller than the smallest of coins", function () { | ||
client.assert(response.status === 400, "Response status is not 400"); | ||
let body = response.body; | ||
client.assert(body.error === "can't make target with given coins", "Error message is incorrect"); | ||
}) | ||
%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
### Large target values | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 999 cents. | ||
# The available coins are 1, 2, 5, 10, 20, 50, and 100 cents. The expected result is two 2 cent coins, one 5 cent coin, two 20 cent coins, one 50 cent coin, and seven 100 cent coins. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
1, | ||
2, | ||
5, | ||
10, | ||
20, | ||
50, | ||
100 | ||
], | ||
"target": 999 | ||
} | ||
|
||
> {% | ||
client.test("Large target values", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 15, "Number of coins is not 15"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 2).length === 2, "The coins do not include two 2 cent coins"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 5).length === 1, "The coins do not include one 5 cent coin"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 20).length === 2, "The coins do not include two 20 cent coins"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 50).length === 1, "The coins do not include one 50 cent coin"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 100).length === 9, "The coins do not include nine 100 cent coins"); | ||
}) | ||
%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
### Multiple coin change | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 15 cents. | ||
# The available coins are 1, 5, 10, 25, and 100 cents. The expected result is one 5 cent coin and one 10 cent coin. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
1, | ||
5, | ||
10, | ||
25, | ||
100 | ||
], | ||
"target": 15 | ||
} | ||
|
||
> {% | ||
client.test("Multiple coin change", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 2, "Number of coins is not 2"); | ||
client.assert(body.fewestCoins.includes(5), "The coins do not include a 5 cent coin"); | ||
client.assert(body.fewestCoins.includes(10), "The coins do not include a 10 cent coin"); | ||
}) | ||
%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
### No coins make 0 change | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 0 cents. | ||
# The available coins are 1, 5, 10, 21, and 25 cents. The expected result is an empty array. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
1, | ||
5, | ||
10, | ||
21, | ||
25 | ||
], | ||
"target": 0 | ||
} | ||
|
||
> {% | ||
client.test("No coins make 0 change", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 0, "Number of coins is not 0"); | ||
}) | ||
%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
### Possible change without unit coins available | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 21 cents. | ||
# The available coins are 2, 5, 10, 20, and 50 cents. The expected result is three 2 cent coins, one 5 cent coin, and one 10 cent coin. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
2, | ||
5, | ||
10, | ||
20, | ||
50 | ||
], | ||
"target": 21 | ||
} | ||
|
||
> {% | ||
client.test("Possible change without unit coins available", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 5, "Number of coins is not 5"); | ||
client.assert(body.fewestCoins.filter(coin => coin === 2).length === 3, "The coins do not include three 2 cent coins"); | ||
client.assert(body.fewestCoins.includes(5), "The coins do not include a 5 cent coin"); | ||
client.assert(body.fewestCoins.includes(10), "The coins do not include a 10 cent coin"); | ||
}) | ||
%} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
### Single coin change | ||
# This test case checks if the API correctly returns the fewest number of coins for a target of 25 cents. | ||
# The available coins are 1, 5, 10, 25, and 100 cents. The expected result is a single 25 cent coin. | ||
|
||
POST {{host}}/api/change HTTP/1.1 | ||
Content-Type: application/json | ||
|
||
{ | ||
"coins": [ | ||
1, | ||
5, | ||
10, | ||
25, | ||
100 | ||
], | ||
"target": 25 | ||
} | ||
|
||
> {% | ||
client.test("Single coin change", function () { | ||
client.assert(response.status === 200, "Response status is not 200"); | ||
const type = response.contentType.mimeType; | ||
client.assert(type === "application/json", `Expected 'application/json' but received '${type}'`); | ||
let body = response.body; | ||
client.assert(body.fewestCoins.length === 1, "Number of coins is not 1"); | ||
client.assert(body.fewestCoins[0] === 25, "The coin is not 25 cents"); | ||
}) | ||
%} |
Oops, something went wrong.