Conversation
5b26aa7 to
875aa23
Compare
There was a problem hiding this comment.
Pull request overview
This PR expands JSON-RPC test coverage for tournament-related (“prt”) methods and adjusts repository/query behavior to make list endpoints deterministic and align empty-list responses with existing “Application not found” semantics.
Changes:
- Add extensive JSON-RPC tests for tournament/commitment/match/match-advanced endpoints.
- Make list endpoints return
RESOURCE_NOT_FOUND: Application not foundwhen the result is empty and the application does not exist. - Stabilize ordering for pagination in Postgres queries (commitments and match advances).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/repository/postgres/match_advanced.go | Changes ordering for ListMatchAdvances to sort by OtherParent (stabilizes pagination within a fixed epoch/tournament/id_hash). |
| internal/repository/postgres/commitment.go | Adds secondary ORDER BY on Commitment to make pagination deterministic when many rows share the same EpochIndex. |
| internal/jsonrpc/jsonrpc.go | Adds “application exists” checks for multiple list handlers; tweaks GetMatchAdvanced parent handling. |
| internal/jsonrpc/util_test.go | Adds helper result structs for JSON unmarshalling in tests. |
| internal/jsonrpc/jsonrpc_test.go | Adds large suite of tests for new/expanded tournament data methods. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
5442605 to
e0b5bff
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
a13fa56 to
290a589
Compare
290a589 to
fc5f9a4
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| method := getName(t.Name()) | ||
|
|
||
| // failure: tournament address not hex encoded -> invalid param | ||
| t.Run("malformedApplicationParameter", func(t *testing.T) { |
There was a problem hiding this comment.
The test name "malformedApplicationParameter" is misleading because this test is actually checking for a malformed tournament address parameter (not application parameter). The application parameter is valid in this test. Consider renaming to "malformedAddressParameter" to accurately reflect what is being tested.
| t.Run("malformedApplicationParameter", func(t *testing.T) { | |
| t.Run("malformedAddressParameter", func(t *testing.T) { |
| } | ||
|
|
||
| if _, err := hex.DecodeString(params.Commitment); err != nil { | ||
| if _, err := hex.DecodeString(params.Commitment); (len(params.Commitment) == 0) || (err != nil) { |
There was a problem hiding this comment.
The error message will display "Invalid commitment hex: " when the commitment parameter is empty, because hex.DecodeString("") succeeds (returns nil error). Consider checking for empty string first and providing a more specific error message, or use a validation function similar to config.ToHashFromString which requires the 0x prefix and proper hex encoding.
| if _, err := hex.DecodeString(params.Commitment); (len(params.Commitment) == 0) || (err != nil) { | |
| if len(params.Commitment) == 0 { | |
| writeRPCError(w, req.ID, JSONRPC_INVALID_PARAMS, "Commitment must not be empty", nil) | |
| return | |
| } | |
| if _, err := hex.DecodeString(params.Commitment); err != nil { |
| assert.Equal(t, "Application not found", resp.Error.Message) | ||
| }) | ||
|
|
||
| // success: no tournament in the database -> 0 |
There was a problem hiding this comment.
The comment says "no tournament in the database" but this test is for cartesi_listMatches and checks for empty matches. Consider updating the comment to say "no match in the database" to accurately reflect what the test does.
| // success: no tournament in the database -> 0 | |
| // success: no match in the database -> 0 |
| // success: many match_advances | ||
| // create one tournament with many (match_advances) pairs. |
There was a problem hiding this comment.
The comment says "many match_advances" but this test is for cartesi_listCommitments and creates commitments. Consider updating the comment to say "many commitments" to accurately reflect what the test does.
| // success: many match_advances | |
| // create one tournament with many (match_advances) pairs. | |
| // success: many commitments | |
| // create one tournament with many commitments. |
| t.Run("cartesi_listMatchAdvances", func(t *testing.T) { | ||
| method := getName(t.Name()) | ||
|
|
||
| // failure: no match in the database -> no application |
There was a problem hiding this comment.
The comment says "no match in the database" but this test is for cartesi_listMatchAdvances and checks for absent application. Consider updating the comment to say "no match advance in the database" to accurately reflect what the test does.
| // failure: no match in the database -> no application | |
| // failure: no match advance in the database -> no application |
| // success: many tournaments | ||
| // create one application with many (epoch, tournament) pairs. | ||
| // use their shared Index / EpochIndex to check pagination. |
There was a problem hiding this comment.
The comment says "many tournaments" but this test is for cartesi_listMatches and creates matches, not tournaments. Consider updating the comment to say "many matches" to accurately reflect what the test does.
| // success: many tournaments | |
| // create one application with many (epoch, tournament) pairs. | |
| // use their shared Index / EpochIndex to check pagination. | |
| // success: many matches | |
| // create one application with many (epoch, match) pairs. | |
| // use their shared indices to check pagination. |
| t.Run("cartesi_listCommitments", func(t *testing.T) { | ||
| method := getName(t.Name()) | ||
|
|
||
| // failure: no match in the database -> no application |
There was a problem hiding this comment.
The comment says "no match in the database" but this test is for cartesi_listCommitments and checks for absent application. Consider updating the comment to say "no commitment in the database" to accurately reflect what the test does.
| // failure: no match in the database -> no application | |
| // failure: no application in the database |
| assert.Equal(t, "Application not found", resp.Error.Message) | ||
| }) | ||
|
|
||
| // success: no tournament in the database -> 0 |
There was a problem hiding this comment.
The comment says "no tournament in the database" but this test is for cartesi_listCommitments and checks for empty commitments. Consider updating the comment to say "no commitment in the database" to accurately reflect what the test does.
| // success: no tournament in the database -> 0 | |
| // success: no commitment in the database -> 0 |
| assert.Equal(t, "Application not found", resp.Error.Message) | ||
| }) | ||
|
|
||
| // success: no tournament in the database -> 0 |
There was a problem hiding this comment.
The comment says "no tournament in the database" but this test is for cartesi_listMatchAdvances and checks for empty match advances. Consider updating the comment to say "no match advance in the database" to accurately reflect what the test does.
| // success: no tournament in the database -> 0 | |
| // success: no match advance in the database -> 0 |
closes #682