Skip to content

Commit

Permalink
refactoring webhook (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
walkerus authored Aug 10, 2023
1 parent 170000e commit ec5b9b2
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 78 deletions.
7 changes: 4 additions & 3 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@ func TestStubRule_ToJson(t *testing.T) {
WithHeader("Content-Type", "application/json").
WithBody(`{"code": 400, "detail": "detail"}`).
WithFault(FaultConnectionResetByPeer).
WithFixedDelay(time.Second * 5),
WithFixedDelay(time.Second*5),
).
WithPostServeAction("webhook", Webhook().
WithPostServeAction("webhook", NewWebhook().
WithMethod("POST").
WithURL("http://my-target-host/callback").
WithHeader("Content-Type", "application/json").
WithBody(`{ "result": "SUCCESS" }`)).
WithBody(`{ "result": "SUCCESS" }`).
WithFixedDelay(time.Second)).
AtPriority(1).
InScenario("Scenario").
WhenScenarioStateIs("Started").
Expand Down
25 changes: 24 additions & 1 deletion delay.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package wiremock

import "encoding/json"
import (
"encoding/json"
"time"
)

type DelayInterface interface {
ParseDelay() map[string]interface{}
Expand Down Expand Up @@ -56,3 +59,23 @@ func (d chunkedDribbleDelay) MarshalJSON() ([]byte, error) {

return json.Marshal(jsonMap)
}

func NewLogNormalRandomDelay(median time.Duration, sigma float64) DelayInterface {
return logNormalRandomDelay{
median: median.Milliseconds(),
sigma: sigma,
}
}

func NewFixedDelay(delay time.Duration) DelayInterface {
return fixedDelay{
milliseconds: delay.Milliseconds(),
}
}

func NewUniformRandomDelay(lower, upper time.Duration) DelayInterface {
return uniformRandomDelay{
lower: lower.Milliseconds(),
upper: upper.Milliseconds(),
}
}
6 changes: 5 additions & 1 deletion expected-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@
"headers": {
"Content-Type": "application/json"
},
"body": "{ \"result\": \"SUCCESS\" }"
"body": "{ \"result\": \"SUCCESS\" }",
"delay": {
"type": "fixed",
"milliseconds": 1000
}
}
}
]
Expand Down
25 changes: 10 additions & 15 deletions response.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,31 +37,26 @@ func NewResponse() Response {
}

