Skip to content
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

test: migrate e2e/distribution to system tests #21908

Merged
merged 31 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
31aa851
WIP: authz systemtests
akhilkumarpilli Sep 12, 2024
de098de
Merge branch 'main' into akhil/authz-system-tests
akhilkumarpilli Sep 17, 2024
5a85f11
wip: tests
akhilkumarpilli Sep 17, 2024
977f45b
WIP: tests
akhilkumarpilli Sep 18, 2024
aadce22
add more tests
akhilkumarpilli Sep 19, 2024
2a17147
add generic exec tests
akhilkumarpilli Sep 19, 2024
926b01c
add few more tests
akhilkumarpilli Sep 20, 2024
43d34a7
tests done
akhilkumarpilli Sep 23, 2024
9f83e3f
delete old e2e tests
akhilkumarpilli Sep 23, 2024
3e9e8ca
update godoc and move method
akhilkumarpilli Sep 23, 2024
ce7655c
add build flag and APIAddress method
akhilkumarpilli Sep 23, 2024
5fb43c9
fix lint
akhilkumarpilli Sep 23, 2024
e0b3ecf
Merge branch 'main' into akhil/authz-system-tests
akhilkumarpilli Sep 23, 2024
4e48f8b
address comments
akhilkumarpilli Sep 24, 2024
3edaedd
fix lint and add build tag
akhilkumarpilli Sep 25, 2024
621723c
Merge branch 'main' into akhil/authz-system-tests
akhilkumarpilli Sep 25, 2024
2ce8237
address comments
akhilkumarpilli Sep 25, 2024
ffdfd2a
test: migrate e2e/distribution to system tests
akhilkumarpilli Sep 25, 2024
2d99740
add grpc request with headers method
akhilkumarpilli Sep 25, 2024
228ed90
add remaining tests
akhilkumarpilli Sep 26, 2024
3c99fde
Merge branch 'main' into akhil/distr-system-tests
akhilkumarpilli Oct 1, 2024
81ab8b9
typo
akhilkumarpilli Oct 1, 2024
2fca8c4
Merge branch 'main' into akhil/distr-system-tests
akhilkumarpilli Oct 4, 2024
32ae1f2
fix typo
akhilkumarpilli Oct 4, 2024
12def9e
fix lint
akhilkumarpilli Oct 4, 2024
4a056ba
fix lint
akhilkumarpilli Oct 4, 2024
d748c46
delete e2e tests
akhilkumarpilli Oct 4, 2024
95cc7c4
fix ci
akhilkumarpilli Oct 4, 2024
1cf1862
revert change
akhilkumarpilli Oct 4, 2024
9c261aa
address comments
akhilkumarpilli Oct 4, 2024
ccf100f
fix failing ci
akhilkumarpilli Oct 4, 2024
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
349 changes: 349 additions & 0 deletions tests/systemtests/distribution_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,349 @@
package systemtests

import (
"fmt"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
)

func TestWithdrawAllRewardsCmd(t *testing.T) {
// scenario: test distribution withdraw all rewards command
// given a running chain

sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)

newAddr := cli.AddKey("newAddr")
require.NotEmpty(t, newAddr)

testDenom := "stake"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Define 'testDenom' as a constant

The variable testDenom is a constant value throughout the tests. Defining it as a constant improves code readability and conveys that its value does not change.

Apply this diff:

-testDenom := "stake"
+const testDenom = "stake"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
testDenom := "stake"
const testDenom = "stake"


var initialAmount int64 = 10000000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Define 'initialAmount' as a constant

Since initialAmount represents a fixed initial value, consider defining it as a constant to enhance code clarity.

Apply this diff:

-var initialAmount int64 = 10000000
+const initialAmount int64 = 10_000_000
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var initialAmount int64 = 10000000
const initialAmount int64 = 10_000_000

initialBalance := fmt.Sprintf("%d%s", initialAmount, testDenom)
sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", newAddr, initialBalance},
)
sut.StartChain(t)

// query balance
newAddrBal := cli.QueryBalance(newAddr, testDenom)
require.Equal(t, initialAmount, newAddrBal)

// query validator operator address
rsp := cli.CustomQuery("q", "staking", "validators")
validators := gjson.Get(rsp, "validators.#.operator_address").Array()
require.GreaterOrEqual(t, len(validators), 2)
val1Addr := validators[0].String()
val2Addr := validators[1].String()

var delegationAmount int64 = 100000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Define 'delegationAmount' as a constant

The delegationAmount variable holds a constant value used in multiple places. Defining it as a constant will make the code more maintainable.

Apply this diff:

-var delegationAmount int64 = 100000
+const delegationAmount int64 = 100_000
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var delegationAmount int64 = 100000
const delegationAmount int64 = 100_000

delegation := fmt.Sprintf("%d%s", delegationAmount, testDenom)

// delegate tokens to validator1
rsp = cli.RunAndWait("tx", "staking", "delegate", val1Addr, delegation, "--from="+newAddr, "--fees=1"+testDenom)
RequireTxSuccess(t, rsp)

// delegate tokens to validator2
rsp = cli.RunAndWait("tx", "staking", "delegate", val2Addr, delegation, "--from="+newAddr, "--fees=1"+testDenom)
RequireTxSuccess(t, rsp)

// check updated balance: newAddrBal - delegatedBal - fees
expBal := newAddrBal - (delegationAmount * 2) - 2
newAddrBal = cli.QueryBalance(newAddr, testDenom)
require.Equal(t, expBal, newAddrBal)

withdrawCmdArgs := []string{"tx", "distribution", "withdraw-all-rewards", "--from=" + newAddr, "--fees=1" + testDenom}

// test with --max-msgs
testCases := []struct {
name string
maxMsgs int
expTxLen int
}{
{
"--max-msgs value is 1",
1,
2,
},
{
"--max-msgs value is 2",
2,
1,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assertGenOnlyOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool {
require.Len(t, gotOutputs, 1)
// gets output combining two objects without any space or new line
splitOutput := strings.Split(gotOutputs[0].(string), "}{")
require.Len(t, splitOutput, tc.expTxLen)
return false
}
cmd := append(withdrawCmdArgs, fmt.Sprintf("--max-msgs=%d", tc.maxMsgs), "--generate-only")
_ = cli.WithRunErrorMatcher(assertGenOnlyOutput).Run(cmd...)
})
}
Comment on lines +88 to +100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Simplify the test case loop by extracting common logic

In the loop over test cases, the construction of cmd and the assertion function are repeated. Consider refactoring to reduce duplication and improve readability.

You can extract the assertion function and command construction outside the loop:

 for _, tc := range testCases {
     t.Run(tc.name, func(t *testing.T) {
+        cmd := append(withdrawCmdArgs, fmt.Sprintf("--max-msgs=%d", tc.maxMsgs), "--generate-only")
         assertGenOnlyOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool {
             require.Len(t, gotOutputs, 1)
             // gets output combining two objects without any space or new line
             splitOutput := strings.Split(gotOutputs[0].(string), "}{")
             require.Len(t, splitOutput, tc.expTxLen)
             return false
         }
-        cmd := append(withdrawCmdArgs, fmt.Sprintf("--max-msgs=%d", tc.maxMsgs), "--generate-only")
         _ = cli.WithRunErrorMatcher(assertGenOnlyOutput).Run(cmd...)
     })
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assertGenOnlyOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool {
require.Len(t, gotOutputs, 1)
// gets output combining two objects without any space or new line
splitOutput := strings.Split(gotOutputs[0].(string), "}{")
require.Len(t, splitOutput, tc.expTxLen)
return false
}
cmd := append(withdrawCmdArgs, fmt.Sprintf("--max-msgs=%d", tc.maxMsgs), "--generate-only")
_ = cli.WithRunErrorMatcher(assertGenOnlyOutput).Run(cmd...)
})
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
cmd := append(withdrawCmdArgs, fmt.Sprintf("--max-msgs=%d", tc.maxMsgs), "--generate-only")
assertGenOnlyOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool {
require.Len(t, gotOutputs, 1)
// gets output combining two objects without any space or new line
splitOutput := strings.Split(gotOutputs[0].(string), "}{")
require.Len(t, splitOutput, tc.expTxLen)
return false
}
_ = cli.WithRunErrorMatcher(assertGenOnlyOutput).Run(cmd...)
})
}


// test withdraw-all-rewards transaction
rsp = cli.RunAndWait(withdrawCmdArgs...)
RequireTxSuccess(t, rsp)
}

