mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
Added tests for tier edit modal (#17369)
refs https://github.com/TryGhost/Product/issues/3580
This commit is contained in:
parent
704fc18856
commit
0137f498d7
7 changed files with 262 additions and 36 deletions
|
@ -43,7 +43,8 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
||||||
const [errors, setErrors] = useState<{ [key in keyof Tier]?: string }>({}); // eslint-disable-line no-unused-vars
|
const [errors, setErrors] = useState<{ [key in keyof Tier]?: string }>({}); // eslint-disable-line no-unused-vars
|
||||||
|
|
||||||
const setError = (field: keyof Tier, error: string | undefined) => {
|
const setError = (field: keyof Tier, error: string | undefined) => {
|
||||||
setErrors({...errors, [field]: error});
|
setErrors(errs => ({...errs, [field]: error}));
|
||||||
|
return error;
|
||||||
};
|
};
|
||||||
|
|
||||||
const {formState, updateForm, handleSave} = useForm<TierFormState>({
|
const {formState, updateForm, handleSave} = useForm<TierFormState>({
|
||||||
|
@ -55,14 +56,6 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
||||||
currency: tier?.currency || currencies[0].isoCode
|
currency: tier?.currency || currencies[0].isoCode
|
||||||
},
|
},
|
||||||
onSave: async () => {
|
onSave: async () => {
|
||||||
if (Object.values(errors).some(error => error)) {
|
|
||||||
showToast({
|
|
||||||
type: 'pageError',
|
|
||||||
message: 'One or more fields have errors'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {monthly_price: monthlyPrice, yearly_price: yearlyPrice, trial_days: trialDays, currency, ...rest} = formState;
|
const {monthly_price: monthlyPrice, yearly_price: yearlyPrice, trial_days: trialDays, currency, ...rest} = formState;
|
||||||
const values: Partial<Tier> = rest;
|
const values: Partial<Tier> = rest;
|
||||||
|
|
||||||
|
@ -85,6 +78,14 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const currencySymbol = formState.currency ? getSymbol(formState.currency) : '$';
|
||||||
|
|
||||||
|
const validators = {
|
||||||
|
name: () => setError('name', formState.name ? undefined : 'You must specify a name'),
|
||||||
|
monthly_price: () => setError('monthly_price', (isFreeTier || (formState.monthly_price && parseFloat(formState.monthly_price) >= 1)) ? undefined : `Subscription amount must be at least ${currencySymbol}1.00`),
|
||||||
|
yearly_price: () => setError('yearly_price', (isFreeTier || (formState.yearly_price && parseFloat(formState.yearly_price) >= 1)) ? undefined : `Subscription amount must be at least ${currencySymbol}1.00`)
|
||||||
|
};
|
||||||
|
|
||||||
const benefits = useSortableIndexedList({
|
const benefits = useSortableIndexedList({
|
||||||
items: formState.benefits || [],
|
items: formState.benefits || [],
|
||||||
setItems: newBenefits => updateForm(state => ({...state, benefits: newBenefits})),
|
setItems: newBenefits => updateForm(state => ({...state, benefits: newBenefits})),
|
||||||
|
@ -96,17 +97,26 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
||||||
return value.match(/[\d]+\.?[\d]{0,2}/)?.[0] || '';
|
return value.match(/[\d]+\.?[\d]{0,2}/)?.[0] || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const currencySymbol = formState.currency ? getSymbol(formState.currency) : '$';
|
|
||||||
|
|
||||||
return <Modal
|
return <Modal
|
||||||
afterClose={() => {
|
afterClose={() => {
|
||||||
updateRoute('tiers');
|
updateRoute('tiers');
|
||||||
}}
|
}}
|
||||||
okLabel='Save & close'
|
okLabel='Save & close'
|
||||||
size='lg'
|
size='lg'
|
||||||
|
testId='tier-detail-modal'
|
||||||
title='Tier'
|
title='Tier'
|
||||||
stickyFooter
|
stickyFooter
|
||||||
onOk={handleSave}
|
onOk={() => {
|
||||||
|
if (Object.values(validators).filter(validator => validator()).length) {
|
||||||
|
showToast({
|
||||||
|
type: 'pageError',
|
||||||
|
message: 'One or more fields have errors'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSave();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className='mt-8 flex items-start gap-16'>
|
<div className='mt-8 flex items-start gap-16'>
|
||||||
<div className='flex grow flex-col gap-5'>
|
<div className='flex grow flex-col gap-5'>
|
||||||
|
@ -118,7 +128,7 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
||||||
placeholder='Bronze'
|
placeholder='Bronze'
|
||||||
title='Name'
|
title='Name'
|
||||||
value={formState.name || ''}
|
value={formState.name || ''}
|
||||||
onBlur={e => setError('name', e.target.value ? undefined : 'You must specify a name')}
|
onBlur={() => validators.name()}
|
||||||
onChange={e => updateForm(state => ({...state, name: e.target.value}))}
|
onChange={e => updateForm(state => ({...state, name: e.target.value}))}
|
||||||
/>}
|
/>}
|
||||||
<TextField
|
<TextField
|
||||||
|
@ -155,8 +165,10 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
||||||
hint={errors.monthly_price}
|
hint={errors.monthly_price}
|
||||||
placeholder='1'
|
placeholder='1'
|
||||||
rightPlaceholder={`${formState.currency}/month`}
|
rightPlaceholder={`${formState.currency}/month`}
|
||||||
|
title='Monthly price'
|
||||||
value={formState.monthly_price}
|
value={formState.monthly_price}
|
||||||
onBlur={e => setError('monthly_price', e.target.value ? undefined : `Subscription amount must be at least ${currencySymbol}1.00`)}
|
hideTitle
|
||||||
|
onBlur={() => validators.monthly_price()}
|
||||||
onChange={e => updateForm(state => ({...state, monthly_price: forceCurrencyValue(e.target.value)}))}
|
onChange={e => updateForm(state => ({...state, monthly_price: forceCurrencyValue(e.target.value)}))}
|
||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
|
@ -164,16 +176,17 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
||||||
hint={errors.yearly_price}
|
hint={errors.yearly_price}
|
||||||
placeholder='10'
|
placeholder='10'
|
||||||
rightPlaceholder={`${formState.currency}/year`}
|
rightPlaceholder={`${formState.currency}/year`}
|
||||||
|
title='Yearly price'
|
||||||
value={formState.yearly_price}
|
value={formState.yearly_price}
|
||||||
onBlur={e => setError('yearly_price', e.target.value ? undefined : `Subscription amount must be at least ${currencySymbol}1.00`)}
|
hideTitle
|
||||||
|
onBlur={() => validators.yearly_price()}
|
||||||
onChange={e => updateForm(state => ({...state, yearly_price: forceCurrencyValue(e.target.value)}))}
|
onChange={e => updateForm(state => ({...state, yearly_price: forceCurrencyValue(e.target.value)}))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='basis-1/2'>
|
<div className='basis-1/2'>
|
||||||
<div className='mb-1 flex h-6 items-center justify-between'>
|
<div className='mb-1 flex h-6 flex-col justify-center'>
|
||||||
<Heading level={6}>Add a free trial</Heading>
|
<Toggle label='Add a free trial' labelStyle='heading' onChange={e => setHasFreeTrial(e.target.checked)} />
|
||||||
<Toggle onChange={e => setHasFreeTrial(e.target.checked)} />
|
|
||||||
</div>
|
</div>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={!hasFreeTrial}
|
disabled={!hasFreeTrial}
|
||||||
|
@ -182,7 +195,9 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
||||||
</>}
|
</>}
|
||||||
placeholder='0'
|
placeholder='0'
|
||||||
rightPlaceholder='days'
|
rightPlaceholder='days'
|
||||||
|
title='Trial days'
|
||||||
value={formState.trial_days}
|
value={formState.trial_days}
|
||||||
|
hideTitle
|
||||||
onChange={e => updateForm(state => ({...state, trial_days: e.target.value.replace(/[^\d]/, '')}))}
|
onChange={e => updateForm(state => ({...state, trial_days: e.target.value.replace(/[^\d]/, '')}))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -210,10 +225,21 @@ const TierDetailModal: React.FC<TierDetailModalProps> = ({tier}) => {
|
||||||
<TextField
|
<TextField
|
||||||
className='grow'
|
className='grow'
|
||||||
placeholder='Expert analysis'
|
placeholder='Expert analysis'
|
||||||
|
title='New benefit'
|
||||||
value={benefits.newItem}
|
value={benefits.newItem}
|
||||||
|
hideTitle
|
||||||
onChange={e => benefits.setNewItem(e.target.value)}
|
onChange={e => benefits.setNewItem(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<Button className='absolute right-0 top-1' color='green' icon="add" iconColorClass='text-white' size='sm' onClick={() => benefits.addItem()} />
|
<Button
|
||||||
|
className='absolute right-0 top-1'
|
||||||
|
color='green'
|
||||||
|
icon='add'
|
||||||
|
iconColorClass='text-white'
|
||||||
|
label='Add'
|
||||||
|
size='sm'
|
||||||
|
hideLabel
|
||||||
|
onClick={() => benefits.addItem()}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -29,7 +29,7 @@ const TierCard: React.FC<TierCardProps> = ({
|
||||||
const currencySymbol = currency ? getSymbol(currency) : '$';
|
const currencySymbol = currency ? getSymbol(currency) : '$';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cardContainerClasses}>
|
<div className={cardContainerClasses} data-testid='tier-card'>
|
||||||
<div className='w-full grow cursor-pointer' onClick={() => {
|
<div className='w-full grow cursor-pointer' onClick={() => {
|
||||||
NiceModal.show(TierDetailModal, {tier});
|
NiceModal.show(TierDetailModal, {tier});
|
||||||
}}>
|
}}>
|
||||||
|
@ -81,7 +81,7 @@ const TiersList: React.FC<TiersListProps> = ({
|
||||||
return <TierCard tier={tier} updateTier={updateTier} />;
|
return <TierCard tier={tier} updateTier={updateTier} />;
|
||||||
})}
|
})}
|
||||||
{tab === 'active-tiers' && (
|
{tab === 'active-tiers' && (
|
||||||
<div className={`${cardContainerClasses} group cursor-pointer`} onClick={() => {
|
<button className={`${cardContainerClasses} group cursor-pointer`} type='button' onClick={() => {
|
||||||
openTierModal();
|
openTierModal();
|
||||||
}}>
|
}}>
|
||||||
<div className='flex h-full w-full flex-col items-center justify-center'>
|
<div className='flex h-full w-full flex-col items-center justify-center'>
|
||||||
|
@ -90,7 +90,7 @@ const TiersList: React.FC<TiersListProps> = ({
|
||||||
<div className='mt-2 translate-y-[-10px] text-sm font-semibold text-green opacity-0 transition-all group-hover:translate-y-0 group-hover:opacity-100'>Add tier</div>
|
<div className='mt-2 translate-y-[-10px] text-sm font-semibold text-green opacity-0 transition-all group-hover:translate-y-0 group-hover:opacity-100'>Add tier</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -64,7 +64,7 @@ test.describe('Access settings', async () => {
|
||||||
await section.getByLabel('Select tiers').click();
|
await section.getByLabel('Select tiers').click();
|
||||||
|
|
||||||
await section.locator('[data-testid="multiselect-option"]', {hasText: 'Basic Supporter'}).click();
|
await section.locator('[data-testid="multiselect-option"]', {hasText: 'Basic Supporter'}).click();
|
||||||
await section.locator('[data-testid="multiselect-option"]', {hasText: 'Ultimate Starlight Diamond Supporter'}).click();
|
await section.locator('[data-testid="multiselect-option"]', {hasText: 'Ultimate Starlight Diamond Tier'}).click();
|
||||||
|
|
||||||
await section.getByRole('button', {name: 'Save'}).click();
|
await section.getByRole('button', {name: 'Save'}).click();
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ test.describe('Access settings', async () => {
|
||||||
expect(lastApiRequests.settings.edit.body).toEqual({
|
expect(lastApiRequests.settings.edit.body).toEqual({
|
||||||
settings: [
|
settings: [
|
||||||
{key: 'default_content_visibility', value: 'tiers'},
|
{key: 'default_content_visibility', value: 'tiers'},
|
||||||
{key: 'default_content_visibility_tiers', value: JSON.stringify(responseFixtures.tiers.tiers.map(tier => tier.id))}
|
{key: 'default_content_visibility_tiers', value: JSON.stringify(responseFixtures.tiers.tiers.slice(1).map(tier => tier.id))}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
168
apps/admin-x-settings/test/e2e/membership/tiers.test.ts
Normal file
168
apps/admin-x-settings/test/e2e/membership/tiers.test.ts
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
import {expect, test} from '@playwright/test';
|
||||||
|
import {mockApi, responseFixtures} from '../../utils/e2e';
|
||||||
|
|
||||||
|
test.describe('Tier settings', async () => {
|
||||||
|
test('Supports creating a new tier', async ({page}) => {
|
||||||
|
const lastApiRequests = await mockApi({page, responses: {
|
||||||
|
tiers: {
|
||||||
|
add: {
|
||||||
|
tiers: [{
|
||||||
|
id: 'new-tier',
|
||||||
|
type: 'paid',
|
||||||
|
active: true,
|
||||||
|
name: 'Plus tier',
|
||||||
|
slug: 'plus-tier',
|
||||||
|
description: null,
|
||||||
|
monthly_price: 800,
|
||||||
|
yearly_price: 8000,
|
||||||
|
benefits: [],
|
||||||
|
welcome_page_url: null,
|
||||||
|
trial_days: 0,
|
||||||
|
visibility: 'public',
|
||||||
|
created_at: new Date().toISOString(),
|
||||||
|
updated_at: new Date().toISOString()
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
|
||||||
|
await page.goto('/');
|
||||||
|
|
||||||
|
const section = page.getByTestId('tiers');
|
||||||
|
|
||||||
|
await section.getByRole('button', {name: 'Add tier'}).click();
|
||||||
|
|
||||||
|
const modal = page.getByTestId('tier-detail-modal');
|
||||||
|
|
||||||
|
await modal.getByRole('button', {name: 'Save & close'}).click();
|
||||||
|
|
||||||
|
await expect(page.getByTestId('toast')).toHaveText(/One or more fields have errors/);
|
||||||
|
await expect(modal).toHaveText(/You must specify a name/);
|
||||||
|
await expect(modal).toHaveText(/Subscription amount must be at least \$1\.00/);
|
||||||
|
|
||||||
|
await modal.getByLabel('Name').fill('Plus tier');
|
||||||
|
await modal.getByLabel('Monthly price').fill('8');
|
||||||
|
await modal.getByLabel('Yearly price').fill('80');
|
||||||
|
|
||||||
|
await modal.getByRole('button', {name: 'Save & close'}).click();
|
||||||
|
|
||||||
|
await expect(section.getByTestId('tier-card').filter({hasText: /Plus/})).toHaveText(/Plus tier/);
|
||||||
|
await expect(section.getByTestId('tier-card').filter({hasText: /Plus/})).toHaveText(/\$8\/month/);
|
||||||
|
|
||||||
|
expect(lastApiRequests.tiers.add.body).toMatchObject({
|
||||||
|
tiers: [{
|
||||||
|
name: 'Plus tier',
|
||||||
|
monthly_price: 800,
|
||||||
|
yearly_price: 8000,
|
||||||
|
trial_days: null
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Supports updating a tier', async ({page}) => {
|
||||||
|
const lastApiRequests = await mockApi({page, responses: {
|
||||||
|
tiers: {
|
||||||
|
edit: {
|
||||||
|
tiers: [{
|
||||||
|
...responseFixtures.tiers.tiers[1],
|
||||||
|
name: 'Supporter updated',
|
||||||
|
description: 'Supporter description',
|
||||||
|
monthly_price: 1001,
|
||||||
|
trial_days: 7,
|
||||||
|
benefits: [
|
||||||
|
'Simple benefit',
|
||||||
|
'New benefit'
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
|
||||||
|
await page.goto('/');
|
||||||
|
|
||||||
|
const section = page.getByTestId('tiers');
|
||||||
|
|
||||||
|
await section.getByTestId('tier-card').filter({hasText: /Supporter/}).click();
|
||||||
|
|
||||||
|
const modal = page.getByTestId('tier-detail-modal');
|
||||||
|
|
||||||
|
await modal.getByLabel('Name').fill('');
|
||||||
|
await modal.getByRole('button', {name: 'Save & close'}).click();
|
||||||
|
|
||||||
|
await expect(page.getByTestId('toast')).toHaveText(/One or more fields have errors/);
|
||||||
|
await expect(modal).toHaveText(/You must specify a name/);
|
||||||
|
|
||||||
|
await modal.getByLabel('Name').fill('Supporter updated');
|
||||||
|
await modal.getByLabel('Description').fill('Supporter description');
|
||||||
|
await modal.getByLabel('Monthly price').fill('10.01');
|
||||||
|
await modal.getByLabel('Add a free trial').check();
|
||||||
|
await modal.getByLabel('Trial days').fill('7');
|
||||||
|
await modal.getByLabel('New benefit').fill('New benefit');
|
||||||
|
await modal.getByRole('button', {name: 'Add'}).click();
|
||||||
|
|
||||||
|
await modal.getByRole('button', {name: 'Save & close'}).click();
|
||||||
|
|
||||||
|
await expect(section.getByTestId('tier-card').filter({hasText: /Supporter/})).toHaveText(/Supporter updated/);
|
||||||
|
await expect(section.getByTestId('tier-card').filter({hasText: /Supporter/})).toHaveText(/Supporter description/);
|
||||||
|
await expect(section.getByTestId('tier-card').filter({hasText: /Supporter/})).toHaveText(/\$10\.01\/month/);
|
||||||
|
|
||||||
|
expect(lastApiRequests.tiers.edit.body).toMatchObject({
|
||||||
|
tiers: [{
|
||||||
|
id: responseFixtures.tiers.tiers[1].id,
|
||||||
|
name: 'Supporter updated',
|
||||||
|
description: 'Supporter description',
|
||||||
|
monthly_price: 1001,
|
||||||
|
trial_days: 7,
|
||||||
|
benefits: [
|
||||||
|
'Simple benefit',
|
||||||
|
'New benefit'
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Supports editing the free tier', async ({page}) => {
|
||||||
|
const lastApiRequests = await mockApi({page, responses: {
|
||||||
|
tiers: {
|
||||||
|
edit: {
|
||||||
|
tiers: [{
|
||||||
|
...responseFixtures.tiers.tiers[0],
|
||||||
|
description: 'Free tier description',
|
||||||
|
benefits: [
|
||||||
|
'First benefit',
|
||||||
|
'Second benefit'
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
|
||||||
|
await page.goto('/');
|
||||||
|
|
||||||
|
const section = page.getByTestId('tiers');
|
||||||
|
|
||||||
|
await section.getByTestId('tier-card').filter({hasText: /Free/}).click();
|
||||||
|
|
||||||
|
const modal = page.getByTestId('tier-detail-modal');
|
||||||
|
|
||||||
|
await modal.getByLabel('Description').fill('Free tier description');
|
||||||
|
await modal.getByLabel('New benefit').fill('First benefit');
|
||||||
|
await modal.getByRole('button', {name: 'Add'}).click();
|
||||||
|
await modal.getByLabel('New benefit').fill('Second benefit');
|
||||||
|
|
||||||
|
await modal.getByRole('button', {name: 'Save & close'}).click();
|
||||||
|
|
||||||
|
await expect(section.getByTestId('tier-card').filter({hasText: /Free/})).toHaveText(/Free tier description/);
|
||||||
|
|
||||||
|
expect(lastApiRequests.tiers.edit.body).toMatchObject({
|
||||||
|
tiers: [{
|
||||||
|
id: responseFixtures.tiers.tiers[0].id,
|
||||||
|
description: 'Free tier description',
|
||||||
|
benefits: [
|
||||||
|
'First benefit',
|
||||||
|
'Second benefit'
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,8 +0,0 @@
|
||||||
const assert = require('assert/strict');
|
|
||||||
|
|
||||||
describe('Hello world', function () {
|
|
||||||
it('Runs a test', function () {
|
|
||||||
// TODO: Write me!
|
|
||||||
assert.ok(require('../index'));
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -56,6 +56,8 @@ interface Responses {
|
||||||
}
|
}
|
||||||
tiers?: {
|
tiers?: {
|
||||||
browse?: TiersResponseType
|
browse?: TiersResponseType
|
||||||
|
edit?: TiersResponseType
|
||||||
|
add?: TiersResponseType
|
||||||
}
|
}
|
||||||
labels?: {
|
labels?: {
|
||||||
browse?: LabelsResponseType
|
browse?: LabelsResponseType
|
||||||
|
@ -121,6 +123,8 @@ type LastRequests = {
|
||||||
}
|
}
|
||||||
tiers: {
|
tiers: {
|
||||||
browse: RequestRecord
|
browse: RequestRecord
|
||||||
|
edit: RequestRecord
|
||||||
|
add: RequestRecord
|
||||||
}
|
}
|
||||||
labels: {
|
labels: {
|
||||||
browse: RequestRecord
|
browse: RequestRecord
|
||||||
|
@ -152,7 +156,7 @@ export async function mockApi({page,responses}: {page: Page, responses?: Respons
|
||||||
images: {upload: {}},
|
images: {upload: {}},
|
||||||
customThemeSettings: {browse: {}, edit: {}},
|
customThemeSettings: {browse: {}, edit: {}},
|
||||||
latestPost: {browse: {}},
|
latestPost: {browse: {}},
|
||||||
tiers: {browse: {}},
|
tiers: {browse: {}, edit: {}, add: {}},
|
||||||
labels: {browse: {}},
|
labels: {browse: {}},
|
||||||
offers: {browse: {}},
|
offers: {browse: {}},
|
||||||
themes: {browse: {}, activate: {}, delete: {}, install: {}, upload: {}},
|
themes: {browse: {}, activate: {}, delete: {}, install: {}, upload: {}},
|
||||||
|
@ -386,7 +390,29 @@ export async function mockApi({page,responses}: {page: Page, responses?: Respons
|
||||||
|
|
||||||
await mockApiResponse({
|
await mockApiResponse({
|
||||||
page,
|
page,
|
||||||
path: /\/ghost\/api\/admin\/tiers\//,
|
path: /\/ghost\/api\/admin\/tiers\/\w{24}/,
|
||||||
|
respondTo: {
|
||||||
|
PUT: {
|
||||||
|
body: responses?.tiers?.edit ?? responseFixtures.tiers,
|
||||||
|
updateLastRequest: lastApiRequests.tiers.edit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await mockApiResponse({
|
||||||
|
page,
|
||||||
|
path: /\/ghost\/api\/admin\/tiers\/$/,
|
||||||
|
respondTo: {
|
||||||
|
POST: {
|
||||||
|
body: responses?.tiers?.add ?? responseFixtures.tiers,
|
||||||
|
updateLastRequest: lastApiRequests.tiers.add
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await mockApiResponse({
|
||||||
|
page,
|
||||||
|
path: /\/ghost\/api\/admin\/tiers\/\?limit/,
|
||||||
respondTo: {
|
respondTo: {
|
||||||
GET: {
|
GET: {
|
||||||
body: responses?.tiers?.browse ?? responseFixtures.tiers,
|
body: responses?.tiers?.browse ?? responseFixtures.tiers,
|
||||||
|
|
|
@ -1,5 +1,19 @@
|
||||||
{
|
{
|
||||||
"tiers": [
|
"tiers": [
|
||||||
|
{
|
||||||
|
"id": "645453f4d254799990dd0e21",
|
||||||
|
"name": "Free",
|
||||||
|
"description": null,
|
||||||
|
"slug": "free",
|
||||||
|
"active": true,
|
||||||
|
"type": "free",
|
||||||
|
"welcome_page_url": null,
|
||||||
|
"created_at": "2023-05-05T00:55:16.000Z",
|
||||||
|
"updated_at": "2023-05-08T06:08:47.000Z",
|
||||||
|
"visibility": "public",
|
||||||
|
"benefits": [],
|
||||||
|
"trial_days": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "645453f4d254799990dd0e22",
|
"id": "645453f4d254799990dd0e22",
|
||||||
"name": "Basic Supporter",
|
"name": "Basic Supporter",
|
||||||
|
@ -21,9 +35,9 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "649a4f08e1de1c862cd79063",
|
"id": "649a4f08e1de1c862cd79063",
|
||||||
"name": "Ultimate Starlight Diamond Supporter",
|
"name": "Ultimate Starlight Diamond Tier",
|
||||||
"description": null,
|
"description": null,
|
||||||
"slug": "ultimate-starlight-diamond-supporter",
|
"slug": "ultimate-starlight-diamond-tier",
|
||||||
"active": true,
|
"active": true,
|
||||||
"type": "paid",
|
"type": "paid",
|
||||||
"welcome_page_url": null,
|
"welcome_page_url": null,
|
||||||
|
|
Loading…
Add table
Reference in a new issue