// WithLogNormalRandomDelay sets log normal random delay for response
func (r Response) WithLogNormalRandomDelay(mediana time.Duration, sigma float64) Response {
r.delayDistribution = logNormalRandomDelay{
median: mediana.Milliseconds(),
sigma: sigma,
}

func (r Response) WithLogNormalRandomDelay(median time.Duration, sigma float64) Response {
r.delayDistribution = NewLogNormalRandomDelay(median, sigma)
return r
}

// WithUniformRandomDelay sets uniform random delay for response
func (r Response) WithUniformRandomDelay(lower, upper time.Duration) Response {
r.delayDistribution = uniformRandomDelay{
lower: lower.Milliseconds(),
upper: upper.Milliseconds(),
}

r.delayDistribution = NewUniformRandomDelay(lower, upper)
return r
}

// WithFixedDelay sets fixed delay milliseconds for response
func (r Response) WithFixedDelay(time time.Duration) Response {
r.delayDistribution = fixedDelay{
milliseconds: time.Milliseconds(),
}
func (r Response) WithFixedDelay(delay time.Duration) Response {
r.delayDistribution = NewFixedDelay(delay)
return r
}

// WithDelay sets delay for response
func (r Response) WithDelay(delay DelayInterface) Response {
r.delayDistribution = delay
return r
}

Expand Down
39 changes: 6 additions & 33 deletions stub_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,6 @@ import (

const ScenarioStateStarted = "Started"

type Matcher interface {
StringValueMatcher | MultiValueMatcher
}

type postServeAction struct {
extensionName string
parameters PostServeActionParameters
}

type PostServeActionParameters interface {
ToMap() map[string]interface{}
}

// StubRule is struct of http Request body to WireMock
type StubRule struct {
uuid string
Expand All @@ -33,7 +20,7 @@ type StubRule struct {
scenarioName *string
requiredScenarioState *string
newScenarioState *string
postServeActions []postServeAction
postServeActions []WebhookInterface
}

// NewStubRule returns a new *StubRule.
Expand Down Expand Up @@ -201,11 +188,8 @@ func Patch(urlMatchingPair URLMatcher) *StubRule {
return NewStubRule(http.MethodPatch, urlMatchingPair)
}

func (s *StubRule) WithPostServeAction(extensionName string, parameters PostServeActionParameters) *StubRule {
s.postServeActions = append(s.postServeActions, postServeAction{
extensionName: extensionName,
parameters: parameters,
})
func (s *StubRule) WithPostServeAction(extensionName string, webhook WebhookInterface) *StubRule {
s.postServeActions = append(s.postServeActions, webhook.WithName(extensionName))
return s
}

Expand All @@ -220,26 +204,15 @@ func (s *StubRule) MarshalJSON() ([]byte, error) {
NewScenarioState *string `json:"newScenarioState,omitempty"`
Request *Request `json:"request"`
Response map[string]interface{} `json:"response"`
PostServeActions []struct {
Name string `json:"name"`
Parameters map[string]interface{} `json:"parameters"`
} `json:"postServeActions,omitempty"`
PostServeActions []WebhookInterface `json:"postServeActions,omitempty"`
}{}

jsonStubRule.Priority = s.priority
jsonStubRule.ScenarioName = s.scenarioName
jsonStubRule.RequiredScenarioScenarioState = s.requiredScenarioState
jsonStubRule.NewScenarioState = s.newScenarioState
jsonStubRule.Response = s.response.ParseResponse()

for _, postServeAction := range s.postServeActions {
jsonStubRule.PostServeActions = append(jsonStubRule.PostServeActions, struct {
Name string `json:"name"`
Parameters map[string]interface{} `json:"parameters"`
}{
Name: postServeAction.extensionName,
Parameters: postServeAction.parameters.ToMap(),
})
}
jsonStubRule.PostServeActions = s.postServeActions

if s.fixedDelayMilliseconds != nil {
jsonStubRule.Response["fixedDelayMilliseconds"] = *s.fixedDelayMilliseconds
Expand Down
118 changes: 93 additions & 25 deletions webhook.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,113 @@
package wiremock

type WebhookDefinition struct {
m map[string]any
import (
"encoding/json"
"time"
)

type WebhookInterface interface {
json.Marshaler
WithName(name string) WebhookInterface
ParseWebhook() map[string]interface{}
}

type Webhook struct {
name string
parameters webhookParameters
}

type webhookParameters struct {
method string
url string
body string
headers map[string]string
delay DelayInterface
}

func (w webhookParameters) MarshalJSON() ([]byte, error) {
jsonMap := map[string]interface{}{
"method": w.method,
"url": w.url,
"body": w.body,
"headers": w.headers,
"delay": w.delay.ParseDelay(),
}

return json.Marshal(jsonMap)
}

// WithName sets the name of the webhook and returns the webhook.
func (w Webhook) WithName(name string) WebhookInterface {
w.name = name
return w
}

func Webhook() WebhookDefinition {
return WebhookDefinition{
m: make(map[string]any),
// ParseWebhook returns a map representation of the webhook.
func (w Webhook) ParseWebhook() map[string]interface{} {
return map[string]interface{}{
"name": w.name,
"parameters": w.parameters,
}
}

func (d WebhookDefinition) WithMethod(method string) WebhookDefinition {
d.m["method"] = method
return d
// MarshalJSON implements the json.Marshaler interface.
func (w Webhook) MarshalJSON() ([]byte, error) {
return json.Marshal(w.ParseWebhook())
}

func (d WebhookDefinition) WithURL(url string) WebhookDefinition {
d.m["url"] = url
return d
// WithMethod sets the HTTP method of the webhook.
func (w Webhook) WithMethod(method string) Webhook {
w.parameters.method = method
return w
}

func (d WebhookDefinition) WithHeader(key string, value string) WebhookDefinition {
var headers map[string]string
// WithURL sets the URL of the webhook.
func (w Webhook) WithURL(url string) Webhook {
w.parameters.url = url
return w
}

if headersAny, ok := d.m["headers"]; ok {
headers = headersAny.(map[string]string)
} else {
headers = make(map[string]string)
d.m["headers"] = headers
// WithHeader sets a header of the webhook.
func (w Webhook) WithHeader(key string, value string) Webhook {
if w.parameters.headers == nil {
w.parameters.headers = make(map[string]string)
}

headers[key] = value
w.parameters.headers[key] = value

return w
}

// WithBody sets the body of the webhook.
func (w Webhook) WithBody(body string) Webhook {
w.parameters.body = body
return w
}

// WithDelay sets the delay of the webhook.
func (w Webhook) WithDelay(delay DelayInterface) Webhook {
w.parameters.delay = delay
return w
}

// WithFixedDelay sets the fixed delay of the webhook.
func (w Webhook) WithFixedDelay(delay time.Duration) Webhook {
w.parameters.delay = NewFixedDelay(delay)
return w
}

return d
// WithLogNormalRandomDelay sets the log normal delay of the webhook.
func (w Webhook) WithLogNormalRandomDelay(median time.Duration, sigma float64) Webhook {
w.parameters.delay = NewLogNormalRandomDelay(median, sigma)
return w
}

func (d WebhookDefinition) WithBody(body string) WebhookDefinition {
d.m["body"] = body
return d
// WithUniformRandomDelay sets the uniform random delay of the webhook.
func (w Webhook) WithUniformRandomDelay(lower, upper time.Duration) Webhook {
w.parameters.delay = NewUniformRandomDelay(lower, upper)
return w
}

func (d WebhookDefinition) ToMap() map[string]any {
return d.m
func NewWebhook() Webhook {
return Webhook{}
}

0 comments on commit ec5b9b2

Please sign in to comment.