-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
TT-7306: Migrate Mock Response from Classic API Definition to OAS API Definition #6894
base: master
Are you sure you want to change the base?
Conversation
This PR is too huge for one to review 💔
Consider breaking it down into multiple small PRs. Check out this guide to learn more about PR best-practices. |
Let's make that PR title a 💯 shall we? 💪 Your PR title and story title look slightly different. Just checking in to know if it was intentional!
Check out this guide to learn more about PR best-practices. |
API Changes --- prev.txt 2025-02-25 12:55:37.129731102 +0000
+++ current.txt 2025-02-25 12:55:32.968699417 +0000
@@ -3300,6 +3300,11 @@
}
MockResponse configures the mock responses.
+func (m *MockResponse) ExtractTo(meta *apidef.MockResponseMeta)
+
+func (m *MockResponse) Fill(op apidef.MockResponseMeta)
+ Fill populates the MockResponse fields from a classic API MockResponseMeta.
+
func (m *MockResponse) Import(enabled bool)
Import populates *MockResponse with enabled argument for FromOASExamples.
|
PR Reviewer Guide 🔍(Review updated until commit cb56906)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to cb56906
Previous suggestionsSuggestions up to commit 845f0bc
|
Persistent review updated to latest commit cb56906 |
apidef/oas/operation.go
Outdated
contentType := "text/plain" | ||
if ct, ok := mockResponse.Headers["Content-Type"]; ok && ct != "" { | ||
contentType = ct | ||
} else if ct, ok := mockResponse.Headers["content-type"]; ok && ct != "" { | ||
contentType = ct | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit of a code smell, headers have canonical formatting and we're checking two casings.
https://pkg.go.dev/net/http#CanonicalHeaderKey
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, let me correct it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed it, PTAL
apidef/oas/operation.go
Outdated
|
||
// Detect JSON content | ||
if mockResponse.Body != "" { | ||
var js interface{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var js interface{} | |
var js interface{} |
Could this be json.RawMessage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let fix that, thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed it, PTAL
apidef/oas/operation.go
Outdated
var body json.RawMessage | ||
if err := json.Unmarshal([]byte(mock.Body), &body); err == nil { | ||
contentType = "application/json" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, thanks @jeffy-mathew.
A quick question, do you think we should also unmarshal to []interface{}, to cover arrays?
Co-authored-by: Jeffy Mathew <[email protected]>
PTAL again @titpetric and @jeffy-mathew |
|
// - Checking the Content-Type header if present | ||
// - Attempting to parse the body as JSON | ||
// - Defaulting to text/plain if neither above applies | ||
func (s *OAS) fillMockResponsePaths(paths openapi3.Paths, ep apidef.ExtendedPathsSet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the function body is way too long, we should create helper functions whenever possible to increase readability and reduce complexity
|
||
// Response description is required by the OAS spec, but we don't have it in Tyk classic. | ||
// So we're using a dummy value to satisfy the spec. | ||
dummyDescription := "CHANGE ME" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"oasRequiredDummyValue" sounds more indicative than "CHANGE ME"
|
||
// We attempt to guess the content type by checking if the body is a valid JSON. | ||
if mock.Body != "" { | ||
var jsonValue = []interface{}{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to create a slice of variants, its easier to read if you check for both
for name, value := range mock.Headers { | ||
if http.CanonicalHeaderKey(name) == tykheader.ContentType { | ||
contentType = value | ||
break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you split the method into multiple helpers. you will be able to just return from the underlying helper instead of breaking the for loop
|
||
// Sort the mock response paths by path, method, and response code. | ||
// This ensures a deterministic order of mock responses. | ||
sort.Slice(ep.WhiteList, func(i, j int) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extract this into a helper to not increase the body of the extractPathsAndOperations function
mockResp := ep.WhiteList[0] | ||
assert.Equal(t, "/test", mockResp.Path) | ||
assert.Equal(t, "GET", mockResp.Method) | ||
require.NotNil(t, mockResp.MethodActions["GET"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use either assert or require
require.NotNil(t, pathItem) | ||
|
||
// Verify operation | ||
require.NotNil(t, pathItem.Get) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use either only assert or only require
require.NotNil(t, pathItem) | ||
|
||
// Helper function to verify operation | ||
verifyOperation := func(op *openapi3.Operation, method string, code int, body string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function in function looks concise but it's hard to review in a web editor
User description
TT-7306
Description
This PR adds support for converting
mock responses
between Tyk's classic API format and OAS format.Related Issue
https://tyktech.atlassian.net/browse/TT-7306
Motivation and Context
How This Has Been Tested
Screenshots (if appropriate)
Types of changes
Checklist
PR Type
Enhancement, Tests
Description
Added support for migrating mock responses between Classic and OAS API definitions.
Implemented methods to fill and extract mock responses in OAS middleware.
Enhanced test coverage for mock response handling, including edge cases.
Introduced YAML fixtures for mock response scenarios in OAS and Classic formats.
Changes walkthrough 📝
middleware.go
Enhance middleware to support mock responses
apidef/oas/middleware.go
Operations
in theFill
method.Fill
method to handle mock responses.operation.go
Add mock response handling in OAS operations
apidef/oas/operation.go
generateOperationID
utility for mock responses.middleware_test.go
Add tests for middleware mock response handling
apidef/oas/middleware_test.go
operation_test.go
Add tests for OAS mock response operations
apidef/oas/operation_test.go
mock_response.yml
Add YAML fixtures for mock response testing
apidef/oas/testdata/fixtures/mock_response.yml