Update UI, improve E2E tests and modify trial period configuration

The code changes incorporate UI updates for better usability and user experience. E2E test scripts(in `user-billing.spec.ts` and `team-billing.spec.ts`) were also updated for improved efficiency and accuracy, primarily replacing 'Active' status check with 'Trial'. Changes have been made in the trialDays configuration, with the term 'trialPeriod' now replaced by 'trialDays' across different components. Notably, a new error handling case is included in `lemon-squeezy-billing-strategy.service.ts` for failed subscription cancellation attempts.
This commit is contained in:
giancarlo
2024-04-15 01:18:27 +08:00
parent 26f1371283
commit 4e305bf8c9
14 changed files with 69 additions and 86 deletions

View File

@@ -13,7 +13,7 @@ test.describe('Team Billing', () => {
await po.teamAccounts.goToBilling();
});
test('a team can subscribe to a plan', async ({page}) => {
test('a team can subscribe to a plan', async () => {
await po.billing.selectPlan(0);
await po.billing.proceedToCheckout();
@@ -25,7 +25,7 @@ test.describe('Team Billing', () => {
await po.teamAccounts.goToBilling();
await expect(await po.billing.getStatus()).toContainText('Active');
await expect(await po.billing.getStatus()).toContainText('Trial');
await expect(po.billing.manageBillingButton()).toBeVisible();
});
});

View File

@@ -22,15 +22,13 @@ test.describe('User Billing', () => {
await expect(po.billing.successStatus()).toBeVisible();
await po.billing.returnToHome();
await page.waitForURL('http://localhost:3000/home');
const link = page.locator('button', {
hasText: 'Billing'
});
await link.click();
await expect(await po.billing.getStatus()).toContainText('Active');
await expect(await po.billing.getStatus()).toContainText('Trial');
await expect(po.billing.manageBillingButton()).toBeVisible();
});
});

View File

@@ -1,4 +1,4 @@
import { expect, Page } from '@playwright/test';
import { Page } from '@playwright/test';
import { StripePageObject } from './stripe.po';
export class BillingPageObject {
@@ -32,7 +32,7 @@ export class BillingPageObject {
// wait a bit for the webhook to be processed
await this.page.waitForTimeout(1000);
return this.page.locator('[data-test="checkout-success-back-link"]').click();
return this.page.locator('[data-test="checkout-success-back-link"] button').click();
}
proceedToCheckout() {

View File

@@ -8,6 +8,7 @@ import { Alert, AlertDescription, AlertTitle } from '@kit/ui/alert';
import { If } from '@kit/ui/if';
import { PageBody, PageHeader } from '@kit/ui/page';
import { Trans } from '@kit/ui/trans';
import { cn } from '@kit/ui/utils';
import { createBillingPortalSession } from '~/(dashboard)/home/[account]/billing/server-actions';
import billingConfig from '~/config/billing.config';
@@ -75,13 +76,17 @@ async function TeamAccountBillingPage({ params }: Params) {
/>
<PageBody>
<div className={'mx-auto flex w-full max-w-2xl flex-col space-y-6'}>
<div
className={cn(`flex w-full flex-col space-y-6`, {
'mx-auto max-w-2xl ': subscription,
})}
>
<If
condition={subscription}
fallback={
<>
<div>
<Checkout />
</>
</div>
}
>
{(subscription) => (

View File

@@ -1,3 +1,4 @@
import { revalidatePath } from 'next/cache';
import dynamic from 'next/dynamic';
import { notFound, redirect } from 'next/navigation';
@@ -7,17 +8,12 @@ import { requireUser } from '@kit/supabase/require-user';
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
import billingConfig from '~/config/billing.config';
import pathsConfig from '~/config/paths.config';
import { withI18n } from '~/lib/i18n/with-i18n';
interface SessionPageProps {
searchParams: {
session_id: string;
};
params: {
account: string;
};
}
const LazyEmbeddedCheckout = dynamic(
@@ -31,10 +27,7 @@ const LazyEmbeddedCheckout = dynamic(
},
);
async function ReturnCheckoutSessionPage({
searchParams,
params,
}: SessionPageProps) {
async function ReturnCheckoutSessionPage({ searchParams }: SessionPageProps) {
const sessionId = searchParams.session_id;
if (!sessionId) {
@@ -52,17 +45,12 @@ async function ReturnCheckoutSessionPage({
);
}
const redirectPath = pathsConfig.app.accountHome.replace(
'[account]',
params.account,
);
return (
<>
<div className={'fixed left-0 top-48 z-50 mx-auto w-full'}>
<BillingSessionStatus
onRedirect={onRedirect}
customerEmail={customerEmail ?? ''}
redirectPath={redirectPath}
/>
</div>
@@ -106,3 +94,15 @@ async function loadCheckoutSession(sessionId: string) {
checkoutToken,
};
}
// eslint-disable-next-line @typescript-eslint/require-await
async function onRedirect() {
'use server';
// revalidate the home page to update cached pages
// which may have changed due to the billing session
revalidatePath('/home', 'layout');
// redirect back
redirect('../');
}

View File

@@ -26,7 +26,7 @@ export default createBillingSchema({
{
name: 'Starter Monthly',
id: 'starter-monthly',
trialPeriod: 7,
trialDays: 7,
paymentType: 'recurring',
interval: 'month',
lineItems: [