Skip to content

Commit

Permalink
feat: new experimental v3 api for http and messages
Browse files Browse the repository at this point in the history
  • Loading branch information
mefellows committed May 29, 2021
1 parent 3797399 commit 31fb98c
Show file tree
Hide file tree
Showing 10 changed files with 339 additions and 206 deletions.
168 changes: 77 additions & 91 deletions examples/v3/consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"testing"

v3 "github.com/pact-foundation/pact-go/v3"
"github.com/stretchr/testify/assert"
)

type s = v3.String
Expand Down Expand Up @@ -46,41 +47,36 @@ func TestConsumerV2(t *testing.T) {
AddInteraction().
Given("User foo exists").
UponReceiving("A request to do a foo").
WithRequest(v3.Request{
Method: "POST",
Path: v3.Regex("/foobar", `\/foo.*`),
Headers: v3.MapMatcher{"Content-Type": s("application/json"), "Authorization": v3.Like("Bearer 1234")},
Query: v3.QueryMatcher{
"baz": []v3.Matcher{
v3.Regex("bar", "[a-z]+"),
v3.Regex("bat", "[a-z]+"),
v3.Regex("baz", "[a-z]+"),
},
WithRequest("POST", v3.Regex("/foobar", `\/foo.*`)).
Headers(v3.MapMatcher{"Content-Type": s("application/json"), "Authorization": v3.Like("Bearer 1234")}).
Query(v3.QueryMatcher{
"baz": []v3.Matcher{
v3.Regex("bar", "[a-z]+"),
v3.Regex("bat", "[a-z]+"),
v3.Regex("baz", "[a-z]+"),
},
// Body: v3.MapMatcher{
// "id": v3.Like(27),
// "name": v3.Like("billy"),
// "datetime": v3.Like("2020-01-01'T'08:00:45"),
// "lastName": v3.Like("billy"),
// },
Body: v3.MatchV2(&User{}),
}).
WillRespondWith(v3.Response{
Status: 200,
Headers: v3.MapMatcher{"Content-Type": v3.Regex("application/json", "application\\/json")},
// Body: v3.Match(&User{}),
Body: v3.MapMatcher{
"dateTime": v3.Regex("2020-01-01", "[0-9\\-]+"),
"name": s("FirstName"),
"lastName": s("LastName"),
"itemsMin": v3.ArrayMinLike("thereshouldbe3ofthese", 3),
// Add any of these this to demonstrate adding a v3 matcher failing the build (not at the type system level unfortunately)
// "id": v3.Integer(1),
// "superstring": v3.Includes("foo"),
// "accountBalance": v3.Decimal(123.76),
// "itemsMinMax": v3.ArrayMinMaxLike(27, 3, 5),
// "equality": v3.Equality("a thing"),
},
// Body: v3.MatchV2(&User{}),
JSON(v3.MapMatcher{
"id": v3.Like(27),
"name": v3.Like("billy"),
"datetime": v3.Like("2020-01-01'T'08:00:45"),
"lastName": v3.Like("billy"),
}).
WillRespondWith(200).
Headers(v3.MapMatcher{"Content-Type": v3.Regex("application/json", "application\\/json")}).
// // Body: v3.Match(&User{}),
JSON(v3.MapMatcher{
"dateTime": v3.Regex("2020-01-01", "[0-9\\-]+"),
"name": s("FirstName"),
"lastName": s("LastName"),
"itemsMin": v3.ArrayMinLike("thereshouldbe3ofthese", 3),
// Add any of these this to demonstrate adding a v3 matcher failing the build (not at the type system level unfortunately)
// "id": v3.Integer(1),
// "superstring": v3.Includes("foo"),
// "accountBalance": v3.Decimal(123.76),
// "itemsMinMax": v3.ArrayMinMaxLike(27, 3, 5),
// "equality": v3.Equality("a thing"),
})

// Execute pact test
Expand All @@ -107,58 +103,48 @@ func TestConsumerV3(t *testing.T) {
// Set up our expected interactions.
mockProvider.
AddInteraction().
// TODO: map this to given_with_param interface!
Given(v3.ProviderStateV3{
Name: "User foo exists",
Parameters: map[string]interface{}{
"id": "foo",
},
}).
UponReceiving("A request to do a foo").
WithRequest(v3.Request{
Method: "POST",
Path: v3.Regex("/foobar", `\/foo.*`),
Headers: v3.MapMatcher{"Content-Type": s("application/json"), "Authorization": v3.Like("Bearer 1234")},
Body: v3.MapMatcher{
"id": v3.Like(27),
"name": v3.FromProviderState("${name}", "billy"),
"lastName": v3.Like("billy"),
"datetime": v3.DateTimeGenerated("2020-01-01T08:00:45", "yyyy-MM-dd'T'HH:mm:ss"),
},

// Alternative use MatchV3
// Body: v3.MatchV3(&User{}),
// Body: v3.MatchV2(&User{}),
Query: v3.QueryMatcher{
"baz": []v3.Matcher{
v3.Regex("bar", "[a-z]+"),
v3.Regex("bat", "[a-z]+"),
v3.Regex("baz", "[a-z]+"),
},
},
WithRequest("POST", v3.Regex("/foobar", `\/foo.*`)).
Headers(v3.MapMatcher{"Content-Type": s("application/json"), "Authorization": v3.Like("Bearer 1234")}).
JSON(v3.MapMatcher{
"id": v3.Like(27),
"name": v3.FromProviderState("${name}", "billy"),
"lastName": v3.Like("billy"),
"datetime": v3.DateTimeGenerated("2020-01-01T08:00:45", "yyyy-MM-dd'T'HH:mm:ss"),
}).
WillRespondWith(v3.Response{
Status: 200,
Headers: v3.MapMatcher{"Content-Type": s("application/json")},
// Body: v3.MatchV3(&User{}),
Body: v3.MapMatcher{
"dateTime": v3.Regex("2020-01-01", "[0-9\\-]+"),
"name": s("FirstName"),
"lastName": s("LastName"),
"superstring": v3.Includes("foo"),
"id": v3.Integer(12),
"accountBalance": v3.Decimal(123.76),
"itemsMinMax": v3.ArrayMinMaxLike(27, 3, 5),
"itemsMin": v3.ArrayMinLike("thereshouldbe3ofthese", 3),
"equality": v3.Equality("a thing"),
"arrayContaining": v3.ArrayContaining([]interface{}{
v3.Like("string"),
v3.Integer(1),
v3.MapMatcher{
"foo": v3.Like("bar"),
},
}),
Query(v3.QueryMatcher{
"baz": []v3.Matcher{
v3.Regex("bar", "[a-z]+"),
v3.Regex("bat", "[a-z]+"),
v3.Regex("baz", "[a-z]+"),
},
}).
WillRespondWith(200).
Headers(v3.MapMatcher{"Content-Type": s("application/json")}).
// Body: v3.MatchV3(&User{}),
JSON(v3.MapMatcher{
"dateTime": v3.Regex("2020-01-01", "[0-9\\-]+"),
"name": s("FirstName"),
"lastName": s("LastName"),
"superstring": v3.Includes("foo"),
"id": v3.Integer(12),
"accountBalance": v3.Decimal(123.76),
"itemsMinMax": v3.ArrayMinMaxLike(27, 3, 5),
"itemsMin": v3.ArrayMinLike("thereshouldbe3ofthese", 3),
"equality": v3.Equality("a thing"),
"arrayContaining": v3.ArrayContaining([]interface{}{
v3.Like("string"),
v3.Integer(1),
v3.MapMatcher{
"foo": v3.Like("bar"),
},
}),
})

// Execute pact test
Expand All @@ -168,37 +154,37 @@ func TestConsumerV3(t *testing.T) {
}

func TestMessagePact(t *testing.T) {
v3.SetLogLevel("TRACE")

provider, err := v3.NewMessagePactV3(v3.MessageConfig{
Consumer: "V3MessageConsumer",
Provider: "V3MessageProvider", // must be different to the HTTP one, can't mix both interaction styles
SpecificationVersion: v3.V3,
Consumer: "V3MessageConsumer",
Provider: "V3MessageProvider", // must be different to the HTTP one, can't mix both interaction styles
// SpecificationVersion: v3.V3,
})
assert.NoError(t, err)

if err != nil {
t.Fatal(err)
}

message := provider.AddMessage()
message.
err = provider.AddMessage().
Given(v3.ProviderStateV3{
Name: "User with id 127 exists",
Parameters: map[string]interface{}{
"id": 127,
},
}).
ExpectsToReceive("a user event").
WithMetadata(v3.MapMatcher{
"Content-Type": s("application/json; charset=utf-8"),
WithMetadata(map[string]string{
"Content-Type": "application/json",
}).
WithContent(v3.MapMatcher{
JSON(v3.MapMatcher{
"datetime": v3.Regex("2020-01-01", "[0-9\\-]+"),
"name": s("FirstName"),
"lastName": s("LastName"),
"id": v3.Integer(12),
}).
AsType(&User{})
AsType(&User{}).
ConsumedBy(userHandlerWrapper).
Verify(t)

provider.VerifyMessageConsumer(t, message, userHandlerWrapper)
assert.NoError(t, err)
}

type User struct {
Expand Down Expand Up @@ -244,7 +230,7 @@ var test = func(config v3.MockServerConfig) error {
}

// Message Pact - wrapped handler extracts the message
var userHandlerWrapper = func(m v3.Message) error {
var userHandlerWrapper = func(m v3.AsynchronousMessage) error {
return userHandler(*m.Content.(*User))
}

Expand Down
Loading

0 comments on commit 31fb98c

Please sign in to comment.