diff --git a/api/order_test.go b/api/order_test.go index 9d56e1c..31790fc 100644 --- a/api/order_test.go +++ b/api/order_test.go @@ -217,7 +217,7 @@ func TestOrderCreate(t *testing.T) { Claims: map[string]string{ "email": test.Data.testUser.Email, }, - Percentage: 15, + Percentage: 15, ProductTypes: []string{"Book"}, }, }, @@ -249,6 +249,68 @@ func TestOrderCreate(t *testing.T) { assert.Equal(t, uint64(15), discountItem.Percentage) assert.Equal(t, uint64(0), discountItem.Fixed) }) + + t.Run("MultipleItemsWithDownloads", func(t *testing.T) { + test := NewRouteTest(t) + + site := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/i/believe/i/can/fly": + fmt.Fprint(w, productMetaFrame( + `{ + "sku": "123-i-can-fly-456", + "downloads": [{"title": "First Download", "url": "/assets/first-download"}], + "prices": [{"currency": "USD", "amount": "3.00"}] + }`, + )) + return + case "/its/not/about/the/money": + fmt.Fprintf(w, productMetaFrame( + `{ + "sku": "not-about-the-money", + "downloads": [{"title": "Second Download", "url": "/assets/second-download"}], + "prices": [{"currency": "USD", "amount": "5.00"}] + }`, + )) + return + } + w.WriteHeader(http.StatusNotFound) + })) + defer site.Close() + test.Config.SiteURL = site.URL + + body := strings.NewReader(`{ + "email": "info@example.com", + "shipping_address": { + "name": "Test User", + "address1": "Branengebranen", + "city": "Berlin", "country": "Germany", "zip": "94107" + }, + "line_items": [ + {"path": "/i/believe/i/can/fly", "quantity": 1}, + {"path": "/its/not/about/the/money", "quantity": 1} + ] + }`) + token := test.Data.testUserToken + recorder := test.TestEndpoint(http.MethodPost, "/orders", body, token) + + order := &models.Order{} + extractPayload(t, http.StatusCreated, recorder, order) + assert.Len(t, order.Downloads, 2) + for _, dl := range order.Downloads { + fmt.Printf("dl: %+v\n", dl) + switch dl.Sku { + case "123-i-can-fly-456": + assert.Equal(t, "First Download", dl.Title) + assert.Equal(t, "/assets/first-download", dl.URL) + case "not-about-the-money": + assert.Equal(t, "Second Download", dl.Title) + assert.Equal(t, "/assets/second-download", dl.URL) + default: + t.Errorf("Unknown download item: %+v", dl) + } + } + }) } func TestOrderCreateNewUser(t *testing.T) { diff --git a/models/line_item.go b/models/line_item.go index 50ed44b..80ab3ac 100644 --- a/models/line_item.go +++ b/models/line_item.go @@ -285,7 +285,7 @@ func (i *LineItem) Process(config *conf.Configuration, userClaims map[string]int i.AddonItems[index].Price = lowestPrice.cents } - order.Downloads = i.MissingDownloads(order, meta) + order.Downloads = append(order.Downloads, i.MissingDownloads(order, meta)...) return i.calculatePrice(userClaims, meta.Prices, order.Currency) } @@ -338,10 +338,10 @@ func (i *LineItem) FetchMeta(siteURL string) (*LineItemMetadata, error) { // MissingDownloads returns all downloads that are not yet listed in the order func (i *LineItem) MissingDownloads(order *Order, meta *LineItemMetadata) []Download { downloads := []Download{} - for _, download := range meta.Downloads { + for _, metaDownload := range meta.Downloads { alreadyCreated := false for _, d := range order.Downloads { - if d.URL == download.URL { + if d.URL == metaDownload.URL { alreadyCreated = true break } @@ -349,11 +349,14 @@ func (i *LineItem) MissingDownloads(order *Order, meta *LineItemMetadata) []Down if alreadyCreated { continue } - download.ID = uuid.NewRandom().String() - download.OrderID = order.ID - download.Title = i.Title - download.Sku = i.Sku - downloads = append(downloads, download) + orderDownload := metaDownload + orderDownload.ID = uuid.NewRandom().String() + orderDownload.OrderID = order.ID + orderDownload.Sku = i.Sku + if orderDownload.Title == "" { + orderDownload.Title = i.Title + } + downloads = append(downloads, orderDownload) } return downloads }