flamingo.me/flamingo-commerce/v3@v3.11.0/test/integrationtest/projecttest/tests/graphql/testutil_test.go (about) 1 //go:build integration 2 // +build integration 3 4 package graphql_test 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "net/http" 10 "os" 11 "path" 12 "strings" 13 "testing" 14 "unicode" 15 16 "github.com/gavv/httpexpect/v2" 17 "github.com/google/go-cmp/cmp" 18 "github.com/stretchr/testify/require" 19 20 "flamingo.me/flamingo-commerce/v3/test/integrationtest/projecttest/helper" 21 ) 22 23 func loadGraphQL(t *testing.T, name string, replacements map[string]string) string { 24 t.Helper() 25 content, err := os.ReadFile(path.Join("testdata", name+".graphql")) 26 if err != nil { 27 t.Fatal(err) 28 } 29 30 r := make([]string, 2*len(replacements)) 31 i := 0 32 for key, val := range replacements { 33 r[i] = fmt.Sprintf("###%s###", key) 34 r[i+1] = val 35 i = i + 2 36 } 37 replacer := strings.NewReplacer(r...) 38 39 return replacer.Replace(string(content)) 40 } 41 42 // loginTestCustomer performs a login of the configured fake user 43 func loginTestCustomer(t *testing.T, e *httpexpect.Expect) { 44 t.Helper() 45 // perform login 46 e.POST("/en/core/auth/callback/fake"). 47 WithForm(map[string]interface{}{"username": "username", "password": "password"}). 48 Expect() 49 50 // check if login succeeded 51 resp := e.GET("/en/core/auth/debug").Expect() 52 resp.Status(http.StatusOK) 53 body := resp.Body().Raw() 54 if !strings.Contains(body, "fake: fake/username:") || strings.Contains(body, "fake: identity not saved in session") { 55 t.Fatal("login failed") 56 } 57 } 58 59 // prepareCart adds a simple product via graphQl 60 func prepareCart(t *testing.T, e *httpexpect.Expect) { 61 t.Helper() 62 helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_add_to_cart", map[string]string{"MARKETPLACE_CODE": "fake_simple", "DELIVERY_CODE": "delivery"})).Expect().Status(http.StatusOK) 63 } 64 65 // prepareCartWithPaymentSelection adds a simple product via graphQl 66 func prepareCartWithPaymentSelection(t *testing.T, e *httpexpect.Expect, paymentMethod string, marketPlaceCode *string) { 67 t.Helper() 68 69 code := "fake_simple" 70 if marketPlaceCode != nil { 71 code = *marketPlaceCode 72 } 73 74 helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_add_to_cart", map[string]string{"MARKETPLACE_CODE": code, "DELIVERY_CODE": "delivery"})).Expect().Status(http.StatusOK) 75 helper.GraphQlRequest(t, e, loadGraphQL(t, "update_payment_selection", map[string]string{"PAYMENT_METHOD": paymentMethod})).Expect().Status(http.StatusOK) 76 } 77 78 func updatePaymentSelection(t *testing.T, e *httpexpect.Expect, paymentMethod string) { 79 t.Helper() 80 query := loadGraphQL(t, "update_payment_selection", map[string]string{"PAYMENT_METHOD": paymentMethod}) 81 82 response := helper.GraphQlRequest(t, e, query).Expect() 83 response.Status(http.StatusOK) 84 } 85 86 func performRefreshPlaceOrder(t *testing.T, e *httpexpect.Expect, blocking bool) *httpexpect.Response { 87 t.Helper() 88 fileName := "refresh" 89 if blocking { 90 fileName = "refresh_blocking" 91 } 92 mutation := loadGraphQL(t, fileName, nil) 93 request := helper.GraphQlRequest(t, e, mutation) 94 95 return request.Expect() 96 } 97 98 func checkRefreshForExpectedState(t *testing.T, e *httpexpect.Expect, expectedUUID string, expectedState map[string]interface{}) error { 99 t.Helper() 100 response := performRefreshPlaceOrder(t, e, false) 101 data := make(map[string]interface{}) 102 require.NoError(t, json.Unmarshal([]byte(response.Body().Raw()), &data)) 103 var theData interface{} 104 var ok bool 105 if theData, ok = data["data"]; !ok || theData == nil { 106 return fmt.Errorf("no data in response: %s", response.Body().Raw()) 107 } 108 data = theData.(map[string]interface{}) 109 110 if theData, ok = data["Commerce_Checkout_RefreshPlaceOrder"]; !ok { 111 return fmt.Errorf("no data>Commerce_Checkout_RefreshPlaceOrder in response: %s", response.Body().Raw()) 112 } 113 114 data = theData.(map[string]interface{}) 115 116 refreshUUID := data["uuid"] 117 if expectedUUID != refreshUUID { 118 return fmt.Errorf("uuid has changed: expected: %q, got from refresh: %q", expectedUUID, refreshUUID) 119 } 120 actualState := data["state"] 121 if diff := cmp.Diff(actualState, expectedState); diff != "" { 122 return fmt.Errorf("timeout reached, -actual state +expected state =%v", diff) 123 } 124 return nil 125 } 126 127 func assertRefreshPlaceOrder(t *testing.T, e *httpexpect.Expect, blocking bool) (*httpexpect.Response, string) { 128 t.Helper() 129 response := performRefreshPlaceOrder(t, e, blocking) 130 mutationName := "Commerce_Checkout_RefreshPlaceOrder" 131 if blocking { 132 mutationName = "Commerce_Checkout_RefreshPlaceOrderBlocking" 133 } 134 refreshUUID := getValue(response, mutationName, "uuid").String().Raw() 135 136 return response, refreshUUID 137 } 138 139 func assertStartPlaceOrderWithValidUUID(t *testing.T, e *httpexpect.Expect) (*httpexpect.Response, string) { 140 t.Helper() 141 mutation := loadGraphQL(t, "start", nil) 142 request := helper.GraphQlRequest(t, e, mutation) 143 response := request.Expect() 144 response.Status(http.StatusOK) 145 uuidMatches := getValue(response, "Commerce_Checkout_StartPlaceOrder", "uuid").String(). 146 Match("(?i)^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$") 147 uuidMatches.Length().IsEqual(1) 148 149 return response, uuidMatches.Index(0).Raw() 150 } 151 152 func getValue(response *httpexpect.Response, queryName, key string) *httpexpect.Value { 153 return response.JSON().Object().Value("data").Object().Value(queryName).Object().Value(key) 154 } 155 156 func getArray(response *httpexpect.Response, queryName string) *httpexpect.Array { 157 return response.JSON().Object().Value("data").Object().Value(queryName).Array() 158 } 159 160 func assertResponseForExpectedState(t *testing.T, response *httpexpect.Response, expectedState map[string]interface{}) { 161 t.Helper() 162 data := make(map[string]interface{}) 163 require.NoError(t, json.Unmarshal([]byte(response.Body().Raw()), &data)) 164 var theData interface{} 165 var ok bool 166 if theData, ok = data["data"]; !ok || theData == nil { 167 t.Fatalf("no data in response: %s", response.Body().Raw()) 168 return 169 } 170 data = theData.(map[string]interface{}) 171 172 if diff := cmp.Diff(data, expectedState); diff != "" { 173 t.Errorf("diff mismatch (-want +got):\\n%s", diff) 174 } 175 } 176 177 // spaceMap strips all whitespace from given string 178 func spaceMap(str string) string { 179 return strings.Map(func(r rune) rune { 180 if unicode.IsSpace(r) { 181 return -1 182 } 183 return r 184 }, str) 185 }