diff --git a/client_test.go b/client_test.go index 9945ac1..ce32bae 100644 --- a/client_test.go +++ b/client_test.go @@ -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"). diff --git a/delay.go b/delay.go index 50cb95d..7418f1a 100644 --- a/delay.go +++ b/delay.go @@ -1,6 +1,9 @@ package wiremock -import "encoding/json" +import ( + "encoding/json" + "time" +) type DelayInterface interface { ParseDelay() map[string]interface{} @@ -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(), + } +} diff --git a/expected-template.json b/expected-template.json index bde2202..4e22e3b 100644 --- a/expected-template.json +++ b/expected-template.json @@ -122,7 +122,11 @@ "headers": { "Content-Type": "application/json" }, - "body": "{ \"result\": \"SUCCESS\" }" + "body": "{ \"result\": \"SUCCESS\" }", + "delay": { + "type": "fixed", + "milliseconds": 1000 + } } } ] diff --git a/response.go b/response.go index 1270b13..e80830d 100644 --- a/response.go +++ b/response.go @@ -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 } diff --git a/stub_rule.go b/stub_rule.go index 72f95aa..99d73ac 100644 --- a/stub_rule.go +++ b/stub_rule.go @@ -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 @@ -33,7 +20,7 @@ type StubRule struct { scenarioName *string requiredScenarioState *string newScenarioState *string - postServeActions []postServeAction + postServeActions []WebhookInterface } // NewStubRule returns a new *StubRule. @@ -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 } @@ -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 diff --git a/webhook.go b/webhook.go index 8b7e7a0..3eec53f 100644 --- a/webhook.go +++ b/webhook.go @@ -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{} }