feat(subscription): display jalali expiry date and handle no expiry case in current plan card
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { screen, fireEvent, within } from '@testing-library/react';
|
||||
import { renderWithProviders } from '../test/utils';
|
||||
import { formatRial } from '../lib/utils';
|
||||
import { formatRial, formatDate } from '../lib/utils';
|
||||
|
||||
vi.mock('sonner', () => ({ toast: { success: vi.fn(), error: vi.fn() } }));
|
||||
vi.mock('../lib/api', () => ({
|
||||
@@ -67,6 +67,27 @@ describe('SubscriptionPage', () => {
|
||||
expect(await screen.findByText(/روز تا پایان اشتراک/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows the jalali expiry date on the current-plan card', async () => {
|
||||
// 1767225600 = 2026-01-01T00:00:00Z → ۱۴۰۴/۱۰/۱۱ in Tehran
|
||||
mockApi({ my: { ...DEFAULT_MY, subscription: { ...DEFAULT_MY.subscription, expires_at: 1767225600 } } });
|
||||
renderWithProviders(<SubscriptionPage />, { route: '/admin/subscription' });
|
||||
|
||||
expect(await screen.findByText('زمان پایان اشتراک:')).toBeInTheDocument();
|
||||
expect(screen.getByText(formatDate(1767225600))).toBeInTheDocument();
|
||||
expect(screen.getByText(/روز مانده/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('falls back to «بدون تاریخ انقضا» when the subscription has no expiry', async () => {
|
||||
renderWithProviders(<SubscriptionPage />, { route: '/admin/subscription' });
|
||||
expect(await screen.findByText('بدون تاریخ انقضا')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders the current-plan card right-to-left', async () => {
|
||||
renderWithProviders(<SubscriptionPage />, { route: '/admin/subscription' });
|
||||
const label = await screen.findByText('پلن فعلی شما:');
|
||||
expect(label.closest('[dir]')).toHaveAttribute('dir', 'rtl');
|
||||
});
|
||||
|
||||
it('shows the expired message when no days remain', async () => {
|
||||
mockApi({ my: { ...DEFAULT_MY, subscription: { ...DEFAULT_MY.subscription, days_remaining: 0 } } });
|
||||
renderWithProviders(<SubscriptionPage />, { route: '/admin/subscription' });
|
||||
|
||||
@@ -7,7 +7,7 @@ import { api } from '../lib/api';
|
||||
import type { ApiResponse } from '../lib/api';
|
||||
import type { SubscriptionPlan, MySubscriptionData, SubscriptionPeriod } from '../types';
|
||||
import { usePaymentConfig } from '../hooks/usePaymentConfig';
|
||||
import { formatRial, formatNumber } from '../lib/utils';
|
||||
import { formatRial, formatNumber, formatDate } from '../lib/utils';
|
||||
import Modal from '../components/ui/Modal';
|
||||
import SettingsLayout from '../components/layout/SettingsLayout';
|
||||
import {
|
||||
@@ -270,9 +270,10 @@ export default function SubscriptionPage() {
|
||||
|
||||
function CurrentPlanCard({ my, onRenew }: { my: MySubscriptionData['subscription']; onRenew: () => void }) {
|
||||
const daysLeft = my?.days_remaining ?? 0;
|
||||
const expiresAt = my?.expires_at ?? null;
|
||||
return (
|
||||
<div
|
||||
dir="ltr"
|
||||
dir="rtl"
|
||||
style={{
|
||||
width: 365, maxWidth: '100%', minHeight: 104,
|
||||
background: 'var(--surface-2)', border: '1px solid var(--border)',
|
||||
@@ -286,6 +287,21 @@ function CurrentPlanCard({ my, onRenew }: { my: MySubscriptionData['subscription
|
||||
<span style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-2)' }}>پلن فعلی شما:</span>
|
||||
<span style={{ fontSize: 14, fontWeight: 700, color: 'var(--text)' }}>{planMetaOf(my.plan.name).label}</span>
|
||||
</div>
|
||||
{expiresAt ? (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 4, marginTop: 4 }}>
|
||||
<span style={{ fontSize: 12, fontWeight: 500, color: 'var(--text-3)' }}>زمان پایان اشتراک:</span>
|
||||
<span style={{ fontSize: 12, fontWeight: 600, color: 'var(--text-2)' }}>{formatDate(expiresAt)}</span>
|
||||
{daysLeft > 0 && (
|
||||
<span style={{ fontSize: 12, fontWeight: 500, color: 'var(--text-3)' }}>
|
||||
({formatNumber(daysLeft)} روز مانده)
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ marginTop: 4 }}>
|
||||
<span style={{ fontSize: 12, fontWeight: 500, color: 'var(--text-3)' }}>بدون تاریخ انقضا</span>
|
||||
</div>
|
||||
)}
|
||||
{daysLeft < 3 && (
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 4 }}>
|
||||
<div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
|
||||
|
||||
Reference in New Issue
Block a user