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

feat: [#441] Optimize the HTTP testing process [#2] #708

Merged
merged 13 commits into from
Nov 2, 2024

Conversation

kkumar-gcc
Copy link
Member

@kkumar-gcc kkumar-gcc commented Nov 1, 2024

📑 Description

RelatedTo goravel/goravel#441

Summary by CodeRabbit

  • New Features

    • Introduced a new interface AssertableJSON for flexible JSON representation.
    • Enhanced TestRequest interface with methods for various HTTP request types and context management.
    • Expanded TestResponse interface with new methods for response verification and content handling.
    • Added AssertableJSONString type for handling JSON strings and decoding.
  • Bug Fixes

    • Improved error handling for JSON parsing in AssertableJSONString.
  • Documentation

    • Updated method signatures for clarity and consistency in TestResponse.

✅ Checks

  • Added test cases for my code

@kkumar-gcc kkumar-gcc requested a review from a team as a code owner November 1, 2024 16:22
Copy link
Contributor

coderabbitai bot commented Nov 1, 2024

Important

Review skipped

Auto reviews are limited to specific labels.

🏷️ Labels to auto review (1)
  • 🚀 Review Ready

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This pull request introduces several enhancements to the testing package, including the addition of new interfaces and methods for handling JSON and HTTP requests/responses. A new AssertableJSON interface is created to provide a flexible JSON representation, while the TestRequest and TestResponse interfaces are extended with additional methods for managing HTTP requests and responses, including context support and various HTTP method implementations. Additionally, a new struct AssertableJSONString is defined to facilitate JSON handling.

Changes

File Change Summary
contracts/testing/assertable_json.go - New interface: AssertableJSON with method Json() map[string]any.
contracts/testing/test_request.go - Modified TestRequest interface:
- New method: WithContext(ctx context.Context) TestRequest.
- New methods for HTTP verbs: Post, Put, Patch, Delete, Head, Options.
- context and io packages imported.
contracts/testing/test_response.go - Modified TestResponse interface:
- New methods: IsSuccessful(), IsServerError(), Content(), Json(), AssertSuccessful(), AssertServerError(), AssertDontSee(), AssertSee(), AssertSeeInOrder().
- Simplified method signatures.
testing/assertable_json_string.go - New file: AssertableJSONString struct with methods: NewAssertableJSONString(jsonAble string) (contractstesting.AssertableJSON, error) and Json() map[string]any.
testing/test_request.go - Modified TestRequest struct:
- New field: ctx context.Context.
- Updated call method to accept body io.Reader.
- New HTTP method implementations added.
testing/test_response.go - Enhanced TestResponseImpl struct with new methods for content verification and status checking.

Possibly related PRs

  • feat: [#441] Optimize the HTTP testing process [#1] #704: The introduction of the TestRequest interface in contracts/testing/test_request.go is related to the main PR's addition of the AssertableJSON interface, as both enhance the testing capabilities within the testing package by providing structured ways to handle requests and responses.

Suggested labels

🚀 Review Ready

Suggested reviewers

  • hwbrzzl

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@kkumar-gcc kkumar-gcc closed this Nov 1, 2024
@kkumar-gcc kkumar-gcc reopened this Nov 1, 2024
@kkumar-gcc kkumar-gcc marked this pull request as draft November 1, 2024 16:23
@kkumar-gcc kkumar-gcc closed this Nov 2, 2024
@kkumar-gcc kkumar-gcc reopened this Nov 2, 2024
@kkumar-gcc kkumar-gcc closed this Nov 2, 2024
@kkumar-gcc kkumar-gcc reopened this Nov 2, 2024
Copy link
Contributor

coderabbitai bot commented Nov 2, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: e0d80c7 Previous: 8b33e6b Ratio
Benchmark_Panic 0.001133 ns/op 0 B/op 0 allocs/op 0.000695 ns/op 0 B/op 0 allocs/op 1.63
Benchmark_Panic - ns/op 0.001133 ns/op 0.000695 ns/op 1.63

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Outside diff range and nitpick comments (8)
contracts/testing/assertable_json.go (1)

3-5: LGTM! Clean and well-designed interface.

The interface follows Go best practices with a focused, single-method design that adheres to interface segregation principles.

Consider adding a doc comment to describe the interface's purpose and usage:

+// AssertableJSON represents a type that can provide its data as a JSON object.
+// This interface is typically used in testing scenarios to assert on JSON responses.
 type AssertableJSON interface {
+	// Json returns the underlying data as a map representation of a JSON object.
 	Json() map[string]any
 }
testing/assertable_json_string.go (2)

9-12: Consider adding field documentation.

While the field names are concise, adding documentation comments would improve code maintainability by clarifying the purpose of each field.

 type AssertableJSONString struct {
+	// json holds the original JSON string representation
 	json    string
+	// decoded holds the unmarshaled JSON data as a map
 	decoded map[string]any
 }

27-29: LGTM! Consider adding compile-time interface check.

The implementation is clean and correct. To ensure continued interface compliance, consider adding a compile-time check.

Add this line at the package level:

var _ contractstesting.AssertableJSON = (*AssertableJSONString)(nil)
contracts/testing/test_request.go (1)

14-14: LGTM: Context support follows best practices

The WithContext method follows Go's context propagation patterns, enabling proper request cancellation and timeout management.

Consider adding a doc comment explaining the context behavior, e.g.:

// WithContext returns a new TestRequest with the provided context
// The context will be used for all subsequent HTTP requests
contracts/testing/test_response.go (1)

39-43: Consider adding documentation for the boolean variadic parameters

The new assertion methods AssertDontSee, AssertSee, and AssertSeeInOrder use variadic boolean parameters, but their purpose isn't immediately clear. Consider adding interface documentation to explain:

  • What the boolean parameters control (case sensitivity?)
  • The expected behavior when no boolean flags are provided
  • The order of precedence if multiple flags are given

Example documentation:

// AssertSee checks if the response contains all given strings.
// Optional boolean parameters control case sensitivity (default: true).
testing/test_request.go (2)

57-60: Consider adding documentation for the WithContext method.

The implementation is correct and follows the builder pattern consistently. Consider adding a doc comment to describe the method's purpose and any context-specific considerations.

Add documentation:

+// WithContext sets the context for subsequent HTTP requests.
+// This context will be used for all requests made through this TestRequest instance.
 func (r *TestRequest) WithContext(ctx context.Context) contractstesting.TestRequest {

66-88: Add tests for new HTTP methods and context handling.

Please ensure comprehensive test coverage for:

  1. Context propagation through the request chain
  2. All new HTTP methods (POST, PUT, PATCH, DELETE, HEAD, OPTIONS)
  3. Error cases for invalid requests

Would you like me to help create test cases for these scenarios?

testing/test_response.go (1)

246-249: Consider clarifying the escaped parameter usage in assertion methods

In the methods AssertDontSee, AssertSee, and AssertSeeInOrder, the escaped parameter determines whether to escape HTML characters in the values before comparison. The current implementation defaults shouldEscape to true when escaped is not provided, which might be counterintuitive. Consider:

  • Renaming the parameter to escape to reflect its action more clearly.
  • Adjusting the default behavior to false to align with the principle of least surprise.

This change would enhance the clarity and intuitiveness of the API for users.

Also applies to: 267-270, 288-291

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 8b33e6b and e0d80c7.

⛔ Files ignored due to path filters (3)
  • mocks/testing/AssertableJSON.go is excluded by !mocks/**
  • mocks/testing/TestRequest.go is excluded by !mocks/**
  • mocks/testing/TestResponse.go is excluded by !mocks/**
📒 Files selected for processing (6)
  • contracts/testing/assertable_json.go (1 hunks)
  • contracts/testing/test_request.go (1 hunks)
  • contracts/testing/test_response.go (2 hunks)
  • testing/assertable_json_string.go (1 hunks)
  • testing/test_request.go (3 hunks)
  • testing/test_response.go (4 hunks)
🔇 Additional comments (16)
contracts/testing/assertable_json.go (1)

4-4: 🛠️ Refactor suggestion

Consider adding error handling to the Json method.

Since JSON operations can fail (e.g., parsing errors, invalid data), it might be beneficial to include error handling in the interface contract.

Consider modifying the method signature to include an error return:

-	Json() map[string]any
+	Json() (map[string]any, error)

Let's check if other JSON-related operations in the codebase handle errors:

testing/assertable_json_string.go (2)

1-7: LGTM! Clean package structure and imports.

The package name and imports are well-organized, with appropriate use of aliasing for the testing contract.


1-29: Verify if similar functionality exists in testing libraries.

While the implementation is solid, it's worth checking if this functionality already exists in commonly used Go testing libraries to avoid duplication.

contracts/testing/test_request.go (1)

3-6: LGTM: Clean import additions

The new imports are appropriate for the enhanced HTTP testing functionality.

contracts/testing/test_response.go (3)

4-5: LGTM: Status check methods follow standard HTTP conventions

The new methods IsSuccessful() and IsServerError() are well-named and follow HTTP status code conventions for success (2xx) and server errors (5xx).


34-34: LGTM: Simplified method signatures improve readability

The removal of parameter names in these method signatures follows Go interface best practices, making the interface more concise while maintaining clarity.

Also applies to: 36-38


6-7: Verify error handling in Content() and Json() implementations

The new content retrieval methods look good, but their implementations should handle various edge cases:

  • Empty response bodies
  • Invalid JSON formatting
  • Character encoding issues
✅ Verification successful

Error handling is properly implemented

The implementations handle the key edge cases appropriately:

  • Empty responses: The getContent() method properly reads the response body using io.ReadAll and returns any errors
  • Invalid JSON: The Json() method uses json.Unmarshal through NewAssertableJSONString which returns an error for malformed JSON
  • Character encoding: Content is properly handled as strings and bytes throughout the chain
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the implementation of these methods to verify error handling
ast-grep --pattern 'func ($receiver $_) Content() (string, error) {
  $$$
}'

ast-grep --pattern 'func ($receiver $_) Json() (map[string]any, error) {
  $$$
}'

Length of output: 162


Script:

#!/bin/bash
# Let's try with ripgrep to find these method implementations
rg -U "func.*Content\(\).*\(string, error\)" -A 10
rg -U "func.*Json\(\).*\(map\[string\]any, error\)" -A 10

Length of output: 2953


Script:

#!/bin/bash
# Let's check the NewAssertableJSONString implementation for JSON validation
rg -U "func NewAssertableJSONString" -A 10

# Also check if there's any content validation in getContent
rg -U "r.content = " -A 5

Length of output: 1053

testing/test_request.go (2)

4-5: LGTM! Well-structured context integration.

The addition of context support is implemented cleanly with proper initialization using context.Background() as the default value.

Also applies to: 18-18, 26-26


90-91: Verify error handling for nil context.

The implementation looks good, but let's ensure proper error handling when the context is nil.

testing/test_response.go (7)

28-40: Well-implemented Json method for parsing response content

The Json method correctly retrieves the response content and parses it into a JSON map with proper error handling. This enhances the usability of the TestResponseImpl by providing a straightforward way to work with JSON responses.


42-45: Accurate implementation of IsSuccessful method

The IsSuccessful method properly checks if the response status code indicates a successful response (status code 200-299). This offers a convenient way to validate successful HTTP responses in tests.


47-50: Correct IsServerError method to detect server errors

The IsServerError method accurately identifies server error responses (status code 500-599), aiding in asserting that the server responded with an error as expected.


52-54: Proper Content method to retrieve response content

The Content method effectively returns the response content by invoking getContent, allowing testers to access the raw response body for further assertions.


82-84: Appropriate content assertion in AssertNoContent

The added assertions in AssertNoContent correctly verify that the response content is empty, ensuring the response complies with the expected no-content status.


230-234: AssertSuccessful method correctly asserts successful responses

The AssertSuccessful method utilizes IsSuccessful to confirm that the response status code indicates success, streamlining success assertions in tests.


236-240: AssertServerError method properly asserts server error responses

The AssertServerError method checks for server error status codes using IsServerError, providing a clear way to assert server errors in the response.

testing/assertable_json_string.go Outdated Show resolved Hide resolved
contracts/testing/test_request.go Outdated Show resolved Hide resolved
contracts/testing/test_response.go Show resolved Hide resolved
testing/test_request.go Outdated Show resolved Hide resolved
testing/test_response.go Outdated Show resolved Hide resolved
@kkumar-gcc kkumar-gcc marked this pull request as ready for review November 2, 2024 11:07
coderabbitai[bot]
coderabbitai bot previously approved these changes Nov 2, 2024
Copy link

codecov bot commented Nov 2, 2024

Codecov Report

Attention: Patch coverage is 48.78049% with 63 lines in your changes missing coverage. Please review.

Project coverage is 69.60%. Comparing base (8b33e6b) to head (c524163).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
testing/test_response.go 65.21% 30 Missing and 2 partials ⚠️
testing/test_request.go 0.00% 19 Missing ⚠️
testing/assertable_json_string.go 0.00% 12 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #708      +/-   ##
==========================================
- Coverage   69.75%   69.60%   -0.15%     
==========================================
  Files         194      195       +1     
  Lines       15108    15225     +117     
==========================================
+ Hits        10539    10598      +59     
- Misses       3999     4055      +56     
- Partials      570      572       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kkumar-gcc kkumar-gcc closed this Nov 2, 2024
@kkumar-gcc kkumar-gcc reopened this Nov 2, 2024
Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

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

Great PR 👍 just one question.

Get(uri string) (TestResponse, error)
Post(uri string, body io.Reader) (TestResponse, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

body io.Reader is a bit difficult to build. Can we provide a simple way to do so?

image

Copy link
Member Author

@kkumar-gcc kkumar-gcc Nov 2, 2024

Choose a reason for hiding this comment

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

Sure, we can provide a interface to write body. (May be in next PR?)

Copy link
Contributor

Choose a reason for hiding this comment

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

We can optimize it in another PR if you want.

@kkumar-gcc kkumar-gcc merged commit b461b0f into master Nov 2, 2024
10 of 12 checks passed
@kkumar-gcc kkumar-gcc deleted the kkumar-gcc/#441-1 branch November 2, 2024 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants