-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added function to writer CORS headers * Added Content-Type type resolving * Added correct response and header writing * Replace headers to constatant * Fixed issues
- Loading branch information
Evgeny Abramovich
authored
Nov 1, 2022
1 parent
1fdf4fd
commit 78369b9
Showing
16 changed files
with
382 additions
and
56 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
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
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,13 @@ | ||
package infrastructure | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/go-http-utils/headers" | ||
) | ||
|
||
func WriteCorsHeaders(header http.Header) { | ||
header.Set(headers.AccessControlAllowOrigin, "*") | ||
header.Set(headers.AccessControlAllowCredentials, "true") | ||
header.Set(headers.AccessControlAllowMethods, "GET, PUT, POST, HEAD, TRACE, DELETE, PATCH, COPY, HEAD, LINK, OPTIONS") | ||
} |
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,80 @@ | ||
package infrastructure_test | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/evg4b/uncors/internal/infrastructure" | ||
"github.com/evg4b/uncors/testing/testutils" | ||
"github.com/go-http-utils/headers" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestWriteCorsHeaders(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
recorderFactory func() *httptest.ResponseRecorder | ||
expected http.Header | ||
}{ | ||
{ | ||
name: "should append data in empty writer", | ||
recorderFactory: httptest.NewRecorder, | ||
expected: map[string][]string{ | ||
headers.AccessControlAllowOrigin: {"*"}, | ||
headers.AccessControlAllowCredentials: {"true"}, | ||
headers.AccessControlAllowMethods: { | ||
"GET, PUT, POST, HEAD, TRACE, DELETE, PATCH, COPY, HEAD, LINK, OPTIONS", | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "should append data in filled writer", | ||
recorderFactory: func() *httptest.ResponseRecorder { | ||
writer := httptest.NewRecorder() | ||
writer.Header().Set("Test-Header", "true") | ||
writer.Header().Set("X-Hey-Header", "123") | ||
|
||
return writer | ||
}, | ||
expected: map[string][]string{ | ||
"Test-Header": {"true"}, | ||
"X-Hey-Header": {"123"}, | ||
headers.AccessControlAllowOrigin: {"*"}, | ||
headers.AccessControlAllowCredentials: {"true"}, | ||
headers.AccessControlAllowMethods: { | ||
"GET, PUT, POST, HEAD, TRACE, DELETE, PATCH, COPY, HEAD, LINK, OPTIONS", | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "should override same headers", | ||
recorderFactory: func() *httptest.ResponseRecorder { | ||
writer := httptest.NewRecorder() | ||
writer.Header().Set("Test-Header", "true") | ||
writer.Header().Set(headers.AccessControlAllowOrigin, "localhost:3000") | ||
|
||
return writer | ||
}, | ||
expected: map[string][]string{ | ||
"Test-Header": {"true"}, | ||
headers.AccessControlAllowOrigin: {"*"}, | ||
headers.AccessControlAllowCredentials: {"true"}, | ||
headers.AccessControlAllowMethods: { | ||
"GET, PUT, POST, HEAD, TRACE, DELETE, PATCH, COPY, HEAD, LINK, OPTIONS", | ||
}, | ||
}, | ||
}, | ||
} | ||
for _, testCase := range tests { | ||
t.Run(testCase.name, func(t *testing.T) { | ||
resp := testCase.recorderFactory() | ||
infrastructure.WriteCorsHeaders(resp.Header()) | ||
|
||
response := resp.Result() | ||
defer testutils.CheckNoError(t, response.Body.Close()) | ||
|
||
assert.Equal(t, response.Header, testCase.expected) | ||
}) | ||
} | ||
} |
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
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,205 @@ | ||
package mock_test | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/evg4b/uncors/internal/mock" | ||
"github.com/evg4b/uncors/testing/mocks" | ||
"github.com/evg4b/uncors/testing/testutils" | ||
"github.com/go-http-utils/headers" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
const textPlain = "text/plain; charset=utf-8" | ||
|
||
func TestHandler(t *testing.T) { | ||
logger := mocks.NewNoopLogger(t) | ||
|
||
t.Run("content type setting", func(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
body string | ||
expected string | ||
}{ | ||
{ | ||
name: "plain text", | ||
body: `status: ok`, | ||
expected: textPlain, | ||
}, | ||
{ | ||
name: "json", | ||
body: `{ "status": "ok" }`, | ||
expected: textPlain, | ||
}, | ||
{ | ||
name: "html", | ||
body: `<html></html>`, | ||
expected: "text/html; charset=utf-8", | ||
}, | ||
{ | ||
name: "xml", | ||
body: `<?xml />`, | ||
expected: "text/xml; charset=utf-8", | ||
}, | ||
{ | ||
name: "png", | ||
body: "\x89PNG\x0D\x0A\x1A\x0A", | ||
expected: "image/png", | ||
}, | ||
} | ||
for _, testCase := range tests { | ||
t.Run(testCase.name, func(t *testing.T) { | ||
handler := mock.NewMockHandler(mock.WithLogger(logger), mock.WithResponse(mock.Response{ | ||
Code: 200, | ||
RawContent: testCase.body, | ||
})) | ||
|
||
recorder := httptest.NewRecorder() | ||
request := httptest.NewRequest(http.MethodGet, "/", nil) | ||
handler.ServeHTTP(recorder, request) | ||
|
||
header := testutils.ReadHeader(t, recorder) | ||
assert.EqualValues(t, testCase.expected, header.Get(headers.ContentType)) | ||
}) | ||
} | ||
}) | ||
|
||
t.Run("headers settings", func(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
response mock.Response | ||
expected http.Header | ||
}{ | ||
{ | ||
name: "should put default CORS headers", | ||
response: mock.Response{ | ||
Code: 200, | ||
RawContent: "test content", | ||
}, | ||
expected: map[string][]string{ | ||
headers.AccessControlAllowOrigin: {"*"}, | ||
headers.AccessControlAllowCredentials: {"true"}, | ||
headers.ContentType: {textPlain}, | ||
headers.AccessControlAllowMethods: { | ||
"GET, PUT, POST, HEAD, TRACE, DELETE, PATCH, COPY, HEAD, LINK, OPTIONS", | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "should set response code", | ||
response: mock.Response{ | ||
Code: 200, | ||
RawContent: "test content", | ||
}, | ||
expected: map[string][]string{ | ||
headers.AccessControlAllowOrigin: {"*"}, | ||
headers.AccessControlAllowCredentials: {"true"}, | ||
headers.ContentType: {textPlain}, | ||
headers.AccessControlAllowMethods: { | ||
"GET, PUT, POST, HEAD, TRACE, DELETE, PATCH, COPY, HEAD, LINK, OPTIONS", | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "should set custom headers", | ||
response: mock.Response{ | ||
Code: 200, | ||
Headers: map[string]string{ | ||
"X-Key": "X-Key-Value", | ||
}, | ||
RawContent: "test content", | ||
}, | ||
expected: map[string][]string{ | ||
headers.AccessControlAllowOrigin: {"*"}, | ||
headers.AccessControlAllowCredentials: {"true"}, | ||
headers.ContentType: {textPlain}, | ||
"X-Key": {"X-Key-Value"}, | ||
headers.AccessControlAllowMethods: { | ||
"GET, PUT, POST, HEAD, TRACE, DELETE, PATCH, COPY, HEAD, LINK, OPTIONS", | ||
}, | ||
}, | ||
}, | ||
{ | ||
name: "should override default headers", | ||
response: mock.Response{ | ||
Code: 200, | ||
Headers: map[string]string{ | ||
headers.AccessControlAllowOrigin: "localhost", | ||
headers.AccessControlAllowCredentials: "false", | ||
headers.ContentType: "none", | ||
}, | ||
RawContent: "test content", | ||
}, | ||
expected: map[string][]string{ | ||
headers.AccessControlAllowOrigin: {"localhost"}, | ||
headers.AccessControlAllowCredentials: {"false"}, | ||
headers.ContentType: {"none"}, | ||
headers.AccessControlAllowMethods: { | ||
"GET, PUT, POST, HEAD, TRACE, DELETE, PATCH, COPY, HEAD, LINK, OPTIONS", | ||
}, | ||
}, | ||
}, | ||
} | ||
for _, testCase := range tests { | ||
t.Run(testCase.name, func(t *testing.T) { | ||
handler := mock.NewMockHandler( | ||
mock.WithResponse(testCase.response), | ||
mock.WithLogger(logger), | ||
) | ||
|
||
request := httptest.NewRequest(http.MethodGet, "/", nil) | ||
recorder := httptest.NewRecorder() | ||
|
||
handler.ServeHTTP(recorder, request) | ||
|
||
assert.EqualValues(t, testCase.expected, testutils.ReadHeader(t, recorder)) | ||
assert.Equal(t, 200, recorder.Code) | ||
}) | ||
} | ||
}) | ||
|
||
t.Run("status code", func(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
response mock.Response | ||
expected int | ||
}{ | ||
{ | ||
name: "provide 201 code", | ||
response: mock.Response{ | ||
Code: 201, | ||
}, | ||
expected: 201, | ||
}, | ||
{ | ||
name: "provide 503 code", | ||
response: mock.Response{ | ||
Code: 503, | ||
}, | ||
expected: 503, | ||
}, | ||
{ | ||
name: "automatically provide 200 code", | ||
response: mock.Response{}, | ||
expected: 200, | ||
}, | ||
} | ||
for _, testCase := range tests { | ||
t.Run(testCase.name, func(t *testing.T) { | ||
handler := mock.NewMockHandler( | ||
mock.WithResponse(testCase.response), | ||
mock.WithLogger(logger), | ||
) | ||
|
||
request := httptest.NewRequest(http.MethodGet, "/", nil) | ||
recorder := httptest.NewRecorder() | ||
|
||
handler.ServeHTTP(recorder, request) | ||
|
||
assert.Equal(t, testCase.expected, recorder.Code) | ||
}) | ||
} | ||
}) | ||
} |
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
Oops, something went wrong.