func TestDistrValidatorGRPCQueries(t *testing.T) {
// scenario: test distribution validator gsrpc gateway queries
akhilkumarpilli marked this conversation as resolved.
Show resolved Hide resolved
// given a running chain

sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
valOperAddr := cli.GetKeyAddrPrefix("node0", "val")
require.NotEmpty(t, valOperAddr)

denom := "stake"
sut.StartChain(t)

sut.AwaitNBlocks(t, 3)

baseurl := sut.APIAddress()
expectedAmountOutput := fmt.Sprintf(`{"denom":"%s","amount":"203.105000000000000000"}`, denom)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid hardcoding amounts in expected outputs

The expectedAmountOutput variable contains hardcoded amounts, which may cause tests to fail if the underlying calculations change. Consider computing expected amounts dynamically.

Calculate the expected amount based on initial conditions:

-expectedAmountOutput := fmt.Sprintf(`{"denom":"%s","amount":"203.105000000000000000"}`, denom)
+commissionAmount := calculateExpectedCommissionAmount()
+expectedAmountOutput := fmt.Sprintf(`{"denom":"%s","amount":"%s"}`, denom, commissionAmount)

Where calculateExpectedCommissionAmount() is a helper function that computes the expected commission.

Committable suggestion was skipped due to low confidence.


// test params grpc endpoint
paramsURL := baseurl + "/cosmos/distribution/v1beta1/params"

paramsTestCases := []RestTestCase{
{
"gRPC request params",
paramsURL,
http.StatusOK,
`{"params":{"community_tax":"0.020000000000000000","base_proposer_reward":"0.000000000000000000","bonus_proposer_reward":"0.000000000000000000","withdraw_addr_enabled":true}}`,
},
}
RunRestQueries(t, paramsTestCases)

// test validator distribution info grpc endpoint
validatorsURL := baseurl + `/cosmos/distribution/v1beta1/validators/%s`
decodingFailedOutput := `{"code":2, "message":"decoding bech32 failed: invalid separator index -1", "details":[]}`
validatorsOutput := fmt.Sprintf(`{"operator_address":"%s","self_bond_rewards":[],"commission":[%s]}`, valAddr, expectedAmountOutput)

validatorsTestCases := []RestTestCase{
{
"invalid validator gRPC request with wrong validator address",
fmt.Sprintf(validatorsURL, "wrongaddress"),
http.StatusInternalServerError,
decodingFailedOutput,
},
{
"gRPC request validator with valid validator address",
fmt.Sprintf(validatorsURL, valOperAddr),
http.StatusOK,
validatorsOutput,
},
}
TestRestQueryIgnoreNumbers(t, validatorsTestCases)

// test outstanding rewards grpc endpoint
outstandingRewardsURL := baseurl + `/cosmos/distribution/v1beta1/validators/%s/outstanding_rewards`

rewardsTestCases := []RestTestCase{
{
"invalid outstanding rewards gRPC request with wrong validator address",
fmt.Sprintf(outstandingRewardsURL, "wrongaddress"),
http.StatusInternalServerError,
decodingFailedOutput,
},
{
"gRPC request outstanding rewards with valid validator address",
fmt.Sprintf(outstandingRewardsURL, valOperAddr),
http.StatusOK,
fmt.Sprintf(`{"rewards":{"rewards":[%s]}}`, expectedAmountOutput),
},
}
TestRestQueryIgnoreNumbers(t, rewardsTestCases)

// test validator commission grpc endpoint
commissionURL := baseurl + `/cosmos/distribution/v1beta1/validators/%s/commission`

commissionTestCases := []RestTestCase{
{
"invalid commission gRPC request with wrong validator address",
fmt.Sprintf(commissionURL, "wrongaddress"),
http.StatusInternalServerError,
decodingFailedOutput,
},
{
"gRPC request commission with valid validator address",
fmt.Sprintf(commissionURL, valOperAddr),
http.StatusOK,
fmt.Sprintf(`{"commission":{"commission":[%s]}}`, expectedAmountOutput),
},
}
TestRestQueryIgnoreNumbers(t, commissionTestCases)

// test validator slashes grpc endpoint
slashURL := baseurl + `/cosmos/distribution/v1beta1/validators/%s/slashes`
invalidHeightOutput := `{"code":3, "message":"strconv.ParseUint: parsing \"-3\": invalid syntax", "details":[]}`

slashTestCases := []RestTestCase{
{
"invalid slashes gRPC request with wrong validator address",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

fmt.Sprintf(slashURL, "wrongaddress"),
http.StatusBadRequest,
`{"code":3, "message":"invalid validator address", "details":[]}`,
},
{
"invalid start height",
fmt.Sprintf(slashURL+`?starting_height=%s&ending_height=%s`, valOperAddr, "-3", "3"),
http.StatusBadRequest,
invalidHeightOutput,
},
{
"invalid end height",
fmt.Sprintf(slashURL+`?starting_height=%s&ending_height=%s`, valOperAddr, "1", "-3"),
http.StatusBadRequest,
invalidHeightOutput,
},
{
"valid request get slashes",
fmt.Sprintf(slashURL+`?starting_height=%s&ending_height=%s`, valOperAddr, "1", "3"),
http.StatusOK,
`{"slashes":[],"pagination":{"next_key":null,"total":"0"}}`,
},
}
RunRestQueries(t, slashTestCases)
}

