From f344879599d0540118f077b2ecae8ceccc5cc557 Mon Sep 17 00:00:00 2001 From: Giuseppe Ciotola <30926550+gciotola@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:33:25 +0100 Subject: [PATCH 1/3] fix: add frequency badge in line items summary --- package.json | 1 + packages/cart/package.json | 2 + packages/cart/specs/e2e/frequency.spec.ts | 34 +++++++++++++++++ packages/cart/specs/fixtures/CartPage.ts | 8 ++++ packages/cart/specs/types/index.ts | 1 + .../cart/src/assets/locales/de/common.json | 17 +++++++++ .../cart/src/assets/locales/en/common.json | 21 +++++++++- .../cart/src/assets/locales/it/common.json | 21 +++++++++- .../Cart/Summary/LineItemFrequency.tsx | 38 +++++++++++++++++++ .../src/components/Cart/Summary/index.tsx | 6 +++ .../cart/src/components/atoms/IconRepeat.tsx | 14 +++++++ packages/cart/src/utils/frequency.test.ts | 13 +++++++ packages/cart/src/utils/frequency.ts | 12 ++++++ pnpm-lock.yaml | 23 +++++++++++ 14 files changed, 207 insertions(+), 4 deletions(-) create mode 100644 packages/cart/specs/e2e/frequency.spec.ts create mode 100644 packages/cart/src/components/Cart/Summary/LineItemFrequency.tsx create mode 100644 packages/cart/src/components/atoms/IconRepeat.tsx create mode 100644 packages/cart/src/utils/frequency.test.ts create mode 100644 packages/cart/src/utils/frequency.ts diff --git a/package.json b/package.json index c05ea61e..19a043b6 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "lint": "pnpm -r lint", "lint:fix": "pnpm -r lint:fix", "test": "pnpm -r test", + "test:watch": "pnpm -r test:watch", "test:e2e": "pnpm -r test:e2e", "dep:upgrade:major": "pnpm -r exec npm-check-updates -u", "dep:upgrade:minor": "pnpm dep:upgrade:major -t minor", diff --git a/packages/cart/package.json b/packages/cart/package.json index b88974d0..bac59036 100644 --- a/packages/cart/package.json +++ b/packages/cart/package.json @@ -52,6 +52,8 @@ "async-retry": "^1.3.3", "autoprefixer": "^10.4.16", "classnames": "^2.3.2", + "cron-parser": "^4.9.0", + "cronstrue": "^2.44.0", "dotenv": "^16.3.1", "i18next": "^23.6.0", "jwt-decode": "^4.0.0", diff --git a/packages/cart/specs/e2e/frequency.spec.ts b/packages/cart/specs/e2e/frequency.spec.ts new file mode 100644 index 00000000..75785974 --- /dev/null +++ b/packages/cart/specs/e2e/frequency.spec.ts @@ -0,0 +1,34 @@ +import { test } from "../fixtures/tokenizedPage" + +test.describe("Frequency", () => { + test.use({ + options: { + orderType: "with-items", + + lineItemsAttributes: [ + { + sku_code: "TSHIRTMS000000FFFFFFLXXX", + quantity: 1, + frequency: "monthly", + }, + { + sku_code: "PLAINTSHIRT001", + quantity: 1, + frequency: "yearly", + }, + { + sku_code: "HOODIEUZ000000FFFFFFSXXX", + quantity: 1, + }, + ], + }, + }) + + test("Should see frequency monthly", async ({ CartPage }) => { + await CartPage.checkLineItemFrequency("Monthly") + }) + + test("Should see frequency yearly", async ({ CartPage }) => { + await CartPage.checkLineItemFrequency("Yearly") + }) +}) diff --git a/packages/cart/specs/fixtures/CartPage.ts b/packages/cart/specs/fixtures/CartPage.ts index a4f84c6e..4ec2d388 100644 --- a/packages/cart/specs/fixtures/CartPage.ts +++ b/packages/cart/specs/fixtures/CartPage.ts @@ -118,6 +118,14 @@ export class CartPage { ) } + async checkLineItemFrequency(frequency: string) { + await expect( + this.page.locator("[data-test-id=frequency]", { + hasText: frequency, + }) + ).toBeVisible() + } + async addCouponOrGiftCard(code: string) { await this.page.locator("data-test-id=coupon-input").fill(code) await this.page.locator("data-test-id=coupon-submit").click() diff --git a/packages/cart/specs/types/index.ts b/packages/cart/specs/types/index.ts index 3e1c4bf7..775b96a0 100644 --- a/packages/cart/specs/types/index.ts +++ b/packages/cart/specs/types/index.ts @@ -15,6 +15,7 @@ export type BaseLineItemObject = { export type SkuItem = BaseLineItemObject & { sku_code: string + frequency?: string } export type BundleItem = BaseLineItemObject & { diff --git a/packages/cart/src/assets/locales/de/common.json b/packages/cart/src/assets/locales/de/common.json index 788f16ca..e1729c39 100644 --- a/packages/cart/src/assets/locales/de/common.json +++ b/packages/cart/src/assets/locales/de/common.json @@ -17,6 +17,23 @@ "retryableErrorCode": "Verbindungsprobleme", "retryableErrorDescription": "Bitte lade die Seite einmal neu" }, + "item": { + "frequency": { + "hourly": "Hourly", + "daily": "Daily", + "weekly": "Weekly", + "monthly": "Monthly", + "two-months": "Every two months", + "two-month": "Every two months", + "three-months": "Every three months", + "three-month": "Every three months", + "four-months": "Every four months", + "four-month": "Every four months", + "six-months": "Every six months", + "six-month": "Every six months", + "yearly": "Yearly" + } + }, "couponOrGift": { "label": "Rabattcode vorhanden?", "submit": "Anwenden", diff --git a/packages/cart/src/assets/locales/en/common.json b/packages/cart/src/assets/locales/en/common.json index 599bae6a..0e25d646 100644 --- a/packages/cart/src/assets/locales/en/common.json +++ b/packages/cart/src/assets/locales/en/common.json @@ -17,6 +17,23 @@ "retryableErrorCode": "Connectivity issues", "retryableErrorDescription": "Try to reload the page" }, + "item": { + "frequency": { + "hourly": "Hourly", + "daily": "Daily", + "weekly": "Weekly", + "monthly": "Monthly", + "two-months": "Every two months", + "two-month": "Every two months", + "three-months": "Every three months", + "three-month": "Every three months", + "four-months": "Every four months", + "four-month": "Every four months", + "six-months": "Every six months", + "six-month": "Every six months", + "yearly": "Yearly" + } + }, "couponOrGift": { "label": "Have a promo code?", "submit": "Apply", @@ -25,10 +42,10 @@ "gift_card_code": "Gift card", "coupon_code": "Coupon code" }, - "error": { + "error": { "gift_card_or_coupon_code": "Please enter a valid gift card or coupon", "gift_card_code": "Please enter a valid gift card", "coupon_code": "Please enter a valid coupon" } } -} \ No newline at end of file +} diff --git a/packages/cart/src/assets/locales/it/common.json b/packages/cart/src/assets/locales/it/common.json index 6f449760..2490f842 100644 --- a/packages/cart/src/assets/locales/it/common.json +++ b/packages/cart/src/assets/locales/it/common.json @@ -17,6 +17,23 @@ "retryableErrorCode": "Problemi di connessione", "retryableErrorDescription": "Prova a ricaricare la pagina" }, + "item": { + "frequency": { + "hourly": "Orario", + "daily": "Giornaliero", + "weekly": "Settimanale", + "monthly": "Mensile", + "two-months": "Ogni due mesi", + "two-month": "Ogni due mesi", + "three-months": "Ogni tre mesi", + "three-month": "Ogni tre mesi", + "four-months": "Ogni quattro mesi", + "four-month": "Ogni quattro mesi", + "six-months": "Ogni sei mesi", + "six-month": "Ogni sei mesi", + "yearly": "Annuale" + } + }, "couponOrGift": { "label": "Hai un codice da usare?", "submit": "Applica", @@ -25,10 +42,10 @@ "gift_card_code": "Codice gift card", "coupon_code": "Codice coupon" }, - "error": { + "error": { "gift_card_or_coupon_code": "Non corrisponde ad alcuna carta regalo o coupon attivo", "gift_card_code": "Non corrisponde ad una carta regalo attiva", "coupon_code": "Non corrisponde ad un coupon attivo" } } -} \ No newline at end of file +} diff --git a/packages/cart/src/components/Cart/Summary/LineItemFrequency.tsx b/packages/cart/src/components/Cart/Summary/LineItemFrequency.tsx new file mode 100644 index 00000000..ecd5ace9 --- /dev/null +++ b/packages/cart/src/components/Cart/Summary/LineItemFrequency.tsx @@ -0,0 +1,38 @@ +import { LineItemField } from "@commercelayer/react-components" +import { toString as cronsToString } from "cronstrue" +import { FC } from "react" +import { useTranslation } from "react-i18next" + +import { IconRepeat } from "#components/atoms/IconRepeat" +import { isValidCronExpression } from "#utils/frequency" + +export const LineItemFrequency: FC = () => { + const { t, i18n } = useTranslation() + + return ( + + {/* @ts-expect-error typing on attribute */} + {({ attributeValue }) => { + if (attributeValue == null) { + return null + } + + const frequency = isValidCronExpression(attributeValue) + ? cronsToString(attributeValue, { + locale: i18n.language, + }) + : t(`item.frequency.${attributeValue}`) + + return ( +
+ + {frequency} +
+ ) + }} +
+ ) +} diff --git a/packages/cart/src/components/Cart/Summary/index.tsx b/packages/cart/src/components/Cart/Summary/index.tsx index 416f9115..a7636d2c 100644 --- a/packages/cart/src/components/Cart/Summary/index.tsx +++ b/packages/cart/src/components/Cart/Summary/index.tsx @@ -10,6 +10,7 @@ import { FC } from "react" import { useTranslation } from "react-i18next" import { ButtonRemoveItem } from "./ButtonRemoveItem" +import { LineItemFrequency } from "./LineItemFrequency" import { LineItemOptions } from "./LineItemOptions" import { QuantitySelector } from "./QuantitySelector" @@ -58,8 +59,13 @@ export const Summary: FC = ({ listTypes }) => {
{type === "gift_cards" ?
: } +
+ +
+ +
diff --git a/packages/cart/src/components/atoms/IconRepeat.tsx b/packages/cart/src/components/atoms/IconRepeat.tsx new file mode 100644 index 00000000..b0a9dc3f --- /dev/null +++ b/packages/cart/src/components/atoms/IconRepeat.tsx @@ -0,0 +1,14 @@ +import { FC } from "react" + +export const IconRepeat: FC<{ className?: string }> = ({ className }) => ( + + {" "} + +) diff --git a/packages/cart/src/utils/frequency.test.ts b/packages/cart/src/utils/frequency.test.ts new file mode 100644 index 00000000..afb02dc8 --- /dev/null +++ b/packages/cart/src/utils/frequency.test.ts @@ -0,0 +1,13 @@ +import { isValidCronExpression } from "#utils/frequency" + +describe("isValidCronExpression", () => { + test("Should return true for valid cron expressions", () => { + expect(isValidCronExpression("0 0 1 * *")).toBe(true) + expect(isValidCronExpression("0 3 * 3 *")).toBe(true) + }) + + test("Should return false for invalid cron expressions", () => { + expect(isValidCronExpression("0 0 A")).toBe(false) + expect(isValidCronExpression("* 1 3 0 * * 2")).toBe(false) + }) +}) diff --git a/packages/cart/src/utils/frequency.ts b/packages/cart/src/utils/frequency.ts new file mode 100644 index 00000000..8d97d5ba --- /dev/null +++ b/packages/cart/src/utils/frequency.ts @@ -0,0 +1,12 @@ +import { parseExpression } from "cron-parser" + +export function isValidCronExpression( + cronExpression: any +): cronExpression is string { + try { + parseExpression(cronExpression) + return true + } catch (e) { + return false + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11a34abf..ef8d5bc7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,12 @@ importers: classnames: specifier: ^2.3.2 version: 2.3.2 + cron-parser: + specifier: ^4.9.0 + version: 4.9.0 + cronstrue: + specifier: ^2.44.0 + version: 2.44.0 dotenv: specifier: ^16.3.1 version: 16.3.1 @@ -3080,6 +3086,18 @@ packages: resolution: {integrity: sha512-CpNFuLxiPFxuZqhSKml3M+t0K/484pMAnfYWH14JoD7OZMnmC0Lmo+P7JX9SobqFpRoo7ifA18kOHdxJywYPEA==} dev: false + /cron-parser@4.9.0: + resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} + engines: {node: '>=12.0.0'} + dependencies: + luxon: 3.4.4 + dev: false + + /cronstrue@2.44.0: + resolution: {integrity: sha512-71aQD16uXrqjDUYHsFYY4/SSmEepzQZqTqWsU9x2kDMCYKyIp/5e0QW/cp2lBNO9PJB1xOpIbBJuQEa5yKx98A==} + hasBin: true + dev: false + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -5724,6 +5742,11 @@ packages: engines: {node: 14 || >=16.14} dev: true + /luxon@3.4.4: + resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==} + engines: {node: '>=12'} + dev: false + /magic-string@0.30.5: resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} From 4b202e019ce9af7f5973c434b9e6d57124b941ac Mon Sep 17 00:00:00 2001 From: Giuseppe Ciotola <30926550+gciotola@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:00:23 +0100 Subject: [PATCH 2/3] fix: uniform frequency badge spacing --- packages/cart/src/components/Cart/Summary/LineItemFrequency.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cart/src/components/Cart/Summary/LineItemFrequency.tsx b/packages/cart/src/components/Cart/Summary/LineItemFrequency.tsx index ecd5ace9..8d97fe54 100644 --- a/packages/cart/src/components/Cart/Summary/LineItemFrequency.tsx +++ b/packages/cart/src/components/Cart/Summary/LineItemFrequency.tsx @@ -25,7 +25,7 @@ export const LineItemFrequency: FC = () => { return (
From d3e323b6175a398bdc236d5636d17f11d0115083 Mon Sep 17 00:00:00 2001 From: Giuseppe Ciotola <30926550+gciotola@users.noreply.github.com> Date: Wed, 22 Nov 2023 08:41:29 +0100 Subject: [PATCH 3/3] v3.2.4 --- lerna.json | 2 +- packages/cart/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lerna.json b/lerna.json index a3ffe3cf..0176f4d0 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "3.2.3", + "version": "3.2.4", "$schema": "node_modules/lerna/schemas/lerna-schema.json", "useNx": false, "npmClient": "pnpm", diff --git a/packages/cart/package.json b/packages/cart/package.json index bac59036..ba1b99a5 100644 --- a/packages/cart/package.json +++ b/packages/cart/package.json @@ -1,6 +1,6 @@ { "name": "mfe-cart", - "version": "3.2.3", + "version": "3.2.4", "private": true, "author": { "name": "Giuseppe Ciotola",