From 5dd4a008fd8fc5e3ae1bb09fd01fcf1496a574d6 Mon Sep 17 00:00:00 2001 From: Yann D'Isanto Date: Wed, 30 Oct 2024 14:43:59 +0100 Subject: [PATCH] feat: invocation request with url encoded form (#8) --- invocations.go | 31 ++++++++++++++ invocations_test.go | 98 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/invocations.go b/invocations.go index 6f0fe2b..5ceb3de 100644 --- a/invocations.go +++ b/invocations.go @@ -5,6 +5,7 @@ import ( "encoding/json" "io" "net/http" + "net/url" assertions "github.com/stretchr/testify/assert" ) @@ -15,6 +16,11 @@ type Invocation struct { testState TestingT } +type InvocationRequestForm struct { + invocation *Invocation + formValues url.Values +} + func newInvocation(request *http.Request, testState TestingT) *Invocation { var data []byte var err error @@ -71,3 +77,28 @@ func (call *Invocation) ReadJSONPayload(obj any) { call.testState.Fatal(err) } } + +func (call *Invocation) WithUrlEncodedFormPayload() *InvocationRequestForm { + formValues, err := url.ParseQuery(string(call.GetPayload())) + if err != nil { + call.testState.Fatal(err) + return nil + } + return &InvocationRequestForm{ + invocation: call.WithHeader("Content-Type", "application/x-www-form-urlencoded"), + formValues: formValues, + } +} + +func (form InvocationRequestForm) WithValues(expectedValues map[string]string) { + for key, value := range expectedValues { + assertions.Equal(form.invocation.testState, value, form.formValues.Get(key)) + } +} + +func (form InvocationRequestForm) WithValuesExactly(expectedValues map[string]string) { + assertions.Equal(form.invocation.testState, len(expectedValues), len(form.formValues)) + for key, value := range expectedValues { + assertions.Equal(form.invocation.testState, value, form.formValues.Get(key)) + } +} diff --git a/invocations_test.go b/invocations_test.go index 455c5e8..b319818 100644 --- a/invocations_test.go +++ b/invocations_test.go @@ -211,6 +211,104 @@ func TestInvocation_ReadJsonPayload_ErrorHandling(t *testing.T) { testState.assertFailedWithFatal() } +func TestInvocation_WithUrlEncodedForm_Fail(t *testing.T) { + t.Parallel() + request := buildRequestWithBody(t, []byte("key1=value1&key2=value+2%21")) + + testState := NewTestingMock(t) + invocation := newInvocation(request, testState) + + invocation.WithUrlEncodedFormPayload() + testState.assertFailedWithError() +} + +func TestInvocation_WithUrlEncodedForm_Values_Pass(t *testing.T) { + t.Parallel() + + testCases := []map[string]string{ + {"key1": "value1"}, + {"key1": "value1", "key2": "value 2!"}, + } + + for i := range testCases { + values := testCases[i] + t.Run("", func(t *testing.T) { + t.Parallel() + request := buildRequestWithBody(t, []byte("key1=value1&key2=value+2%21")) + request.Header.Add("Content-Type", "application/x-www-form-urlencoded") + testState := NewTestingMock(t) + invocation := newInvocation(request, testState) + + invocation.WithUrlEncodedFormPayload().WithValues(values) + + testState.assertDidNotFailed() + }) + } +} + +func TestInvocation_WithUrlEncodedForm_Values_Fail(t *testing.T) { + t.Parallel() + + testCases := []map[string]string{ + {"key1": "not value1"}, + {"not_key1": "value1"}, + } + + for i := range testCases { + values := testCases[i] + t.Run("", func(t *testing.T) { + t.Parallel() + request := buildRequestWithBody(t, []byte("key1=value1&key2=value+2%21")) + request.Header.Add("Content-Type", "application/x-www-form-urlencoded") + testState := NewTestingMock(t) + invocation := newInvocation(request, testState) + + invocation.WithUrlEncodedFormPayload().WithValues(values) + + testState.assertFailedWithError() + }) + } +} + +func TestInvocation_WithUrlEncodedForm_ValuesExactly_Pass(t *testing.T) { + t.Parallel() + request := buildRequestWithBody(t, []byte("key1=value1&key2=value+2%21")) + request.Header.Add("Content-Type", "application/x-www-form-urlencoded") + + testState := NewTestingMock(t) + invocation := newInvocation(request, testState) + invocation. + WithUrlEncodedFormPayload(). + WithValuesExactly(map[string]string{"key1": "value1", "key2": "value 2!"}) + + testState.assertDidNotFailed() +} + +func TestInvocation_WithUrlEncodedForm_ValuesExactly_Fail(t *testing.T) { + t.Parallel() + + testCases := []map[string]string{ + {"key1": "value1"}, + {"key1": "not value1"}, + {"not_key1": "value1"}, + } + + for i := range testCases { + values := testCases[i] + t.Run("", func(t *testing.T) { + t.Parallel() + request := buildRequestWithBody(t, []byte("key1=value1&key2=value+2%21")) + request.Header.Add("Content-Type", "application/x-www-form-urlencoded") + testState := NewTestingMock(t) + invocation := newInvocation(request, testState) + + invocation.WithUrlEncodedFormPayload().WithValuesExactly(values) + + testState.assertFailedWithError() + }) + } +} + func buildRequest(t *testing.T, method string, url string, data []byte) *http.Request { request, err := http.NewRequest(method, url, bytes.NewReader(data)) if err != nil {