func TestDistrDelegatorGRPCQueries(t *testing.T) {
// scenario: test distribution validator gsrpc gateway queries
// given a running chain

sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
denom := "stake"

// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
valOperAddr := cli.GetKeyAddrPrefix("node0", "val")
require.NotEmpty(t, valOperAddr)

// update commission rate of node0 validator
// generate new gentx and copy it to genesis.json before starting network
rsp := cli.RunCommandWithArgs("genesis", "gentx", "node0", "100000000"+denom, "--chain-id="+cli.chainID, "--commission-rate=0.01", "--home", sut.nodePath(0), "--keyring-backend=test")
// extract gentx path from above command output
re := regexp.MustCompile(`"(.*?\.json)"`)
match := re.FindStringSubmatch(rsp)
require.GreaterOrEqual(t, len(match), 1)

updatedGentx := filepath.Join(WorkDir, match[1])
updatedGentxBz, err := os.ReadFile(updatedGentx) // #nosec G304
require.NoError(t, err)

sut.ModifyGenesisJSON(t, func(genesis []byte) []byte {
state, err := sjson.SetRawBytes(genesis, "app_state.genutil.gen_txs.0", updatedGentxBz)
require.NoError(t, err)
return state
})
Comment on lines +222 to +235
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle errors from 'regexp.MustCompile' and improve error checking

Using regexp.MustCompile will panic if the regex is invalid. Instead, use regexp.Compile and handle the error. Additionally, ensure all errors are checked for robustness.

Apply this diff:

-re := regexp.MustCompile(`"(.*?\.json)"`)
+re, err := regexp.Compile(`"(.*?\.json)"`)
+require.NoError(t, err)

Committable suggestion was skipped due to low confidence.


// create new address which will be used as delegator address
delAddr := cli.AddKey("delAddr")
require.NotEmpty(t, delAddr)

var initialAmount int64 = 1000000000
initialBalance := fmt.Sprintf("%d%s", initialAmount, denom)
sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", delAddr, initialBalance},
)

sut.StartChain(t)

// delegate some tokens to valOperAddr
rsp = cli.RunAndWait("tx", "staking", "delegate", valOperAddr, "100000000"+denom, "--from="+delAddr)
RequireTxSuccess(t, rsp)

sut.AwaitNBlocks(t, 5)

