flamingo.me/flamingo-commerce/v3@v3.11.0/cart/infrastructure/defaultCartBehaviour_test.go (about)

     1  package infrastructure
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"testing"
     7  
     8  	"flamingo.me/flamingo/v3/framework/flamingo"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/mock"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	domaincart "flamingo.me/flamingo-commerce/v3/cart/domain/cart"
    14  	"flamingo.me/flamingo-commerce/v3/cart/infrastructure/mocks"
    15  	priceDomain "flamingo.me/flamingo-commerce/v3/price/domain"
    16  	"flamingo.me/flamingo-commerce/v3/product/domain"
    17  	"flamingo.me/flamingo-commerce/v3/product/infrastructure/fake"
    18  )
    19  
    20  func TestDefaultCartBehaviour_CleanCart(t *testing.T) {
    21  	t.Parallel()
    22  
    23  	t.Run("clean cart", func(t *testing.T) {
    24  		t.Parallel()
    25  
    26  		cob := &DefaultCartBehaviour{}
    27  		cob.Inject(
    28  			newInMemoryStorage(),
    29  			nil,
    30  			flamingo.NullLogger{},
    31  			nil,
    32  			nil,
    33  			nil,
    34  		)
    35  
    36  		cart := &domaincart.Cart{
    37  			ID: "17",
    38  			Deliveries: []domaincart.Delivery{
    39  				{
    40  					DeliveryInfo: domaincart.DeliveryInfo{
    41  						Code: "dev-1",
    42  					},
    43  					Cartitems: nil,
    44  				},
    45  			},
    46  		}
    47  
    48  		err := cob.cartStorage.StoreCart(context.Background(), cart)
    49  		assert.NoError(t, err)
    50  
    51  		got, _, err := cob.CleanCart(context.Background(), cart)
    52  		assert.NoError(t, err)
    53  		assert.Empty(t, got.Deliveries)
    54  	})
    55  }
    56  
    57  func TestDefaultCartBehaviour_CleanDelivery(t *testing.T) {
    58  	t.Parallel()
    59  
    60  	t.Run("clean dev-1", func(t *testing.T) {
    61  		t.Parallel()
    62  
    63  		cob := &DefaultCartBehaviour{}
    64  		cob.Inject(
    65  			newInMemoryStorage(),
    66  			nil,
    67  			flamingo.NullLogger{},
    68  			nil,
    69  			nil,
    70  			nil,
    71  		)
    72  
    73  		cart := &domaincart.Cart{
    74  			ID: "17",
    75  			Deliveries: []domaincart.Delivery{
    76  				{
    77  					DeliveryInfo: domaincart.DeliveryInfo{
    78  						Code: "dev-1",
    79  					},
    80  					Cartitems: nil,
    81  				},
    82  				{
    83  					DeliveryInfo: domaincart.DeliveryInfo{
    84  						Code: "dev-2",
    85  					},
    86  					Cartitems: nil,
    87  				},
    88  			},
    89  		}
    90  
    91  		err := cob.cartStorage.StoreCart(context.Background(), cart)
    92  		assert.NoError(t, err)
    93  
    94  		got, _, err := cob.CleanDelivery(context.Background(), cart, "dev-1")
    95  		assert.NoError(t, err)
    96  		assert.Equal(t, 1, len(got.Deliveries))
    97  		assert.Equal(t, "dev-2", got.Deliveries[0].DeliveryInfo.Code)
    98  	})
    99  
   100  	t.Run("delivery not found", func(t *testing.T) {
   101  		t.Parallel()
   102  
   103  		cob := &DefaultCartBehaviour{}
   104  		cob.Inject(
   105  			newInMemoryStorage(),
   106  			nil,
   107  			flamingo.NullLogger{},
   108  			nil,
   109  			nil,
   110  			nil,
   111  		)
   112  
   113  		cart := &domaincart.Cart{
   114  			ID: "17",
   115  			Deliveries: []domaincart.Delivery{
   116  				{
   117  					DeliveryInfo: domaincart.DeliveryInfo{
   118  						Code: "dev-1",
   119  					},
   120  					Cartitems: nil,
   121  				},
   122  				{
   123  					DeliveryInfo: domaincart.DeliveryInfo{
   124  						Code: "dev-2",
   125  					},
   126  					Cartitems: nil,
   127  				},
   128  			},
   129  		}
   130  
   131  		err := cob.cartStorage.StoreCart(context.Background(), cart)
   132  		assert.NoError(t, err)
   133  
   134  		got, _, err := cob.CleanDelivery(context.Background(), cart, "dev-3")
   135  		assert.EqualError(t, err, "DefaultCartBehaviour: delivery dev-3 not found")
   136  		assert.Nil(t, got)
   137  	})
   138  }
   139  
   140  var errInvalidVoucher = errors.New("invalid voucher")
   141  var errInvalidGiftCard = errors.New("invalid gift card")
   142  
   143  func TestDefaultCartBehaviour_ApplyVoucher(t *testing.T) {
   144  	t.Parallel()
   145  
   146  	t.Run("apply voucher successful", func(t *testing.T) {
   147  		t.Parallel()
   148  
   149  		voucherHandler := mocks.NewVoucherHandler(t)
   150  		voucherHandler.EXPECT().ApplyVoucher(mock.Anything, mock.Anything, "voucher").
   151  			Return(&domaincart.Cart{ID: "voucher"}, nil)
   152  
   153  		cob := &DefaultCartBehaviour{}
   154  		cob.Inject(
   155  			newInMemoryStorage(),
   156  			nil,
   157  			flamingo.NullLogger{},
   158  			voucherHandler,
   159  			nil,
   160  			nil,
   161  		)
   162  
   163  		got, _, err := cob.ApplyVoucher(context.Background(), &domaincart.Cart{ID: "test"}, "voucher")
   164  		assert.NoError(t, err)
   165  		assert.Equal(t, "voucher", got.ID)
   166  		voucherHandler.AssertCalled(t, "ApplyVoucher", mock.Anything, mock.Anything, "voucher")
   167  	})
   168  
   169  	t.Run("apply voucher error", func(t *testing.T) {
   170  		t.Parallel()
   171  
   172  		voucherHandler := mocks.NewVoucherHandler(t)
   173  		voucherHandler.EXPECT().ApplyVoucher(mock.Anything, mock.Anything, "voucher").
   174  			Return(nil, errInvalidVoucher)
   175  
   176  		cob := &DefaultCartBehaviour{}
   177  		cob.Inject(
   178  			newInMemoryStorage(),
   179  			nil,
   180  			flamingo.NullLogger{},
   181  			voucherHandler,
   182  			nil,
   183  			nil,
   184  		)
   185  
   186  		got, _, err := cob.ApplyVoucher(context.Background(), &domaincart.Cart{ID: "test"}, "voucher")
   187  		assert.EqualError(t, err, "invalid voucher")
   188  		assert.Nil(t, got)
   189  		voucherHandler.AssertCalled(t, "ApplyVoucher", mock.Anything, mock.Anything, "voucher")
   190  	})
   191  }
   192  
   193  func TestDefaultCartBehaviour_RemoveVoucher(t *testing.T) {
   194  	t.Parallel()
   195  
   196  	t.Run("remove voucher successful", func(t *testing.T) {
   197  		t.Parallel()
   198  
   199  		voucherHandler := mocks.NewVoucherHandler(t)
   200  		voucherHandler.EXPECT().RemoveVoucher(mock.Anything, mock.Anything, "voucher").
   201  			Return(&domaincart.Cart{ID: "voucher"}, nil)
   202  
   203  		cob := &DefaultCartBehaviour{}
   204  		cob.Inject(
   205  			newInMemoryStorage(),
   206  			nil,
   207  			flamingo.NullLogger{},
   208  			voucherHandler,
   209  			nil,
   210  			nil,
   211  		)
   212  
   213  		got, _, err := cob.RemoveVoucher(context.Background(), &domaincart.Cart{ID: "test"}, "voucher")
   214  		assert.NoError(t, err)
   215  		assert.Equal(t, "voucher", got.ID)
   216  		voucherHandler.AssertCalled(t, "RemoveVoucher", mock.Anything, mock.Anything, "voucher")
   217  	})
   218  
   219  	t.Run("remove voucher error", func(t *testing.T) {
   220  		t.Parallel()
   221  
   222  		voucherHandler := mocks.NewVoucherHandler(t)
   223  		voucherHandler.EXPECT().RemoveVoucher(mock.Anything, mock.Anything, "voucher").
   224  			Return(nil, errInvalidVoucher)
   225  
   226  		cob := &DefaultCartBehaviour{}
   227  		cob.Inject(
   228  			newInMemoryStorage(),
   229  			nil,
   230  			flamingo.NullLogger{},
   231  			voucherHandler,
   232  			nil,
   233  			nil,
   234  		)
   235  
   236  		got, _, err := cob.RemoveVoucher(context.Background(), &domaincart.Cart{ID: "test"}, "voucher")
   237  		assert.EqualError(t, err, "invalid voucher")
   238  		assert.Nil(t, got)
   239  		voucherHandler.AssertCalled(t, "RemoveVoucher", mock.Anything, mock.Anything, "voucher")
   240  	})
   241  }
   242  
   243  func TestDefaultCartBehaviour_ApplyGiftCard(t *testing.T) {
   244  	t.Parallel()
   245  
   246  	t.Run("apply gift card successful", func(t *testing.T) {
   247  		t.Parallel()
   248  
   249  		giftCardHandler := mocks.NewGiftCardHandler(t)
   250  		giftCardHandler.EXPECT().ApplyGiftCard(mock.Anything, mock.Anything, "giftCard").
   251  			Return(&domaincart.Cart{ID: "giftCard"}, nil)
   252  
   253  		cob := &DefaultCartBehaviour{}
   254  		cob.Inject(
   255  			newInMemoryStorage(),
   256  			nil,
   257  			flamingo.NullLogger{},
   258  			nil,
   259  			giftCardHandler,
   260  			nil,
   261  		)
   262  
   263  		got, _, err := cob.ApplyGiftCard(context.Background(), &domaincart.Cart{ID: "test"}, "giftCard")
   264  		assert.NoError(t, err)
   265  		assert.Equal(t, "giftCard", got.ID)
   266  		giftCardHandler.AssertCalled(t, "ApplyGiftCard", mock.Anything, mock.Anything, "giftCard")
   267  	})
   268  
   269  	t.Run("apply gift card error", func(t *testing.T) {
   270  		t.Parallel()
   271  
   272  		giftCardHandler := mocks.NewGiftCardHandler(t)
   273  		giftCardHandler.EXPECT().ApplyGiftCard(mock.Anything, mock.Anything, "giftCard").
   274  			Return(nil, errInvalidGiftCard)
   275  
   276  		cob := &DefaultCartBehaviour{}
   277  		cob.Inject(
   278  			newInMemoryStorage(),
   279  			nil,
   280  			flamingo.NullLogger{},
   281  			nil,
   282  			giftCardHandler,
   283  			nil,
   284  		)
   285  
   286  		got, _, err := cob.ApplyGiftCard(context.Background(), &domaincart.Cart{ID: "test"}, "giftCard")
   287  		assert.EqualError(t, err, "invalid gift card")
   288  		assert.Nil(t, got)
   289  		giftCardHandler.AssertCalled(t, "ApplyGiftCard", mock.Anything, mock.Anything, "giftCard")
   290  	})
   291  }
   292  
   293  func TestDefaultCartBehaviour_RemoveGiftCard(t *testing.T) {
   294  	t.Parallel()
   295  
   296  	t.Run("remove gift card successful", func(t *testing.T) {
   297  		t.Parallel()
   298  
   299  		giftCardHandler := mocks.NewGiftCardHandler(t)
   300  		giftCardHandler.EXPECT().RemoveGiftCard(mock.Anything, mock.Anything, "giftCard").
   301  			Return(&domaincart.Cart{ID: "giftCard"}, nil)
   302  
   303  		cob := &DefaultCartBehaviour{}
   304  		cob.Inject(
   305  			newInMemoryStorage(),
   306  			nil,
   307  			flamingo.NullLogger{},
   308  			nil,
   309  			giftCardHandler,
   310  			nil,
   311  		)
   312  
   313  		got, _, err := cob.RemoveGiftCard(context.Background(), &domaincart.Cart{ID: "test"}, "giftCard")
   314  		assert.NoError(t, err)
   315  		assert.Equal(t, "giftCard", got.ID)
   316  		giftCardHandler.AssertCalled(t, "RemoveGiftCard", mock.Anything, mock.Anything, "giftCard")
   317  	})
   318  
   319  	t.Run("remove gift card error", func(t *testing.T) {
   320  		t.Parallel()
   321  
   322  		giftCardHandler := mocks.NewGiftCardHandler(t)
   323  		giftCardHandler.EXPECT().RemoveGiftCard(mock.Anything, mock.Anything, "giftCard").
   324  			Return(nil, errInvalidGiftCard)
   325  
   326  		cob := &DefaultCartBehaviour{}
   327  		cob.Inject(
   328  			newInMemoryStorage(),
   329  			nil,
   330  			flamingo.NullLogger{},
   331  			nil,
   332  			giftCardHandler,
   333  			nil,
   334  		)
   335  
   336  		got, _, err := cob.RemoveGiftCard(context.Background(), &domaincart.Cart{ID: "test"}, "giftCard")
   337  		assert.EqualError(t, err, "invalid gift card")
   338  		assert.Nil(t, got)
   339  		giftCardHandler.AssertCalled(t, "RemoveGiftCard", mock.Anything, mock.Anything, "giftCard")
   340  	})
   341  }
   342  
   343  func TestDefaultCartBehaviour_Complete(t *testing.T) {
   344  	t.Parallel()
   345  
   346  	t.Run("happy path", func(t *testing.T) {
   347  		t.Parallel()
   348  
   349  		cob := &DefaultCartBehaviour{}
   350  		cob.Inject(
   351  			newInMemoryStorage(),
   352  			nil,
   353  			flamingo.NullLogger{},
   354  			nil,
   355  			nil,
   356  			nil,
   357  		)
   358  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{ID: "test-id"})
   359  		assert.NoError(t, err)
   360  
   361  		got, _, err := cob.Complete(context.Background(), cart)
   362  		assert.NoError(t, err)
   363  		assert.Equal(t, cart, got)
   364  
   365  		_, err = cob.GetCart(context.Background(), "test-id")
   366  		assert.Error(t, err, "Cart should not be stored any more")
   367  	})
   368  }
   369  
   370  func TestDefaultCartBehaviour_Restore(t *testing.T) {
   371  	t.Parallel()
   372  
   373  	t.Run("happy path", func(t *testing.T) {
   374  		t.Parallel()
   375  
   376  		cob := &DefaultCartBehaviour{}
   377  		cob.Inject(
   378  			newInMemoryStorage(),
   379  			nil,
   380  			flamingo.NullLogger{},
   381  			nil,
   382  			nil,
   383  			nil,
   384  		)
   385  		cart := &domaincart.Cart{ID: "1234"}
   386  
   387  		got, _, err := cob.Restore(context.Background(), cart)
   388  		assert.NoError(t, err)
   389  
   390  		_, err = cob.GetCart(context.Background(), got.ID)
   391  		assert.Nil(t, err)
   392  	})
   393  }
   394  
   395  func TestDefaultCartBehaviour_DeleteItem(t *testing.T) {
   396  	t.Parallel()
   397  
   398  	t.Run("cart does not exist", func(t *testing.T) {
   399  		t.Parallel()
   400  
   401  		cob := &DefaultCartBehaviour{}
   402  		cob.Inject(
   403  			newInMemoryStorage(),
   404  			&fake.ProductService{},
   405  			flamingo.NullLogger{},
   406  			nil,
   407  			nil,
   408  			nil,
   409  		)
   410  
   411  		cart := &domaincart.Cart{
   412  			ID: "1234",
   413  			Deliveries: []domaincart.Delivery{
   414  				{
   415  					DeliveryInfo: domaincart.DeliveryInfo{
   416  						Code: "delivery",
   417  					},
   418  					Cartitems: []domaincart.Item{
   419  						{
   420  							ID: "abc",
   421  						},
   422  					},
   423  				},
   424  			},
   425  		}
   426  
   427  		_, _, err := cob.DeleteItem(context.Background(), cart, "abc", "delivery")
   428  		assert.Error(t, err)
   429  	})
   430  
   431  	t.Run("item in first place in delivery deleted", func(t *testing.T) {
   432  		t.Parallel()
   433  
   434  		cob := &DefaultCartBehaviour{}
   435  		cob.Inject(
   436  			newInMemoryStorage(),
   437  			&fake.ProductService{},
   438  			flamingo.NullLogger{},
   439  			nil,
   440  			nil,
   441  			nil,
   442  		)
   443  
   444  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   445  			ID: "1234",
   446  			Deliveries: []domaincart.Delivery{
   447  				{
   448  					DeliveryInfo: domaincart.DeliveryInfo{
   449  						Code: "delivery",
   450  					},
   451  					Cartitems: []domaincart.Item{
   452  						{
   453  							ID: "id-1",
   454  						},
   455  						{
   456  							ID: "id-2",
   457  						},
   458  						{
   459  							ID: "id-3",
   460  						},
   461  					},
   462  				},
   463  			},
   464  		})
   465  		assert.NoError(t, err)
   466  
   467  		got, _, err := cob.DeleteItem(context.Background(), cart, "id-1", "delivery")
   468  		assert.NoError(t, err)
   469  		assert.Equal(t, 2, len(got.Deliveries[0].Cartitems))
   470  		assert.Equal(t, "id-2", got.Deliveries[0].Cartitems[0].ID)
   471  		assert.Equal(t, "id-3", got.Deliveries[0].Cartitems[1].ID)
   472  	})
   473  
   474  	t.Run("item in middle of delivery deleted", func(t *testing.T) {
   475  		t.Parallel()
   476  
   477  		cob := &DefaultCartBehaviour{}
   478  		cob.Inject(
   479  			newInMemoryStorage(),
   480  			&fake.ProductService{},
   481  			flamingo.NullLogger{},
   482  			nil,
   483  			nil,
   484  			nil,
   485  		)
   486  
   487  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   488  			ID: "1234",
   489  			Deliveries: []domaincart.Delivery{
   490  				{
   491  					DeliveryInfo: domaincart.DeliveryInfo{
   492  						Code: "delivery",
   493  					},
   494  					Cartitems: []domaincart.Item{
   495  						{
   496  							ID: "id-1",
   497  						},
   498  						{
   499  							ID: "id-2",
   500  						},
   501  						{
   502  							ID: "id-3",
   503  						},
   504  					},
   505  				},
   506  			},
   507  		})
   508  		assert.NoError(t, err)
   509  
   510  		got, _, err := cob.DeleteItem(context.Background(), cart, "id-2", "delivery")
   511  		assert.NoError(t, err)
   512  		assert.Equal(t, 2, len(got.Deliveries[0].Cartitems))
   513  		assert.Equal(t, "id-1", got.Deliveries[0].Cartitems[0].ID)
   514  		assert.Equal(t, "id-3", got.Deliveries[0].Cartitems[1].ID)
   515  	})
   516  
   517  	t.Run("item in last place in delivery deleted", func(t *testing.T) {
   518  		t.Parallel()
   519  
   520  		cob := &DefaultCartBehaviour{}
   521  		cob.Inject(
   522  			newInMemoryStorage(),
   523  			&fake.ProductService{},
   524  			flamingo.NullLogger{},
   525  			nil,
   526  			nil,
   527  			nil,
   528  		)
   529  
   530  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   531  			ID: "1234",
   532  			Deliveries: []domaincart.Delivery{
   533  				{
   534  					DeliveryInfo: domaincart.DeliveryInfo{
   535  						Code: "delivery",
   536  					},
   537  					Cartitems: []domaincart.Item{
   538  						{
   539  							ID: "id-1",
   540  						},
   541  						{
   542  							ID: "id-2",
   543  						},
   544  						{
   545  							ID: "id-3",
   546  						},
   547  					},
   548  				},
   549  			},
   550  		})
   551  		assert.NoError(t, err)
   552  
   553  		got, _, err := cob.DeleteItem(context.Background(), cart, "id-3", "delivery")
   554  		assert.NoError(t, err)
   555  		assert.Equal(t, 2, len(got.Deliveries[0].Cartitems))
   556  		assert.Equal(t, "id-1", got.Deliveries[0].Cartitems[0].ID)
   557  		assert.Equal(t, "id-2", got.Deliveries[0].Cartitems[1].ID)
   558  	})
   559  
   560  	t.Run("item in different delivery not deleted", func(t *testing.T) {
   561  		t.Parallel()
   562  
   563  		cob := &DefaultCartBehaviour{}
   564  		cob.Inject(
   565  			newInMemoryStorage(),
   566  			&fake.ProductService{},
   567  			flamingo.NullLogger{},
   568  			nil,
   569  			nil,
   570  			nil,
   571  		)
   572  
   573  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   574  			ID: "1234",
   575  			Deliveries: []domaincart.Delivery{
   576  				{
   577  					DeliveryInfo: domaincart.DeliveryInfo{
   578  						Code: "delivery",
   579  					},
   580  					Cartitems: []domaincart.Item{
   581  						{
   582  							ID: "abc",
   583  						},
   584  					},
   585  				},
   586  			},
   587  		})
   588  		assert.NoError(t, err)
   589  
   590  		got, _, err := cob.DeleteItem(context.Background(), cart, "abc", "delivery-2")
   591  		assert.NoError(t, err)
   592  		assert.Equal(t, 1, len(got.Deliveries[0].Cartitems))
   593  		assert.Equal(t, "abc", got.Deliveries[0].Cartitems[0].ID)
   594  	})
   595  }
   596  
   597  func TestDefaultCartBehaviour_UpdateItems(t *testing.T) {
   598  	t.Parallel()
   599  
   600  	t.Run("cart does not exist", func(t *testing.T) {
   601  		t.Parallel()
   602  
   603  		cob := &DefaultCartBehaviour{}
   604  		cob.Inject(
   605  			newInMemoryStorage(),
   606  			&fake.ProductService{},
   607  			flamingo.NullLogger{},
   608  			nil,
   609  			nil,
   610  			nil,
   611  		)
   612  
   613  		cart := &domaincart.Cart{
   614  			ID: "1234",
   615  			Deliveries: []domaincart.Delivery{
   616  				{
   617  					DeliveryInfo: domaincart.DeliveryInfo{
   618  						Code: "delivery",
   619  					},
   620  					Cartitems: []domaincart.Item{
   621  						{
   622  							ID: "abc",
   623  						},
   624  					},
   625  				},
   626  			},
   627  		}
   628  
   629  		_, _, err := cob.UpdateItems(context.Background(), cart, []domaincart.ItemUpdateCommand{})
   630  		assert.Error(t, err)
   631  	})
   632  
   633  	t.Run("item not found in delivery", func(t *testing.T) {
   634  		t.Parallel()
   635  
   636  		cob := &DefaultCartBehaviour{}
   637  		cob.Inject(
   638  			newInMemoryStorage(),
   639  			&fake.ProductService{},
   640  			flamingo.NullLogger{},
   641  			nil,
   642  			nil,
   643  			nil,
   644  		)
   645  
   646  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   647  			ID: "1234",
   648  		})
   649  		assert.NoError(t, err)
   650  
   651  		got, _, err := cob.UpdateItems(context.Background(), cart, []domaincart.ItemUpdateCommand{
   652  			{
   653  				ItemID: "abc",
   654  			},
   655  		})
   656  		assert.Empty(t, got)
   657  		assert.EqualError(t, err, "DefaultCartBehaviour: error finding delivery of item: delivery not found for \"abc\"")
   658  	})
   659  
   660  	t.Run("item updated in delivery", func(t *testing.T) {
   661  		t.Parallel()
   662  
   663  		cob := &DefaultCartBehaviour{}
   664  		cob.Inject(
   665  			newInMemoryStorage(),
   666  			&fake.ProductService{},
   667  			flamingo.NullLogger{},
   668  			nil,
   669  			nil,
   670  			nil,
   671  		)
   672  
   673  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   674  			ID: "1234",
   675  			Deliveries: []domaincart.Delivery{
   676  				{
   677  					Cartitems: []domaincart.Item{
   678  						{
   679  							ID:              "abc",
   680  							Qty:             1,
   681  							MarketplaceCode: "fake_fixed_simple_without_discounts",
   682  							AdditionalData: map[string]string{
   683  								"1": "a",
   684  							},
   685  							SinglePriceGross:          priceDomain.NewFromFloat(20.99, "EUR"),
   686  							RowPriceGross:             priceDomain.NewFromFloat(20.99, "EUR"),
   687  							RowPriceGrossWithDiscount: priceDomain.NewFromFloat(20.98, "EUR"),
   688  							TotalDiscountAmount:       priceDomain.NewFromFloat(0.01, "EUR"),
   689  							ItemRelatedDiscountAmount: priceDomain.NewFromFloat(0.01, "EUR"),
   690  						},
   691  					},
   692  				},
   693  			},
   694  		})
   695  		assert.NoError(t, err)
   696  
   697  		qty := 2
   698  		got, _, err := cob.UpdateItems(context.Background(), cart, []domaincart.ItemUpdateCommand{
   699  			{
   700  				ItemID: "abc",
   701  				Qty:    &qty,
   702  				AdditionalData: map[string]string{
   703  					"2": "b",
   704  				},
   705  			},
   706  		})
   707  		assert.NoError(t, err)
   708  		assert.Equal(t, map[string]string{"2": "b"}, got.Deliveries[0].Cartitems[0].AdditionalData)
   709  		assert.Equal(t, 2, got.Deliveries[0].Cartitems[0].Qty)
   710  		assert.Equal(t, 20.99, got.Deliveries[0].Cartitems[0].SinglePriceGross.FloatAmount())
   711  		assert.Equal(t, 41.98, got.Deliveries[0].Cartitems[0].RowPriceGross.FloatAmount())
   712  		assert.Equal(t, 41.97, got.Deliveries[0].Cartitems[0].RowPriceGrossWithDiscount.FloatAmount())
   713  		assert.Equal(t, 0.01, got.Deliveries[0].Cartitems[0].TotalDiscountAmount.FloatAmount())
   714  		assert.Equal(t, 0.01, got.Deliveries[0].Cartitems[0].ItemRelatedDiscountAmount.FloatAmount())
   715  		assert.Equal(t, 41.97, got.GrandTotal.FloatAmount())
   716  	})
   717  
   718  	t.Run("item updated with qty 0 is deleted", func(t *testing.T) {
   719  		t.Parallel()
   720  
   721  		cob := &DefaultCartBehaviour{}
   722  		cob.Inject(
   723  			newInMemoryStorage(),
   724  			&fake.ProductService{},
   725  			flamingo.NullLogger{},
   726  			nil,
   727  			nil,
   728  			nil,
   729  		)
   730  
   731  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   732  			ID: "1234",
   733  			Deliveries: []domaincart.Delivery{
   734  				{
   735  					Cartitems: []domaincart.Item{
   736  						{
   737  							ID:              "abc",
   738  							Qty:             1,
   739  							MarketplaceCode: "fake_fixed_simple_without_discounts",
   740  						},
   741  					},
   742  				},
   743  			},
   744  		})
   745  		assert.NoError(t, err)
   746  
   747  		qty := 0
   748  		got, _, err := cob.UpdateItems(context.Background(), cart, []domaincart.ItemUpdateCommand{
   749  			{
   750  				ItemID: "abc",
   751  				Qty:    &qty,
   752  			},
   753  		})
   754  		assert.NoError(t, err)
   755  		assert.Equal(t, 0, len(got.Deliveries[0].Cartitems))
   756  		assert.Equal(t, 0.0, got.GrandTotal.FloatAmount())
   757  	})
   758  
   759  	t.Run("update without qty still updates other fields", func(t *testing.T) {
   760  		t.Parallel()
   761  
   762  		cob := &DefaultCartBehaviour{}
   763  		cob.Inject(
   764  			newInMemoryStorage(),
   765  			&fake.ProductService{},
   766  			flamingo.NullLogger{},
   767  			nil,
   768  			nil,
   769  			nil,
   770  		)
   771  
   772  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   773  			ID: "cartID",
   774  			Deliveries: []domaincart.Delivery{
   775  				{
   776  					Cartitems: []domaincart.Item{
   777  						{
   778  							ID:              "firstItem",
   779  							Qty:             1,
   780  							MarketplaceCode: "fake_fixed_simple_without_discounts",
   781  						},
   782  						{
   783  							ID:              "secondItem",
   784  							MarketplaceCode: "fake_bundle",
   785  							Qty:             1,
   786  							BundleConfig: map[domain.Identifier]domain.ChoiceConfiguration{
   787  								"identifier1": {
   788  									MarketplaceCode: "simple_option1",
   789  									Qty:             1,
   790  								},
   791  								"identifier2": {
   792  									MarketplaceCode:        "configurable_option2",
   793  									VariantMarketplaceCode: "shirt-black-s",
   794  									Qty:                    1,
   795  								},
   796  							},
   797  						},
   798  					},
   799  				},
   800  			},
   801  		})
   802  		assert.NoError(t, err)
   803  
   804  		source := "baz"
   805  		got, _, err := cob.UpdateItems(context.Background(), cart, []domaincart.ItemUpdateCommand{
   806  			{
   807  				ItemID:         "firstItem",
   808  				AdditionalData: map[string]string{"foo": "bar"},
   809  				SourceID:       &source,
   810  			},
   811  			{
   812  				ItemID: "secondItem",
   813  				BundleConfiguration: map[domain.Identifier]domain.ChoiceConfiguration{
   814  					"identifier1": {
   815  						MarketplaceCode: "simple_option2",
   816  						Qty:             1,
   817  					},
   818  					"identifier2": {
   819  						MarketplaceCode:        "configurable_option1",
   820  						VariantMarketplaceCode: "shirt-black-l",
   821  						Qty:                    1,
   822  					},
   823  				},
   824  			},
   825  		})
   826  
   827  		assert.NoError(t, err)
   828  
   829  		assert.Equal(t, "firstItem", got.Deliveries[0].Cartitems[0].ID)
   830  		assert.Equal(t, "fake_fixed_simple_without_discounts", got.Deliveries[0].Cartitems[0].MarketplaceCode)
   831  		assert.Equal(t, map[string]string{"foo": "bar"}, got.Deliveries[0].Cartitems[0].AdditionalData)
   832  		assert.Equal(t, "baz", got.Deliveries[0].Cartitems[0].SourceID)
   833  
   834  		assert.Equal(t, "secondItem", got.Deliveries[0].Cartitems[1].ID)
   835  		assert.Equal(t, "fake_bundle", got.Deliveries[0].Cartitems[1].MarketplaceCode)
   836  		assert.Equal(t, "simple_option2", got.Deliveries[0].Cartitems[1].BundleConfig["identifier1"].MarketplaceCode)
   837  		assert.Equal(t, 1, got.Deliveries[0].Cartitems[1].BundleConfig["identifier1"].Qty)
   838  		assert.Equal(t, "configurable_option1", got.Deliveries[0].Cartitems[1].BundleConfig["identifier2"].MarketplaceCode)
   839  		assert.Equal(t, "shirt-black-l", got.Deliveries[0].Cartitems[1].BundleConfig["identifier2"].VariantMarketplaceCode)
   840  		assert.Equal(t, 1, got.Deliveries[0].Cartitems[1].BundleConfig["identifier2"].Qty)
   841  	})
   842  
   843  	t.Run("update bundle configuration for a cart item", func(t *testing.T) {
   844  		t.Parallel()
   845  
   846  		cob := &DefaultCartBehaviour{}
   847  		cob.Inject(
   848  			newInMemoryStorage(),
   849  			&fake.ProductService{},
   850  			flamingo.NullLogger{},
   851  			nil,
   852  			nil,
   853  			nil,
   854  		)
   855  
   856  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   857  			ID: "1234",
   858  			Deliveries: []domaincart.Delivery{
   859  				{
   860  					DeliveryInfo: domaincart.DeliveryInfo{
   861  						Code: "delivery",
   862  					},
   863  					Cartitems: []domaincart.Item{
   864  						{
   865  							ID:              "1234",
   866  							MarketplaceCode: "fake_bundle",
   867  							Qty:             1,
   868  							BundleConfig: map[domain.Identifier]domain.ChoiceConfiguration{
   869  								"identifier1": {
   870  									MarketplaceCode: "simple_option1",
   871  									Qty:             1,
   872  								},
   873  								"identifier2": {
   874  									MarketplaceCode:        "configurable_option2",
   875  									VariantMarketplaceCode: "shirt-black-s",
   876  									Qty:                    1,
   877  								},
   878  							},
   879  						},
   880  					},
   881  				},
   882  			},
   883  		})
   884  		assert.NoError(t, err)
   885  
   886  		qty := 1
   887  		got, _, err := cob.UpdateItems(context.Background(), cart, []domaincart.ItemUpdateCommand{{
   888  			ItemID: "1234",
   889  			Qty:    &qty,
   890  			BundleConfiguration: map[domain.Identifier]domain.ChoiceConfiguration{
   891  				"identifier1": {
   892  					MarketplaceCode: "simple_option2",
   893  					Qty:             2,
   894  				},
   895  				"identifier2": {
   896  					MarketplaceCode:        "configurable_option1",
   897  					VariantMarketplaceCode: "shirt-black-l",
   898  					Qty:                    2,
   899  				},
   900  			},
   901  		}})
   902  
   903  		assert.NoError(t, err)
   904  		assert.Equal(t, "fake_bundle", got.Deliveries[0].Cartitems[0].MarketplaceCode)
   905  		assert.Equal(t, "simple_option2", got.Deliveries[0].Cartitems[0].BundleConfig["identifier1"].MarketplaceCode)
   906  		assert.Equal(t, 2, got.Deliveries[0].Cartitems[0].BundleConfig["identifier1"].Qty)
   907  		assert.Equal(t, "configurable_option1", got.Deliveries[0].Cartitems[0].BundleConfig["identifier2"].MarketplaceCode)
   908  		assert.Equal(t, "shirt-black-l", got.Deliveries[0].Cartitems[0].BundleConfig["identifier2"].VariantMarketplaceCode)
   909  		assert.Equal(t, 2, got.Deliveries[0].Cartitems[0].BundleConfig["identifier2"].Qty)
   910  	})
   911  }
   912  
   913  func TestDefaultCartBehaviour_AddToCart(t *testing.T) {
   914  	t.Parallel()
   915  
   916  	t.Run("adding product to empty cart adds delivery", func(t *testing.T) {
   917  		t.Parallel()
   918  
   919  		cob := &DefaultCartBehaviour{}
   920  		cob.Inject(
   921  			newInMemoryStorage(),
   922  			&fake.ProductService{},
   923  			flamingo.NullLogger{},
   924  			nil,
   925  			nil,
   926  			nil,
   927  		)
   928  
   929  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   930  			ID: "1234",
   931  		})
   932  		assert.NoError(t, err)
   933  
   934  		got, _, err := cob.AddToCart(context.Background(), cart, "delivery", domaincart.AddRequest{
   935  			MarketplaceCode: "fake_fixed_simple_without_discounts",
   936  			Qty:             1,
   937  		})
   938  
   939  		assert.NoError(t, err)
   940  		assert.Equal(t, 1, len(got.Deliveries))
   941  		assert.Equal(t, 1, len(got.Deliveries[0].Cartitems))
   942  		assert.Equal(t, "fake_fixed_simple_without_discounts", got.Deliveries[0].Cartitems[0].MarketplaceCode)
   943  		assert.Equal(t, 1, got.Deliveries[0].Cartitems[0].Qty)
   944  		assert.Equal(t, 20.99, got.GrandTotal.FloatAmount())
   945  	})
   946  
   947  	t.Run("adding the same product increases qty", func(t *testing.T) {
   948  		t.Parallel()
   949  
   950  		cob := &DefaultCartBehaviour{}
   951  		cob.Inject(
   952  			newInMemoryStorage(),
   953  			&fake.ProductService{},
   954  			flamingo.NullLogger{},
   955  			nil,
   956  			nil,
   957  			nil,
   958  		)
   959  
   960  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
   961  			ID: "1234",
   962  			Deliveries: []domaincart.Delivery{
   963  				{
   964  					DeliveryInfo: domaincart.DeliveryInfo{
   965  						Code: "delivery",
   966  					},
   967  					Cartitems: []domaincart.Item{
   968  						{
   969  							MarketplaceCode: "fake_fixed_simple_without_discounts",
   970  							Qty:             1,
   971  							AdditionalData: map[string]string{
   972  								"1": "a",
   973  							},
   974  						},
   975  					},
   976  				},
   977  			},
   978  		})
   979  		assert.NoError(t, err)
   980  
   981  		got, _, err := cob.AddToCart(context.Background(), cart, "delivery", domaincart.AddRequest{
   982  			MarketplaceCode: "fake_fixed_simple_without_discounts",
   983  			Qty:             1,
   984  			AdditionalData: map[string]string{
   985  				"2": "b",
   986  			},
   987  		})
   988  
   989  		assert.NoError(t, err)
   990  		assert.Equal(t, 1, len(got.Deliveries[0].Cartitems))
   991  		assert.Equal(t, "fake_fixed_simple_without_discounts", got.Deliveries[0].Cartitems[0].MarketplaceCode)
   992  		assert.Equal(t, map[string]string{"1": "a", "2": "b"}, got.Deliveries[0].Cartitems[0].AdditionalData)
   993  		assert.Equal(t, 2, got.Deliveries[0].Cartitems[0].Qty)
   994  		assert.Equal(t, 41.98, got.GrandTotal.FloatAmount())
   995  	})
   996  
   997  	t.Run("adding the same configurable product with different active variant", func(t *testing.T) {
   998  		t.Parallel()
   999  
  1000  		cob := &DefaultCartBehaviour{}
  1001  		cob.Inject(
  1002  			newInMemoryStorage(),
  1003  			&fake.ProductService{},
  1004  			flamingo.NullLogger{},
  1005  			nil,
  1006  			nil,
  1007  			nil,
  1008  		)
  1009  
  1010  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
  1011  			ID: "1234",
  1012  			Deliveries: []domaincart.Delivery{
  1013  				{
  1014  					DeliveryInfo: domaincart.DeliveryInfo{
  1015  						Code: "delivery",
  1016  					},
  1017  					Cartitems: []domaincart.Item{
  1018  						{
  1019  							MarketplaceCode:        "fake_configurable_with_active_variant",
  1020  							VariantMarketPlaceCode: "shirt-red-s",
  1021  							Qty:                    1,
  1022  						},
  1023  					},
  1024  				},
  1025  			},
  1026  		})
  1027  		assert.NoError(t, err)
  1028  
  1029  		got, _, err := cob.AddToCart(context.Background(), cart, "delivery", domaincart.AddRequest{
  1030  			MarketplaceCode:        "fake_configurable_with_active_variant",
  1031  			VariantMarketplaceCode: "shirt-black-l",
  1032  			Qty:                    1,
  1033  		})
  1034  
  1035  		assert.NoError(t, err)
  1036  		assert.Equal(t, 2, len(got.Deliveries[0].Cartitems))
  1037  		assert.Equal(t, "fake_configurable_with_active_variant", got.Deliveries[0].Cartitems[0].MarketplaceCode)
  1038  		assert.Equal(t, "shirt-red-s", got.Deliveries[0].Cartitems[0].VariantMarketPlaceCode)
  1039  		assert.Equal(t, "fake_configurable_with_active_variant", got.Deliveries[0].Cartitems[1].MarketplaceCode)
  1040  		assert.Equal(t, "shirt-black-l", got.Deliveries[0].Cartitems[1].VariantMarketPlaceCode)
  1041  	})
  1042  
  1043  	t.Run("adding the same bundle product with different choices", func(t *testing.T) {
  1044  		t.Parallel()
  1045  
  1046  		cob := &DefaultCartBehaviour{}
  1047  		cob.Inject(
  1048  			newInMemoryStorage(),
  1049  			&fake.ProductService{},
  1050  			flamingo.NullLogger{},
  1051  			nil,
  1052  			nil,
  1053  			nil,
  1054  		)
  1055  
  1056  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
  1057  			ID: "1234",
  1058  			Deliveries: []domaincart.Delivery{
  1059  				{
  1060  					DeliveryInfo: domaincart.DeliveryInfo{
  1061  						Code: "delivery",
  1062  					},
  1063  					Cartitems: []domaincart.Item{
  1064  						{
  1065  							MarketplaceCode: "fake_bundle",
  1066  							Qty:             1,
  1067  							BundleConfig: map[domain.Identifier]domain.ChoiceConfiguration{
  1068  								"identifier1": {
  1069  									MarketplaceCode: "simple_option1",
  1070  									Qty:             1,
  1071  								},
  1072  								"identifier2": {
  1073  									MarketplaceCode:        "configurable_option1",
  1074  									VariantMarketplaceCode: "shirt-black-l",
  1075  									Qty:                    1,
  1076  								},
  1077  							},
  1078  						},
  1079  					},
  1080  				},
  1081  			},
  1082  		})
  1083  		assert.NoError(t, err)
  1084  
  1085  		got, _, err := cob.AddToCart(context.Background(), cart, "delivery", domaincart.AddRequest{
  1086  			MarketplaceCode: "fake_bundle",
  1087  			Qty:             1,
  1088  			BundleConfiguration: map[domain.Identifier]domain.ChoiceConfiguration{
  1089  				"identifier1": {
  1090  					MarketplaceCode: "simple_option2",
  1091  					Qty:             1,
  1092  				},
  1093  				"identifier2": {
  1094  					MarketplaceCode:        "configurable_option1",
  1095  					VariantMarketplaceCode: "shirt-black-l",
  1096  					Qty:                    1,
  1097  				},
  1098  			},
  1099  		})
  1100  
  1101  		assert.NoError(t, err)
  1102  		assert.Equal(t, 2, len(got.Deliveries[0].Cartitems))
  1103  		assert.Equal(t, "fake_bundle", got.Deliveries[0].Cartitems[0].MarketplaceCode)
  1104  		assert.Equal(t, "simple_option1", got.Deliveries[0].Cartitems[0].BundleConfig["identifier1"].MarketplaceCode)
  1105  		assert.Equal(t, "fake_bundle", got.Deliveries[0].Cartitems[1].MarketplaceCode)
  1106  		assert.Equal(t, "simple_option2", got.Deliveries[0].Cartitems[1].BundleConfig["identifier1"].MarketplaceCode)
  1107  	})
  1108  }
  1109  
  1110  func TestDefaultCartBehaviour_UpdatePurchaser(t *testing.T) {
  1111  	t.Parallel()
  1112  
  1113  	t.Run("additional data custom attributes are merged", func(t *testing.T) {
  1114  		t.Parallel()
  1115  
  1116  		cob := &DefaultCartBehaviour{}
  1117  		cob.Inject(
  1118  			newInMemoryStorage(),
  1119  			nil,
  1120  			flamingo.NullLogger{},
  1121  			nil,
  1122  			nil,
  1123  			nil,
  1124  		)
  1125  
  1126  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
  1127  			ID: "1234",
  1128  			Deliveries: []domaincart.Delivery{
  1129  				{
  1130  					DeliveryInfo: domaincart.DeliveryInfo{
  1131  						Code: "delivery",
  1132  					},
  1133  				},
  1134  			},
  1135  			AdditionalData: domaincart.AdditionalData{
  1136  				CustomAttributes: map[string]string{
  1137  					"1": "a",
  1138  				},
  1139  			},
  1140  		})
  1141  		assert.NoError(t, err)
  1142  
  1143  		got, _, err := cob.UpdatePurchaser(
  1144  			context.Background(),
  1145  			cart,
  1146  			&domaincart.Person{
  1147  				Address: &domaincart.Address{
  1148  					Firstname: "test",
  1149  				},
  1150  			},
  1151  			&domaincart.AdditionalData{
  1152  				CustomAttributes: map[string]string{
  1153  					"2": "b",
  1154  				},
  1155  			})
  1156  		assert.NoError(t, err)
  1157  		assert.Equal(t, "test", got.Purchaser.Address.Firstname)
  1158  		assert.Equal(t, map[string]string{"1": "a", "2": "b"}, got.AdditionalData.CustomAttributes)
  1159  	})
  1160  }
  1161  
  1162  func TestDefaultCartBehaviour_UpdateBillingAddress(t *testing.T) {
  1163  	t.Parallel()
  1164  
  1165  	t.Run("add billing address", func(t *testing.T) {
  1166  		t.Parallel()
  1167  
  1168  		cob := &DefaultCartBehaviour{}
  1169  		cob.Inject(
  1170  			newInMemoryStorage(),
  1171  			nil,
  1172  			flamingo.NullLogger{},
  1173  			nil,
  1174  			nil,
  1175  			nil,
  1176  		)
  1177  
  1178  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{ID: "1234"})
  1179  		assert.NoError(t, err)
  1180  
  1181  		got, _, err := cob.UpdateBillingAddress(context.Background(), cart, domaincart.Address{
  1182  			Firstname: "first",
  1183  		})
  1184  		assert.NoError(t, err)
  1185  		assert.Equal(t, "first", got.BillingAddress.Firstname)
  1186  	})
  1187  
  1188  	t.Run("update billing address", func(t *testing.T) {
  1189  		t.Parallel()
  1190  
  1191  		cob := &DefaultCartBehaviour{}
  1192  		cob.Inject(
  1193  			newInMemoryStorage(),
  1194  			nil,
  1195  			flamingo.NullLogger{},
  1196  			nil,
  1197  			nil,
  1198  			nil,
  1199  		)
  1200  
  1201  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
  1202  			ID: "1234",
  1203  			BillingAddress: &domaincart.Address{
  1204  				Firstname: "first-1",
  1205  			},
  1206  		})
  1207  		assert.NoError(t, err)
  1208  
  1209  		got, _, err := cob.UpdateBillingAddress(context.Background(), cart, domaincart.Address{
  1210  			Firstname: "first-2",
  1211  		})
  1212  		assert.NoError(t, err)
  1213  		assert.Equal(t, "first-2", got.BillingAddress.Firstname)
  1214  	})
  1215  }
  1216  
  1217  func TestDefaultCartBehaviour_UpdateAdditionalData(t *testing.T) {
  1218  	t.Parallel()
  1219  
  1220  	t.Run("add additional data", func(t *testing.T) {
  1221  		t.Parallel()
  1222  
  1223  		cob := &DefaultCartBehaviour{}
  1224  		cob.Inject(
  1225  			newInMemoryStorage(),
  1226  			nil,
  1227  			flamingo.NullLogger{},
  1228  			nil,
  1229  			nil,
  1230  			nil,
  1231  		)
  1232  
  1233  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{ID: "1234"})
  1234  		assert.NoError(t, err)
  1235  
  1236  		got, _, err := cob.UpdateAdditionalData(context.Background(), cart, &domaincart.AdditionalData{
  1237  			ReservedOrderID:  "id-1",
  1238  			CustomAttributes: map[string]string{"1": "a"},
  1239  		})
  1240  		assert.NoError(t, err)
  1241  		assert.Equal(t, "id-1", got.AdditionalData.ReservedOrderID)
  1242  		assert.Equal(t, map[string]string{"1": "a"}, got.AdditionalData.CustomAttributes)
  1243  	})
  1244  
  1245  	t.Run("update additional data", func(t *testing.T) {
  1246  		t.Parallel()
  1247  
  1248  		cob := &DefaultCartBehaviour{}
  1249  		cob.Inject(
  1250  			newInMemoryStorage(),
  1251  			nil,
  1252  			flamingo.NullLogger{},
  1253  			nil,
  1254  			nil,
  1255  			nil,
  1256  		)
  1257  
  1258  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
  1259  			ID: "1234",
  1260  			AdditionalData: domaincart.AdditionalData{
  1261  				ReservedOrderID:  "id-1",
  1262  				CustomAttributes: map[string]string{"1": "a"},
  1263  			},
  1264  		})
  1265  		assert.NoError(t, err)
  1266  
  1267  		got, _, err := cob.UpdateAdditionalData(context.Background(), cart, &domaincart.AdditionalData{
  1268  			ReservedOrderID:  "id-2",
  1269  			CustomAttributes: map[string]string{"2": "b"},
  1270  		})
  1271  		assert.NoError(t, err)
  1272  		assert.Equal(t, "id-2", got.AdditionalData.ReservedOrderID)
  1273  		assert.Equal(t, map[string]string{"2": "b"}, got.AdditionalData.CustomAttributes)
  1274  	})
  1275  }
  1276  
  1277  func TestDefaultCartBehaviour_UpdatePaymentSelection(t *testing.T) {
  1278  	t.Parallel()
  1279  
  1280  	t.Run("add payment selection", func(t *testing.T) {
  1281  		t.Parallel()
  1282  
  1283  		cob := &DefaultCartBehaviour{}
  1284  		cob.Inject(
  1285  			newInMemoryStorage(),
  1286  			nil,
  1287  			flamingo.NullLogger{},
  1288  			nil,
  1289  			nil,
  1290  			nil,
  1291  		)
  1292  
  1293  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{ID: "1234"})
  1294  		assert.NoError(t, err)
  1295  
  1296  		got, _, err := cob.UpdatePaymentSelection(context.Background(), cart, &domaincart.DefaultPaymentSelection{
  1297  			GatewayProp: "gateway-1",
  1298  		})
  1299  		assert.NoError(t, err)
  1300  		assert.Equal(t, "gateway-1", got.PaymentSelection.Gateway())
  1301  	})
  1302  
  1303  	t.Run("update payment selection", func(t *testing.T) {
  1304  		t.Parallel()
  1305  
  1306  		cob := &DefaultCartBehaviour{}
  1307  		cob.Inject(
  1308  			newInMemoryStorage(),
  1309  			nil,
  1310  			flamingo.NullLogger{},
  1311  			nil,
  1312  			nil,
  1313  			nil,
  1314  		)
  1315  
  1316  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
  1317  			ID: "1234",
  1318  			PaymentSelection: &domaincart.DefaultPaymentSelection{
  1319  				GatewayProp: "gateway-1",
  1320  			},
  1321  		})
  1322  		assert.NoError(t, err)
  1323  
  1324  		got, _, err := cob.UpdatePaymentSelection(context.Background(), cart, &domaincart.DefaultPaymentSelection{
  1325  			GatewayProp: "gateway-2",
  1326  		})
  1327  		assert.NoError(t, err)
  1328  		assert.Equal(t, "gateway-2", got.PaymentSelection.Gateway())
  1329  	})
  1330  }
  1331  
  1332  func TestDefaultCartBehaviour_UpdateDeliveryInfo(t *testing.T) {
  1333  	t.Parallel()
  1334  
  1335  	t.Run("add new delivery info", func(t *testing.T) {
  1336  		t.Parallel()
  1337  
  1338  		cob := &DefaultCartBehaviour{}
  1339  		cob.Inject(
  1340  			newInMemoryStorage(),
  1341  			nil,
  1342  			flamingo.NullLogger{},
  1343  			nil,
  1344  			nil,
  1345  			nil,
  1346  		)
  1347  
  1348  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{ID: "1234"})
  1349  		assert.NoError(t, err)
  1350  
  1351  		got, _, err := cob.UpdateDeliveryInfo(context.Background(), cart, "delivery", domaincart.DeliveryInfoUpdateCommand{
  1352  			DeliveryInfo: domaincart.DeliveryInfo{
  1353  				Code: "delivery",
  1354  			},
  1355  		})
  1356  		assert.NoError(t, err)
  1357  		assert.Equal(t, 1, len(got.Deliveries))
  1358  		assert.Equal(t, "delivery", got.Deliveries[0].DeliveryInfo.Code)
  1359  	})
  1360  
  1361  	t.Run("update delivery info", func(t *testing.T) {
  1362  		t.Parallel()
  1363  
  1364  		cob := &DefaultCartBehaviour{}
  1365  		cob.Inject(
  1366  			newInMemoryStorage(),
  1367  			nil,
  1368  			flamingo.NullLogger{},
  1369  			nil,
  1370  			nil,
  1371  			nil,
  1372  		)
  1373  
  1374  		cart, err := cob.StoreNewCart(context.Background(), &domaincart.Cart{
  1375  			ID: "1234",
  1376  			Deliveries: []domaincart.Delivery{
  1377  				{
  1378  					DeliveryInfo: domaincart.DeliveryInfo{
  1379  						Code: "delivery-1",
  1380  					},
  1381  				},
  1382  			},
  1383  		})
  1384  		assert.NoError(t, err)
  1385  
  1386  		got, _, err := cob.UpdateDeliveryInfo(context.Background(), cart, "delivery-1", domaincart.DeliveryInfoUpdateCommand{
  1387  			DeliveryInfo: domaincart.DeliveryInfo{
  1388  				Code: "delivery-2",
  1389  			},
  1390  		})
  1391  		assert.NoError(t, err)
  1392  		assert.Equal(t, 1, len(got.Deliveries))
  1393  		assert.Equal(t, "delivery-2", got.Deliveries[0].DeliveryInfo.Code)
  1394  	})
  1395  }
  1396  
  1397  func newInMemoryStorage() *InMemoryCartStorage {
  1398  	result := &InMemoryCartStorage{}
  1399  	result.Inject()
  1400  
  1401  	return result
  1402  }
  1403  
  1404  func TestDefaultCartBehaviour_createCartItemFromProduct(t *testing.T) {
  1405  	t.Parallel()
  1406  
  1407  	t.Run("gross", func(t *testing.T) {
  1408  		t.Parallel()
  1409  
  1410  		cob := DefaultCartBehaviour{}
  1411  		cob.Inject(nil, nil, flamingo.NullLogger{}, nil, nil, &struct {
  1412  			DefaultTaxRate  float64 `inject:"config:commerce.cart.defaultCartAdapter.defaultTaxRate,optional"`
  1413  			ProductPricing  string  `inject:"config:commerce.cart.defaultCartAdapter.productPrices"`
  1414  			DefaultCurrency string  `inject:"config:commerce.cart.defaultCartAdapter.defaultCurrency"`
  1415  		}{ProductPricing: "gross", DefaultTaxRate: 10.0, DefaultCurrency: "EUR"})
  1416  
  1417  		item, err := cob.createCartItemFromProduct(2, "ma", "", map[string]string{}, nil, domain.SimpleProduct{
  1418  			Saleable: domain.Saleable{
  1419  				IsSaleable: true,
  1420  				ActivePrice: domain.PriceInfo{
  1421  					Default: priceDomain.NewFromFloat(50.00, "USD"),
  1422  				},
  1423  			},
  1424  		})
  1425  
  1426  		require.NoError(t, err)
  1427  		assert.True(t, item.SinglePriceGross.Equal(priceDomain.NewFromFloat(50.00, "USD")))
  1428  		assert.Equal(t, 45.45, item.SinglePriceNet.FloatAmount())
  1429  		assert.Equal(t, 100.00, item.RowPriceGross.FloatAmount())
  1430  		assert.Equal(t, 45.45*2, item.RowPriceNet.FloatAmount())
  1431  		assert.Equal(t, 100.00-45.45*2, item.TotalTaxAmount().FloatAmount())
  1432  	})
  1433  
  1434  	t.Run("net", func(t *testing.T) {
  1435  		t.Parallel()
  1436  
  1437  		cob := DefaultCartBehaviour{}
  1438  		cob.Inject(nil, nil, flamingo.NullLogger{}, nil, nil, &struct {
  1439  			DefaultTaxRate  float64 `inject:"config:commerce.cart.defaultCartAdapter.defaultTaxRate,optional"`
  1440  			ProductPricing  string  `inject:"config:commerce.cart.defaultCartAdapter.productPrices"`
  1441  			DefaultCurrency string  `inject:"config:commerce.cart.defaultCartAdapter.defaultCurrency"`
  1442  		}{ProductPricing: "net", DefaultTaxRate: 10.0, DefaultCurrency: "EUR"})
  1443  
  1444  		item, err := cob.createCartItemFromProduct(2, "ma", "", map[string]string{}, nil, domain.SimpleProduct{
  1445  			Saleable: domain.Saleable{
  1446  				IsSaleable: true,
  1447  				ActivePrice: domain.PriceInfo{
  1448  					Default: priceDomain.NewFromFloat(50.00, "USD"),
  1449  				},
  1450  			},
  1451  		})
  1452  
  1453  		require.NoError(t, err)
  1454  		assert.True(t, item.SinglePriceNet.Equal(priceDomain.NewFromFloat(50.00, "USD")))
  1455  		assert.Equal(t, 55.00, item.SinglePriceGross.FloatAmount())
  1456  		assert.Equal(t, 55.00*2, item.RowPriceGross.FloatAmount())
  1457  		assert.Equal(t, 50.00*2, item.RowPriceNet.FloatAmount())
  1458  		assert.Equal(t, 10.0, item.TotalTaxAmount().FloatAmount())
  1459  	})
  1460  }