Skip to content

Commit adf8045

Browse files
authored
Merge pull request #1 from walkerus/priority-scenarios
Added priority and scenarios
2 parents 09ecbe8 + 969d4b4 commit adf8045

File tree

4 files changed

+143
-49
lines changed

4 files changed

+143
-49
lines changed

README.md

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,62 @@
22
[![Actions Status](https://github.com/walkerus/go-wiremock/workflows/build/badge.svg)](https://github.com/walkerus/go-wiremock/actions?query=workflow%3Abuild)
33
[![Go Report Card](https://goreportcard.com/badge/github.com/walkerus/go-wiremock)](https://goreportcard.com/report/github.com/walkerus/go-wiremock)
44

5-
A simple package for stub http resource using [WireMock admin](http://wiremock.org/docs/api/)
6-
7-
## Install
8-
```go get https://github.com/walkerus/go-wiremock```
5+
The simple package to stub HTTP resource using [WireMock admin](http://wiremock.org/docs/api/)
96

107
## Usage
118
```
129
docker run -it --rm -p 8080:8080 rodolpheche/wiremock
1310
```
1411
```go
15-
wiremockClient := NewClient("http://0.0.0.0:8080")
16-
defer wiremockClient.Reset()
17-
wiremockClient.StubFor(Post(URLPathEqualTo("/example")).
18-
WithQueryParam("firstName", EqualTo("Jhon")).
19-
WithQueryParam("lastName", NotMatching("Black")).
20-
WithBodyPattern(EqualToJson(`{"meta": "information"}`)).
21-
WithHeader("x-session", Matching("^\\S+fingerprint\\S+$")).
12+
package main
13+
14+
import (
15+
"testing"
16+
"github.com/walkerus/go-wiremock"
17+
)
18+
19+
func TestSome(t *testing.T) {
20+
wiremockClient := wiremock.NewClient("http://0.0.0.0:8080")
21+
defer wiremockClient.Reset()
22+
23+
// stubbing POST http://0.0.0.0:8080/example
24+
wiremockClient.StubFor(wiremock.Post(wiremock.URLPathEqualTo("/example")).
25+
WithQueryParam("firstName", wiremock.EqualTo("Jhon")).
26+
WithQueryParam("lastName", wiremock.NotMatching("Black")).
27+
WithBodyPattern(wiremock.EqualToJson(`{"meta": "information"}`)).
28+
WithHeader("x-session", wiremock.Matching("^\\S+fingerprint\\S+$")).
29+
WillReturn(
30+
`{"code": 400, "detail": "detail"}`,
31+
map[string]string{"Content-Type": "application/json"},
32+
400,
33+
).
34+
AtPriority(1))
35+
36+
// scenario
37+
defer wiremockClient.ResetAllScenarios()
38+
wiremockClient.StubFor(wiremock.Get(wiremock.URLPathEqualTo("/status")).
2239
WillReturn(
23-
`{"code": 400, "detail": "detail"}`,
40+
`{"status": null}`,
2441
map[string]string{"Content-Type": "application/json"},
25-
400,
26-
))
42+
200,
43+
).
44+
InScenario("Set status").
45+
WhenScenarioStateIs(wiremock.ScenarioStateStarted))
46+
47+
wiremockClient.StubFor(wiremock.Post(wiremock.URLPathEqualTo("/state")).
48+
WithBodyPattern(wiremock.EqualToJson(`{"status": "started"}`)).
49+
InScenario("Set status").
50+
WillSetStateTo("Status started"))
51+
52+
wiremockClient.StubFor(wiremock.Get(wiremock.URLPathEqualTo("/status")).
53+
WillReturn(
54+
`{"status": "started"}`,
55+
map[string]string{"Content-Type": "application/json"},
56+
200,
57+
).
58+
InScenario("Set status").
59+
WhenScenarioStateIs("Status started"))
2760

28-
// testing code...
61+
//testing code...
62+
}
2963
```

client.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import (
88
"net/http"
99
)
1010

11-
const wiremockAdminURN = "__admin/mappings"
11+
const (
12+
wiremockAdminURN = "__admin"
13+
wiremockAdminMappingsURN = "__admin/mappings"
14+
)
1215

1316
// A Client implements requests to the wiremock server
1417
type Client struct {
@@ -27,10 +30,11 @@ func (c *Client) StubFor(stubRule *StubRule) error {
2730
return fmt.Errorf("build stub request error: %s", err.Error())
2831
}
2932

30-
res, err := http.Post(fmt.Sprintf("%s/%s", c.url, wiremockAdminURN), "application/json", bytes.NewBuffer(requestBody))
33+
res, err := http.Post(fmt.Sprintf("%s/%s", c.url, wiremockAdminMappingsURN), "application/json", bytes.NewBuffer(requestBody))
3134
if err != nil {
3235
return fmt.Errorf("stub request error: %s", err.Error())
3336
}
37+
defer res.Body.Close()
3438

3539
if res.StatusCode != http.StatusCreated {
3640
bodyBytes, err := ioutil.ReadAll(res.Body)
@@ -46,7 +50,7 @@ func (c *Client) StubFor(stubRule *StubRule) error {
4650

4751
// Clear deletes all stub mappings.
4852
func (c *Client) Clear() error {
49-
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/%s", c.url, wiremockAdminURN), nil)
53+
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/%s", c.url, wiremockAdminMappingsURN), nil)
5054
if err != nil {
5155
return fmt.Errorf("build cleare request error: %s", err.Error())
5256
}
@@ -55,6 +59,7 @@ func (c *Client) Clear() error {
5559
if err != nil {
5660
return fmt.Errorf("clear request error: %s", err.Error())
5761
}
62+
defer res.Body.Close()
5863

5964
if res.StatusCode != http.StatusOK {
6065
return fmt.Errorf("bad response status: %d", res.StatusCode)
@@ -65,10 +70,31 @@ func (c *Client) Clear() error {
6570

6671
// Reset restores stub mappings to the defaults defined back in the backing store.
6772
func (c *Client) Reset() error {
68-
res, err := http.Post(fmt.Sprintf("%s/%s/reset", c.url, wiremockAdminURN), "application/json", nil)
73+
res, err := http.Post(fmt.Sprintf("%s/%s/reset", c.url, wiremockAdminMappingsURN), "application/json", nil)
6974
if err != nil {
7075
return fmt.Errorf("reset request error: %s", err.Error())
7176
}
77+
defer res.Body.Close()
78+
79+
if res.StatusCode != http.StatusOK {
80+
bodyBytes, err := ioutil.ReadAll(res.Body)
81+
if err != nil {
82+
return fmt.Errorf("read response error: %s", err.Error())
83+
}
84+
85+
return fmt.Errorf("bad response status: %d, response: %s", res.StatusCode, string(bodyBytes))
86+
}
87+
88+
return nil
89+
}
90+
91+
// ResetAllScenarios resets back to start of the state of all configured scenarios.
92+
func (c *Client) ResetAllScenarios() error {
93+
res, err := http.Post(fmt.Sprintf("%s/%s/scenarios/reset", c.url, wiremockAdminURN), "application/json", nil)
94+
if err != nil {
95+
return fmt.Errorf("reset all scenarios request error: %s", err.Error())
96+
}
97+
defer res.Body.Close()
7298

7399
if res.StatusCode != http.StatusOK {
74100
bodyBytes, err := ioutil.ReadAll(res.Body)

client_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ func TestStubRule_ToJson(t *testing.T) {
2828
`{"code": 400, "detail": "detail"}`,
2929
map[string]string{"Content-Type": "application/json"},
3030
400,
31-
)
31+
).
32+
AtPriority(1).
33+
InScenario("Scenario").
34+
WhenScenarioStateIs("Started").
35+
WillSetStateTo("Stopped")
3236

33-
expectedRequestBody = `{"request":` +
34-
`{"bodyPatterns":[{"equalToJson":"{\"meta\": \"information\"}"},{"contains":"information"}],` +
37+
expectedRequestBody = `{"priority":1,"scenarioName":"Scenario","requiredScenarioState":"Started","newScenarioState":"Stopped",` +
38+
`"request":{"bodyPatterns":[{"equalToJson":"{\"meta\": \"information\"}"},{"contains":"information"}],` +
3539
`"cookies":{"session":{"equalToXml":"\u003cxml\u003e"}},` +
3640
`"headers":{"x-session":{"matches":"^\\S+@\\S+$"}},` +
3741
`"method":"POST","queryParameters":{"firstName":{"equalTo":"Jhon"},"lastName":{"doesNotMatch":"Black"}},"urlPath":"/example"},` +

stub_rule.go

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"net/http"
66
)
77

8+
const ScenarioStateStarted = "Started"
9+
810
// ParamMatcherInterface is pair ParamMatchingStrategy and string matched value
911
type ParamMatcherInterface interface {
1012
Strategy() ParamMatchingStrategy
@@ -34,17 +36,31 @@ type response struct {
3436

3537
// StubRule is struct of http request body to WireMock
3638
type StubRule struct {
37-
request request
38-
response response
39+
request request
40+
response response
41+
priority *int64
42+
scenarioName *string
43+
requiredScenarioState *string
44+
newScenarioState *string
45+
}
46+
47+
// NewStubRule returns a new *StubRule.
48+
func NewStubRule(method string, urlMatcher URLMatcher) *StubRule {
49+
return &StubRule{
50+
request: request{
51+
urlMatcher: urlMatcher,
52+
method: method,
53+
},
54+
response: response{
55+
status: http.StatusOK,
56+
},
57+
}
3958
}
4059

4160
// WithQueryParam adds query param and returns *StubRule
4261
func (s *StubRule) WithQueryParam(param string, matcher ParamMatcherInterface) *StubRule {
4362
if s.request.queryParams == nil {
44-
s.request.queryParams = map[string]ParamMatcherInterface{
45-
param: matcher,
46-
}
47-
return s
63+
s.request.queryParams = map[string]ParamMatcherInterface{}
4864
}
4965

5066
s.request.queryParams[param] = matcher
@@ -54,10 +70,7 @@ func (s *StubRule) WithQueryParam(param string, matcher ParamMatcherInterface) *
5470
// WithHeader adds header to Headers and returns *StubRule
5571
func (s *StubRule) WithHeader(header string, matcher ParamMatcherInterface) *StubRule {
5672
if s.request.headers == nil {
57-
s.request.headers = map[string]ParamMatcherInterface{
58-
header: matcher,
59-
}
60-
return s
73+
s.request.headers = map[string]ParamMatcherInterface{}
6174
}
6275

6376
s.request.headers[header] = matcher
@@ -67,10 +80,7 @@ func (s *StubRule) WithHeader(header string, matcher ParamMatcherInterface) *Stu
6780
// WithCookie adds cookie and returns *StubRule
6881
func (s *StubRule) WithCookie(cookie string, matcher ParamMatcherInterface) *StubRule {
6982
if s.request.cookies == nil {
70-
s.request.cookies = map[string]ParamMatcherInterface{
71-
cookie: matcher,
72-
}
73-
return s
83+
s.request.cookies = map[string]ParamMatcherInterface{}
7484
}
7585

7686
s.request.cookies[cookie] = matcher
@@ -91,17 +101,28 @@ func (s *StubRule) WillReturn(body string, headers map[string]string, status int
91101
return s
92102
}
93103

94-
// NewStubRule returns a new *StubRule.
95-
func NewStubRule(method string, urlMatcher URLMatcher) *StubRule {
96-
return &StubRule{
97-
request: request{
98-
urlMatcher: urlMatcher,
99-
method: method,
100-
},
101-
response: response{
102-
status: http.StatusOK,
103-
},
104-
}
104+
// AtPriority sets priority and returns *StubRule
105+
func (s *StubRule) AtPriority(priority int64) *StubRule {
106+
s.priority = &priority
107+
return s
108+
}
109+
110+
// InScenario sets scenarioName and returns *StubRule
111+
func (s *StubRule) InScenario(scenarioName string) *StubRule {
112+
s.scenarioName = &scenarioName
113+
return s
114+
}
115+
116+
// WhenScenarioStateIs sets requiredScenarioState and returns *StubRule
117+
func (s *StubRule) WhenScenarioStateIs(scenarioState string) *StubRule {
118+
s.requiredScenarioState = &scenarioState
119+
return s
120+
}
121+
122+
// WillSetStateTo sets newScenarioState and returns *StubRule
123+
func (s *StubRule) WillSetStateTo(scenarioState string) *StubRule {
124+
s.newScenarioState = &scenarioState
125+
return s
105126
}
106127

107128
// Post returns *StubRule for POST method.
@@ -124,15 +145,24 @@ func Put(urlMatchingPair URLMatcher) *StubRule {
124145
return NewStubRule(http.MethodPut, urlMatchingPair)
125146
}
126147

148+
//MarshalJSON makes json body for http request
127149
func (s *StubRule) MarshalJSON() ([]byte, error) {
128150
jsonStubRule := struct {
129-
Request map[string]interface{} `json:"request"`
130-
Response struct {
151+
Priority *int64 `json:"priority,omitempty"`
152+
ScenarioName *string `json:"scenarioName,omitempty"`
153+
RequiredScenarioScenarioState *string `json:"requiredScenarioState,omitempty"`
154+
NewScenarioState *string `json:"newScenarioState,omitempty"`
155+
Request map[string]interface{} `json:"request"`
156+
Response struct {
131157
Body string `json:"body,omitempty"`
132158
Headers map[string]string `json:"headers,omitempty"`
133159
Status int64 `json:"status,omitempty"`
134160
} `json:"response"`
135161
}{}
162+
jsonStubRule.Priority = s.priority
163+
jsonStubRule.ScenarioName = s.scenarioName
164+
jsonStubRule.RequiredScenarioScenarioState = s.requiredScenarioState
165+
jsonStubRule.NewScenarioState = s.newScenarioState
136166
jsonStubRule.Response.Body = s.response.body
137167
jsonStubRule.Response.Headers = s.response.headers
138168
jsonStubRule.Response.Status = s.response.status

0 commit comments

Comments
 (0)