baseurl := sut.APIAddress()
decodingFailedOutput := `{"code":2, "message":"decoding bech32 failed: invalid separator index -1", "details":[]}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Reuse 'decodingFailedOutput' variable

The decodingFailedOutput variable is redefined in multiple test functions. Consider defining it once and reusing it across tests to avoid duplication.

Move decodingFailedOutput to a common location:

+const decodingFailedOutput = `{"code":2, "message":"decoding bech32 failed: invalid separator index -1", "details":[]}`

 func TestDistrValidatorGRPCQueries(t *testing.T) {
     // ...
-    decodingFailedOutput := `{"code":2, "message":"decoding bech32 failed: invalid separator index -1", "details":[]}`
     // ...
 }

 func TestDistrDelegatorGRPCQueries(t *testing.T) {
     // ...
-    decodingFailedOutput := `{"code":2, "message":"decoding bech32 failed: invalid separator index -1", "details":[]}`
     // ...
 }

Committable suggestion was skipped due to low confidence.


// test delegator rewards grpc endpoint
delegatorRewardsURL := baseurl + `/cosmos/distribution/v1beta1/delegators/%s/rewards`
expectedAmountOutput := `{"denom":"stake","amount":"0.121275000000000000"}`
rewardsOutput := fmt.Sprintf(`{"rewards":[{"validator_address":"%s","reward":[%s]}],"total":[%s]}`, valOperAddr, expectedAmountOutput, expectedAmountOutput)

delegatorRewardsTestCases := []RestTestCase{
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

"wrong delegator address",
fmt.Sprintf(delegatorRewardsURL, "wrongdeladdress"),
http.StatusInternalServerError,
decodingFailedOutput,
},
{
"valid rewards request with valid delegator address",
fmt.Sprintf(delegatorRewardsURL, delAddr),
http.StatusOK,
rewardsOutput,
},
{
"wrong validator address (specific validator rewards)",
fmt.Sprintf(delegatorRewardsURL+`/%s`, delAddr, "wrongvaladdress"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

http.StatusInternalServerError,
decodingFailedOutput,
},
{
"valid request(specific validator rewards)",
fmt.Sprintf(delegatorRewardsURL+`/%s`, delAddr, valOperAddr),
http.StatusOK,
fmt.Sprintf(`{"rewards":[%s]}`, expectedAmountOutput),
},
}
TestRestQueryIgnoreNumbers(t, delegatorRewardsTestCases)

// test delegator validators grpc endpoint
delegatorValsURL := baseurl + `/cosmos/distribution/v1beta1/delegators/%s/validators`
valsTestCases := []RestTestCase{
{
"invalid delegator validators gRPC request with wrong delegator address",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

fmt.Sprintf(delegatorValsURL, "wrongaddress"),
http.StatusInternalServerError,
decodingFailedOutput,
},
{
"gRPC request delegator validators with valid delegator address",
fmt.Sprintf(delegatorValsURL, delAddr),
http.StatusOK,
fmt.Sprintf(`{"validators":["%s"]}`, valOperAddr),
},
}
RunRestQueries(t, valsTestCases)

// test withdraw address grpc endpoint
withdrawAddrURL := baseurl + `/cosmos/distribution/v1beta1/delegators/%s/withdraw_address`
withdrawAddrTestCases := []RestTestCase{
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we can remove those cases, this is catched by unit tests

"invalid withdraw address gRPC request with wrong delegator address",
fmt.Sprintf(withdrawAddrURL, "wrongaddress"),
http.StatusInternalServerError,
decodingFailedOutput,
},
{
"gRPC request withdraw address with valid delegator address",
fmt.Sprintf(withdrawAddrURL, delAddr),
http.StatusOK,
fmt.Sprintf(`{"withdraw_address":"%s"}`, delAddr),
},
}
RunRestQueries(t, withdrawAddrTestCases)
}
31 changes: 31 additions & 0 deletions tests/systemtests/rest_cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package systemtests
import (
"io"
"net/http"
"regexp"
"testing"

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/testutil"
)

type RestTestCase struct {
Expand All @@ -28,6 +31,34 @@ func RunRestQueries(t *testing.T, testCases []RestTestCase) {
}
}

// TestRestQueryIgnoreNumbers runs given rest testcases by making requests and
// checking response with expected output ignoring number values
// This method is used when number values in response are non-deterministic
func TestRestQueryIgnoreNumbers(t *testing.T, testCases []RestTestCase) {
t.Helper()

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
resp, err := testutil.GetRequest(tc.url)
require.NoError(t, err)

// regular expression pattern to match any numeric value in the JSON
numberRegexPattern := `"\d+(\.\d+)?"`

// compile the regex
r, err := regexp.Compile(numberRegexPattern)
require.NoError(t, err)

// replace all numeric values in the above JSONs with `NUMBER` text
expectedJSON := r.ReplaceAllString(tc.expOut, `"NUMBER"`)
actualJSON := r.ReplaceAllString(string(resp), `"NUMBER"`)

// compare two jsons
require.JSONEq(t, expectedJSON, actualJSON)
})
}
}

func GetRequest(t *testing.T, url string) []byte {
t.Helper()
return GetRequestWithHeaders(t, url, nil, http.StatusOK)
Expand Down
Loading
Loading