Skip to content
This repository was archived by the owner on Aug 7, 2022. It is now read-only.

Commit 45f3833

Browse files
authoredAug 6, 2022
feat: support auto_cors option (#7)
1 parent a4b841a commit 45f3833

File tree

6 files changed

+99
-86
lines changed

6 files changed

+99
-86
lines changed
 

‎engine.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,14 @@ func (eng *Engine) Handler(w http.ResponseWriter, r *http.Request) {
8585
response := eng.Match(r)
8686
if response == nil {
8787
mok := eng.getMock()
88+
89+
if mok.AutoCORS && r.Method == http.MethodOptions {
90+
eng.corsHandler(w, r)
91+
return
92+
}
93+
8894
if mok.ProxyEnabled() {
89-
eng.handleProxy(w, r)
95+
eng.proxyHandler(w, r)
9096
return
9197
}
9298

@@ -106,7 +112,11 @@ func (eng *Engine) noMatchHandler(w http.ResponseWriter) {
106112
w.WriteHeader(http.StatusNotFound)
107113
}
108114

109-
func (eng *Engine) handleProxy(w http.ResponseWriter, r *http.Request) {
115+
func (eng *Engine) corsHandler(w http.ResponseWriter, r *http.Request) {
116+
w.WriteHeader(http.StatusOK)
117+
}
118+
119+
func (eng *Engine) proxyHandler(w http.ResponseWriter, r *http.Request) {
110120
proxy := eng.getMock().Proxy
111121

112122
req, err := copyProxyRequest(r, proxy)

‎engine_test.go

+72-1
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,80 @@ func TestEngine_ProxyHandler(t *testing.T) {
174174
assert.Equal(t, "from response", res.Header.Get("X-Response"))
175175
}
176176

177+
func TestEngine_CORS_Request(t *testing.T) {
178+
tests := []struct {
179+
name string
180+
mok *mock.Mock
181+
expectedStatusCode int
182+
}{
183+
{
184+
"Auto CORS option is disabled, and no matching response, expect default 404",
185+
&mock.Mock{
186+
ID: "mock-id",
187+
},
188+
http.StatusNotFound,
189+
}, {
190+
"Auto CORS option is enabled, and no matching response, expect 200 OK",
191+
&mock.Mock{
192+
ID: "mock-id",
193+
AutoCORS: true,
194+
},
195+
http.StatusOK,
196+
},
197+
{
198+
"Auto CORS option is enabled, and has matching response, use the matched response",
199+
&mock.Mock{
200+
ID: "mock-id",
201+
AutoCORS: true,
202+
Routes: []*mock.Route{
203+
{
204+
Method: "OPTIONS",
205+
Path: "/hello",
206+
Responses: []mock.Response{
207+
{
208+
Status: 201,
209+
},
210+
},
211+
},
212+
},
213+
},
214+
http.StatusCreated,
215+
},
216+
}
217+
218+
for _, tt := range tests {
219+
t.Run(tt.name, func(t *testing.T) {
220+
mem := memory.New()
221+
_ = mem.SetMock(context.Background(), tt.mok)
222+
eng := engine.New("mock-id", mem)
223+
req := httptest.NewRequest(http.MethodOptions, "/hello", nil)
224+
w := httptest.NewRecorder()
225+
eng.Handler(w, req)
226+
res := w.Result()
227+
defer func() {
228+
_ = res.Body.Close()
229+
}()
230+
231+
assert.Equal(t, tt.expectedStatusCode, res.StatusCode)
232+
})
233+
}
234+
}
235+
236+
func TestEngine_MockNotFound(t *testing.T) {
237+
mem := memory.New()
238+
_ = mem.SetMock(context.Background(), &mock.Mock{
239+
ID: "mock-2",
240+
})
241+
eng := engine.New("mock-1", mem)
242+
req, _ := http.NewRequest(http.MethodGet, "/hello", nil)
243+
244+
assert.Nil(t, eng.Match(req))
245+
}
246+
177247
func setupMock() persistent.Persistent {
178248
mok := &mock.Mock{
179-
ID: "mock-id",
249+
ID: "mock-id",
250+
AutoCORS: true,
180251
Routes: []*mock.Route{
181252
{
182253
Method: "GET",

‎mock/fixtures/mock.golden.yml

+1
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,4 @@ proxy:
5858
X-Forward: "123"
5959
response_headers:
6060
X-Response: "123"
61+
auto_cors: true

‎mock/fixtures/mock.json

-72
This file was deleted.

‎mock/fixtures/mock.yml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ proxy:
66
X-Forward: 123
77
response_headers:
88
X-Response: 123
9+
auto_cors: true
910
routes:
1011
- method: GET
1112
path: /hello/world

‎mock/mock.go

+13-11
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ import (
1212
)
1313

1414
type Mock struct {
15-
ID string `yaml:"id,omitempty" json:"id,omitempty"`
16-
Name string `yaml:"name,omitempty" json:"name,omitempty"`
17-
Port string `yaml:"port,omitempty" json:"port,omitempty"`
18-
Routes []*Route `yaml:"routes,omitempty" json:"routes,omitempty"`
19-
Proxy *Proxy `yaml:"proxy,omitempty" json:"proxy,omitempty"`
20-
options mockOptions
15+
ID string `yaml:"id,omitempty" json:"id,omitempty"`
16+
Name string `yaml:"name,omitempty" json:"name,omitempty"`
17+
Port string `yaml:"port,omitempty" json:"port,omitempty"`
18+
Routes []*Route `yaml:"routes,omitempty" json:"routes,omitempty"`
19+
Proxy *Proxy `yaml:"proxy,omitempty" json:"proxy,omitempty"`
20+
// all OPTIONS calls are responded with success if AutoCORS is true
21+
AutoCORS bool `yaml:"auto_cors,omitempty" json:"auto_cors,omitempty"`
22+
options mockOptions
2123
}
2224

2325
func New(opts ...Option) *Mock {
@@ -56,15 +58,15 @@ func FromYaml(text string, opts ...Option) (*Mock, error) {
5658
return m, nil
5759
}
5860

59-
func (c Mock) Validate() error {
61+
func (m Mock) Validate() error {
6062
return validation.ValidateStruct(
61-
&c,
62-
validation.Field(&c.Routes, validation.Required),
63+
&m,
64+
validation.Field(&m.Routes, validation.Required),
6365
)
6466
}
6567

66-
func (c Mock) ProxyEnabled() bool {
67-
return c.Proxy != nil && c.Proxy.Enabled
68+
func (m Mock) ProxyEnabled() bool {
69+
return m.Proxy != nil && m.Proxy.Enabled
6870
}
6971

7072
func defaultValues(m *Mock) {

0 commit comments

Comments
 (0)
This repository has been archived.