flamingo.me/flamingo-commerce/v3@v3.11.0/test/integrationtest/projecttest/tests/graphql/cart_test.go (about) 1 //go:build integration 2 // +build integration 3 4 package graphql_test 5 6 import ( 7 "net/http" 8 "strings" 9 "testing" 10 11 "github.com/gavv/httpexpect/v2" 12 13 "flamingo.me/flamingo-commerce/v3/test/integrationtest" 14 "flamingo.me/flamingo-commerce/v3/test/integrationtest/projecttest/helper" 15 ) 16 17 func Test_CartUpdateDeliveryAddresses(t *testing.T) { 18 baseURL := "http://" + FlamingoURL 19 e := integrationtest.NewHTTPExpect(t, baseURL) 20 21 // check response of update delivery mutation 22 response := helper.GraphQlRequest(t, e, loadGraphQL(t, "update_delivery_addresses", nil)).Expect() 23 response.Status(http.StatusOK) 24 forms := getArray(response, "Commerce_Cart_UpdateDeliveryAddresses") 25 forms.Length().IsEqual(3) 26 27 address := forms.Value(0).Object() 28 address.Value("deliveryCode").String().IsEqual("foo") 29 address.Value("carrier").String().IsEqual("carrier") 30 address.Value("method").String().IsEqual("method") 31 address.Value("processed").Boolean().IsEqual(true) 32 address.Value("useBillingAddress").Boolean().IsEqual(false) 33 formData := address.Value("formData").Object() 34 formData.Value("firstname").String().IsEqual("Foo-firstname") 35 formData.Value("lastname").String().IsEqual("Foo-lastname") 36 formData.Value("email").String().IsEqual("foo@flamingo.me") 37 validation := address.Value("validationInfo").Object() 38 validation.Value("generalErrors").IsNull() 39 validation.Value("fieldErrors").IsNull() 40 41 address = forms.Value(1).Object() 42 address.Value("deliveryCode").IsEqual("bar") 43 address.Value("carrier").String().IsEqual("") 44 address.Value("method").String().IsEqual("") 45 address.Value("processed").Boolean().IsEqual(true) 46 address.Value("useBillingAddress").Boolean().IsEqual(true) 47 formData = address.Value("formData").Object() 48 formData.Value("firstname").String().IsEqual("") 49 formData.Value("lastname").String().IsEqual("") 50 formData.Value("email").String().IsEqual("") 51 validation = address.Value("validationInfo").Object() 52 validation.Value("generalErrors").IsNull() 53 validation.Value("fieldErrors").IsNull() 54 55 address = forms.Value(2).Object() 56 address.Value("deliveryCode").IsEqual("invalid-email-address") 57 address.Value("carrier").String().IsEqual("") 58 address.Value("method").String().IsEqual("") 59 address.Value("processed").Boolean().IsEqual(false) 60 address.Value("useBillingAddress").Boolean().IsEqual(false) 61 validation = address.Value("validationInfo").Object() 62 validation.Value("generalErrors").IsNull() 63 validation.Value("fieldErrors").NotNull() 64 65 // check that deliveries are saved to cart 66 response = helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_decorated_cart", nil)).Expect() 67 response.Status(http.StatusOK) 68 getValue(response, "Commerce_Cart_DecoratedCart", "cart").Object().Value("deliveries").Array().Length().IsEqual(2) 69 } 70 71 func Test_CommerceCartUpdateDeliveryShippingOptions(t *testing.T) { 72 baseURL := "http://" + FlamingoURL 73 e := integrationtest.NewHTTPExpect(t, baseURL) 74 75 // add some deliveries 76 response := helper.GraphQlRequest(t, e, loadGraphQL(t, "update_delivery_addresses", nil)).Expect() 77 response.Status(http.StatusOK) 78 forms := getArray(response, "Commerce_Cart_UpdateDeliveryAddresses") 79 forms.Length().IsEqual(3) 80 81 // update shipping options 82 response = helper.GraphQlRequest(t, e, loadGraphQL(t, "update_delivery_shipping_options", nil)).Expect() 83 response.Status(http.StatusOK) 84 getValue(response, "Commerce_Cart_UpdateDeliveryShippingOptions", "processed").Boolean().IsEqual(true) 85 86 // check cart 87 response = helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_decorated_cart", nil)).Expect() 88 response.Status(http.StatusOK) 89 deliveries := getValue(response, "Commerce_Cart_DecoratedCart", "cart").Object().Value("deliveries").Array() 90 deliveries.Length().IsEqual(2) 91 deliveries.Value(0).Object().Value("deliveryInfo").Object().Value("carrier").String().IsEqual("foo-carrier") 92 deliveries.Value(0).Object().Value("deliveryInfo").Object().Value("method").String().IsEqual("foo-method") 93 deliveries.Value(1).Object().Value("deliveryInfo").Object().Value("carrier").String().IsEqual("bar-carrier") 94 deliveries.Value(1).Object().Value("deliveryInfo").Object().Value("method").String().IsEqual("bar-method") 95 } 96 97 func Test_CommerceCartClean(t *testing.T) { 98 baseURL := "http://" + FlamingoURL 99 e := integrationtest.NewHTTPExpect(t, baseURL) 100 101 prepareCart(t, e) 102 103 response := helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_decorated_cart", nil)).Expect() 104 response.Status(http.StatusOK) 105 getValue(response, "Commerce_Cart_DecoratedCart", "cart").Object().Value("itemCount").IsEqual(1) 106 107 helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_clear", nil)).Expect().Status(http.StatusOK) 108 109 response = helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_decorated_cart", nil)).Expect().Status(http.StatusOK) 110 getValue(response, "Commerce_Cart_DecoratedCart", "cart").Object().Value("itemCount").IsEqual(0) 111 } 112 113 func Test_CommerceCartUpdateAdditionalData(t *testing.T) { 114 baseURL := "http://" + FlamingoURL 115 e := integrationtest.NewHTTPExpect(t, baseURL) 116 117 request := helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_update_additional_data", nil)) 118 response := request.Expect().Body() 119 120 expected := `{ 121 "data": { 122 "Commerce_Cart_UpdateAdditionalData": { 123 "cart": { 124 "additionalData": { 125 "customAttributes": { 126 "foo": { 127 "key": "foo", 128 "value": "bar" 129 }, 130 "biz": { 131 "key": "biz", 132 "value": "baz" 133 } 134 } 135 } 136 } 137 } 138 } 139 }` 140 141 expected = spaceMap(expected) 142 response.IsEqual(expected) 143 } 144 145 func Test_CommerceCartUpdateDeliveriesAdditionalData(t *testing.T) { 146 baseURL := "http://" + FlamingoURL 147 e := integrationtest.NewHTTPExpect(t, baseURL) 148 149 prepareCartWithDeliveries(t, e) 150 request := helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_update_deliveries_additional_data", nil)) 151 response := request.Expect().Body() 152 153 expected := `{ 154 "data": { 155 "Commerce_Cart_UpdateDeliveriesAdditionalData": { 156 "cart": { 157 "deliveries": [ 158 { 159 "deliveryInfo": { 160 "additionalData": { 161 "foo": { 162 "key": "foo", 163 "value": "bar" 164 }, 165 "biz": { 166 "key": "biz", 167 "value": "baz" 168 }, 169 "one": null, 170 "three": null 171 } 172 } 173 }, 174 { 175 "deliveryInfo": { 176 "additionalData": { 177 "foo": null, 178 "biz": null, 179 "one": { 180 "key": "one", 181 "value": "two" 182 }, 183 "three": { 184 "key": "three", 185 "value": "four" 186 } 187 } 188 } 189 } 190 ] 191 } 192 } 193 } 194 }` 195 196 expected = spaceMap(expected) 197 response.IsEqual(expected) 198 } 199 200 // prepareCartWithDeliveries adds a simple product with different delivery codes via graphQl 201 func prepareCartWithDeliveries(t *testing.T, e *httpexpect.Expect) { 202 t.Helper() 203 helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_add_to_cart", map[string]string{"MARKETPLACE_CODE": "fake_simple", "DELIVERY_CODE": "delivery1"})).Expect().Status(http.StatusOK) 204 helper.GraphQlRequest(t, e, loadGraphQL(t, "cart_add_to_cart", map[string]string{"MARKETPLACE_CODE": "fake_simple", "DELIVERY_CODE": "delivery2"})).Expect().Status(http.StatusOK) 205 } 206 207 func TestAddBundleProductToCart(t *testing.T) { 208 t.Parallel() 209 210 t.Run("add to cart bundle product", func(t *testing.T) { 211 t.Parallel() 212 e := httpexpect.Default(t, "http://"+FlamingoURL) 213 response := helper.GraphQlRequest(t, e, loadGraphQL(t, "commerce_cart_AddBundleToCart", map[string]string{ 214 "MARKETPLACE_CODE": "fake_bundle", 215 "DELIVERY_CODE": "delivery", 216 "IDENTIFIER1": "identifier1", 217 "MARKETPLACE_CODE1": "simple_option1", 218 "IDENTIFIER2": "identifier2", 219 "MARKETPLACE_CODE2": "configurable_option2", 220 "VARIANT_MARKETPLACE_CODE2": "shirt-red-s", 221 })) 222 223 body := response.Expect().Body() 224 225 expected := `{ 226 "data": { 227 "Commerce_Cart_AddToCart": { 228 "decoratedDeliveries": [ 229 { 230 "decoratedItems": [ 231 { 232 "product": { 233 "marketPlaceCode": "fake_bundle", 234 "choices": [ 235 { 236 "identifier": "identifier1", 237 "active": { 238 "marketPlaceCode": "simple_option1" 239 }, 240 "activeOption": { 241 "product": { 242 "marketPlaceCode": "simple_option1" 243 }, 244 "qty": 1 245 } 246 }, 247 { 248 "identifier": "identifier2", 249 "active": { 250 "marketPlaceCode": "configurable_option2", 251 "variantMarketPlaceCode": "shirt-red-s" 252 }, 253 "activeOption": { 254 "product": { 255 "marketPlaceCode": "configurable_option2", 256 "variantMarketPlaceCode": "shirt-red-s" 257 }, 258 "qty": 1 259 } 260 } 261 ] 262 } 263 } 264 ] 265 } 266 ] 267 } 268 } 269 }` 270 271 expected = spaceMap(expected) 272 body.IsEqual(expected) 273 }) 274 275 t.Run("add to cart bundle product, selected variant do not exists", func(t *testing.T) { 276 t.Parallel() 277 e := httpexpect.Default(t, "http://"+FlamingoURL) 278 response := helper.GraphQlRequest(t, e, loadGraphQL(t, "commerce_cart_AddBundleToCart", map[string]string{ 279 "MARKETPLACE_CODE": "fake_bundle", 280 "DELIVERY_CODE": "delivery", 281 "IDENTIFIER1": "identifier1", 282 "MARKETPLACE_CODE1": "simple_option1", 283 "IDENTIFIER2": "identifier2", 284 "MARKETPLACE_CODE2": "configurable_option2", 285 "VARIANT_MARKETPLACE_CODE2": "there is no option like this", 286 })) 287 288 data := response.Expect().Status(http.StatusOK).JSON().Object() 289 290 errorMessage := data.Value("errors").Array().Value(0).Object().Value("message").String().Raw() 291 292 if !strings.Contains(errorMessage, "No Variant with code there is no option like this found") { 293 t.Error("error do not contain: No Variant with code there is no option like this found ") 294 } 295 }) 296 297 t.Run("add to cart bundle product, required choice is not selected", func(t *testing.T) { 298 t.Parallel() 299 e := httpexpect.Default(t, "http://"+FlamingoURL) 300 response := helper.GraphQlRequest(t, e, loadGraphQL(t, "commerce_cart_AddBundleToCart", map[string]string{ 301 "MARKETPLACE_CODE": "fake_bundle", 302 "DELIVERY_CODE": "delivery", 303 "IDENTIFIER1": "identifier1", 304 "MARKETPLACE_CODE1": "simple_option1", 305 })) 306 307 data := response.Expect().Status(http.StatusOK).JSON().Object() 308 309 errorMessage := data.Value("errors").Array().Value(0).Object().Value("message").String().Raw() 310 311 if !strings.Contains(errorMessage, "required choices are not selected") { 312 t.Error("error do not contain: required choices are not selected") 313 } 314 }) 315 316 t.Run("add to cart bundle product, not existing marketplace code selected", func(t *testing.T) { 317 t.Parallel() 318 e := httpexpect.Default(t, "http://"+FlamingoURL) 319 response := helper.GraphQlRequest(t, e, loadGraphQL(t, "commerce_cart_AddBundleToCart", map[string]string{ 320 "MARKETPLACE_CODE": "fake_bundle", 321 "DELIVERY_CODE": "delivery", 322 "IDENTIFIER1": "identifier1", 323 "MARKETPLACE_CODE1": "simple_option1xxxxwrong", 324 "IDENTIFIER2": "identifier2", 325 "MARKETPLACE_CODE2": "configurable_option2", 326 "VARIANT_MARKETPLACE_CODE2": "shirt-red-s", 327 })) 328 329 data := response.Expect().Status(http.StatusOK).JSON().Object() 330 331 errorMessage := data.Value("errors").Array().Value(0).Object().Value("message").String().Raw() 332 333 if !strings.Contains(errorMessage, "selected marketplace code does not exist") { 334 t.Error("want: selected marketplace code does not exist, but have: ", errorMessage) 335 } 336 }) 337 } 338 339 func TestUpdateBundleProductQty(t *testing.T) { 340 t.Parallel() 341 342 t.Run("update should update quantity of bundle product", func(t *testing.T) { 343 t.Parallel() 344 345 e := httpexpect.Default(t, "http://"+FlamingoURL) 346 addResponse := helper.GraphQlRequest(t, e, loadGraphQL(t, "commerce_cart_AddBundleToCart_Update_Qty_Helper", map[string]string{ 347 "MARKETPLACE_CODE": "fake_bundle", 348 "DELIVERY_CODE": "delivery", 349 "IDENTIFIER1": "identifier1", 350 "MARKETPLACE_CODE1": "simple_option1", 351 "IDENTIFIER2": "identifier2", 352 "MARKETPLACE_CODE2": "configurable_option2", 353 "VARIANT_MARKETPLACE_CODE2": "shirt-red-s", 354 })) 355 356 itemID := addResponse.Expect().Status(http.StatusOK).JSON().Object().Value("data").Object(). 357 Value("Commerce_Cart_AddToCart").Object().Value("decoratedDeliveries").Array(). 358 Value(0).Object().Value("decoratedItems").Array().Value(0).Object(). 359 Value("item").Object().Value("id").String().Raw() 360 361 updateResponse := helper.GraphQlRequest(t, e, loadGraphQL(t, "update_item_quantity", map[string]string{ 362 "ITEM_ID": itemID, 363 "DELIVERY_CODE": "inflight", 364 "QTY": "4", 365 })) 366 367 updateResponse.Expect().Status(http.StatusOK).JSON().Object().Value("data").Object(). 368 Value("Commerce_Cart_UpdateItemQty").Object().Value("decoratedDeliveries").Array(). 369 Value(0).Object().Value("decoratedItems").Array().Value(0).Object(). 370 Value("item").Object().Value("qty").IsEqual(4) 371 }) 372 } 373 374 func TestUpdateBundleConfiguration(t *testing.T) { 375 t.Parallel() 376 377 t.Run("update should update the bundle config", func(t *testing.T) { 378 t.Parallel() 379 380 e := httpexpect.Default(t, "http://"+FlamingoURL) 381 addResponse := helper.GraphQlRequest(t, e, loadGraphQL(t, "commerce_cart_AddBundleToCart_Update_Qty_Helper", map[string]string{ 382 "MARKETPLACE_CODE": "fake_bundle", 383 "DELIVERY_CODE": "delivery", 384 "IDENTIFIER1": "identifier1", 385 "MARKETPLACE_CODE1": "simple_option1", 386 "IDENTIFIER2": "identifier2", 387 "MARKETPLACE_CODE2": "configurable_option2", 388 "VARIANT_MARKETPLACE_CODE2": "shirt-red-s", 389 })) 390 391 itemID := addResponse.Expect().Status(http.StatusOK).JSON().Object().Value("data").Object(). 392 Value("Commerce_Cart_AddToCart").Object().Value("decoratedDeliveries").Array(). 393 Value(0).Object().Value("decoratedItems").Array().Value(0).Object(). 394 Value("item").Object().Value("id").String().Raw() 395 396 updateResponse := helper.GraphQlRequest(t, e, loadGraphQL(t, "Commerce_Cart_UpdateItemBundleConfig", map[string]string{ 397 "ITEM_ID": itemID, 398 "IDENTIFIER1": "identifier1", 399 "MARKETPLACE_CODE1": "simple_option2", 400 "VARIANT_MARKETPLACE_CODE1": "", 401 "QTY1": "1", 402 "IDENTIFIER2": "identifier2", 403 "MARKETPLACE_CODE2": "configurable_option1", 404 "VARIANT_MARKETPLACE_CODE2": "shirt-red-m", 405 "QTY2": "1", 406 })) 407 408 body := updateResponse.Expect().Body() 409 410 expected := `{ 411 "data": { 412 "Commerce_Cart_UpdateItemBundleConfig": { 413 "decoratedDeliveries": [ 414 { 415 "decoratedItems": [ 416 { 417 "product": { 418 "marketPlaceCode": "fake_bundle", 419 "choices": [ 420 { 421 "identifier": "identifier1", 422 "active": { 423 "marketPlaceCode": "simple_option2" 424 }, 425 "activeOption": { 426 "product": { 427 "marketPlaceCode": "simple_option2" 428 }, 429 "qty": 1 430 } 431 }, 432 { 433 "identifier": "identifier2", 434 "active": { 435 "marketPlaceCode": "configurable_option1", 436 "variantMarketPlaceCode": "shirt-red-m" 437 }, 438 "activeOption": { 439 "product": { 440 "marketPlaceCode": "configurable_option1", 441 "variantMarketPlaceCode": "shirt-red-m" 442 }, 443 "qty": 1 444 } 445 } 446 ] 447 } 448 } 449 ] 450 } 451 ] 452 } 453 } 454 }` 455 456 expected = spaceMap(expected) 457 body.IsEqual(expected) 458 }) 459 460 t.Run("update should lead to an error if invalid bundle config (qty)", func(t *testing.T) { 461 t.Parallel() 462 463 e := httpexpect.Default(t, "http://"+FlamingoURL) 464 addResponse := helper.GraphQlRequest(t, e, loadGraphQL(t, "commerce_cart_AddBundleToCart_Update_Qty_Helper", map[string]string{ 465 "MARKETPLACE_CODE": "fake_bundle", 466 "DELIVERY_CODE": "delivery", 467 "IDENTIFIER1": "identifier1", 468 "MARKETPLACE_CODE1": "simple_option1", 469 "IDENTIFIER2": "identifier2", 470 "MARKETPLACE_CODE2": "configurable_option2", 471 "VARIANT_MARKETPLACE_CODE2": "shirt-red-s", 472 })) 473 474 itemID := addResponse.Expect().Status(http.StatusOK).JSON().Object().Value("data").Object(). 475 Value("Commerce_Cart_AddToCart").Object().Value("decoratedDeliveries").Array(). 476 Value(0).Object().Value("decoratedItems").Array().Value(0).Object(). 477 Value("item").Object().Value("id").String().Raw() 478 479 updateResponse := helper.GraphQlRequest(t, e, loadGraphQL(t, "Commerce_Cart_UpdateItemBundleConfig", map[string]string{ 480 "ITEM_ID": itemID, 481 "IDENTIFIER1": "identifier1", 482 "MARKETPLACE_CODE1": "simple_option2", 483 "VARIANT_MARKETPLACE_CODE1": "", 484 "QTY1": "1", 485 "IDENTIFIER2": "identifier2", 486 "MARKETPLACE_CODE2": "configurable_option1", 487 "VARIANT_MARKETPLACE_CODE2": "shirt-red-m", 488 "QTY2": "0", // invalid qty 489 })) 490 491 data := updateResponse.Expect().Status(http.StatusOK).JSON().Object() 492 493 errorMessage := data.Value("errors").Array().Value(0).Object().Value("message").String().Raw() 494 495 if !strings.Contains(errorMessage, "selected quantity is out of range") { 496 t.Error("want: selected quantity is out of range, but have: ", errorMessage) 497 } 498 }) 499 500 t.Run("update should lead to an error if invalid bundle config (not all required choices set)", func(t *testing.T) { 501 t.Parallel() 502 503 e := httpexpect.Default(t, "http://"+FlamingoURL) 504 addResponse := helper.GraphQlRequest(t, e, loadGraphQL(t, "commerce_cart_AddBundleToCart_Update_Qty_Helper", map[string]string{ 505 "MARKETPLACE_CODE": "fake_bundle", 506 "DELIVERY_CODE": "delivery", 507 "IDENTIFIER1": "identifier1", 508 "MARKETPLACE_CODE1": "simple_option1", 509 "IDENTIFIER2": "identifier2", 510 "MARKETPLACE_CODE2": "configurable_option2", 511 "VARIANT_MARKETPLACE_CODE2": "shirt-red-s", 512 })) 513 514 itemID := addResponse.Expect().Status(http.StatusOK).JSON().Object().Value("data").Object(). 515 Value("Commerce_Cart_AddToCart").Object().Value("decoratedDeliveries").Array(). 516 Value(0).Object().Value("decoratedItems").Array().Value(0).Object(). 517 Value("item").Object().Value("id").String().Raw() 518 519 updateResponse := helper.GraphQlRequest(t, e, loadGraphQL(t, "Commerce_Cart_UpdateItemBundleConfig_one", map[string]string{ 520 "ITEM_ID": itemID, 521 "IDENTIFIER1": "identifier1", 522 "MARKETPLACE_CODE1": "simple_option2", 523 "VARIANT_MARKETPLACE_CODE1": "", 524 "QTY1": "1", 525 })) 526 527 data := updateResponse.Expect().Status(http.StatusOK).JSON().Object() 528 529 errorMessage := data.Value("errors").Array().Value(0).Object().Value("message").String().Raw() 530 531 if !strings.Contains(errorMessage, "required choices are not selected") { 532 t.Error("want: required choices are not selected, but have: ", errorMessage) 533 } 534 }) 535 }