feat(t240): cache freight item images
This commit is contained in:
@@ -479,6 +479,41 @@ func TestAdminFreightAPIImportsAllItemsWithoutPII(t *testing.T) {
|
||||
detail.Header().Get("Cache-Control") != "no-store" {
|
||||
t.Fatalf("freight detail status/body = %d / %s", detail.Code, detail.Body)
|
||||
}
|
||||
var detailBody struct {
|
||||
Items []struct {
|
||||
ID string `json:"id"`
|
||||
ImageStatus string `json:"image_status"`
|
||||
ImageURL string `json:"image_url"`
|
||||
} `json:"items"`
|
||||
}
|
||||
decodeResponse(t, detail, &detailBody)
|
||||
if len(detailBody.Items) != 2 ||
|
||||
detailBody.Items[0].ImageStatus != "READY" ||
|
||||
detailBody.Items[0].ImageURL == "" {
|
||||
t.Fatalf("freight detail images = %+v", detailBody.Items)
|
||||
}
|
||||
imageResponse := performAdminRequest(
|
||||
t,
|
||||
router,
|
||||
http.MethodGet,
|
||||
detailBody.Items[0].ImageURL,
|
||||
"",
|
||||
nil,
|
||||
"",
|
||||
)
|
||||
if imageResponse.Code != http.StatusOK ||
|
||||
imageResponse.Header().Get("Content-Type") != "image/jpeg" ||
|
||||
imageResponse.Header().Get("Cache-Control") != "private, no-store" ||
|
||||
imageResponse.Header().Get("X-Content-Type-Options") != "nosniff" ||
|
||||
imageResponse.Header().Get("ETag") == "" ||
|
||||
!bytes.HasPrefix(imageResponse.Body.Bytes(), []byte{0xff, 0xd8}) {
|
||||
t.Fatalf(
|
||||
"freight image status/headers/body = %d / %#v / %x",
|
||||
imageResponse.Code,
|
||||
imageResponse.Header(),
|
||||
imageResponse.Body.Bytes(),
|
||||
)
|
||||
}
|
||||
replay := performAdminRequest(
|
||||
t,
|
||||
router,
|
||||
@@ -875,6 +910,9 @@ func TestAdminOrderAuthorizationIsIdempotentAndRevisioned(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("migration.New() error = %v", err)
|
||||
}
|
||||
if err := runner.Down(context.Background()); err != nil {
|
||||
t.Fatalf("image migration down: %v", err)
|
||||
}
|
||||
if err := runner.Down(context.Background()); err != nil {
|
||||
t.Fatalf("metadata migration down: %v", err)
|
||||
}
|
||||
@@ -1211,12 +1249,22 @@ func newAdminIntegrationFixture(t *testing.T) *adminIntegrationFixture {
|
||||
if err != nil {
|
||||
t.Fatalf("usecase.NewOrderAuthorizationService() error = %v", err)
|
||||
}
|
||||
freightImages, err := usecase.NewFreightImageService(
|
||||
repositories,
|
||||
staticFreightSource{},
|
||||
files,
|
||||
clock,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("usecase.NewFreightImageService() error = %v", err)
|
||||
}
|
||||
freight, err := usecase.NewFreightService(
|
||||
repositories,
|
||||
staticFreightSource{},
|
||||
clock,
|
||||
ids,
|
||||
time.Second,
|
||||
usecase.WithFreightImageCache(freightImages),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("usecase.NewFreightService() error = %v", err)
|
||||
@@ -1236,6 +1284,7 @@ func newAdminIntegrationFixture(t *testing.T) *adminIntegrationFixture {
|
||||
Results: results,
|
||||
Authorizations: authorizations,
|
||||
Freight: freight,
|
||||
FreightImages: freightImages,
|
||||
Procurement: procurement,
|
||||
},
|
||||
emptyAdminWeb{},
|
||||
@@ -1270,6 +1319,8 @@ func (staticFreightSource) QueryOrder(
|
||||
quantityTwo := 2
|
||||
priceOne := int64(12950)
|
||||
priceTwo := int64(8800)
|
||||
thumbOne := "190"
|
||||
thumbTwo := "191"
|
||||
return domain.FreightSourceBatch{
|
||||
SchemaVersion: 1,
|
||||
Query: domain.FreightSourceQuery{
|
||||
@@ -1289,6 +1340,7 @@ func (staticFreightSource) QueryOrder(
|
||||
Quantity: &quantityOne,
|
||||
OriginalUnitPriceMinor: &priceOne,
|
||||
OriginalCurrency: domain.FreightCurrencyTWD,
|
||||
ProductThumbRef: &thumbOne,
|
||||
},
|
||||
{
|
||||
ExternalItemID: "89",
|
||||
@@ -1298,12 +1350,41 @@ func (staticFreightSource) QueryOrder(
|
||||
Quantity: &quantityTwo,
|
||||
OriginalUnitPriceMinor: &priceTwo,
|
||||
OriginalCurrency: domain.FreightCurrencyTWD,
|
||||
ProductThumbRef: &thumbTwo,
|
||||
},
|
||||
},
|
||||
}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (staticFreightSource) FetchProductImage(
|
||||
context.Context,
|
||||
string,
|
||||
) (usecase.FreightSourceImage, error) {
|
||||
var imageBytes bytes.Buffer
|
||||
source := image.NewRGBA(image.Rect(0, 0, 8, 6))
|
||||
for y := 0; y < 6; y++ {
|
||||
for x := 0; x < 8; x++ {
|
||||
source.Set(
|
||||
x,
|
||||
y,
|
||||
color.RGBA{R: uint8(x * 20), G: 80, B: 160, A: 255},
|
||||
)
|
||||
}
|
||||
}
|
||||
if err := jpeg.Encode(
|
||||
&imageBytes,
|
||||
source,
|
||||
&jpeg.Options{Quality: 85},
|
||||
); err != nil {
|
||||
return usecase.FreightSourceImage{}, err
|
||||
}
|
||||
return usecase.FreightSourceImage{
|
||||
Content: io.NopCloser(bytes.NewReader(imageBytes.Bytes())),
|
||||
MediaType: "image/jpeg",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (staticFreightSource) QueryCreatedRange(
|
||||
_ context.Context,
|
||||
createdFrom, createdTo string,
|
||||
|
||||
Reference in New Issue
Block a user