@reorderjs/reorder 1.0.7 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/e2e/auth.setup.js +26 -0
- package/.medusa/server/e2e/cancellation-retention.spec.js +133 -0
- package/.medusa/server/e2e/pages/CancellationCaseDetailPage.js +69 -0
- package/.medusa/server/e2e/pages/CancellationsListPage.js +34 -0
- package/.medusa/server/e2e/pages/PlanFormPage.js +89 -0
- package/.medusa/server/e2e/pages/RenewalDetailPage.js +101 -0
- package/.medusa/server/e2e/pages/SubscriptionDetailPage.js +102 -0
- package/.medusa/server/e2e/plans-offers.spec.js +96 -0
- package/.medusa/server/e2e/renewal-force.spec.js +154 -0
- package/.medusa/server/e2e/seed.setup.js +80 -0
- package/.medusa/server/e2e/subscription-status.spec.js +109 -0
- package/.medusa/server/e2e/subscriptions-list.spec.js +84 -0
- package/.medusa/server/playwright.config.js +37 -0
- package/.medusa/server/scripts/reset-subscriptions-test-data.js +279 -0
- package/.medusa/server/scripts/seed-subscriptions-test-data.js +2425 -0
- package/.medusa/server/scripts/wipe-test-data.js +44 -0
- package/.medusa/server/src/admin/index.js +13142 -11709
- package/.medusa/server/src/admin/index.mjs +13136 -11703
- package/.medusa/server/src/admin/types/activity-log.js +2 -1
- package/.medusa/server/src/admin/types/analytics.js +2 -1
- package/.medusa/server/src/api/admin/cancellations/validators.js +2 -2
- package/.medusa/server/src/api/admin/dunning/validators.js +2 -2
- package/.medusa/server/src/api/admin/renewals/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscription-analytics/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscription-logs/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscription-offers/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscription-settings/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscriptions/[id]/payment-method/route.js +19 -0
- package/.medusa/server/src/api/admin/subscriptions/[id]/payment-methods/route.js +10 -0
- package/.medusa/server/src/api/admin/subscriptions/middlewares.js +8 -1
- package/.medusa/server/src/api/admin/subscriptions/utils.js +5 -1
- package/.medusa/server/src/api/admin/subscriptions/validators.js +7 -3
- package/.medusa/server/src/api/store/customers/me/subscriptions/[id]/payment-method/route.js +26 -0
- package/.medusa/server/src/api/store/customers/me/subscriptions/[id]/payment-methods/route.js +15 -0
- package/.medusa/server/src/api/store/customers/me/subscriptions/middlewares.js +8 -1
- package/.medusa/server/src/api/store/customers/me/subscriptions/utils.js +72 -1
- package/.medusa/server/src/api/store/customers/me/subscriptions/validators.js +7 -3
- package/.medusa/server/src/api/store/products/validators.js +2 -2
- package/.medusa/server/src/modules/activity-log/__tests__/create-subscription-log-event.spec.js +257 -0
- package/.medusa/server/src/modules/activity-log/__tests__/normalize-log-event.spec.js +231 -0
- package/.medusa/server/src/modules/activity-log/migrations/Migration20260524220933.js +16 -0
- package/.medusa/server/src/modules/activity-log/migrations/Migration20260524225625.js +16 -0
- package/.medusa/server/src/modules/activity-log/migrations/Migration20260818120000.js +16 -0
- package/.medusa/server/src/modules/activity-log/types/index.js +4 -1
- package/.medusa/server/src/modules/activity-log/utils/admin-query.js +15 -1
- package/.medusa/server/src/modules/analytics/__tests__/admin-query.spec.js +560 -0
- package/.medusa/server/src/modules/analytics/index.js +2 -2
- package/.medusa/server/src/modules/analytics/utils/admin-query.js +157 -5
- package/.medusa/server/src/modules/plan-offer/__tests__/service.spec.js +94 -0
- package/.medusa/server/src/modules/renewal/__tests__/service.spec.js +89 -0
- package/.medusa/server/src/modules/settings/__tests__/normalize-settings.spec.js +86 -0
- package/.medusa/server/src/modules/settings/__tests__/service.spec.js +124 -0
- package/.medusa/server/src/modules/subscription/__tests__/payment-methods.spec.js +186 -0
- package/.medusa/server/src/modules/subscription/__tests__/service.spec.js +124 -0
- package/.medusa/server/src/modules/subscription/utils/admin-query.js +196 -14
- package/.medusa/server/src/modules/subscription/utils/payment-methods.js +146 -0
- package/.medusa/server/src/subscription-flows/create-subscription-from-cart.js +55 -2
- package/.medusa/server/src/workflows/__tests__/cancel-subscription.spec.js +20 -0
- package/.medusa/server/src/workflows/__tests__/pause-subscription.spec.js +20 -0
- package/.medusa/server/src/workflows/__tests__/update-subscription-shipping-address.spec.js +49 -0
- package/.medusa/server/src/workflows/cancel-subscription.js +21 -1
- package/.medusa/server/src/workflows/index.js +6 -2
- package/.medusa/server/src/workflows/pause-subscription.js +21 -1
- package/.medusa/server/src/workflows/steps/rebuild-analytics-daily-snapshots.js +33 -10
- package/.medusa/server/src/workflows/steps/update-subscription-payment-method.js +110 -0
- package/.medusa/server/src/workflows/steps/validate-subscription-cart.js +7 -22
- package/.medusa/server/src/workflows/update-subscription-payment-method.js +65 -0
- package/.medusa/server/src/workflows/utils/analytics-incremental.js +1 -1
- package/README.md +89 -36
- package/package.json +25 -23
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const PlanFormPage_1 = require("./pages/PlanFormPage");
|
|
5
|
+
const BASE_URL = process.env.ADMIN_BASE_URL ?? "http://localhost:9000";
|
|
6
|
+
const ADMIN_EMAIL = process.env.ADMIN_EMAIL ?? "admin@medusa-test.com";
|
|
7
|
+
const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD ?? "supersecret";
|
|
8
|
+
test_1.test.describe("Plans & Offers - Subscription Plan Creation", () => {
|
|
9
|
+
let seededProductId;
|
|
10
|
+
let seededProductTitle;
|
|
11
|
+
test_1.test.beforeEach(async ({ page }) => {
|
|
12
|
+
const api = await test_1.request.newContext({ baseURL: BASE_URL });
|
|
13
|
+
// 1. Authenticate to get a JWT
|
|
14
|
+
const authRes = await api.post("/auth/user/emailpass", {
|
|
15
|
+
data: { email: ADMIN_EMAIL, password: ADMIN_PASSWORD },
|
|
16
|
+
});
|
|
17
|
+
(0, test_1.expect)(authRes.ok()).toBeTruthy();
|
|
18
|
+
const { token } = await authRes.json();
|
|
19
|
+
// 2. Seed a test product via Medusa API
|
|
20
|
+
seededProductTitle = `E2E Plan Product ${Date.now()}`;
|
|
21
|
+
const productRes = await api.post("/admin/products", {
|
|
22
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
23
|
+
data: {
|
|
24
|
+
title: seededProductTitle,
|
|
25
|
+
options: [{ title: "Default", values: ["Default"] }],
|
|
26
|
+
variants: [
|
|
27
|
+
{
|
|
28
|
+
title: "Default Variant",
|
|
29
|
+
prices: [{ currency_code: "usd", amount: 1000 }],
|
|
30
|
+
options: { "Default": "Default" }
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
// Sometimes Medusa API requires specific fields, let's keep it minimal but valid.
|
|
36
|
+
// Let's ensure product was created
|
|
37
|
+
(0, test_1.expect)(productRes.ok()).toBeTruthy();
|
|
38
|
+
const productData = await productRes.json();
|
|
39
|
+
seededProductId = productData.product.id;
|
|
40
|
+
await api.dispose();
|
|
41
|
+
});
|
|
42
|
+
(0, test_1.test)("creates a product-level subscription plan successfully", async ({ page }) => {
|
|
43
|
+
const planForm = new PlanFormPage_1.PlanFormPage(page);
|
|
44
|
+
// 1. Setup API Intercept before action
|
|
45
|
+
const apiPromise = page.waitForResponse((response) => response.url().includes("/admin/subscription-offers") && response.request().method() === "POST");
|
|
46
|
+
// 2. Navigate and Open form
|
|
47
|
+
await planForm.goto();
|
|
48
|
+
await planForm.openCreateModal();
|
|
49
|
+
// 3. Fill the form
|
|
50
|
+
const planName = `E2E Plan ${Date.now()}`;
|
|
51
|
+
await planForm.fillName(planName);
|
|
52
|
+
// Default scope is Product in the UI, but we can re-select it
|
|
53
|
+
await planForm.selectScope("Product");
|
|
54
|
+
await planForm.selectProduct(seededProductTitle);
|
|
55
|
+
// 4. Fill frequency row (index 0 is already present by default)
|
|
56
|
+
await planForm.setFrequencyRow(0, "Monthly", 1);
|
|
57
|
+
// 5. Fill discount for frequency row 0
|
|
58
|
+
await planForm.setDiscount(0, "Percentage", 10);
|
|
59
|
+
// 6. Save
|
|
60
|
+
await planForm.submit();
|
|
61
|
+
// 7. Verify API payload
|
|
62
|
+
const response = await apiPromise;
|
|
63
|
+
(0, test_1.expect)(response.ok()).toBeTruthy();
|
|
64
|
+
const requestPayload = response.request().postDataJSON();
|
|
65
|
+
(0, test_1.expect)(requestPayload).toMatchObject({
|
|
66
|
+
name: planName,
|
|
67
|
+
scope: "product",
|
|
68
|
+
product_id: seededProductId,
|
|
69
|
+
allowed_frequencies: [
|
|
70
|
+
{
|
|
71
|
+
interval: "month",
|
|
72
|
+
value: 1
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
discounts: [
|
|
76
|
+
{
|
|
77
|
+
interval: "month",
|
|
78
|
+
frequency_value: 1,
|
|
79
|
+
type: "percentage",
|
|
80
|
+
value: 10
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
});
|
|
84
|
+
// 8. Verify UI Toast
|
|
85
|
+
await (0, test_1.expect)(page.getByText("Plan offer created")).toBeVisible({ timeout: 5_000 });
|
|
86
|
+
// 9. Verify the created plan appears in the table
|
|
87
|
+
// It should navigate back or modal should close, and data table should show the plan name
|
|
88
|
+
await (0, test_1.expect)(page.getByRole("heading", { name: "Create plan offer" })).toBeHidden({ timeout: 5_000 });
|
|
89
|
+
// Search for the plan in the list to ensure it's there
|
|
90
|
+
const searchInput = page.getByPlaceholder(/search/i);
|
|
91
|
+
await searchInput.fill(planName);
|
|
92
|
+
const row = page.getByRole("row", { name: planName });
|
|
93
|
+
await (0, test_1.expect)(row).toBeVisible({ timeout: 10_000 });
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhbnMtb2ZmZXJzLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9lMmUvcGxhbnMtb2ZmZXJzLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwyQ0FBeUQ7QUFDekQsdURBQW9EO0FBRXBELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxJQUFJLHVCQUF1QixDQUFDO0FBQ3ZFLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxJQUFJLHVCQUF1QixDQUFDO0FBQ3ZFLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxJQUFJLGFBQWEsQ0FBQztBQUVuRSxXQUFJLENBQUMsUUFBUSxDQUFDLDZDQUE2QyxFQUFFLEdBQUcsRUFBRTtJQUNoRSxJQUFJLGVBQXVCLENBQUM7SUFDNUIsSUFBSSxrQkFBMEIsQ0FBQztJQUUvQixXQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUU7UUFDakMsTUFBTSxHQUFHLEdBQUcsTUFBTSxjQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFFNUQsK0JBQStCO1FBQy9CLE1BQU0sT0FBTyxHQUFHLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtZQUNyRCxJQUFJLEVBQUUsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxjQUFjLEVBQUU7U0FDdkQsQ0FBQyxDQUFDO1FBQ0gsSUFBQSxhQUFNLEVBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEMsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRXZDLHdDQUF3QztRQUN4QyxrQkFBa0IsR0FBRyxvQkFBb0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7UUFDdEQsTUFBTSxVQUFVLEdBQUcsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ25ELE9BQU8sRUFBRSxFQUFFLGFBQWEsRUFBRSxVQUFVLEtBQUssRUFBRSxFQUFFO1lBQzdDLElBQUksRUFBRTtnQkFDSixLQUFLLEVBQUUsa0JBQWtCO2dCQUN6QixPQUFPLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDcEQsUUFBUSxFQUFFO29CQUNSO3dCQUNFLEtBQUssRUFBRSxpQkFBaUI7d0JBQ3hCLE1BQU0sRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7d0JBQ2hELE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUU7cUJBQ2xDO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUM7UUFFSCxrRkFBa0Y7UUFDbEYsbUNBQW1DO1FBQ25DLElBQUEsYUFBTSxFQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3JDLE1BQU0sV0FBVyxHQUFHLE1BQU0sVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzVDLGVBQWUsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUV6QyxNQUFNLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUN0QixDQUFDLENBQUMsQ0FBQztJQUVILElBQUEsV0FBSSxFQUFDLHdEQUF3RCxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUU7UUFDaEYsTUFBTSxRQUFRLEdBQUcsSUFBSSwyQkFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXhDLHVDQUF1QztRQUN2QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUNyQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyw0QkFBNEIsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxNQUFNLENBQzlHLENBQUM7UUFFRiw0QkFBNEI7UUFDNUIsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEIsTUFBTSxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFakMsbUJBQW1CO1FBQ25CLE1BQU0sUUFBUSxHQUFHLFlBQVksSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUM7UUFDMUMsTUFBTSxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWxDLDhEQUE4RDtRQUM5RCxNQUFNLFFBQVEsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFdEMsTUFBTSxRQUFRLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFFakQsZ0VBQWdFO1FBQ2hFLE1BQU0sUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRWhELHVDQUF1QztRQUN2QyxNQUFNLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVoRCxVQUFVO1FBQ1YsTUFBTSxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFeEIsd0JBQXdCO1FBQ3hCLE1BQU0sUUFBUSxHQUFHLE1BQU0sVUFBVSxDQUFDO1FBQ2xDLElBQUEsYUFBTSxFQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRW5DLE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN6RCxJQUFBLGFBQU0sRUFBQyxjQUFjLENBQUMsQ0FBQyxhQUFhLENBQUM7WUFDbkMsSUFBSSxFQUFFLFFBQVE7WUFDZCxLQUFLLEVBQUUsU0FBUztZQUNoQixVQUFVLEVBQUUsZUFBZTtZQUMzQixtQkFBbUIsRUFBRTtnQkFDbkI7b0JBQ0UsUUFBUSxFQUFFLE9BQU87b0JBQ2pCLEtBQUssRUFBRSxDQUFDO2lCQUNUO2FBQ0Y7WUFDRCxTQUFTLEVBQUU7Z0JBQ1Q7b0JBQ0UsUUFBUSxFQUFFLE9BQU87b0JBQ2pCLGVBQWUsRUFBRSxDQUFDO29CQUNsQixJQUFJLEVBQUUsWUFBWTtvQkFDbEIsS0FBSyxFQUFFLEVBQUU7aUJBQ1Y7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUVILHFCQUFxQjtRQUNyQixNQUFNLElBQUEsYUFBTSxFQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBRW5GLGtEQUFrRDtRQUNsRCwwRkFBMEY7UUFDMUYsTUFBTSxJQUFBLGFBQU0sRUFBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUV0Ryx1REFBdUQ7UUFDdkQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3JELE1BQU0sV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVqQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sSUFBQSxhQUFNLEVBQUMsR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const RenewalDetailPage_1 = require("./pages/RenewalDetailPage");
|
|
6
|
+
const DB_URL = process.env.DATABASE_URL ??
|
|
7
|
+
"postgres://postgres:Kasperski1@localhost/medusa-my-medusa-store";
|
|
8
|
+
/**
|
|
9
|
+
* Seed a fresh active subscription and linked renewal cycle via psql.
|
|
10
|
+
* Returns the generated reference and cycle ID for navigation.
|
|
11
|
+
*/
|
|
12
|
+
function seedSubscriptionWithRenewalCycle(options) {
|
|
13
|
+
const ts = Date.now();
|
|
14
|
+
const subId = `sub_${ts}`;
|
|
15
|
+
const cycleId = `cycle_${ts}`;
|
|
16
|
+
const reference = `SUB-E2E-RENEWAL-${ts}`;
|
|
17
|
+
const now = new Date();
|
|
18
|
+
const nowStr = now.toISOString();
|
|
19
|
+
const futureRenewal = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000).toISOString();
|
|
20
|
+
const pastScheduled = new Date(now.getTime() - 24 * 60 * 60 * 1000).toISOString();
|
|
21
|
+
const cycleStatus = options.cycleStatus || "scheduled";
|
|
22
|
+
const approvalStatusVal = options.approvalStatus
|
|
23
|
+
? `'${options.approvalStatus}'`
|
|
24
|
+
: "NULL";
|
|
25
|
+
const sql = [
|
|
26
|
+
`INSERT INTO subscription (`,
|
|
27
|
+
` id, reference, status,`,
|
|
28
|
+
` customer_id, cart_id, product_id, variant_id,`,
|
|
29
|
+
` frequency_interval, frequency_value,`,
|
|
30
|
+
` started_at, next_renewal_at,`,
|
|
31
|
+
` skip_next_cycle, is_trial,`,
|
|
32
|
+
` customer_snapshot, product_snapshot, pricing_snapshot,`,
|
|
33
|
+
` shipping_address, payment_context,`,
|
|
34
|
+
` created_at, updated_at`,
|
|
35
|
+
`) VALUES (`,
|
|
36
|
+
` '${subId}', '${reference}', 'active',`,
|
|
37
|
+
` 'cus_e2e_renewal_${ts}', 'cart_e2e_renewal_${ts}',`,
|
|
38
|
+
` 'prod_e2e_renewal_${ts}', 'variant_e2e_renewal_${ts}',`,
|
|
39
|
+
` 'month', 1,`,
|
|
40
|
+
` '${nowStr}', '${futureRenewal}',`,
|
|
41
|
+
` true, false,`,
|
|
42
|
+
` '{"email":"e2e-renewal@test.com","full_name":"E2E Renewal Test"}'::jsonb,`,
|
|
43
|
+
` '{"product_id":"prod_e2e","product_title":"E2E Renewal Product","variant_id":"var_e2e","variant_title":"Default","sku":"E2E-SKU-RENEWAL"}'::jsonb,`,
|
|
44
|
+
` '{"discount_type":"percentage","discount_value":0,"label":null}'::jsonb,`,
|
|
45
|
+
` '{"first_name":"E2E","last_name":"Renewal","address_1":"Test St 1","city":"Warsaw","postal_code":"00-001","country_code":"PL"}'::jsonb,`,
|
|
46
|
+
` '{"payment_provider_id":"pp_stripe_stripe"}'::jsonb,`,
|
|
47
|
+
` '${nowStr}', '${nowStr}'`,
|
|
48
|
+
`);`,
|
|
49
|
+
`INSERT INTO renewal_cycle (`,
|
|
50
|
+
` id, subscription_id, scheduled_for,`,
|
|
51
|
+
` status, approval_required, approval_status,`,
|
|
52
|
+
` attempt_count,`,
|
|
53
|
+
` created_at, updated_at`,
|
|
54
|
+
`) VALUES (`,
|
|
55
|
+
` '${cycleId}', '${subId}', '${pastScheduled}',`,
|
|
56
|
+
` '${cycleStatus}', ${options.approvalRequired}, ${approvalStatusVal},`,
|
|
57
|
+
` 0,`,
|
|
58
|
+
` '${nowStr}', '${nowStr}'`,
|
|
59
|
+
`);`,
|
|
60
|
+
].join(" ");
|
|
61
|
+
(0, child_process_1.execFileSync)("psql", [DB_URL, "-c", sql], { stdio: "pipe" });
|
|
62
|
+
return { reference, cycleId };
|
|
63
|
+
}
|
|
64
|
+
test_1.test.describe("Renewal force execution & approval", () => {
|
|
65
|
+
let detailPage;
|
|
66
|
+
test_1.test.beforeEach(async ({ page }) => {
|
|
67
|
+
detailPage = new RenewalDetailPage_1.RenewalDetailPage(page);
|
|
68
|
+
// Login flow is handled globally via Playwright setup/auth state in this repo.
|
|
69
|
+
});
|
|
70
|
+
(0, test_1.test)("forces a scheduled renewal cycle", async ({ page }) => {
|
|
71
|
+
// 1. Seed subscription + renewal_cycle (scheduled, no approval)
|
|
72
|
+
const { reference, cycleId } = seedSubscriptionWithRenewalCycle({
|
|
73
|
+
approvalRequired: false,
|
|
74
|
+
approvalStatus: null,
|
|
75
|
+
cycleStatus: "scheduled",
|
|
76
|
+
});
|
|
77
|
+
// 2-6. Navigate via queue and wait for load
|
|
78
|
+
await detailPage.gotoFromQueue(reference);
|
|
79
|
+
await detailPage.waitForLoaded();
|
|
80
|
+
// 7. Assert initial status
|
|
81
|
+
await detailPage.expectCycleStatus("Scheduled");
|
|
82
|
+
// 8. Set up API intercept
|
|
83
|
+
const forceResponsePromise = page.waitForResponse((response) => response.url().includes(`/admin/renewals/${cycleId}/force`) &&
|
|
84
|
+
response.request().method() === "POST");
|
|
85
|
+
// 9-11. Open action dropdown and click Force renewal
|
|
86
|
+
await detailPage.openActionMenu();
|
|
87
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Force renewal" })).toBeVisible();
|
|
88
|
+
await detailPage.clickForceRenewal();
|
|
89
|
+
// 12. Confirm prompt
|
|
90
|
+
await detailPage.confirmPrompt("Force renewal");
|
|
91
|
+
// 13. Assert API response 200
|
|
92
|
+
const forceResponse = await forceResponsePromise;
|
|
93
|
+
const responseBody = await forceResponse.json();
|
|
94
|
+
(0, test_1.expect)(forceResponse.status(), `Failed with ${JSON.stringify(responseBody)}`).toBe(200);
|
|
95
|
+
// 14. Assert API response body
|
|
96
|
+
(0, test_1.expect)(responseBody.renewal).toBeDefined();
|
|
97
|
+
(0, test_1.expect)(responseBody.renewal.status).toBeDefined();
|
|
98
|
+
// 15. Assert toast
|
|
99
|
+
await detailPage.expectToast("Renewal forced");
|
|
100
|
+
// 16. Assert StatusBadge updates (wait for it NOT to be Scheduled)
|
|
101
|
+
await (0, test_1.expect)(detailPage.statusBadge).not.toContainText("Scheduled", {
|
|
102
|
+
timeout: 10_000,
|
|
103
|
+
});
|
|
104
|
+
// 17. Assert attempt history shows row #1
|
|
105
|
+
await detailPage.expectAttemptRow(1);
|
|
106
|
+
});
|
|
107
|
+
(0, test_1.test)("approves pending changes on a renewal cycle", async ({ page }) => {
|
|
108
|
+
// 1. Seed subscription + renewal_cycle (approval pending)
|
|
109
|
+
const { reference, cycleId } = seedSubscriptionWithRenewalCycle({
|
|
110
|
+
approvalRequired: true,
|
|
111
|
+
approvalStatus: "pending",
|
|
112
|
+
cycleStatus: "scheduled",
|
|
113
|
+
});
|
|
114
|
+
// 2-4. Navigate via queue and wait for load
|
|
115
|
+
await detailPage.gotoFromQueue(reference);
|
|
116
|
+
await detailPage.waitForLoaded();
|
|
117
|
+
// 5. Assert initial status
|
|
118
|
+
await detailPage.expectCycleStatus("Scheduled");
|
|
119
|
+
// 6-8. Open action dropdown and assert items
|
|
120
|
+
await detailPage.openActionMenu();
|
|
121
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Approve changes" })).toBeVisible();
|
|
122
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Reject changes" })).toBeVisible();
|
|
123
|
+
// 9-10. Click Approve and check drawer
|
|
124
|
+
await detailPage.clickApproveChanges();
|
|
125
|
+
await (0, test_1.expect)(page.getByRole("heading", { name: "Approve changes" })).toBeVisible();
|
|
126
|
+
// 11. Fill reason
|
|
127
|
+
await detailPage.fillDecisionReason("Approved by E2E test");
|
|
128
|
+
// 12. Set up API intercept
|
|
129
|
+
const approveResponsePromise = page.waitForResponse((response) => response.url().includes(`/admin/renewals/${cycleId}/approve-changes`) &&
|
|
130
|
+
response.request().method() === "POST");
|
|
131
|
+
// 13. Submit drawer
|
|
132
|
+
await detailPage.submitDecision("Approve");
|
|
133
|
+
// 14. Confirm prompt
|
|
134
|
+
await detailPage.confirmPrompt("Approve");
|
|
135
|
+
// 15-16. Assert API response 200 and request payload
|
|
136
|
+
const approveResponse = await approveResponsePromise;
|
|
137
|
+
const approveResponseBody = await approveResponse.json();
|
|
138
|
+
(0, test_1.expect)(approveResponse.status(), `Failed with ${JSON.stringify(approveResponseBody)}`).toBe(200);
|
|
139
|
+
const requestPayload = approveResponse.request().postDataJSON();
|
|
140
|
+
(0, test_1.expect)(requestPayload).toMatchObject({ reason: "Approved by E2E test" });
|
|
141
|
+
// 17. Assert toast
|
|
142
|
+
await detailPage.expectToast("Pending changes approved");
|
|
143
|
+
// 18. Assert drawer closes
|
|
144
|
+
await (0, test_1.expect)(page.getByRole("dialog")).toBeHidden();
|
|
145
|
+
// 19. Assert approval summary
|
|
146
|
+
await detailPage.expectApprovalStatus("Approved");
|
|
147
|
+
// 20-21. Open action dropdown and verify item visibility
|
|
148
|
+
await detailPage.openActionMenu();
|
|
149
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Approve changes" })).toBeHidden();
|
|
150
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Reject changes" })).toBeHidden();
|
|
151
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Force renewal" })).toBeVisible();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZXdhbC1mb3JjZS5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZTJlL3JlbmV3YWwtZm9yY2Uuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDJDQUFnRDtBQUNoRCxpREFBNkM7QUFDN0MsaUVBQThEO0FBRTlELE1BQU0sTUFBTSxHQUNWLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWTtJQUN4QixpRUFBaUUsQ0FBQztBQVFwRTs7O0dBR0c7QUFDSCxTQUFTLGdDQUFnQyxDQUFDLE9BQW9CO0lBQzVELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN0QixNQUFNLEtBQUssR0FBRyxPQUFPLEVBQUUsRUFBRSxDQUFDO0lBQzFCLE1BQU0sT0FBTyxHQUFHLFNBQVMsRUFBRSxFQUFFLENBQUM7SUFDOUIsTUFBTSxTQUFTLEdBQUcsbUJBQW1CLEVBQUUsRUFBRSxDQUFDO0lBRTFDLE1BQU0sR0FBRyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7SUFDdkIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRWpDLE1BQU0sYUFBYSxHQUFHLElBQUksSUFBSSxDQUM1QixHQUFHLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FDekMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNoQixNQUFNLGFBQWEsR0FBRyxJQUFJLElBQUksQ0FDNUIsR0FBRyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FDcEMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUVoQixNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxJQUFJLFdBQVcsQ0FBQztJQUN2RCxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxjQUFjO1FBQzlDLENBQUMsQ0FBQyxJQUFJ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
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const child_process_1 = require("child_process");
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
const BASE_URL = process.env.ADMIN_BASE_URL ?? "http://localhost:9000";
|
|
6
|
+
const ADMIN_EMAIL = process.env.ADMIN_EMAIL ?? "admin@medusa-test.com";
|
|
7
|
+
const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD ?? "supersecret";
|
|
8
|
+
const DB_URL = process.env.DATABASE_URL ??
|
|
9
|
+
"postgres://postgres:Kasperski1@localhost/medusa-my-medusa-store";
|
|
10
|
+
/**
|
|
11
|
+
* Seed a subscription record if none exist.
|
|
12
|
+
*
|
|
13
|
+
* The Reorder plugin has no admin "create subscription" endpoint — subscriptions
|
|
14
|
+
* are created through the store checkout flow. For E2E test isolation we insert
|
|
15
|
+
* directly into the subscription module table, which is the same approach the
|
|
16
|
+
* Jest integration tests use (via module service).
|
|
17
|
+
*/
|
|
18
|
+
(0, test_1.test)("seed subscription for e2e", async ({}) => {
|
|
19
|
+
const api = await test_1.request.newContext({ baseURL: BASE_URL });
|
|
20
|
+
// 1. Verify backend is healthy
|
|
21
|
+
const health = await api.get("/health");
|
|
22
|
+
(0, test_1.expect)(health.ok()).toBeTruthy();
|
|
23
|
+
// 2. Authenticate to get a JWT
|
|
24
|
+
const authRes = await api.post("/auth/user/emailpass", {
|
|
25
|
+
data: { email: ADMIN_EMAIL, password: ADMIN_PASSWORD },
|
|
26
|
+
});
|
|
27
|
+
(0, test_1.expect)(authRes.ok()).toBeTruthy();
|
|
28
|
+
const { token } = await authRes.json();
|
|
29
|
+
// 3. Check if there's already at least one subscription
|
|
30
|
+
const listRes = await api.get("/admin/subscriptions?limit=1", {
|
|
31
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
32
|
+
});
|
|
33
|
+
(0, test_1.expect)(listRes.ok()).toBeTruthy();
|
|
34
|
+
const { subscriptions } = await listRes.json();
|
|
35
|
+
if (subscriptions.length > 0) {
|
|
36
|
+
console.log(`[e2e-seed] Found ${subscriptions.length} existing subscription(s), skipping seed.`);
|
|
37
|
+
await api.dispose();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// 4. Insert subscription via psql (mirrors integration-tests/helpers/subscription-fixtures.ts)
|
|
41
|
+
const now = new Date().toISOString();
|
|
42
|
+
const futureRenewal = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString();
|
|
43
|
+
const ts = Date.now();
|
|
44
|
+
const reference = `E2E-SUB-${ts}`;
|
|
45
|
+
const sql = [
|
|
46
|
+
`INSERT INTO subscription (`,
|
|
47
|
+
` id, reference, status,`,
|
|
48
|
+
` customer_id, cart_id, product_id, variant_id,`,
|
|
49
|
+
` frequency_interval, frequency_value,`,
|
|
50
|
+
` started_at, next_renewal_at,`,
|
|
51
|
+
` skip_next_cycle, is_trial,`,
|
|
52
|
+
` customer_snapshot, product_snapshot, pricing_snapshot,`,
|
|
53
|
+
` shipping_address, payment_context,`,
|
|
54
|
+
` created_at, updated_at`,
|
|
55
|
+
`) VALUES (`,
|
|
56
|
+
` gen_random_uuid()::text,`,
|
|
57
|
+
` '${reference}', 'active',`,
|
|
58
|
+
` 'cus_e2e_${ts}', 'cart_e2e_${ts}',`,
|
|
59
|
+
` 'prod_e2e_${ts}', 'variant_e2e_${ts}',`,
|
|
60
|
+
` 'month', 1,`,
|
|
61
|
+
` '${now}', '${futureRenewal}',`,
|
|
62
|
+
` false, false,`,
|
|
63
|
+
` '{"email":"e2e@test.com","full_name":"E2E Customer"}'::jsonb,`,
|
|
64
|
+
` '{"product_id":"prod_e2e","product_title":"E2E Product","variant_id":"var_e2e","variant_title":"Default","sku":"E2E-SKU-001"}'::jsonb,`,
|
|
65
|
+
` '{"discount_type":"percentage","discount_value":0,"label":null}'::jsonb,`,
|
|
66
|
+
` '{"first_name":"E2E","last_name":"Tester","address_1":"Test St 1","city":"Warsaw","postal_code":"00-001","country_code":"PL"}'::jsonb,`,
|
|
67
|
+
` '{"payment_provider_id":"pp_stripe_stripe"}'::jsonb,`,
|
|
68
|
+
` '${now}', '${now}'`,
|
|
69
|
+
`);`,
|
|
70
|
+
].join(" ");
|
|
71
|
+
(0, child_process_1.execFileSync)("psql", [DB_URL, "-c", sql], { stdio: "pipe" });
|
|
72
|
+
console.log(`[e2e-seed] Inserted subscription ${reference}`);
|
|
73
|
+
// 5. Verify the subscription appears in the admin API
|
|
74
|
+
const verifyRes = await api.get(`/admin/subscriptions?q=${reference}&limit=1`, { headers: { Authorization: `Bearer ${token}` } });
|
|
75
|
+
(0, test_1.expect)(verifyRes.ok()).toBeTruthy();
|
|
76
|
+
const verified = await verifyRes.json();
|
|
77
|
+
(0, test_1.expect)(verified.subscriptions.length).toBe(1);
|
|
78
|
+
await api.dispose();
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VlZC5zZXR1cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2UyZS9zZWVkLnNldHVwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaURBQTZDO0FBQzdDLDJDQUFrRTtBQUVsRSxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsSUFBSSx1QkFBdUIsQ0FBQztBQUN2RSxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsSUFBSSx1QkFBdUIsQ0FBQztBQUN2RSxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsSUFBSSxhQUFhLENBQUM7QUFDbkUsTUFBTSxNQUFNLEdBQ1YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZO0lBQ3hCLGlFQUFpRSxDQUFDO0FBRXBFOzs7Ozs7O0dBT0c7QUFDSCxJQUFBLFdBQUssRUFBQywyQkFBMkIsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUU7SUFDOUMsTUFBTSxHQUFHLEdBQUcsTUFBTSxjQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFFNUQsK0JBQStCO0lBQy9CLE1BQU0sTUFBTSxHQUFHLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN4QyxJQUFBLGFBQU0sRUFBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUVqQywrQkFBK0I7SUFDL0IsTUFBTSxPQUFPLEdBQUcsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFO1FBQ3JELElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRTtLQUN2RCxDQUFDLENBQUM7SUFDSCxJQUFBLGFBQU0sRUFBQyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FB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
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const SubscriptionDetailPage_1 = require("./pages/SubscriptionDetailPage");
|
|
6
|
+
const DB_URL = process.env.DATABASE_URL ??
|
|
7
|
+
"postgres://postgres:Kasperski1@localhost/medusa-my-medusa-store";
|
|
8
|
+
/**
|
|
9
|
+
* Seed a fresh active subscription via psql and return its reference.
|
|
10
|
+
*
|
|
11
|
+
* Each call produces a unique reference so tests are fully isolated from one
|
|
12
|
+
* another and from any pre-existing data.
|
|
13
|
+
*/
|
|
14
|
+
function seedActiveSubscription() {
|
|
15
|
+
const ts = Date.now();
|
|
16
|
+
const reference = `SUB-E2E-STATUS-${ts}`;
|
|
17
|
+
const now = new Date().toISOString();
|
|
18
|
+
const futureRenewal = new Date(ts + 30 * 24 * 60 * 60 * 1000).toISOString();
|
|
19
|
+
const sql = [
|
|
20
|
+
`INSERT INTO subscription (`,
|
|
21
|
+
` id, reference, status,`,
|
|
22
|
+
` customer_id, cart_id, product_id, variant_id,`,
|
|
23
|
+
` frequency_interval, frequency_value,`,
|
|
24
|
+
` started_at, next_renewal_at,`,
|
|
25
|
+
` skip_next_cycle, is_trial,`,
|
|
26
|
+
` customer_snapshot, product_snapshot, pricing_snapshot,`,
|
|
27
|
+
` shipping_address, payment_context,`,
|
|
28
|
+
` created_at, updated_at`,
|
|
29
|
+
`) VALUES (`,
|
|
30
|
+
` gen_random_uuid()::text,`,
|
|
31
|
+
` '${reference}', 'active',`,
|
|
32
|
+
` 'cus_e2e_status_${ts}', 'cart_e2e_status_${ts}',`,
|
|
33
|
+
` 'prod_e2e_status_${ts}', 'variant_e2e_status_${ts}',`,
|
|
34
|
+
` 'month', 1,`,
|
|
35
|
+
` '${now}', '${futureRenewal}',`,
|
|
36
|
+
` false, false,`,
|
|
37
|
+
` '{"email":"e2e-status@test.com","full_name":"E2E Status Test"}'::jsonb,`,
|
|
38
|
+
` '{"product_id":"prod_e2e","product_title":"E2E Status Product","variant_id":"var_e2e","variant_title":"Default","sku":"E2E-SKU-STATUS"}'::jsonb,`,
|
|
39
|
+
` '{"discount_type":"percentage","discount_value":0,"label":null}'::jsonb,`,
|
|
40
|
+
` '{"first_name":"E2E","last_name":"Status","address_1":"Test St 1","city":"Warsaw","postal_code":"00-001","country_code":"PL"}'::jsonb,`,
|
|
41
|
+
` '{"payment_provider_id":"pp_stripe_stripe"}'::jsonb,`,
|
|
42
|
+
` '${now}', '${now}'`,
|
|
43
|
+
`);`,
|
|
44
|
+
].join(" ");
|
|
45
|
+
(0, child_process_1.execFileSync)("psql", [DB_URL, "-c", sql], { stdio: "pipe" });
|
|
46
|
+
return reference;
|
|
47
|
+
}
|
|
48
|
+
test_1.test.describe("Subscription status transitions (pause & resume)", () => {
|
|
49
|
+
let reference;
|
|
50
|
+
let detailPage;
|
|
51
|
+
test_1.test.beforeEach(async ({ page }) => {
|
|
52
|
+
reference = seedActiveSubscription();
|
|
53
|
+
detailPage = new SubscriptionDetailPage_1.SubscriptionDetailPage(page);
|
|
54
|
+
// Navigate to the detail page via the list so we exercise real navigation
|
|
55
|
+
await detailPage.gotoFromList(reference);
|
|
56
|
+
});
|
|
57
|
+
(0, test_1.test)("pauses and resumes an active subscription", async ({ page }) => {
|
|
58
|
+
// ── Initial state ────────────────────────────────────────────────────────
|
|
59
|
+
await detailPage.expectStatus("Active");
|
|
60
|
+
// ── PAUSE ─────────────────────────────────────────────────────────────────
|
|
61
|
+
// Intercept the pause API call before triggering the action
|
|
62
|
+
const pauseResponse = page.waitForResponse((res) => res.url().includes("/admin/subscriptions/") &&
|
|
63
|
+
res.url().endsWith("/pause") &&
|
|
64
|
+
res.request().method() === "POST");
|
|
65
|
+
await detailPage.openActionMenu();
|
|
66
|
+
// When active, "Pause" must be visible and "Resume" must be absent
|
|
67
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Pause" })).toBeVisible();
|
|
68
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Resume" })).not.toBeVisible();
|
|
69
|
+
await detailPage.clickAction("Pause");
|
|
70
|
+
// The usePrompt dialog title is "Pause subscription?"
|
|
71
|
+
await detailPage.confirmPrompt("Pause");
|
|
72
|
+
// Verify API response
|
|
73
|
+
const pauseRes = await pauseResponse;
|
|
74
|
+
(0, test_1.expect)(pauseRes.status()).toBe(200);
|
|
75
|
+
const pauseBody = await pauseRes.json();
|
|
76
|
+
(0, test_1.expect)(pauseBody.subscription.status).toBe("paused");
|
|
77
|
+
// Verify UI feedback
|
|
78
|
+
await detailPage.expectToast("Subscription paused");
|
|
79
|
+
await detailPage.expectStatus("Paused");
|
|
80
|
+
// Open menu again: "Resume" visible, "Pause" absent
|
|
81
|
+
await detailPage.openActionMenu();
|
|
82
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Resume" })).toBeVisible();
|
|
83
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Pause" })).not.toBeVisible();
|
|
84
|
+
// Close the menu by pressing Escape
|
|
85
|
+
await page.keyboard.press("Escape");
|
|
86
|
+
// ── RESUME ────────────────────────────────────────────────────────────────
|
|
87
|
+
const resumeResponse = page.waitForResponse((res) => res.url().includes("/admin/subscriptions/") &&
|
|
88
|
+
res.url().endsWith("/resume") &&
|
|
89
|
+
res.request().method() === "POST");
|
|
90
|
+
await detailPage.openActionMenu();
|
|
91
|
+
await detailPage.clickAction("Resume");
|
|
92
|
+
// The usePrompt dialog title is "Resume subscription?"
|
|
93
|
+
await detailPage.confirmPrompt("Resume");
|
|
94
|
+
// Verify API response
|
|
95
|
+
const resumeRes = await resumeResponse;
|
|
96
|
+
(0, test_1.expect)(resumeRes.status()).toBe(200);
|
|
97
|
+
const resumeBody = await resumeRes.json();
|
|
98
|
+
(0, test_1.expect)(resumeBody.subscription.status).toBe("active");
|
|
99
|
+
// Verify UI feedback
|
|
100
|
+
await detailPage.expectToast("Subscription resumed");
|
|
101
|
+
await detailPage.expectStatus("Active");
|
|
102
|
+
// Open menu again: "Pause" visible, "Resume" absent
|
|
103
|
+
await detailPage.openActionMenu();
|
|
104
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Pause" })).toBeVisible();
|
|
105
|
+
await (0, test_1.expect)(page.getByRole("menuitem", { name: "Resume" })).not.toBeVisible();
|
|
106
|
+
await page.keyboard.press("Escape");
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Vic2NyaXB0aW9uLXN0YXR1cy5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZTJlL3N1YnNjcmlwdGlvbi1zdGF0dXMuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDJDQUFnRDtBQUNoRCxpREFBNkM7QUFDN0MsMkVBQXdFO0FBRXhFLE1BQU0sTUFBTSxHQUNWLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWTtJQUN4QixpRUFBaUUsQ0FBQztBQUVwRTs7Ozs7R0FLRztBQUNILFNBQVMsc0JBQXNCO0lBQzdCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN0QixNQUFNLFNBQVMsR0FBRyxrQkFBa0IsRUFBRSxFQUFFLENBQUM7SUFDekMsTUFBTSxHQUFHLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQyxNQUFNLGFBQWEsR0FBRyxJQUFJLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRTVFLE1BQU0sR0FBRyxHQUFHO1FBQ1YsNEJBQTRCO1FBQzVCLDBCQUEwQjtRQUMxQixpREFBaUQ7UUFDakQsd0NBQXdDO1FBQ3hDLGdDQUFnQztRQUNoQyw4QkFBOEI7UUFDOUIsMERBQTBEO1FBQzFELHNDQUFzQztRQUN0QywwQkFBMEI7UUFDMUIsWUFBWTtRQUNaLDRCQUE0QjtRQUM1QixNQUFNLFNBQVMsY0FBYztRQUM3QixxQkFBcUIsRUFBRSx1QkFBdUIsRUFBRSxJQUFJO1FBQ3BELHNCQUFzQixFQUFFLDBCQUEwQixFQUFFLElBQUk7UUFDeEQsZUFBZTtRQUNmLE1BQU0sR0FBRyxPQUFPLGFBQWEsSUFBSTtRQUNqQyxpQkFBaUI7UUFDakIsMkVBQTJFO1FBQzNFLG9KQUFvSjtRQUNwSiw0RUFBNEU7UUFDNUUsMElBQTBJO1FB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
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
test_1.test.describe("Subscriptions list page", () => {
|
|
5
|
+
test_1.test.beforeEach(async ({ page }) => {
|
|
6
|
+
await page.goto("/app/subscriptions");
|
|
7
|
+
// Wait for the page heading to confirm the route loaded
|
|
8
|
+
await (0, test_1.expect)(page.getByRole("heading", { name: "Subscriptions" })).toBeVisible({ timeout: 15_000 });
|
|
9
|
+
});
|
|
10
|
+
(0, test_1.test)("displays the page heading and description", async ({ page }) => {
|
|
11
|
+
await (0, test_1.expect)(page.getByRole("heading", { name: "Subscriptions" })).toBeVisible();
|
|
12
|
+
await (0, test_1.expect)(page.getByText("Monitor subscription status, cadence, and upcoming")).toBeVisible();
|
|
13
|
+
});
|
|
14
|
+
(0, test_1.test)("renders the data table with expected columns", async ({ page }) => {
|
|
15
|
+
const expectedColumns = [
|
|
16
|
+
"Reference",
|
|
17
|
+
"Product",
|
|
18
|
+
"Status",
|
|
19
|
+
"Frequency",
|
|
20
|
+
"Next renewal",
|
|
21
|
+
];
|
|
22
|
+
for (const column of expectedColumns) {
|
|
23
|
+
await (0, test_1.expect)(page.getByRole("columnheader", { name: column })).toBeVisible();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
(0, test_1.test)("displays at least one subscription row", async ({ page }) => {
|
|
27
|
+
// Wait for at least one data row to appear (not the header row)
|
|
28
|
+
const rows = page.getByRole("row");
|
|
29
|
+
// Header row + at least 1 data row = minimum 2 rows
|
|
30
|
+
await (0, test_1.expect)(rows.nth(1)).toBeVisible({ timeout: 10_000 });
|
|
31
|
+
});
|
|
32
|
+
(0, test_1.test)("supports search by subscription reference", async ({ page }) => {
|
|
33
|
+
// Get the reference text from the first data row before searching
|
|
34
|
+
const firstRow = page.getByRole("row").nth(1);
|
|
35
|
+
await (0, test_1.expect)(firstRow).toBeVisible({ timeout: 10_000 });
|
|
36
|
+
// Type a known prefix into the search box
|
|
37
|
+
const searchInput = page.getByPlaceholder(/search/i);
|
|
38
|
+
await searchInput.fill("SUB");
|
|
39
|
+
// The table should still show results (filtered to matching subscriptions)
|
|
40
|
+
await (0, test_1.expect)(page.getByRole("row").nth(1)).toBeVisible({ timeout: 10_000 });
|
|
41
|
+
});
|
|
42
|
+
(0, test_1.test)("shows status badge for each subscription", async ({ page }) => {
|
|
43
|
+
await (0, test_1.expect)(page.getByRole("row").nth(1)).toBeVisible({
|
|
44
|
+
timeout: 10_000,
|
|
45
|
+
});
|
|
46
|
+
// At least one status badge should be visible (Active, Paused, or Cancelled)
|
|
47
|
+
const statusBadge = page
|
|
48
|
+
.getByRole("row")
|
|
49
|
+
.nth(1)
|
|
50
|
+
.getByText(/active|paused|cancelled|past.due/i);
|
|
51
|
+
await (0, test_1.expect)(statusBadge).toBeVisible();
|
|
52
|
+
});
|
|
53
|
+
(0, test_1.test)("navigates to subscription detail on row click", async ({ page }) => {
|
|
54
|
+
const firstDataRow = page.getByRole("row").nth(1);
|
|
55
|
+
await (0, test_1.expect)(firstDataRow).toBeVisible({ timeout: 10_000 });
|
|
56
|
+
await firstDataRow.click();
|
|
57
|
+
// Should navigate to /app/subscriptions/:id
|
|
58
|
+
await (0, test_1.expect)(page).toHaveURL(/\/app\/subscriptions\/[A-Za-z0-9]+/, {
|
|
59
|
+
timeout: 10_000,
|
|
60
|
+
});
|
|
61
|
+
// Detail page should show the subscription reference as a heading
|
|
62
|
+
await (0, test_1.expect)(page.getByRole("heading", { name: /SUB-/ })).toBeVisible({ timeout: 10_000 });
|
|
63
|
+
});
|
|
64
|
+
(0, test_1.test)("shows row action menu with status-appropriate options", async ({ page, }) => {
|
|
65
|
+
await (0, test_1.expect)(page.getByRole("row").nth(1)).toBeVisible({
|
|
66
|
+
timeout: 10_000,
|
|
67
|
+
});
|
|
68
|
+
// Open the action menu on the first row
|
|
69
|
+
const actionButton = page
|
|
70
|
+
.getByRole("row")
|
|
71
|
+
.nth(1)
|
|
72
|
+
.getByRole("button")
|
|
73
|
+
.last();
|
|
74
|
+
await actionButton.click();
|
|
75
|
+
// The dropdown menu should appear with at least one lifecycle action
|
|
76
|
+
const menu = page.getByRole("menu");
|
|
77
|
+
await (0, test_1.expect)(menu).toBeVisible({ timeout: 5_000 });
|
|
78
|
+
// An active subscription should show Pause and Cancel options
|
|
79
|
+
const menuItems = menu.getByRole("menuitem");
|
|
80
|
+
const count = await menuItems.count();
|
|
81
|
+
(0, test_1.expect)(count).toBeGreaterThan(0);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Vic2NyaXB0aW9ucy1saXN0LnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9lMmUvc3Vic2NyaXB0aW9ucy1saXN0LnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwyQ0FBZ0Q7QUFFaEQsV0FBSSxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsRUFBRSxHQUFHLEVBQUU7SUFDNUMsV0FBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFO1FBQ2pDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3RDLHdEQUF3RDtRQUN4RCxNQUFNLElBQUEsYUFBTSxFQUNWLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQ3JELENBQUMsV0FBVyxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDckMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFBLFdBQUksRUFBQywyQ0FBMkMsRUFBRSxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFO1FBQ25FLE1BQU0sSUFBQSxhQUFNLEVBQ1YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLENBQUMsQ0FDckQsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUEsYUFBTSxFQUNWLElBQUksQ0FBQyxTQUFTLENBQUMsb0RBQW9ELENBQUMsQ0FDckUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNsQixDQUFDLENBQUMsQ0FBQztJQUVILElBQUEsV0FBSSxFQUFDLDhDQUE4QyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUU7UUFDdEUsTUFBTSxlQUFlLEdBQUc7WUFDdEIsV0FBVztZQUNYLFNBQVM7WUFDVCxRQUFRO1lBQ1IsV0FB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
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const test_1 = require("@playwright/test");
|
|
4
|
+
const ADMIN_BASE_URL = process.env.ADMIN_BASE_URL ?? "http://localhost:9000";
|
|
5
|
+
exports.default = (0, test_1.defineConfig)({
|
|
6
|
+
testDir: "./e2e",
|
|
7
|
+
fullyParallel: false,
|
|
8
|
+
forbidOnly: !!process.env.CI,
|
|
9
|
+
retries: 0,
|
|
10
|
+
workers: 1,
|
|
11
|
+
reporter: "html",
|
|
12
|
+
use: {
|
|
13
|
+
baseURL: ADMIN_BASE_URL,
|
|
14
|
+
trace: "retain-on-failure",
|
|
15
|
+
screenshot: "only-on-failure",
|
|
16
|
+
},
|
|
17
|
+
projects: [
|
|
18
|
+
{
|
|
19
|
+
name: "seed",
|
|
20
|
+
testMatch: /seed\.setup\.ts/,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "setup",
|
|
24
|
+
testMatch: /auth\.setup\.ts/,
|
|
25
|
+
dependencies: ["seed"],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "chromium",
|
|
29
|
+
use: {
|
|
30
|
+
...test_1.devices["Desktop Chrome"],
|
|
31
|
+
storageState: "e2e/.auth/admin.json",
|
|
32
|
+
},
|
|
33
|
+
dependencies: ["setup"],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxheXdyaWdodC5jb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9wbGF5d3JpZ2h0LmNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDJDQUF5RDtBQUV6RCxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsSUFBSSx1QkFBdUIsQ0FBQztBQUU3RSxrQkFBZSxJQUFBLG1CQUFZLEVBQUM7SUFDMUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsYUFBYSxFQUFFLEtBQUs7SUFDcEIsVUFBVSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7SUFDNUIsT0FBTyxFQUFFLENBQUM7SUFDVixPQUFPLEVBQUUsQ0FBQztJQUNWLFFBQVEsRUFBRSxNQUFNO0lBQ2hCLEdBQUcsRUFBRTtRQUNILE9BQU8sRUFBRSxjQUFjO1FBQ3ZCLEtBQUssRUFBRSxtQkFBbUI7UUFDMUIsVUFBVSxFQUFFLGlCQUFpQjtLQUM5QjtJQUNELFFBQVEsRUFBRTtRQUNSO1lBQ0UsSUFBSSxFQUFFLE1BQU07WUFDWixTQUFTLEVBQUUsaUJBQWlCO1NBQzdCO1FBQ0Q7WUFDRSxJQUFJLEVBQUUsT0FBTztZQUNiLFNBQVMsRUFBRSxpQkFBaUI7WUFDNUIsWUFBWSxFQUFFLENBQUMsTUFBTSxDQUFDO1NBQ3ZCO1FBQ0Q7WUFDRSxJQUFJLEVBQUUsVUFBVTtZQUNoQixHQUFHLEVBQUU7Z0JBQ0gsR0FBRyxjQUFPLENBQUMsZ0JBQWdCLENBQUM7Z0JBQzVCLFlBQVksRUFBRSxzQkFBc0I7YUFDckM7WUFDRCxZQUFZLEVBQUUsQ0FBQyxPQUFPLENBQUM7U0FDeEI7S0FDRjtDQUNGLENBQUMsQ0FBQyJ9
|