mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 19:02:29 +03:00
AdminX: reroute settings-x to settings (#18360)
refs. https://github.com/TryGhost/Product/issues/3949 --------- Co-authored-by: Jono Mingard <reason.koan@gmail.com> Co-authored-by: Daniel Lockyer <hi@daniellockyer.com>
This commit is contained in:
parent
741a00fe05
commit
e68db848dc
3
.github/workflows/browser-tests.yml
vendored
3
.github/workflows/browser-tests.yml
vendored
@ -77,8 +77,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build Admin
|
- name: Build Admin
|
||||||
if: env.ENVIRONMENT == 'browser-tests-local'
|
if: env.ENVIRONMENT == 'browser-tests-local'
|
||||||
working-directory: ghost/admin
|
run: yarn nx run ghost-admin:build:dev
|
||||||
run: yarn build:dev
|
|
||||||
|
|
||||||
- name: Run Playwright tests on a remote site
|
- name: Run Playwright tests on a remote site
|
||||||
if: env.ENVIRONMENT == 'browser-tests-staging'
|
if: env.ENVIRONMENT == 'browser-tests-staging'
|
||||||
|
@ -26,8 +26,8 @@ const MainContent: React.FC = () => {
|
|||||||
const {route, updateRoute, loadingModal} = useRouting();
|
const {route, updateRoute, loadingModal} = useRouting();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!canAccessSettings(currentUser) && route !== `users/show/${currentUser.slug}`) {
|
if (!canAccessSettings(currentUser) && route !== `staff/${currentUser.slug}`) {
|
||||||
updateRoute(`users/show/${currentUser.slug}`);
|
updateRoute(`staff/${currentUser.slug}`);
|
||||||
}
|
}
|
||||||
}, [currentUser, route, updateRoute]);
|
}, [currentUser, route, updateRoute]);
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ const ClearIndicator: React.FC<ClearIndicatorProps<SelectOption, false>> = props
|
|||||||
|
|
||||||
const Option: React.FC<OptionProps<SelectOption, false>> = ({children, ...optionProps}) => (
|
const Option: React.FC<OptionProps<SelectOption, false>> = ({children, ...optionProps}) => (
|
||||||
<components.Option {...optionProps}>
|
<components.Option {...optionProps}>
|
||||||
<span data-testid="select-option">{children}</span>
|
<span data-testid="select-option" data-value={optionProps.data.value}>{children}</span>
|
||||||
{optionProps.data.hint && <span className="block text-xs text-grey-700 dark:text-grey-300">{optionProps.data.hint}</span>}
|
{optionProps.data.hint && <span className="block text-xs text-grey-700 dark:text-grey-300">{optionProps.data.hint}</span>}
|
||||||
</components.Option>
|
</components.Option>
|
||||||
);
|
);
|
||||||
|
@ -97,13 +97,13 @@ export const getActorLinkTarget = (action: Action): InternalLink | ExternalLink
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {route: `integrations/show/${action.actor.id}`};
|
return {route: `integrations/${action.actor.id}`};
|
||||||
case 'user':
|
case 'user':
|
||||||
if (!action.actor.slug) {
|
if (!action.actor.slug) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {route: `users/show/${action.actor.slug}`};
|
return {route: `staff/${action.actor.slug}`};
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -136,7 +136,7 @@ export const getLinkTarget = (action: Action): InternalLink | ExternalLink | und
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {route: `integrations/show/${action.resource.id}`};
|
return {route: `integrations/${action.resource.id}`};
|
||||||
case 'offer':
|
case 'offer':
|
||||||
if (!action.resource || !action.resource.id) {
|
if (!action.resource || !action.resource.id) {
|
||||||
return;
|
return;
|
||||||
@ -164,7 +164,7 @@ export const getLinkTarget = (action: Action): InternalLink | ExternalLink | und
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {route: `users/show/${action.resource.slug}`};
|
return {route: `staff/${action.resource.slug}`};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,9 +15,6 @@ const Settings: React.FC = () => {
|
|||||||
<MembershipSettings />
|
<MembershipSettings />
|
||||||
<EmailSettings />
|
<EmailSettings />
|
||||||
<AdvancedSettings />
|
<AdvancedSettings />
|
||||||
<div className='mt-40 text-sm'>
|
|
||||||
<a className='text-green' href="/ghost/#/settings">Click here</a> to open the original Admin settings.
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -75,7 +75,7 @@ const Sidebar: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="no-scrollbar hidden pt-10 tablet:!visible tablet:!block tablet:h-[calc(100vh-5vmin-84px-64px)] tablet:w-[240px] tablet:overflow-y-auto" id='admin-x-settings-sidebar'>
|
<div className="no-scrollbar hidden pt-10 tablet:!visible tablet:!block tablet:h-[calc(100vh-5vmin-84px-64px)] tablet:w-[240px] tablet:overflow-y-auto" id='admin-x-settings-sidebar'>
|
||||||
<SettingNavSection keywords={Object.values(generalSearchKeywords).flat()} title="General">
|
<SettingNavSection keywords={Object.values(generalSearchKeywords).flat()} title="General">
|
||||||
<SettingNavItem keywords={generalSearchKeywords.titleAndDescription} navid='title-and-description' title="Title & description" onClick={handleSectionClick} />
|
<SettingNavItem keywords={generalSearchKeywords.titleAndDescription} navid='general' title="Title & description" onClick={handleSectionClick} />
|
||||||
<SettingNavItem keywords={generalSearchKeywords.timeZone} navid='timezone' title="Timezone" onClick={handleSectionClick} />
|
<SettingNavItem keywords={generalSearchKeywords.timeZone} navid='timezone' title="Timezone" onClick={handleSectionClick} />
|
||||||
<SettingNavItem keywords={generalSearchKeywords.publicationLanguage} navid='publication-language' title="Publication language" onClick={handleSectionClick} />
|
<SettingNavItem keywords={generalSearchKeywords.publicationLanguage} navid='publication-language' title="Publication language" onClick={handleSectionClick} />
|
||||||
<SettingNavItem keywords={generalSearchKeywords.metadata} navid='metadata' title="Meta data" onClick={handleSectionClick} />
|
<SettingNavItem keywords={generalSearchKeywords.metadata} navid='metadata' title="Meta data" onClick={handleSectionClick} />
|
||||||
@ -83,7 +83,7 @@ const Sidebar: React.FC = () => {
|
|||||||
<SettingNavItem keywords={generalSearchKeywords.facebook} navid='facebook' title="Facebook card" onClick={handleSectionClick} />
|
<SettingNavItem keywords={generalSearchKeywords.facebook} navid='facebook' title="Facebook card" onClick={handleSectionClick} />
|
||||||
<SettingNavItem keywords={generalSearchKeywords.socialAccounts} navid='social-accounts' title="Social accounts" onClick={handleSectionClick} />
|
<SettingNavItem keywords={generalSearchKeywords.socialAccounts} navid='social-accounts' title="Social accounts" onClick={handleSectionClick} />
|
||||||
<SettingNavItem keywords={generalSearchKeywords.lockSite} navid='locksite' title="Make this site private" onClick={handleSectionClick} />
|
<SettingNavItem keywords={generalSearchKeywords.lockSite} navid='locksite' title="Make this site private" onClick={handleSectionClick} />
|
||||||
<SettingNavItem keywords={generalSearchKeywords.users} navid='users' title="Staff" onClick={handleSectionClick} />
|
<SettingNavItem keywords={generalSearchKeywords.users} navid='staff' title="Staff" onClick={handleSectionClick} />
|
||||||
</SettingNavSection>
|
</SettingNavSection>
|
||||||
|
|
||||||
<SettingNavSection keywords={Object.values(siteSearchKeywords).flat()} title="Site">
|
<SettingNavSection keywords={Object.values(siteSearchKeywords).flat()} title="Site">
|
||||||
@ -93,7 +93,7 @@ const Sidebar: React.FC = () => {
|
|||||||
</SettingNavSection>
|
</SettingNavSection>
|
||||||
|
|
||||||
<SettingNavSection keywords={Object.values(membershipSearchKeywords).flat()} title="Membership">
|
<SettingNavSection keywords={Object.values(membershipSearchKeywords).flat()} title="Membership">
|
||||||
<SettingNavItem keywords={membershipSearchKeywords.access} navid='access' title="Access" onClick={handleSectionClick} />
|
<SettingNavItem keywords={membershipSearchKeywords.access} navid='members' title="Access" onClick={handleSectionClick} />
|
||||||
<SettingNavItem keywords={membershipSearchKeywords.portal} navid='portal' title="Portal" onClick={handleSectionClick} />
|
<SettingNavItem keywords={membershipSearchKeywords.portal} navid='portal' title="Portal" onClick={handleSectionClick} />
|
||||||
<SettingNavItem keywords={membershipSearchKeywords.tiers} navid='tiers' title="Tiers" onClick={handleSectionClick} />
|
<SettingNavItem keywords={membershipSearchKeywords.tiers} navid='tiers' title="Tiers" onClick={handleSectionClick} />
|
||||||
{hasTipsAndDonations && <SettingNavItem keywords={membershipSearchKeywords.tips} navid='tips-or-donations' title="Tips or donations" onClick={handleSectionClick} />}
|
{hasTipsAndDonations && <SettingNavItem keywords={membershipSearchKeywords.tips} navid='tips-or-donations' title="Tips or donations" onClick={handleSectionClick} />}
|
||||||
|
@ -35,19 +35,19 @@ export type RoutingModalProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const modalPaths: {[key: string]: ModalName} = {
|
const modalPaths: {[key: string]: ModalName} = {
|
||||||
'design/edit/themes': 'DesignAndThemeModal',
|
'design/change-theme': 'DesignAndThemeModal',
|
||||||
'design/edit': 'DesignAndThemeModal',
|
'design/edit': 'DesignAndThemeModal',
|
||||||
// this is a special route, because it can install a theme directly from the Ghost Marketplace
|
// this is a special route, because it can install a theme directly from the Ghost Marketplace
|
||||||
'design/change-theme/install': 'DesignAndThemeModal',
|
'design/change-theme/install': 'DesignAndThemeModal',
|
||||||
'navigation/edit': 'NavigationModal',
|
'navigation/edit': 'NavigationModal',
|
||||||
'users/invite': 'InviteUserModal',
|
'staff/invite': 'InviteUserModal',
|
||||||
'users/show/:slug': 'UserDetailModal',
|
'staff/:slug': 'UserDetailModal',
|
||||||
'portal/edit': 'PortalModal',
|
'portal/edit': 'PortalModal',
|
||||||
'tiers/add': 'TierDetailModal',
|
'tiers/add': 'TierDetailModal',
|
||||||
'tiers/show/:id': 'TierDetailModal',
|
'tiers/:id': 'TierDetailModal',
|
||||||
'stripe-connect': 'StripeConnectModal',
|
'stripe-connect': 'StripeConnectModal',
|
||||||
'newsletters/add': 'AddNewsletterModal',
|
'newsletters/new': 'AddNewsletterModal',
|
||||||
'newsletters/show/:id': 'NewsletterDetailModal',
|
'newsletters/:id': 'NewsletterDetailModal',
|
||||||
'history/view': 'HistoryModal',
|
'history/view': 'HistoryModal',
|
||||||
'history/view/:user': 'HistoryModal',
|
'history/view/:user': 'HistoryModal',
|
||||||
'integrations/zapier': 'ZapierModal',
|
'integrations/zapier': 'ZapierModal',
|
||||||
@ -56,8 +56,8 @@ const modalPaths: {[key: string]: ModalName} = {
|
|||||||
'integrations/unsplash': 'UnsplashModal',
|
'integrations/unsplash': 'UnsplashModal',
|
||||||
'integrations/firstpromoter': 'FirstpromoterModal',
|
'integrations/firstpromoter': 'FirstpromoterModal',
|
||||||
'integrations/pintura': 'PinturaModal',
|
'integrations/pintura': 'PinturaModal',
|
||||||
'integrations/add': 'AddIntegrationModal',
|
'integrations/new': 'AddIntegrationModal',
|
||||||
'integrations/show/:id': 'CustomIntegrationModal',
|
'integrations/:id': 'CustomIntegrationModal',
|
||||||
'recommendations/add': 'AddRecommendationModal',
|
'recommendations/add': 'AddRecommendationModal',
|
||||||
'recommendations/edit': 'EditRecommendationModal',
|
'recommendations/edit': 'EditRecommendationModal',
|
||||||
'announcement-bar/edit': 'AnnouncementBarModal',
|
'announcement-bar/edit': 'AnnouncementBarModal',
|
||||||
@ -68,7 +68,7 @@ function getHashPath(urlPath: string | undefined) {
|
|||||||
if (!urlPath) {
|
if (!urlPath) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const regex = /\/settings-x\/(.*)/;
|
const regex = /\/settings\/(.*)/;
|
||||||
const match = urlPath?.match(regex);
|
const match = urlPath?.match(regex);
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
@ -142,9 +142,9 @@ const RoutingProvider: React.FC<RouteProviderProps> = ({externalNavigate, childr
|
|||||||
const newPath = options.route;
|
const newPath = options.route;
|
||||||
|
|
||||||
if (newPath) {
|
if (newPath) {
|
||||||
window.location.hash = `/settings-x/${newPath}`;
|
window.location.hash = `/settings/${newPath}`;
|
||||||
} else {
|
} else {
|
||||||
window.location.hash = `/settings-x`;
|
window.location.hash = `/settings`;
|
||||||
}
|
}
|
||||||
}, [externalNavigate]);
|
}, [externalNavigate]);
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ const CustomIntegrations: React.FC<{integrations: Integration[]}> = ({integratio
|
|||||||
<List borderTop={false}>
|
<List borderTop={false}>
|
||||||
{integrations.map(integration => (
|
{integrations.map(integration => (
|
||||||
<IntegrationItem
|
<IntegrationItem
|
||||||
action={() => updateRoute({route: `integrations/show/${integration.id}`})}
|
action={() => updateRoute({route: `integrations/${integration.id}`})}
|
||||||
detail={integration.description || 'No description'}
|
detail={integration.description || 'No description'}
|
||||||
icon={
|
icon={
|
||||||
integration.icon_image ?
|
integration.icon_image ?
|
||||||
@ -218,7 +218,7 @@ const Integrations: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||||||
|
|
||||||
const buttons = (
|
const buttons = (
|
||||||
<Button className='hidden md:!visible md:!block' color='green' label='Add custom integration' link linkWithPadding onClick={() => {
|
<Button className='hidden md:!visible md:!block' color='green' label='Add custom integration' link linkWithPadding onClick={() => {
|
||||||
updateRoute('integrations/add');
|
updateRoute('integrations/new');
|
||||||
setSelectedTab('custom');
|
setSelectedTab('custom');
|
||||||
}} />
|
}} />
|
||||||
);
|
);
|
||||||
@ -234,7 +234,7 @@ const Integrations: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||||||
>
|
>
|
||||||
<div className='flex justify-center rounded border border-green px-4 py-2 md:hidden'>
|
<div className='flex justify-center rounded border border-green px-4 py-2 md:hidden'>
|
||||||
<Button color='green' label='Add custom integration' link onClick={() => {
|
<Button color='green' label='Add custom integration' link onClick={() => {
|
||||||
updateRoute('integrations/add');
|
updateRoute('integrations/new');
|
||||||
setSelectedTab('custom');
|
setSelectedTab('custom');
|
||||||
}} />
|
}} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -51,7 +51,7 @@ const AddIntegrationModal: React.FC<RoutingModalProps> = () => {
|
|||||||
try {
|
try {
|
||||||
const data = await createIntegration({name});
|
const data = await createIntegration({name});
|
||||||
modal.remove();
|
modal.remove();
|
||||||
updateRoute({route: `integrations/show/${data.integrations[0].id}`});
|
updateRoute({route: `integrations/${data.integrations[0].id}`});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
handleError(e);
|
handleError(e);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ const AlphaFeatures: React.FC = () => {
|
|||||||
<List titleSeparator={false}>
|
<List titleSeparator={false}>
|
||||||
{features.map(feature => (
|
{features.map(feature => (
|
||||||
<LabItem
|
<LabItem
|
||||||
action={<FeatureToggle flag={feature.flag} />}
|
action={<FeatureToggle flag={feature.flag} label={feature.title} />}
|
||||||
detail={feature.description}
|
detail={feature.description}
|
||||||
title={feature.title} />
|
title={feature.title} />
|
||||||
))}
|
))}
|
||||||
|
@ -6,14 +6,14 @@ import {getSettingValue, useEditSettings} from '../../../../api/settings';
|
|||||||
import {useGlobalData} from '../../../providers/GlobalDataProvider';
|
import {useGlobalData} from '../../../providers/GlobalDataProvider';
|
||||||
import {useQueryClient} from '@tanstack/react-query';
|
import {useQueryClient} from '@tanstack/react-query';
|
||||||
|
|
||||||
const FeatureToggle: React.FC<{ flag: string; }> = ({flag}) => {
|
const FeatureToggle: React.FC<{ flag: string; label?: string; }> = ({label, flag}) => {
|
||||||
const {settings} = useGlobalData();
|
const {settings} = useGlobalData();
|
||||||
const labs = JSON.parse(getSettingValue<string>(settings, 'labs') || '{}');
|
const labs = JSON.parse(getSettingValue<string>(settings, 'labs') || '{}');
|
||||||
const {mutateAsync: editSettings} = useEditSettings();
|
const {mutateAsync: editSettings} = useEditSettings();
|
||||||
const client = useQueryClient();
|
const client = useQueryClient();
|
||||||
const handleError = useHandleError();
|
const handleError = useHandleError();
|
||||||
|
|
||||||
return <Toggle checked={labs[flag]} onChange={async () => {
|
return <Toggle checked={labs[flag]} label={label} labelClasses='sr-only' onChange={async () => {
|
||||||
const newValue = !labs[flag];
|
const newValue = !labs[flag];
|
||||||
try {
|
try {
|
||||||
await editSettings([{
|
await editSettings([{
|
||||||
|
@ -10,7 +10,7 @@ import {withErrorBoundary} from '../../../admin-x-ds/global/ErrorBoundary';
|
|||||||
const Newsletters: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
const Newsletters: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
||||||
const {updateRoute} = useRouting();
|
const {updateRoute} = useRouting();
|
||||||
const openNewsletterModal = () => {
|
const openNewsletterModal = () => {
|
||||||
updateRoute('newsletters/add');
|
updateRoute('newsletters/new');
|
||||||
};
|
};
|
||||||
const [selectedTab, setSelectedTab] = useState('active-newsletters');
|
const [selectedTab, setSelectedTab] = useState('active-newsletters');
|
||||||
const {data: {newsletters, meta, isEnd} = {}, fetchNextPage} = useBrowseNewsletters();
|
const {data: {newsletters, meta, isEnd} = {}, fetchNextPage} = useBrowseNewsletters();
|
||||||
|
@ -40,7 +40,7 @@ const AddNewsletterModal: React.FC<RoutingModalProps> = () => {
|
|||||||
feedback_enabled: true
|
feedback_enabled: true
|
||||||
});
|
});
|
||||||
|
|
||||||
updateRoute({route: `newsletters/show/${response.newsletters[0].id}`});
|
updateRoute({route: `newsletters/${response.newsletters[0].id}`});
|
||||||
},
|
},
|
||||||
onSaveError: handleError,
|
onSaveError: handleError,
|
||||||
onValidate: () => {
|
onValidate: () => {
|
||||||
|
@ -16,7 +16,7 @@ const NewsletterItem: React.FC<{newsletter: Newsletter}> = ({newsletter}) => {
|
|||||||
const {updateRoute} = useRouting();
|
const {updateRoute} = useRouting();
|
||||||
|
|
||||||
const showDetails = () => {
|
const showDetails = () => {
|
||||||
updateRoute({route: `newsletters/show/${newsletter.id}`});
|
updateRoute({route: `newsletters/${newsletter.id}`});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -130,7 +130,7 @@ const InviteUserModal = NiceModal.create(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
modal.remove();
|
modal.remove();
|
||||||
updateRoute('users');
|
updateRoute('staff');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setSaveState('error');
|
setSaveState('error');
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ const InviteUserModal = NiceModal.create(() => {
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
afterClose={() => {
|
afterClose={() => {
|
||||||
updateRoute('users');
|
updateRoute('staff');
|
||||||
}}
|
}}
|
||||||
cancelLabel=''
|
cancelLabel=''
|
||||||
okLabel={okLabel}
|
okLabel={okLabel}
|
||||||
|
@ -70,7 +70,7 @@ const TitleAndDescription: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||||||
description='The details used to identify your publication around the web'
|
description='The details used to identify your publication around the web'
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
keywords={keywords}
|
keywords={keywords}
|
||||||
navid='title-and-description'
|
navid='general'
|
||||||
saveState={saveState}
|
saveState={saveState}
|
||||||
testId='title-and-description'
|
testId='title-and-description'
|
||||||
title='Title & description'
|
title='Title & description'
|
||||||
|
@ -80,7 +80,7 @@ const UserDetailModalContent: React.FC<{user: User}> = ({user}) => {
|
|||||||
|
|
||||||
const navigateOnClose = useCallback(() => {
|
const navigateOnClose = useCallback(() => {
|
||||||
if (canAccessSettings(currentUser)) {
|
if (canAccessSettings(currentUser)) {
|
||||||
updateRoute('users');
|
updateRoute('staff');
|
||||||
} else {
|
} else {
|
||||||
updateRoute({isExternal: true, route: 'dashboard'});
|
updateRoute({isExternal: true, route: 'dashboard'});
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ const Owner: React.FC<OwnerProps> = ({user}) => {
|
|||||||
|
|
||||||
const showDetailModal = () => {
|
const showDetailModal = () => {
|
||||||
if (hasAdminAccess(currentUser)) {
|
if (hasAdminAccess(currentUser)) {
|
||||||
updateRoute({route: `users/show/${user.slug}`});
|
updateRoute({route: `staff/${user.slug}`});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ const UsersList: React.FC<UsersListProps> = ({users, groupname}) => {
|
|||||||
const {currentUser} = useGlobalData();
|
const {currentUser} = useGlobalData();
|
||||||
|
|
||||||
const showDetailModal = (user: User) => {
|
const showDetailModal = (user: User) => {
|
||||||
updateRoute({route: `users/show/${user.slug}`});
|
updateRoute({route: `staff/${user.slug}`});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!users || !users.length) {
|
if (!users || !users.length) {
|
||||||
@ -221,7 +221,7 @@ const Users: React.FC<{ keywords: string[], highlight?: boolean }> = ({keywords,
|
|||||||
const {updateRoute} = useRouting();
|
const {updateRoute} = useRouting();
|
||||||
|
|
||||||
const showInviteModal = () => {
|
const showInviteModal = () => {
|
||||||
updateRoute('users/invite');
|
updateRoute('staff/invite');
|
||||||
};
|
};
|
||||||
|
|
||||||
const buttons = (
|
const buttons = (
|
||||||
@ -265,7 +265,7 @@ const Users: React.FC<{ keywords: string[], highlight?: boolean }> = ({keywords,
|
|||||||
customButtons={buttons}
|
customButtons={buttons}
|
||||||
highlightOnModalClose={highlight}
|
highlightOnModalClose={highlight}
|
||||||
keywords={keywords}
|
keywords={keywords}
|
||||||
navid='users'
|
navid='staff'
|
||||||
testId='users'
|
testId='users'
|
||||||
title='Staff'
|
title='Staff'
|
||||||
>
|
>
|
||||||
|
@ -182,7 +182,7 @@ const Access: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||||||
description='Set up default access options for subscription and posts'
|
description='Set up default access options for subscription and posts'
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
keywords={keywords}
|
keywords={keywords}
|
||||||
navid='access'
|
navid='members'
|
||||||
saveState={saveState}
|
saveState={saveState}
|
||||||
testId='access'
|
testId='access'
|
||||||
title='Access'
|
title='Access'
|
||||||
|
@ -17,7 +17,7 @@ const StripeConnectedButton: React.FC<{className?: string; onClick: () => void;}
|
|||||||
className
|
className
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<button className={className} type='button' onClick={onClick}>
|
<button className={className} data-testid='stripe-connected' type='button' onClick={onClick}>
|
||||||
<span className="inline-flex h-2 w-2 rounded-full bg-green transition-all group-hover:bg-[#625BF6]"></span>
|
<span className="inline-flex h-2 w-2 rounded-full bg-green transition-all group-hover:bg-[#625BF6]"></span>
|
||||||
<span className='ml-2'>Connected to Stripe</span>
|
<span className='ml-2'>Connected to Stripe</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -103,6 +103,8 @@ const TipsOrDonations: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
|||||||
fullWidth={false}
|
fullWidth={false}
|
||||||
options={currencySelectGroups()}
|
options={currencySelectGroups()}
|
||||||
selectedOption={currencySelectGroups().flatMap(group => group.options).find(option => option.value === donationsCurrency)}
|
selectedOption={currencySelectGroups().flatMap(group => group.options).find(option => option.value === donationsCurrency)}
|
||||||
|
title='Currency'
|
||||||
|
hideTitle
|
||||||
isSearchable
|
isSearchable
|
||||||
onSelect={option => updateSetting('donations_currency', option?.value || 'USD')}
|
onSelect={option => updateSetting('donations_currency', option?.value || 'USD')}
|
||||||
/>
|
/>
|
||||||
|
@ -2,7 +2,7 @@ import Button from '../../../../admin-x-ds/global/Button';
|
|||||||
import List from '../../../../admin-x-ds/global/List';
|
import List from '../../../../admin-x-ds/global/List';
|
||||||
import ListItem from '../../../../admin-x-ds/global/ListItem';
|
import ListItem from '../../../../admin-x-ds/global/ListItem';
|
||||||
import ModalPage from '../../../../admin-x-ds/global/modal/ModalPage';
|
import ModalPage from '../../../../admin-x-ds/global/modal/ModalPage';
|
||||||
import React, {useEffect, useState} from 'react';
|
import React, {useEffect, useId, useState} from 'react';
|
||||||
import Select from '../../../../admin-x-ds/global/form/Select';
|
import Select from '../../../../admin-x-ds/global/form/Select';
|
||||||
import TextField from '../../../../admin-x-ds/global/form/TextField';
|
import TextField from '../../../../admin-x-ds/global/form/TextField';
|
||||||
import {getHomepageUrl} from '../../../../api/site';
|
import {getHomepageUrl} from '../../../../api/site';
|
||||||
@ -15,6 +15,8 @@ interface PortalLinkPrefs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PortalLink: React.FC<PortalLinkPrefs> = ({name, value}) => {
|
const PortalLink: React.FC<PortalLinkPrefs> = ({name, value}) => {
|
||||||
|
const id = useId();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ListItem
|
<ListItem
|
||||||
action={<Button color='black' label='Copy' link onClick={(e) => {
|
action={<Button color='black' label='Copy' link onClick={(e) => {
|
||||||
@ -29,8 +31,8 @@ const PortalLink: React.FC<PortalLinkPrefs> = ({name, value}) => {
|
|||||||
separator
|
separator
|
||||||
>
|
>
|
||||||
<div className='flex w-full grow items-center gap-5 py-3'>
|
<div className='flex w-full grow items-center gap-5 py-3'>
|
||||||
<span className='inline-block w-[240px] whitespace-nowrap'>{name}</span>
|
<label className='inline-block w-[240px] whitespace-nowrap' htmlFor={id}>{name}</label>
|
||||||
<TextField className='border-b-500 grow bg-transparent p-1 text-grey-700' value={value} disabled unstyled />
|
<TextField className='border-b-500 grow bg-transparent p-1 text-grey-700' id={id} value={value} disabled unstyled />
|
||||||
</div>
|
</div>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
);
|
);
|
||||||
|
@ -52,7 +52,8 @@ const TierDetailModalContent: React.FC<{tier?: Tier}> = ({tier}) => {
|
|||||||
initialState: {
|
initialState: {
|
||||||
...(tier || {}),
|
...(tier || {}),
|
||||||
trial_days: tier?.trial_days?.toString() || '',
|
trial_days: tier?.trial_days?.toString() || '',
|
||||||
currency: tier?.currency || currencies[0].isoCode
|
currency: tier?.currency || currencies[0].isoCode,
|
||||||
|
visibility: tier?.visibility || 'none'
|
||||||
},
|
},
|
||||||
onSave: async () => {
|
onSave: async () => {
|
||||||
const {trial_days: trialDays, currency, ...rest} = formState;
|
const {trial_days: trialDays, currency, ...rest} = formState;
|
||||||
|
@ -27,9 +27,9 @@ const TierCard: React.FC<TierCardProps> = ({tier}) => {
|
|||||||
const currencySymbol = currency ? getSymbol(currency) : '$';
|
const currencySymbol = currency ? getSymbol(currency) : '$';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cardContainerClasses} data-testid='tier-card'>
|
<div className={cardContainerClasses} data-testid='tier-card' data-tier={tier.slug}>
|
||||||
<div className='w-full grow' onClick={() => {
|
<div className='w-full grow' onClick={() => {
|
||||||
updateRoute({route: `tiers/show/${tier.id}`});
|
updateRoute({route: `tiers/${tier.id}`});
|
||||||
}}>
|
}}>
|
||||||
<div className='text-[1.65rem] font-bold leading-tight tracking-tight text-pink'>{tier.name}</div>
|
<div className='text-[1.65rem] font-bold leading-tight tracking-tight text-pink'>{tier.name}</div>
|
||||||
<div className='mt-2 flex items-baseline'>
|
<div className='mt-2 flex items-baseline'>
|
||||||
|
@ -8,7 +8,7 @@ const DesignAndThemeModal: React.FC<RoutingModalProps> = ({pathName}) => {
|
|||||||
|
|
||||||
if (pathName === 'design/edit') {
|
if (pathName === 'design/edit') {
|
||||||
return <DesignModal />;
|
return <DesignModal />;
|
||||||
} else if (pathName === 'design/edit/themes') {
|
} else if (pathName === 'design/change-theme') {
|
||||||
return <ChangeThemeModal />;
|
return <ChangeThemeModal />;
|
||||||
} else if (pathName === 'design/change-theme/install') {
|
} else if (pathName === 'design/change-theme/install') {
|
||||||
const url = window.location.href;
|
const url = window.location.href;
|
||||||
|
@ -66,7 +66,7 @@ const Sidebar: React.FC<{
|
|||||||
<div className='w-full px-7'>
|
<div className='w-full px-7'>
|
||||||
<button className='group flex w-full items-center justify-between text-sm font-medium opacity-80 transition-all hover:opacity-100' data-testid='change-theme' type='button' onClick={async () => {
|
<button className='group flex w-full items-center justify-between text-sm font-medium opacity-80 transition-all hover:opacity-100' data-testid='change-theme' type='button' onClick={async () => {
|
||||||
await handleSave();
|
await handleSave();
|
||||||
updateRoute('design/edit/themes');
|
updateRoute('design/change-theme');
|
||||||
}}>
|
}}>
|
||||||
<div className='text-left'>
|
<div className='text-left'>
|
||||||
<div className='font-semibold'>Change theme</div>
|
<div className='font-semibold'>Change theme</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import IframeBuffering from '../../../../utils/IframeBuffering';
|
import IframeBuffering from '../../../../utils/IframeBuffering';
|
||||||
import React, {memo} from 'react';
|
import React, {useCallback, useMemo} from 'react';
|
||||||
|
|
||||||
const getPreviewData = (announcementBackgroundColor?: string, announcementContent?: string, visibility?: string[]) => {
|
const getPreviewData = (announcementBackgroundColor?: string, announcementContent?: string, visibility?: string[]) => {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
@ -19,7 +19,10 @@ type AnnouncementBarSettings = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcementBackgroundColor, announcementContent, url, visibility}) => {
|
const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcementBackgroundColor, announcementContent, url, visibility}) => {
|
||||||
const injectContentIntoIframe = (iframe: HTMLIFrameElement) => {
|
// Avoid re-rendering iframe if an equivalent array is initialised each render
|
||||||
|
const visibilityMemo = useMemo(() => visibility, [visibility?.join(',')]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
|
const injectContentIntoIframe = useCallback((iframe: HTMLIFrameElement) => {
|
||||||
if (!url) {
|
if (!url) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -31,7 +34,7 @@ const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcement
|
|||||||
'x-ghost-preview': getPreviewData(
|
'x-ghost-preview': getPreviewData(
|
||||||
announcementBackgroundColor,
|
announcementBackgroundColor,
|
||||||
announcementContent,
|
announcementContent,
|
||||||
visibility
|
visibilityMemo
|
||||||
),
|
),
|
||||||
Accept: 'text/plain',
|
Accept: 'text/plain',
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
@ -63,7 +66,7 @@ const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcement
|
|||||||
.catch(() => {
|
.catch(() => {
|
||||||
// handle error in fetching data
|
// handle error in fetching data
|
||||||
});
|
});
|
||||||
};
|
}, [announcementBackgroundColor, announcementContent, url, visibilityMemo]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IframeBuffering
|
<IframeBuffering
|
||||||
@ -78,43 +81,4 @@ const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcement
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function arraysAreEqual(arr1: string[], arr2: string[]) {
|
export default AnnouncementBarPreview;
|
||||||
if (!arr1 || !arr2) {
|
|
||||||
return arr1 === arr2;
|
|
||||||
} // handles null or undefined values
|
|
||||||
if (arr1.length !== arr2.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (let i = 0; i < arr1.length; i++) {
|
|
||||||
if (arr1[i] !== arr2[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(AnnouncementBarPreview, (prevProps, nextProps) => {
|
|
||||||
// Check if announcementBackgroundColor changed
|
|
||||||
if (prevProps.announcementBackgroundColor !== nextProps.announcementBackgroundColor) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if announcementContent changed
|
|
||||||
if (prevProps.announcementContent !== nextProps.announcementContent) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if url changed
|
|
||||||
if (prevProps.url !== nextProps.url) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if visibility array changed in size or content
|
|
||||||
if (!arraysAreEqual(prevProps.visibility || [], nextProps.visibility || [])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we've reached this point, all props are the same
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
@ -89,9 +89,15 @@ const useSettingGroup = ({onValidate}: {onValidate?: () => ErrorMessages} = {}):
|
|||||||
|
|
||||||
// function to update the local state
|
// function to update the local state
|
||||||
const updateSetting = (key: string, value: SettingValue) => {
|
const updateSetting = (key: string, value: SettingValue) => {
|
||||||
updateForm(state => state.map(setting => (
|
updateForm((state) => {
|
||||||
setting.key === key ? {...setting, value, dirty: true} : setting
|
if (state.some(setting => setting.key === key)) {
|
||||||
)));
|
return state.map(setting => (
|
||||||
|
setting.key === key ? {...setting, value, dirty: true} : setting
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
return [...state, {key, value, dirty: true}];
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -593,5 +593,6 @@ add|ember-template-lint|no-action|2|45|2|45|55b33496610b2f4ef6b9fe62713f4b4ddee3
|
|||||||
add|ember-template-lint|no-invalid-interactive|2|45|2|45|918fdec8490009c6197091e319d6ec52ee95b983|1695340800000|1705712400000|1710896400000|app/components/gh-fullscreen-modal.hbs
|
add|ember-template-lint|no-invalid-interactive|2|45|2|45|918fdec8490009c6197091e319d6ec52ee95b983|1695340800000|1705712400000|1710896400000|app/components/gh-fullscreen-modal.hbs
|
||||||
remove|ember-template-lint|no-action|2|45|2|45|a9d29fae15800842d0e7b8f32b035ee22a23f4cb|1688342400000|1698714000000|1703898000000|app/components/gh-fullscreen-modal.hbs
|
remove|ember-template-lint|no-action|2|45|2|45|a9d29fae15800842d0e7b8f32b035ee22a23f4cb|1688342400000|1698714000000|1703898000000|app/components/gh-fullscreen-modal.hbs
|
||||||
remove|ember-template-lint|no-invalid-interactive|2|45|2|45|b6693259da29d433264b59abc9a7c7ac846a4bf6|1688342400000|1698714000000|1703898000000|app/components/gh-fullscreen-modal.hbs
|
remove|ember-template-lint|no-invalid-interactive|2|45|2|45|b6693259da29d433264b59abc9a7c7ac846a4bf6|1688342400000|1698714000000|1703898000000|app/components/gh-fullscreen-modal.hbs
|
||||||
|
remove|ember-template-lint|no-unknown-arguments-for-builtin-components|99|93|99|93|156670ca427c49c51f0a94f862b286ccc9466d92|1694649600000|1705021200000|1710205200000|app/components/gh-nav-menu/footer.hbs
|
||||||
add|ember-template-lint|no-action|213|50|213|50|693211baf08c011e77284b483c30e28ecaf63520|1696204800000|1706576400000|1711760400000|app/components/gh-post-settings-menu.hbs
|
add|ember-template-lint|no-action|213|50|213|50|693211baf08c011e77284b483c30e28ecaf63520|1696204800000|1706576400000|1711760400000|app/components/gh-post-settings-menu.hbs
|
||||||
add|ember-template-lint|no-action|785|168|785|168|0145b67f0faef0aad141c6a4269c35c6ef8f0a47|1696204800000|1706576400000|1711760400000|app/components/gh-post-settings-menu.hbs
|
add|ember-template-lint|no-action|785|168|785|168|0145b67f0faef0aad141c6a4269c35c6ef8f0a47|1696204800000|1706576400000|1711760400000|app/components/gh-post-settings-menu.hbs
|
||||||
|
@ -9,14 +9,8 @@
|
|||||||
<p class="gh-members-empty-secondary-cta">Have members already? <LinkTo @route="member.new">Add them manually</LinkTo> or <LinkTo @route="members.import">import from CSV</LinkTo></p>
|
<p class="gh-members-empty-secondary-cta">Have members already? <LinkTo @route="member.new">Add them manually</LinkTo> or <LinkTo @route="members.import">import from CSV</LinkTo></p>
|
||||||
{{else}}
|
{{else}}
|
||||||
<p>Memberships have been disabled. Adjust your Subscription Access settings to start adding members.</p>
|
<p>Memberships have been disabled. Adjust your Subscription Access settings to start adding members.</p>
|
||||||
{{#if (feature "adminXSettings")}}
|
<LinkTo @route="settings-x.settings-x" @model="access" class="gh-btn gh-btn-green">
|
||||||
<LinkTo @route="settings-x.settings-x" @model="access" class="gh-btn gh-btn-green">
|
<span>Membership settings</span>
|
||||||
<span>Membership settings</span>
|
</LinkTo>
|
||||||
</LinkTo>
|
|
||||||
{{else}}
|
|
||||||
<LinkTo @route="settings.membership" class="gh-btn gh-btn-green">
|
|
||||||
<span>Membership settings</span>
|
|
||||||
</LinkTo>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
@ -55,15 +55,9 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
{{#if (feature "adminXSettings")}}
|
<LinkTo @route="settings-x.settings-x" @model="staff/{{this.session.user.slug}}" class="dropdown-item" @role="menuitem" tabindex="-1" data-test-nav="user-profile">
|
||||||
<LinkTo @route="settings-x.settings-x" @model="users/show/{{this.session.user.slug}}" class="dropdown-item" @role="menuitem" tabindex="-1" data-test-nav="user-profile">
|
Your profile
|
||||||
Your profile
|
</LinkTo>
|
||||||
</LinkTo>
|
|
||||||
{{else}}
|
|
||||||
<LinkTo @route="settings.staff.user" @model={{this.session.user.slug}} class="dropdown-item" @role="menuitem" tabindex="-1" data-test-nav="user-profile">
|
|
||||||
Your profile
|
|
||||||
</LinkTo>
|
|
||||||
{{/if}}
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{{#unless this.session.user.isContributor}}
|
{{#unless this.session.user.isContributor}}
|
||||||
@ -106,11 +100,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center pe-all">
|
<div class="flex items-center pe-all">
|
||||||
{{#if (or (gh-user-can-admin this.session.user) this.session.user.isEditor)}}
|
{{#if (or (gh-user-can-admin this.session.user) this.session.user.isEditor)}}
|
||||||
{{#if (feature "adminXSettings")}}
|
<LinkTo class="gh-nav-bottom-tabicon" @route="settings-x" @current-when={{this.isSettingsRoute}} data-test-nav="settings">{{svg-jar "settings"}}</LinkTo>
|
||||||
<LinkTo class="gh-nav-bottom-tabicon" @route="settings-x" @current-when={{this.isSettingsRoute}} data-test-nav="settings">{{svg-jar "settings"}}</LinkTo>
|
|
||||||
{{else}}
|
|
||||||
<LinkTo class="gh-nav-bottom-tabicon" @route="settings" @current-when={{this.isSettingsRoute}} data-test-nav="settings">{{svg-jar "settings"}}</LinkTo>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="nightshift-toggle-container">
|
<div class="nightshift-toggle-container">
|
||||||
<div class="nightshift-toggle {{if this.feature.nightShift "on"}}" {{action (toggle "nightShift" this.feature)}}>
|
<div class="nightshift-toggle {{if this.feature.nightShift "on"}}" {{action (toggle "nightShift" this.feature)}}>
|
||||||
|
@ -64,7 +64,7 @@ export default class GhSearchInputComponent extends Component {
|
|||||||
|
|
||||||
if (selected.searchable === 'Users') {
|
if (selected.searchable === 'Users') {
|
||||||
let id = selected.id.replace('user.', '');
|
let id = selected.id.replace('user.', '');
|
||||||
this.router.transitionTo('settings.staff.user', id);
|
this.router.transitionTo('settings-x.settings-x', `staff/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected.searchable === 'Tags') {
|
if (selected.searchable === 'Tags') {
|
||||||
|
@ -53,41 +53,13 @@ Router.map(function () {
|
|||||||
this.route('collection.new', {path: '/collections/new'});
|
this.route('collection.new', {path: '/collections/new'});
|
||||||
this.route('collection', {path: '/collections/:collection_slug'});
|
this.route('collection', {path: '/collections/:collection_slug'});
|
||||||
|
|
||||||
this.route('settings-x', function () {
|
this.route('settings-x', {path: '/settings'}, function () {
|
||||||
this.route('settings-x', {path: '/*sub'});
|
this.route('settings-x', {path: '/*sub'});
|
||||||
});
|
});
|
||||||
this.route('settings');
|
|
||||||
this.route('settings.general', {path: '/settings/general'});
|
|
||||||
this.route('settings.membership', {path: '/settings/members'});
|
|
||||||
this.route('settings.code-injection', {path: '/settings/code-injection'});
|
|
||||||
this.route('settings.history', {path: '/settings/history'});
|
|
||||||
this.route('settings.analytics', {path: '/settings/analytics'});
|
|
||||||
this.route('settings.announcement-bar', {path: '/settings/announcement-bar'}, function () {});
|
|
||||||
|
|
||||||
// testing websockets
|
// testing websockets
|
||||||
this.route('websockets');
|
this.route('websockets');
|
||||||
|
|
||||||
// redirect from old /settings/members-email to /settings/newsletters
|
|
||||||
this.route('settings.members-email', {path: '/settings/members-email'});
|
|
||||||
this.route('settings.newsletters', {path: '/settings/newsletters'}, function () {
|
|
||||||
this.route('new-newsletter', {path: 'new'});
|
|
||||||
this.route('edit-newsletter', {path: ':newsletter_id'});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.route('settings.design', {path: '/settings/design'}, function () {
|
|
||||||
this.route('change-theme', function () {
|
|
||||||
this.route('view', {path: ':theme_name'});
|
|
||||||
this.route('install');
|
|
||||||
});
|
|
||||||
this.route('no-theme');
|
|
||||||
});
|
|
||||||
// redirect for old install route used by ghost.org/marketplace
|
|
||||||
this.route('settings.theme-install', {path: '/settings/theme/install'});
|
|
||||||
|
|
||||||
this.route('settings.staff', {path: '/settings/staff'}, function () {
|
|
||||||
this.route('user', {path: ':user_slug'});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.route('explore', function () {
|
this.route('explore', function () {
|
||||||
// actual Ember route, not rendered in iframe
|
// actual Ember route, not rendered in iframe
|
||||||
this.route('connect');
|
this.route('connect');
|
||||||
@ -100,26 +72,6 @@ Router.map(function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('settings.integrations', {path: '/settings/integrations'}, function () {
|
|
||||||
this.route('new');
|
|
||||||
});
|
|
||||||
this.route('settings.integration', {path: '/settings/integrations/:integration_id'}, function () {
|
|
||||||
this.route('webhooks.new', {path: 'webhooks/new'});
|
|
||||||
this.route('webhooks.edit', {path: 'webhooks/:webhook_id'});
|
|
||||||
});
|
|
||||||
this.route('settings.integrations.slack', {path: '/settings/integrations/slack'});
|
|
||||||
this.route('settings.integrations.amp', {path: '/settings/integrations/amp'});
|
|
||||||
this.route('settings.integrations.firstpromoter', {path: '/settings/integrations/firstpromoter'});
|
|
||||||
this.route('settings.integrations.pintura', {path: '/settings/integrations/pintura'});
|
|
||||||
this.route('settings.integrations.unsplash', {path: '/settings/integrations/unsplash'});
|
|
||||||
this.route('settings.integrations.zapier', {path: '/settings/integrations/zapier'});
|
|
||||||
|
|
||||||
this.route('settings.navigation', {path: '/settings/navigation'});
|
|
||||||
this.route('settings.labs', {path: '/settings/labs'}, function () {
|
|
||||||
this.route('import');
|
|
||||||
});
|
|
||||||
// this.route('settings.labs.import', {path: '/settings/labs/import'});
|
|
||||||
|
|
||||||
this.route('migrate');
|
this.route('migrate');
|
||||||
|
|
||||||
this.route('members', function () {
|
this.route('members', function () {
|
||||||
|
@ -7,14 +7,6 @@ export default class SettingsXRoute extends AuthenticatedRoute {
|
|||||||
@service ui;
|
@service ui;
|
||||||
@service modals;
|
@service modals;
|
||||||
|
|
||||||
beforeModel() {
|
|
||||||
super.beforeModel(...arguments);
|
|
||||||
|
|
||||||
if (!this.feature.adminXSettings) {
|
|
||||||
return this.router.transitionTo('settings');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
super.activate(...arguments);
|
super.activate(...arguments);
|
||||||
this.ui.set('isFullScreen', true);
|
this.ui.set('isFullScreen', true);
|
||||||
|
@ -4,6 +4,7 @@ import {inject as service} from '@ember/service';
|
|||||||
// need this to be authenticated
|
// need this to be authenticated
|
||||||
export default class WebsocketRoute extends AuthenticatedRoute {
|
export default class WebsocketRoute extends AuthenticatedRoute {
|
||||||
@service session;
|
@service session;
|
||||||
|
@service router;
|
||||||
|
|
||||||
beforeModel() {
|
beforeModel() {
|
||||||
super.beforeModel(...arguments);
|
super.beforeModel(...arguments);
|
||||||
@ -11,7 +12,7 @@ export default class WebsocketRoute extends AuthenticatedRoute {
|
|||||||
const user = this.session.user;
|
const user = this.session.user;
|
||||||
|
|
||||||
if (!user.isAdmin) {
|
if (!user.isAdmin) {
|
||||||
return this.transitionTo('settings.staff.user', user);
|
return this.router.transitionTo('settings-x.settings-x', `staff/${user.slug}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,15 +30,9 @@
|
|||||||
<div class="gh-offers-list-cta missing-tiers">
|
<div class="gh-offers-list-cta missing-tiers">
|
||||||
{{svg-jar "discount-bubble" class="discount-bubble"}}
|
{{svg-jar "discount-bubble" class="discount-bubble"}}
|
||||||
<h4>You must have an active tier to create offers</h4>
|
<h4>You must have an active tier to create offers</h4>
|
||||||
{{#if (feature "adminXSettings")}}
|
<LinkTo @route="settings-x.settings-x" @model="tiers" class="gh-btn gh-btn-green">
|
||||||
<LinkTo @route="settings-x.settings-x" @model="tiers" class="gh-btn gh-btn-green">
|
<span>Manage tiers</span>
|
||||||
<span>Manage tiers</span>
|
</LinkTo>
|
||||||
</LinkTo>
|
|
||||||
{{else}}
|
|
||||||
<LinkTo @route="settings.membership" class="gh-btn gh-btn-green">
|
|
||||||
<span>Manage tiers</span>
|
|
||||||
</LinkTo>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
{{else if (and this.offersExist this.filteredOffers.length)}}
|
{{else if (and this.offersExist this.filteredOffers.length)}}
|
||||||
<table class="gh-list gh-offers-list" data-test-offers-list>
|
<table class="gh-list gh-offers-list" data-test-offers-list>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<h6>Write your first post</h6>
|
<h6>Write your first post</h6>
|
||||||
<p>Test out the editor and get a feel for creating content inside Ghost.</p>
|
<p>Test out the editor and get a feel for creating content inside Ghost.</p>
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
<LinkTo class="gh-done-green" @route="settings">
|
<LinkTo class="gh-done-green" @route="settings-x">
|
||||||
<span>{{svg-jar "paint-palette"}}</span>
|
<span>{{svg-jar "paint-palette"}}</span>
|
||||||
<h6>Customize your site</h6>
|
<h6>Customize your site</h6>
|
||||||
<p>Review your settings and tweak the design to make your site just right.</p>
|
<p>Review your settings and tweak the design to make your site just right.</p>
|
||||||
|
@ -61,7 +61,7 @@ describe('Acceptance: Authentication', function () {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
await authenticateSession();
|
await authenticateSession();
|
||||||
await visit('/settings/staff');
|
await visit('/members');
|
||||||
|
|
||||||
// running `visit(url)` inside windowProxy.replaceLocation breaks
|
// running `visit(url)` inside windowProxy.replaceLocation breaks
|
||||||
// the async behaviour so we need to run `visit` here to simulate
|
// the async behaviour so we need to run `visit` here to simulate
|
||||||
@ -82,7 +82,7 @@ describe('Acceptance: Authentication', function () {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
await authenticateSession();
|
await authenticateSession();
|
||||||
await visit('/settings/staff');
|
await visit('/members');
|
||||||
|
|
||||||
// running `visit(url)` inside windowProxy.replaceLocation breaks
|
// running `visit(url)` inside windowProxy.replaceLocation breaks
|
||||||
// the async behaviour so we need to run `visit` here to simulate
|
// the async behaviour so we need to run `visit` here to simulate
|
||||||
|
@ -125,100 +125,101 @@ describe('Acceptance: Editor', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('post settings menu', function () {
|
describe('post settings menu', function () {
|
||||||
it('can set publish date', async function () {
|
// TODO: Convert to E2E test
|
||||||
let [post1] = this.server.createList('post', 2, {authors: [author]});
|
// it('can set publish date', async function () {
|
||||||
let futureTime = moment().tz('Etc/UTC').add(10, 'minutes');
|
// let [post1] = this.server.createList('post', 2, {authors: [author]});
|
||||||
|
// let futureTime = moment().tz('Etc/UTC').add(10, 'minutes');
|
||||||
|
|
||||||
// sanity check
|
// // sanity check
|
||||||
expect(
|
// expect(
|
||||||
moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD HH:mm:ss'),
|
// moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD HH:mm:ss'),
|
||||||
'initial publishedAt sanity check')
|
// 'initial publishedAt sanity check')
|
||||||
.to.equal('2015-12-19 16:25:07');
|
// .to.equal('2015-12-19 16:25:07');
|
||||||
|
|
||||||
// post id 1 is a draft, checking for draft behaviour now
|
// // post id 1 is a draft, checking for draft behaviour now
|
||||||
await visit('/editor/post/1');
|
// await visit('/editor/post/1');
|
||||||
|
|
||||||
// open post settings menu
|
// // open post settings menu
|
||||||
await click('[data-test-psm-trigger]');
|
// await click('[data-test-psm-trigger]');
|
||||||
|
|
||||||
// should error, if the publish time is in the wrong format
|
// // should error, if the publish time is in the wrong format
|
||||||
await fillIn('[data-test-date-time-picker-time-input]', 'foo');
|
// await fillIn('[data-test-date-time-picker-time-input]', 'foo');
|
||||||
await blur('[data-test-date-time-picker-time-input]');
|
// await blur('[data-test-date-time-picker-time-input]');
|
||||||
|
|
||||||
expect(find('[data-test-date-time-picker-error]').textContent.trim(), 'inline error response for invalid time')
|
// expect(find('[data-test-date-time-picker-error]').textContent.trim(), 'inline error response for invalid time')
|
||||||
.to.equal('Must be in format: "15:00"');
|
// .to.equal('Must be in format: "15:00"');
|
||||||
|
|
||||||
// should error, if the publish time is in the future
|
// // should error, if the publish time is in the future
|
||||||
// NOTE: date must be selected first, changing the time first will save
|
// // NOTE: date must be selected first, changing the time first will save
|
||||||
// with the new time
|
// // with the new time
|
||||||
await fillIn('[data-test-date-time-picker-datepicker] input', moment.tz('Etc/UTC').add(1, 'day').format('YYYY-MM-DD'));
|
// await fillIn('[data-test-date-time-picker-datepicker] input', moment.tz('Etc/UTC').add(1, 'day').format('YYYY-MM-DD'));
|
||||||
await blur('[data-test-date-time-picker-datepicker] input');
|
// await blur('[data-test-date-time-picker-datepicker] input');
|
||||||
await fillIn('[data-test-date-time-picker-time-input]', futureTime.format('HH:mm'));
|
// await fillIn('[data-test-date-time-picker-time-input]', futureTime.format('HH:mm'));
|
||||||
await blur('[data-test-date-time-picker-time-input]');
|
// await blur('[data-test-date-time-picker-time-input]');
|
||||||
|
|
||||||
expect(find('[data-test-date-time-picker-error]').textContent.trim(), 'inline error response for future time')
|
// expect(find('[data-test-date-time-picker-error]').textContent.trim(), 'inline error response for future time')
|
||||||
.to.equal('Must be in the past');
|
// .to.equal('Must be in the past');
|
||||||
|
|
||||||
// closing the PSM will reset the invalid date/time
|
// // closing the PSM will reset the invalid date/time
|
||||||
await click('[data-test-psm-trigger]');
|
// await click('[data-test-psm-trigger]');
|
||||||
await click('[data-test-psm-trigger]');
|
// await click('[data-test-psm-trigger]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-date-time-picker-error]'),
|
// find('[data-test-date-time-picker-error]'),
|
||||||
'date picker error after closing PSM'
|
// 'date picker error after closing PSM'
|
||||||
).to.not.exist;
|
// ).to.not.exist;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-date-time-picker-date-input]').value,
|
// find('[data-test-date-time-picker-date-input]').value,
|
||||||
'PSM date value after closing with invalid date'
|
// 'PSM date value after closing with invalid date'
|
||||||
).to.equal(moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD'));
|
// ).to.equal(moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD'));
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-date-time-picker-time-input]').value,
|
// find('[data-test-date-time-picker-time-input]').value,
|
||||||
'PSM time value after closing with invalid date'
|
// 'PSM time value after closing with invalid date'
|
||||||
).to.equal(moment(post1.publishedAt).tz('Etc/UTC').format('HH:mm'));
|
// ).to.equal(moment(post1.publishedAt).tz('Etc/UTC').format('HH:mm'));
|
||||||
|
|
||||||
// saves the post with the new date
|
// // saves the post with the new date
|
||||||
let validTime = moment('2017-04-09 12:00');
|
// let validTime = moment('2017-04-09 12:00');
|
||||||
await fillIn('[data-test-date-time-picker-time-input]', validTime.format('HH:mm'));
|
// await fillIn('[data-test-date-time-picker-time-input]', validTime.format('HH:mm'));
|
||||||
await blur('[data-test-date-time-picker-time-input]');
|
// await blur('[data-test-date-time-picker-time-input]');
|
||||||
await datepickerSelect('[data-test-date-time-picker-datepicker]', validTime.toDate());
|
// await datepickerSelect('[data-test-date-time-picker-datepicker]', validTime.toDate());
|
||||||
|
|
||||||
expect(moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD HH:mm:ss')).to.equal('2017-04-09 12:00:00');
|
// expect(moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD HH:mm:ss')).to.equal('2017-04-09 12:00:00');
|
||||||
|
|
||||||
// go to settings to change the timezone
|
// // go to settings to change the timezone
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
await click('[data-test-toggle-timezone]');
|
// await click('[data-test-toggle-timezone]');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL for settings')
|
// expect(currentURL(), 'currentURL for settings')
|
||||||
.to.equal('/settings/general');
|
// .to.equal('/settings/general');
|
||||||
expect(find('#timezone option:checked').textContent.trim(), 'default timezone')
|
// expect(find('#timezone option:checked').textContent.trim(), 'default timezone')
|
||||||
.to.equal('(GMT) UTC');
|
// .to.equal('(GMT) UTC');
|
||||||
|
|
||||||
// select a new timezone
|
// // select a new timezone
|
||||||
find('#timezone option[value="Pacific/Kwajalein"]').selected = true;
|
// find('#timezone option[value="Pacific/Kwajalein"]').selected = true;
|
||||||
|
|
||||||
await triggerEvent('#timezone', 'change');
|
// await triggerEvent('#timezone', 'change');
|
||||||
// save the settings
|
// // save the settings
|
||||||
await click('[data-test-button="save"]');
|
// await click('[data-test-button="save"]');
|
||||||
|
|
||||||
expect(find('#timezone option:checked').textContent.trim(), 'new timezone after saving')
|
// expect(find('#timezone option:checked').textContent.trim(), 'new timezone after saving')
|
||||||
.to.equal('(GMT +12:00) International Date Line West');
|
// .to.equal('(GMT +12:00) International Date Line West');
|
||||||
|
|
||||||
// and now go back to the editor
|
// // and now go back to the editor
|
||||||
await visit('/editor/post/1');
|
// await visit('/editor/post/1');
|
||||||
|
|
||||||
await click('[data-test-psm-trigger]');
|
// await click('[data-test-psm-trigger]');
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-date-time-picker-date-input]').value,
|
// find('[data-test-date-time-picker-date-input]').value,
|
||||||
'date after timezone change'
|
// 'date after timezone change'
|
||||||
).to.equal('2017-04-10');
|
// ).to.equal('2017-04-10');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-date-time-picker-time-input]').value,
|
// find('[data-test-date-time-picker-time-input]').value,
|
||||||
'time after timezone change'
|
// 'time after timezone change'
|
||||||
).to.equal('00:00');
|
// ).to.equal('00:00');
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('handles validation errors when scheduling', async function () {
|
it.skip('handles validation errors when scheduling', async function () {
|
||||||
|
@ -431,39 +431,40 @@ describe('Acceptance: Publish flow', function () {
|
|||||||
it('can publish');
|
it('can publish');
|
||||||
it('can schedule publish');
|
it('can schedule publish');
|
||||||
|
|
||||||
it('respects default recipient settings - usually nobody', async function () {
|
// TODO: Update to E2E test
|
||||||
// switch to "usually nobody" setting
|
// it('respects default recipient settings - usually nobody', async function () {
|
||||||
// - doing it this way so we're not testing potentially stale mocked setting keys/values
|
// // switch to "usually nobody" setting
|
||||||
await loginAsRole('Administrator', this.server);
|
// // - doing it this way so we're not testing potentially stale mocked setting keys/values
|
||||||
await visit('/settings/newsletters');
|
// await loginAsRole('Administrator', this.server);
|
||||||
await click('[data-test-toggle-membersemail]');
|
// await visit('/settings/newsletters');
|
||||||
await selectChoose('[data-test-select="default-recipients"]', 'Usually nobody');
|
// await click('[data-test-toggle-membersemail]');
|
||||||
await click('[data-test-button="save-members-settings"]');
|
// await selectChoose('[data-test-select="default-recipients"]', 'Usually nobody');
|
||||||
|
// await click('[data-test-button="save-members-settings"]');
|
||||||
|
|
||||||
const post = this.server.create('post', {status: 'draft'});
|
// const post = this.server.create('post', {status: 'draft'});
|
||||||
await visit(`/editor/post/${post.id}`);
|
// await visit(`/editor/post/${post.id}`);
|
||||||
await click('[data-test-button="publish-flow"]');
|
// await click('[data-test-button="publish-flow"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-setting="publish-type"] [data-test-setting-title]'), 'publish type title'
|
// find('[data-test-setting="publish-type"] [data-test-setting-title]'), 'publish type title'
|
||||||
).to.have.trimmed.rendered.text('Publish');
|
// ).to.have.trimmed.rendered.text('Publish');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
|
// find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
|
||||||
).to.have.trimmed.rendered.text('Not sent as newsletter');
|
// ).to.have.trimmed.rendered.text('Not sent as newsletter');
|
||||||
|
|
||||||
await click('[data-test-setting="publish-type"] [data-test-setting-title]');
|
// await click('[data-test-setting="publish-type"] [data-test-setting-title]');
|
||||||
|
|
||||||
// email-related options are enabled
|
// // email-related options are enabled
|
||||||
expect(find('[data-test-publish-type="publish+send"]')).to.not.have.attribute('disabled');
|
// expect(find('[data-test-publish-type="publish+send"]')).to.not.have.attribute('disabled');
|
||||||
expect(find('[data-test-publish-type="send"]')).to.not.have.attribute('disabled');
|
// expect(find('[data-test-publish-type="send"]')).to.not.have.attribute('disabled');
|
||||||
|
|
||||||
await click('[data-test-publish-type="publish+send"]');
|
// await click('[data-test-publish-type="publish+send"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
|
// find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
|
||||||
).to.have.trimmed.rendered.text('All 7 subscribers');
|
// ).to.have.trimmed.rendered.text('All 7 subscribers');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('handles Mailgun not being set up', async function () {
|
it('handles Mailgun not being set up', async function () {
|
||||||
disableMailgun(this.server);
|
disableMailgun(this.server);
|
||||||
|
@ -107,14 +107,14 @@ describe('Acceptance: Error Handling', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('handles ember-ajax HTML response', async function () {
|
it('handles ember-ajax HTML response', async function () {
|
||||||
this.server.del('/themes/foo/', htmlErrorResponse);
|
const tag = this.server.create('tag', {slug: 'test'});
|
||||||
|
|
||||||
await visit('/settings/design/change-theme');
|
this.server.del(`/tags/${tag.id}/`, htmlErrorResponse);
|
||||||
|
|
||||||
await click('[data-test-button="toggle-advanced"]');
|
await visit('/tags/test');
|
||||||
await click('[data-test-theme-id="foo"] [data-test-button="actions"]');
|
|
||||||
await click('[data-test-actions-for="foo"] [data-test-button="delete"]');
|
await click('[data-test-button="delete-tag"]');
|
||||||
await click('[data-test-modal="delete-theme"] [data-test-button="confirm"]');
|
await click('[data-test-modal="confirm-delete-tag"] [data-test-button="confirm"]');
|
||||||
|
|
||||||
expect(findAll('.gh-alert').length).to.equal(1);
|
expect(findAll('.gh-alert').length).to.equal(1);
|
||||||
expect(find('.gh-alert').textContent).to.not.match(/html>/);
|
expect(find('.gh-alert').textContent).to.not.match(/html>/);
|
||||||
|
@ -1,130 +1,130 @@
|
|||||||
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {
|
// import {
|
||||||
beforeEach,
|
// beforeEach,
|
||||||
describe,
|
// describe,
|
||||||
it
|
// it
|
||||||
} from 'mocha';
|
// } from 'mocha';
|
||||||
import {click, currentURL, find, findAll, triggerEvent} from '@ember/test-helpers';
|
// import {click, currentURL, find, findAll, triggerEvent} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Integrations - AMP', function () {
|
// describe('Acceptance: Settings - Integrations - AMP', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
it('redirects to signin when not authenticated', async function () {
|
// it('redirects to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/integrations/amp');
|
// await visit('/settings/integrations/amp');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as contributor', async function () {
|
// it('redirects to home page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
// let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/amp');
|
// await visit('/settings/integrations/amp');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/posts');
|
// expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as author', async function () {
|
// it('redirects to home page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
// let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/amp');
|
// await visit('/settings/integrations/amp');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as editor', async function () {
|
// it('redirects to home page when authenticated as editor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Editor'});
|
// let role = this.server.create('role', {name: 'Editor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/amp');
|
// await visit('/settings/integrations/amp');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('when logged in', function () {
|
// describe('when logged in', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it enables or disables AMP properly and saves it', async function () {
|
// it('it enables or disables AMP properly and saves it', async function () {
|
||||||
await visit('/settings/integrations/amp');
|
// await visit('/settings/integrations/amp');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
|
||||||
|
|
||||||
// AMP is disabled by default
|
// // AMP is disabled by default
|
||||||
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
|
// expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
|
||||||
|
|
||||||
await click('[data-test-amp-checkbox]');
|
// await click('[data-test-amp-checkbox]');
|
||||||
|
|
||||||
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.true;
|
// expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.true;
|
||||||
|
|
||||||
await click('[data-test-save-button]');
|
// await click('[data-test-save-button]');
|
||||||
|
|
||||||
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
let params = JSON.parse(lastRequest.requestBody);
|
// let params = JSON.parse(lastRequest.requestBody);
|
||||||
|
|
||||||
expect(params.settings.findBy('key', 'amp').value).to.equal(true);
|
// expect(params.settings.findBy('key', 'amp').value).to.equal(true);
|
||||||
|
|
||||||
// CMD-S shortcut works
|
// // CMD-S shortcut works
|
||||||
await click('[data-test-amp-checkbox]');
|
// await click('[data-test-amp-checkbox]');
|
||||||
await triggerEvent('.gh-app', 'keydown', {
|
// await triggerEvent('.gh-app', 'keydown', {
|
||||||
keyCode: 83, // s
|
// keyCode: 83, // s
|
||||||
metaKey: ctrlOrCmd === 'command',
|
// metaKey: ctrlOrCmd === 'command',
|
||||||
ctrlKey: ctrlOrCmd === 'ctrl'
|
// ctrlKey: ctrlOrCmd === 'ctrl'
|
||||||
});
|
// });
|
||||||
|
|
||||||
// we've already saved in this test so there's no on-screen indication
|
// // we've already saved in this test so there's no on-screen indication
|
||||||
// that we've had another save, check the request was fired instead
|
// // that we've had another save, check the request was fired instead
|
||||||
let [newRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [newRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
params = JSON.parse(newRequest.requestBody);
|
// params = JSON.parse(newRequest.requestBody);
|
||||||
|
|
||||||
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
|
// expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
|
||||||
expect(params.settings.findBy('key', 'amp').value).to.equal(false);
|
// expect(params.settings.findBy('key', 'amp').value).to.equal(false);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('warns when leaving without saving', async function () {
|
// it('warns when leaving without saving', async function () {
|
||||||
await visit('/settings/integrations/amp');
|
// await visit('/settings/integrations/amp');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
|
||||||
|
|
||||||
// AMP is disabled by default
|
// // AMP is disabled by default
|
||||||
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox default').to.be.false;
|
// expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox default').to.be.false;
|
||||||
|
|
||||||
await click('[data-test-amp-checkbox]');
|
// await click('[data-test-amp-checkbox]');
|
||||||
|
|
||||||
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox after click').to.be.true;
|
// expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox after click').to.be.true;
|
||||||
|
|
||||||
await visit('/settings/staff');
|
// await visit('/settings/staff');
|
||||||
|
|
||||||
expect(findAll('[data-test-modal="unsaved-settings"]').length, 'unsaved changes modal exists').to.equal(1);
|
// expect(findAll('[data-test-modal="unsaved-settings"]').length, 'unsaved changes modal exists').to.equal(1);
|
||||||
|
|
||||||
// Leave without saving
|
// // Leave without saving
|
||||||
await click('[data-test-leave-button]');
|
// await click('[data-test-leave-button]');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL after leave without saving').to.equal('/settings/staff');
|
// expect(currentURL(), 'currentURL after leave without saving').to.equal('/settings/staff');
|
||||||
|
|
||||||
await visit('/settings/integrations/amp');
|
// await visit('/settings/integrations/amp');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL after return').to.equal('/settings/integrations/amp');
|
// expect(currentURL(), 'currentURL after return').to.equal('/settings/integrations/amp');
|
||||||
|
|
||||||
// settings were not saved
|
// // settings were not saved
|
||||||
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
|
// expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,80 +1,80 @@
|
|||||||
import {authenticateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession} from 'ember-simple-auth/test-support';
|
||||||
import {click, find} from '@ember/test-helpers';
|
// import {click, find} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Analytics', function () {
|
// describe('Acceptance: Settings - Analytics', function () {
|
||||||
const hooks = setupApplicationTest();
|
// const hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
this.server.loadFixtures('configs', 'newsletters');
|
// this.server.loadFixtures('configs', 'newsletters');
|
||||||
|
|
||||||
const role = this.server.create('role', {name: 'Owner'});
|
// const role = this.server.create('role', {name: 'Owner'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can manage open rate tracking', async function () {
|
// it('can manage open rate tracking', async function () {
|
||||||
this.server.db.settings.update({key: 'email_track_opens'}, {value: 'true'});
|
// this.server.db.settings.update({key: 'email_track_opens'}, {value: 'true'});
|
||||||
|
|
||||||
await visit('/settings/analytics');
|
// await visit('/settings/analytics');
|
||||||
|
|
||||||
expect(find('[data-test-checkbox="email-track-opens"]')).to.be.checked;
|
// expect(find('[data-test-checkbox="email-track-opens"]')).to.be.checked;
|
||||||
|
|
||||||
await click('[data-test-label="email-track-opens"]');
|
// await click('[data-test-label="email-track-opens"]');
|
||||||
expect(find('[data-test-checkbox="email-track-opens"]')).to.not.be.checked;
|
// expect(find('[data-test-checkbox="email-track-opens"]')).to.not.be.checked;
|
||||||
|
|
||||||
await click('[data-test-button="save-analytics-settings"]');
|
// await click('[data-test-button="save-analytics-settings"]');
|
||||||
|
|
||||||
expect(this.server.db.settings.findBy({key: 'email_track_opens'}).value).to.equal(false);
|
// expect(this.server.db.settings.findBy({key: 'email_track_opens'}).value).to.equal(false);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can manage click tracking', async function () {
|
// it('can manage click tracking', async function () {
|
||||||
this.server.db.settings.update({key: 'email_track_clicks'}, {value: 'true'});
|
// this.server.db.settings.update({key: 'email_track_clicks'}, {value: 'true'});
|
||||||
|
|
||||||
await visit('/settings/analytics');
|
// await visit('/settings/analytics');
|
||||||
|
|
||||||
expect(find('[data-test-checkbox="email-track-clicks"]')).to.be.checked;
|
// expect(find('[data-test-checkbox="email-track-clicks"]')).to.be.checked;
|
||||||
|
|
||||||
await click('[data-test-label="email-track-clicks"]');
|
// await click('[data-test-label="email-track-clicks"]');
|
||||||
expect(find('[data-test-checkbox="email-track-clicks"]')).to.not.be.checked;
|
// expect(find('[data-test-checkbox="email-track-clicks"]')).to.not.be.checked;
|
||||||
|
|
||||||
await click('[data-test-button="save-analytics-settings"]');
|
// await click('[data-test-button="save-analytics-settings"]');
|
||||||
|
|
||||||
expect(this.server.db.settings.findBy({key: 'email_track_clicks'}).value).to.equal(false);
|
// expect(this.server.db.settings.findBy({key: 'email_track_clicks'}).value).to.equal(false);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can manage source tracking', async function () {
|
// it('can manage source tracking', async function () {
|
||||||
this.server.db.settings.update({key: 'members_track_sources'}, {value: 'true'});
|
// this.server.db.settings.update({key: 'members_track_sources'}, {value: 'true'});
|
||||||
|
|
||||||
await visit('/settings/analytics');
|
// await visit('/settings/analytics');
|
||||||
|
|
||||||
expect(find('[data-test-checkbox="members-track-sources"]')).to.be.checked;
|
// expect(find('[data-test-checkbox="members-track-sources"]')).to.be.checked;
|
||||||
|
|
||||||
await click('[data-test-label="members-track-sources"]');
|
// await click('[data-test-label="members-track-sources"]');
|
||||||
expect(find('[data-test-checkbox="members-track-sources"]')).to.not.be.checked;
|
// expect(find('[data-test-checkbox="members-track-sources"]')).to.not.be.checked;
|
||||||
|
|
||||||
await click('[data-test-button="save-analytics-settings"]');
|
// await click('[data-test-button="save-analytics-settings"]');
|
||||||
|
|
||||||
expect(this.server.db.settings.findBy({key: 'members_track_sources'}).value).to.equal(false);
|
// expect(this.server.db.settings.findBy({key: 'members_track_sources'}).value).to.equal(false);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can manage outbound link tagging', async function () {
|
// it('can manage outbound link tagging', async function () {
|
||||||
this.server.db.settings.update({key: 'outbound_link_tagging'}, {value: 'true'});
|
// this.server.db.settings.update({key: 'outbound_link_tagging'}, {value: 'true'});
|
||||||
|
|
||||||
await visit('/settings/analytics');
|
// await visit('/settings/analytics');
|
||||||
|
|
||||||
expect(find('[data-test-checkbox="outbound-link-tagging"]')).to.be.checked;
|
// expect(find('[data-test-checkbox="outbound-link-tagging"]')).to.be.checked;
|
||||||
|
|
||||||
await click('[data-test-label="outbound-link-tagging"]');
|
// await click('[data-test-label="outbound-link-tagging"]');
|
||||||
expect(find('[data-test-checkbox="outbound-link-tagging"]')).to.not.be.checked;
|
// expect(find('[data-test-checkbox="outbound-link-tagging"]')).to.not.be.checked;
|
||||||
|
|
||||||
await click('[data-test-button="save-analytics-settings"]');
|
// await click('[data-test-button="save-analytics-settings"]');
|
||||||
|
|
||||||
expect(this.server.db.settings.findBy({key: 'outbound_link_tagging'}).value).to.equal(false);
|
// expect(this.server.db.settings.findBy({key: 'outbound_link_tagging'}).value).to.equal(false);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,113 +1,113 @@
|
|||||||
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {
|
// import {
|
||||||
beforeEach,
|
// beforeEach,
|
||||||
describe,
|
// describe,
|
||||||
it
|
// it
|
||||||
} from 'mocha';
|
// } from 'mocha';
|
||||||
import {click, currentURL, fillIn, find, findAll, triggerEvent} from '@ember/test-helpers';
|
// import {click, currentURL, fillIn, find, findAll, triggerEvent} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Code-Injection', function () {
|
// describe('Acceptance: Settings - Code-Injection', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
it('redirects to signin when not authenticated', async function () {
|
// it('redirects to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/code-injection');
|
// await visit('/settings/code-injection');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as contributor', async function () {
|
// it('redirects to home page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
// let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/code-injection');
|
// await visit('/settings/code-injection');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/posts');
|
// expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to staff page when authenticated as author', async function () {
|
// it('redirects to staff page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
// let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/code-injection');
|
// await visit('/settings/code-injection');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as editor', async function () {
|
// it('redirects to home page when authenticated as editor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Editor'});
|
// let role = this.server.create('role', {name: 'Editor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/code-injection');
|
// await visit('/settings/code-injection');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('when logged in', function () {
|
// describe('when logged in', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it renders, loads and saves editors correctly', async function () {
|
// it('it renders, loads and saves editors correctly', async function () {
|
||||||
await visit('/settings/code-injection');
|
// await visit('/settings/code-injection');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/code-injection');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/code-injection');
|
||||||
|
|
||||||
// has correct page title
|
// // has correct page title
|
||||||
expect(document.title, 'page title').to.equal('Settings - Code injection - Test Blog');
|
// expect(document.title, 'page title').to.equal('Settings - Code injection - Test Blog');
|
||||||
|
|
||||||
expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
// expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
||||||
|
|
||||||
expect(findAll('#ghost-head .CodeMirror').length, 'ghost head codemirror element').to.equal(1);
|
// expect(findAll('#ghost-head .CodeMirror').length, 'ghost head codemirror element').to.equal(1);
|
||||||
expect(find('#ghost-head .CodeMirror'), 'ghost head editor theme').to.have.class('cm-s-xq-light');
|
// expect(find('#ghost-head .CodeMirror'), 'ghost head editor theme').to.have.class('cm-s-xq-light');
|
||||||
|
|
||||||
expect(findAll('#ghost-foot .CodeMirror').length, 'ghost head codemirror element').to.equal(1);
|
// expect(findAll('#ghost-foot .CodeMirror').length, 'ghost head codemirror element').to.equal(1);
|
||||||
expect(find('#ghost-foot .CodeMirror'), 'ghost head editor theme').to.have.class('cm-s-xq-light');
|
// expect(find('#ghost-foot .CodeMirror'), 'ghost head editor theme').to.have.class('cm-s-xq-light');
|
||||||
|
|
||||||
await fillIn('#settings-code #ghost-head textarea', 'Test');
|
// await fillIn('#settings-code #ghost-head textarea', 'Test');
|
||||||
|
|
||||||
await click('[data-test-save-button]');
|
// await click('[data-test-save-button]');
|
||||||
|
|
||||||
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
let params = JSON.parse(lastRequest.requestBody);
|
// let params = JSON.parse(lastRequest.requestBody);
|
||||||
|
|
||||||
expect(params.settings.findBy('key', 'codeinjection_head').value).to.equal('Test');
|
// expect(params.settings.findBy('key', 'codeinjection_head').value).to.equal('Test');
|
||||||
// update should have been partial
|
// // update should have been partial
|
||||||
expect(params.settings.findBy('key', 'navigation')).to.be.undefined;
|
// expect(params.settings.findBy('key', 'navigation')).to.be.undefined;
|
||||||
expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
// expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
||||||
|
|
||||||
await fillIn('#settings-code #ghost-head textarea', '');
|
// await fillIn('#settings-code #ghost-head textarea', '');
|
||||||
|
|
||||||
// CMD-S shortcut works
|
// // CMD-S shortcut works
|
||||||
await triggerEvent('.gh-app', 'keydown', {
|
// await triggerEvent('.gh-app', 'keydown', {
|
||||||
keyCode: 83, // s
|
// keyCode: 83, // s
|
||||||
metaKey: ctrlOrCmd === 'command',
|
// metaKey: ctrlOrCmd === 'command',
|
||||||
ctrlKey: ctrlOrCmd === 'ctrl'
|
// ctrlKey: ctrlOrCmd === 'ctrl'
|
||||||
});
|
// });
|
||||||
|
|
||||||
let [newRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [newRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
params = JSON.parse(newRequest.requestBody);
|
// params = JSON.parse(newRequest.requestBody);
|
||||||
|
|
||||||
expect(params.settings.findBy('key', 'codeinjection_head').value).to.equal('');
|
// expect(params.settings.findBy('key', 'codeinjection_head').value).to.equal('');
|
||||||
expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
// expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
||||||
|
|
||||||
// Saving when no changed have been made should work
|
// // Saving when no changed have been made should work
|
||||||
// (although no api request is expected)
|
// // (although no api request is expected)
|
||||||
await click('[data-test-save-button]');
|
// await click('[data-test-save-button]');
|
||||||
expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
// expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,159 +1,159 @@
|
|||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
|
// import {click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {fileUpload} from '../../helpers/file-upload';
|
// import {fileUpload} from '../../helpers/file-upload';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Design', function () {
|
// describe('Acceptance: Settings - Design', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
this.server.loadFixtures('themes');
|
// this.server.loadFixtures('themes');
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to signin when not authenticated', async function () {
|
// it('redirects to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('renders with no custom theme settings', async function () {
|
// it('renders with no custom theme settings', async function () {
|
||||||
await visit('/settings');
|
// await visit('/settings');
|
||||||
await click('[data-test-nav="design"]');
|
// await click('[data-test-nav="design"]');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/design');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/design');
|
||||||
expect(document.title, 'page title').to.equal('Settings - Design - Test Blog');
|
// expect(document.title, 'page title').to.equal('Settings - Design - Test Blog');
|
||||||
|
|
||||||
// side nav menu changes
|
// // side nav menu changes
|
||||||
expect(find('[data-test-nav-menu="design"]'), 'design menu').to.exist;
|
// expect(find('[data-test-nav-menu="design"]'), 'design menu').to.exist;
|
||||||
expect(find('[data-test-nav-menu="main"]'), 'main menu').to.not.exist;
|
// expect(find('[data-test-nav-menu="main"]'), 'main menu').to.not.exist;
|
||||||
|
|
||||||
// side nav defaults to general group open
|
// // side nav defaults to general group open
|
||||||
expect(find('[data-test-nav-toggle="general"]'), 'general toggle').to.exist;
|
// expect(find('[data-test-nav-toggle="general"]'), 'general toggle').to.exist;
|
||||||
expect(find('[data-test-nav-group="general"]'), 'general form').to.exist;
|
// expect(find('[data-test-nav-group="general"]'), 'general form').to.exist;
|
||||||
|
|
||||||
// no other side nav groups exist
|
// // no other side nav groups exist
|
||||||
expect(findAll('[data-test-nav-toggle]'), 'no of group toggles').to.have.lengthOf(1);
|
// expect(findAll('[data-test-nav-toggle]'), 'no of group toggles').to.have.lengthOf(1);
|
||||||
expect(findAll('[data-test-nav-group]'), 'no of groups open').to.have.lengthOf(1);
|
// expect(findAll('[data-test-nav-group]'), 'no of groups open').to.have.lengthOf(1);
|
||||||
|
|
||||||
// current theme is shown in nav menu
|
// // current theme is shown in nav menu
|
||||||
expect(find('[data-test-text="current-theme"]')).to.contain.text('source - v1.0');
|
// expect(find('[data-test-text="current-theme"]')).to.contain.text('source - v1.0');
|
||||||
|
|
||||||
// defaults to "home" desktop preview
|
// // defaults to "home" desktop preview
|
||||||
expect(find('[data-test-button="desktop-preview"]')).to.have.class('gh-btn-group-selected');
|
// expect(find('[data-test-button="desktop-preview"]')).to.have.class('gh-btn-group-selected');
|
||||||
expect(find('[data-test-button="mobile-preview"]')).to.not.have.class('gh-btn-group-selected');
|
// expect(find('[data-test-button="mobile-preview"]')).to.not.have.class('gh-btn-group-selected');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('has unsaved-changes confirmation', async function () {
|
// it('has unsaved-changes confirmation', async function () {
|
||||||
await visit('/settings/design');
|
// await visit('/settings/design');
|
||||||
await fillIn('[data-test-input="siteDescription"]', 'Changed');
|
// await fillIn('[data-test-input="siteDescription"]', 'Changed');
|
||||||
await click('[data-test-link="back-to-settings"]');
|
// await click('[data-test-link="back-to-settings"]');
|
||||||
|
|
||||||
expect(find('[data-test-modal="unsaved-settings"]')).to.exist;
|
// expect(find('[data-test-modal="unsaved-settings"]')).to.exist;
|
||||||
|
|
||||||
await click('[data-test-modal="unsaved-settings"] [data-test-button="close"]');
|
// await click('[data-test-modal="unsaved-settings"] [data-test-button="close"]');
|
||||||
|
|
||||||
expect(currentURL()).to.equal('/settings/design');
|
// expect(currentURL()).to.equal('/settings/design');
|
||||||
|
|
||||||
await click('[data-test-link="back-to-settings"]');
|
// await click('[data-test-link="back-to-settings"]');
|
||||||
await click('[data-test-modal="unsaved-settings"] [data-test-leave-button]');
|
// await click('[data-test-modal="unsaved-settings"] [data-test-leave-button]');
|
||||||
|
|
||||||
expect(currentURL()).to.equal('/settings');
|
// expect(currentURL()).to.equal('/settings');
|
||||||
|
|
||||||
await click('[data-test-nav="design"]');
|
// await click('[data-test-nav="design"]');
|
||||||
|
|
||||||
expect(find('[data-test-input="siteDescription"]')).to.not.have.value('Changed');
|
// expect(find('[data-test-input="siteDescription"]')).to.not.have.value('Changed');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('renders with custom theme settings');
|
// it('renders with custom theme settings');
|
||||||
|
|
||||||
it('can install an official theme', async function () {
|
// it('can install an official theme', async function () {
|
||||||
await visit('/settings/design');
|
// await visit('/settings/design');
|
||||||
await click('[data-test-nav="change-theme"]');
|
// await click('[data-test-nav="change-theme"]');
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/design/change-theme');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/design/change-theme');
|
||||||
|
|
||||||
await click('[data-test-theme-link="Journal"]');
|
// await click('[data-test-theme-link="Journal"]');
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/design/change-theme/Journal');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/design/change-theme/Journal');
|
||||||
|
|
||||||
await click('[data-test-button="install-theme"]');
|
// await click('[data-test-button="install-theme"]');
|
||||||
expect(find('[data-test-modal="install-theme"]'), 'install-theme modal').to.exist;
|
// expect(find('[data-test-modal="install-theme"]'), 'install-theme modal').to.exist;
|
||||||
expect(find('[data-test-state="confirm"]'), 'confirm state').to.exist;
|
// expect(find('[data-test-state="confirm"]'), 'confirm state').to.exist;
|
||||||
expect(findAll('[data-test-state]').length, 'state count').to.equal(1);
|
// expect(findAll('[data-test-state]').length, 'state count').to.equal(1);
|
||||||
|
|
||||||
await click('[data-test-button="confirm-install"]');
|
// await click('[data-test-button="confirm-install"]');
|
||||||
expect(find('[data-test-state="installed-no-notes"]'), 'success state').to.exist;
|
// expect(find('[data-test-state="installed-no-notes"]'), 'success state').to.exist;
|
||||||
expect(findAll('[data-test-state]').length, 'state count').to.equal(1);
|
// expect(findAll('[data-test-state]').length, 'state count').to.equal(1);
|
||||||
|
|
||||||
// navigates back to design screen in background
|
// // navigates back to design screen in background
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/design');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/design');
|
||||||
|
|
||||||
await click('[data-test-button="cancel"]');
|
// await click('[data-test-button="cancel"]');
|
||||||
expect(find('[data-test-modal="install-theme"]')).to.not.exist;
|
// expect(find('[data-test-modal="install-theme"]')).to.not.exist;
|
||||||
|
|
||||||
// nav menu shows current theme
|
// // nav menu shows current theme
|
||||||
expect(find('[data-test-text="current-theme"]')).to.contain.text('Journal - v0.1');
|
// expect(find('[data-test-text="current-theme"]')).to.contain.text('Journal - v0.1');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can upload custom theme', async function () {
|
// it('can upload custom theme', async function () {
|
||||||
this.server.post('/themes/upload/', function ({themes}) {
|
// this.server.post('/themes/upload/', function ({themes}) {
|
||||||
const theme = themes.create({
|
// const theme = themes.create({
|
||||||
name: 'custom',
|
// name: 'custom',
|
||||||
package: {
|
// package: {
|
||||||
name: 'Custom',
|
// name: 'Custom',
|
||||||
version: '1.0'
|
// version: '1.0'
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
return {themes: [theme]};
|
// return {themes: [theme]};
|
||||||
});
|
// });
|
||||||
|
|
||||||
await visit('/settings/design/change-theme');
|
// await visit('/settings/design/change-theme');
|
||||||
await click('[data-test-button="upload-theme"]');
|
// await click('[data-test-button="upload-theme"]');
|
||||||
|
|
||||||
expect(find('[data-test-modal="upload-theme"]'), 'upload-theme modal').to.exist;
|
// expect(find('[data-test-modal="upload-theme"]'), 'upload-theme modal').to.exist;
|
||||||
|
|
||||||
await fileUpload('[data-test-modal="upload-theme"] input[type="file"]', ['test'], {name: 'valid-theme.zip', type: 'application/zip'});
|
// await fileUpload('[data-test-modal="upload-theme"] input[type="file"]', ['test'], {name: 'valid-theme.zip', type: 'application/zip'});
|
||||||
|
|
||||||
expect(find('[data-test-state="installed-no-notes"]'), 'success state').to.exist;
|
// expect(find('[data-test-state="installed-no-notes"]'), 'success state').to.exist;
|
||||||
expect(currentURL(), 'url after upload').to.equal('/settings/design/change-theme');
|
// expect(currentURL(), 'url after upload').to.equal('/settings/design/change-theme');
|
||||||
|
|
||||||
await click('[data-test-button="activate"]');
|
// await click('[data-test-button="activate"]');
|
||||||
|
|
||||||
expect(currentURL(), 'url after activate').to.equal('/settings/design');
|
// expect(currentURL(), 'url after activate').to.equal('/settings/design');
|
||||||
expect(find('[data-test-modal="install-theme"]')).to.not.exist;
|
// expect(find('[data-test-modal="install-theme"]')).to.not.exist;
|
||||||
expect(find('[data-test-text="current-theme"]')).to.contain.text('custom - v1.0');
|
// expect(find('[data-test-text="current-theme"]')).to.contain.text('custom - v1.0');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can change between installed themes');
|
// it('can change between installed themes');
|
||||||
it('can delete installed theme');
|
// it('can delete installed theme');
|
||||||
|
|
||||||
describe('limits', function () {
|
// describe('limits', function () {
|
||||||
it('displays upgrade notice when custom themes are not allowed', async function () {
|
// it('displays upgrade notice when custom themes are not allowed', async function () {
|
||||||
this.server.loadFixtures('configs');
|
// this.server.loadFixtures('configs');
|
||||||
const config = this.server.db.configs.find(1);
|
// const config = this.server.db.configs.find(1);
|
||||||
config.hostSettings = {
|
// config.hostSettings = {
|
||||||
limits: {
|
// limits: {
|
||||||
customThemes: {
|
// customThemes: {
|
||||||
allowlist: ['source', 'casper', 'dawn', 'lyra'],
|
// allowlist: ['source', 'casper', 'dawn', 'lyra'],
|
||||||
error: 'All our official built-in themes are available the Starter plan, if you upgrade to one of our higher tiers you will also be able to edit and upload custom themes for your site.'
|
// error: 'All our official built-in themes are available the Starter plan, if you upgrade to one of our higher tiers you will also be able to edit and upload custom themes for your site.'
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
this.server.db.configs.update(1, config);
|
// this.server.db.configs.update(1, config);
|
||||||
|
|
||||||
await visit('/settings/design/change-theme');
|
// await visit('/settings/design/change-theme');
|
||||||
await click('[data-test-button="upload-theme"]');
|
// await click('[data-test-button="upload-theme"]');
|
||||||
|
|
||||||
expect(find('[data-test-modal="limits/custom-theme"]'), 'limits/custom-theme modal').to.exist;
|
// expect(find('[data-test-modal="limits/custom-theme"]'), 'limits/custom-theme modal').to.exist;
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,291 +1,291 @@
|
|||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {beforeEach, describe, it} from 'mocha';
|
// import {beforeEach, describe, it} from 'mocha';
|
||||||
import {blur, click, currentURL, fillIn, find, findAll, focus, triggerEvent} from '@ember/test-helpers';
|
// import {blur, click, currentURL, fillIn, find, findAll, focus, triggerEvent} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {keyDown} from 'ember-keyboard/test-support/test-helpers';
|
// import {keyDown} from 'ember-keyboard/test-support/test-helpers';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - General', function () {
|
// describe('Acceptance: Settings - General', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
it('redirects to signin when not authenticated', async function () {
|
// it('redirects to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as contributor', async function () {
|
// it('redirects to home page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
// let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/posts');
|
// expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as author', async function () {
|
// it('redirects to home page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
// let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as editor', async function () {
|
// it('redirects to home page when authenticated as editor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Editor'});
|
// let role = this.server.create('role', {name: 'Editor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('when logged in', function () {
|
// describe('when logged in', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it renders, handles image uploads', async function () {
|
// it('it renders, handles image uploads', async function () {
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/general');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/general');
|
||||||
|
|
||||||
// has correct page title
|
// // has correct page title
|
||||||
expect(document.title, 'page title').to.equal('Settings - General - Test Blog');
|
// expect(document.title, 'page title').to.equal('Settings - General - Test Blog');
|
||||||
|
|
||||||
// highlights nav menu
|
// // highlights nav menu
|
||||||
expect(find('[data-test-nav="settings"]'), 'highlights nav menu item')
|
// expect(find('[data-test-nav="settings"]'), 'highlights nav menu item')
|
||||||
.to.have.class('active');
|
// .to.have.class('active');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-button="save"]').textContent.trim(),
|
// find('[data-test-button="save"]').textContent.trim(),
|
||||||
'save button text'
|
// 'save button text'
|
||||||
).to.equal('Save');
|
// ).to.equal('Save');
|
||||||
|
|
||||||
await click('[data-test-toggle-pub-info]');
|
// await click('[data-test-toggle-pub-info]');
|
||||||
await fillIn('[data-test-title-input]', 'New Blog Title');
|
// await fillIn('[data-test-title-input]', 'New Blog Title');
|
||||||
await click('[data-test-button="save"]');
|
// await click('[data-test-button="save"]');
|
||||||
expect(document.title, 'page title').to.equal('Settings - General - New Blog Title');
|
// expect(document.title, 'page title').to.equal('Settings - General - New Blog Title');
|
||||||
|
|
||||||
// CMD-S shortcut works
|
// // CMD-S shortcut works
|
||||||
// -------------------------------------------------------------- //
|
// // -------------------------------------------------------------- //
|
||||||
await fillIn('[data-test-title-input]', 'CMD-S Test');
|
// await fillIn('[data-test-title-input]', 'CMD-S Test');
|
||||||
await keyDown('cmd+s');
|
// await keyDown('cmd+s');
|
||||||
// we've already saved in this test so there's no on-screen indication
|
// // we've already saved in this test so there's no on-screen indication
|
||||||
// that we've had another save, check the request was fired instead
|
// // that we've had another save, check the request was fired instead
|
||||||
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
let params = JSON.parse(lastRequest.requestBody);
|
// let params = JSON.parse(lastRequest.requestBody);
|
||||||
expect(params.settings.findBy('key', 'title').value).to.equal('CMD-S Test');
|
// expect(params.settings.findBy('key', 'title').value).to.equal('CMD-S Test');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('renders timezone selector correctly', async function () {
|
// it('renders timezone selector correctly', async function () {
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
await click('[data-test-toggle-timezone]');
|
// await click('[data-test-toggle-timezone]');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/general');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/general');
|
||||||
|
|
||||||
expect(findAll('#timezone option').length, 'available timezones').to.equal(66);
|
// expect(findAll('#timezone option').length, 'available timezones').to.equal(66);
|
||||||
expect(find('#timezone option:checked').textContent.trim()).to.equal('(GMT) UTC');
|
// expect(find('#timezone option:checked').textContent.trim()).to.equal('(GMT) UTC');
|
||||||
find('#timezone option[value="Africa/Cairo"]').selected = true;
|
// find('#timezone option[value="Africa/Cairo"]').selected = true;
|
||||||
|
|
||||||
await triggerEvent('#timezone', 'change');
|
// await triggerEvent('#timezone', 'change');
|
||||||
await click('[data-test-button="save"]');
|
// await click('[data-test-button="save"]');
|
||||||
expect(find('#timezone option:checked').textContent.trim()).to.equal('(GMT +2:00) Cairo, Egypt');
|
// expect(find('#timezone option:checked').textContent.trim()).to.equal('(GMT +2:00) Cairo, Egypt');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('handles private blog settings correctly', async function () {
|
// it('handles private blog settings correctly', async function () {
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
|
|
||||||
// handles private blog settings correctly
|
// // handles private blog settings correctly
|
||||||
expect(find('[data-test-private-checkbox]').checked, 'isPrivate checkbox').to.be.false;
|
// expect(find('[data-test-private-checkbox]').checked, 'isPrivate checkbox').to.be.false;
|
||||||
|
|
||||||
await click('[data-test-private-checkbox]');
|
// await click('[data-test-private-checkbox]');
|
||||||
|
|
||||||
expect(find('[data-test-private-checkbox]').checked, 'isPrivate checkbox').to.be.true;
|
// expect(find('[data-test-private-checkbox]').checked, 'isPrivate checkbox').to.be.true;
|
||||||
expect(findAll('[data-test-password-input]').length, 'password input').to.equal(1);
|
// expect(findAll('[data-test-password-input]').length, 'password input').to.equal(1);
|
||||||
expect(find('[data-test-password-input]').value, 'password default value').to.not.equal('');
|
// expect(find('[data-test-password-input]').value, 'password default value').to.not.equal('');
|
||||||
|
|
||||||
await fillIn('[data-test-password-input]', '');
|
// await fillIn('[data-test-password-input]', '');
|
||||||
await blur('[data-test-password-input]');
|
// await blur('[data-test-password-input]');
|
||||||
|
|
||||||
expect(find('[data-test-password-error]').textContent.trim(), 'empty password error')
|
// expect(find('[data-test-password-error]').textContent.trim(), 'empty password error')
|
||||||
.to.equal('Password must be supplied');
|
// .to.equal('Password must be supplied');
|
||||||
|
|
||||||
await fillIn('[data-test-password-input]', 'asdfg');
|
// await fillIn('[data-test-password-input]', 'asdfg');
|
||||||
await blur('[data-test-password-input]');
|
// await blur('[data-test-password-input]');
|
||||||
|
|
||||||
expect(find('[data-test-password-error]').textContent.trim(), 'present password error')
|
// expect(find('[data-test-password-error]').textContent.trim(), 'present password error')
|
||||||
.to.equal('');
|
// .to.equal('');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('handles social blog settings correctly', async function () {
|
// it('handles social blog settings correctly', async function () {
|
||||||
let testSocialInput = async function (type, input, expectedValue, expectedError = '') {
|
// let testSocialInput = async function (type, input, expectedValue, expectedError = '') {
|
||||||
await fillIn(`[data-test-${type}-input]`, input);
|
// await fillIn(`[data-test-${type}-input]`, input);
|
||||||
await blur(`[data-test-${type}-input]`);
|
// await blur(`[data-test-${type}-input]`);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find(`[data-test-${type}-input]`).value,
|
// find(`[data-test-${type}-input]`).value,
|
||||||
`${type} value for ${input}`
|
// `${type} value for ${input}`
|
||||||
).to.equal(expectedValue);
|
// ).to.equal(expectedValue);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find(`[data-test-${type}-error]`).textContent.trim(),
|
// find(`[data-test-${type}-error]`).textContent.trim(),
|
||||||
`${type} validation response for ${input}`
|
// `${type} validation response for ${input}`
|
||||||
).to.equal(expectedError);
|
// ).to.equal(expectedError);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find(`[data-test-${type}-input]`).closest('.form-group').classList.contains('error'),
|
// find(`[data-test-${type}-input]`).closest('.form-group').classList.contains('error'),
|
||||||
`${type} input should be in error state with '${input}'`
|
// `${type} input should be in error state with '${input}'`
|
||||||
).to.equal(!!expectedError);
|
// ).to.equal(!!expectedError);
|
||||||
};
|
// };
|
||||||
|
|
||||||
let testFacebookValidation = async (...args) => testSocialInput('facebook', ...args);
|
// let testFacebookValidation = async (...args) => testSocialInput('facebook', ...args);
|
||||||
let testTwitterValidation = async (...args) => testSocialInput('twitter', ...args);
|
// let testTwitterValidation = async (...args) => testSocialInput('twitter', ...args);
|
||||||
|
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
await click('[data-test-toggle-social]');
|
// await click('[data-test-toggle-social]');
|
||||||
|
|
||||||
// validates a facebook url correctly
|
// // validates a facebook url correctly
|
||||||
// loads fixtures and performs transform
|
// // loads fixtures and performs transform
|
||||||
expect(find('[data-test-facebook-input]').value, 'initial facebook value')
|
// expect(find('[data-test-facebook-input]').value, 'initial facebook value')
|
||||||
.to.equal('https://www.facebook.com/test');
|
// .to.equal('https://www.facebook.com/test');
|
||||||
|
|
||||||
await focus('[data-test-facebook-input]');
|
// await focus('[data-test-facebook-input]');
|
||||||
await blur('[data-test-facebook-input]');
|
// await blur('[data-test-facebook-input]');
|
||||||
|
|
||||||
// regression test: we still have a value after the input is
|
// // regression test: we still have a value after the input is
|
||||||
// focused and then blurred without any changes
|
// // focused and then blurred without any changes
|
||||||
expect(find('[data-test-facebook-input]').value, 'facebook value after blur with no change')
|
// expect(find('[data-test-facebook-input]').value, 'facebook value after blur with no change')
|
||||||
.to.equal('https://www.facebook.com/test');
|
// .to.equal('https://www.facebook.com/test');
|
||||||
|
|
||||||
await testFacebookValidation(
|
// await testFacebookValidation(
|
||||||
'facebook.com/username',
|
// 'facebook.com/username',
|
||||||
'https://www.facebook.com/username');
|
// 'https://www.facebook.com/username');
|
||||||
|
|
||||||
await testFacebookValidation(
|
// await testFacebookValidation(
|
||||||
'testuser',
|
// 'testuser',
|
||||||
'https://www.facebook.com/testuser');
|
// 'https://www.facebook.com/testuser');
|
||||||
|
|
||||||
await testFacebookValidation(
|
// await testFacebookValidation(
|
||||||
'ab99',
|
// 'ab99',
|
||||||
'https://www.facebook.com/ab99');
|
// 'https://www.facebook.com/ab99');
|
||||||
|
|
||||||
await testFacebookValidation(
|
// await testFacebookValidation(
|
||||||
'page/ab99',
|
// 'page/ab99',
|
||||||
'https://www.facebook.com/page/ab99');
|
// 'https://www.facebook.com/page/ab99');
|
||||||
|
|
||||||
await testFacebookValidation(
|
// await testFacebookValidation(
|
||||||
'page/*(&*(%%))',
|
// 'page/*(&*(%%))',
|
||||||
'https://www.facebook.com/page/*(&*(%%))');
|
// 'https://www.facebook.com/page/*(&*(%%))');
|
||||||
|
|
||||||
await testFacebookValidation(
|
// await testFacebookValidation(
|
||||||
'facebook.com/pages/some-facebook-page/857469375913?ref=ts',
|
// 'facebook.com/pages/some-facebook-page/857469375913?ref=ts',
|
||||||
'https://www.facebook.com/pages/some-facebook-page/857469375913?ref=ts');
|
// 'https://www.facebook.com/pages/some-facebook-page/857469375913?ref=ts');
|
||||||
|
|
||||||
await testFacebookValidation(
|
// await testFacebookValidation(
|
||||||
'https://www.facebook.com/groups/savethecrowninn',
|
// 'https://www.facebook.com/groups/savethecrowninn',
|
||||||
'https://www.facebook.com/groups/savethecrowninn');
|
// 'https://www.facebook.com/groups/savethecrowninn');
|
||||||
|
|
||||||
await testFacebookValidation(
|
// await testFacebookValidation(
|
||||||
'http://github.com/username',
|
// 'http://github.com/username',
|
||||||
'http://github.com/username',
|
// 'http://github.com/username',
|
||||||
'The URL must be in a format like https://www.facebook.com/yourPage');
|
// 'The URL must be in a format like https://www.facebook.com/yourPage');
|
||||||
|
|
||||||
await testFacebookValidation(
|
// await testFacebookValidation(
|
||||||
'http://github.com/pages/username',
|
// 'http://github.com/pages/username',
|
||||||
'http://github.com/pages/username',
|
// 'http://github.com/pages/username',
|
||||||
'The URL must be in a format like https://www.facebook.com/yourPage');
|
// 'The URL must be in a format like https://www.facebook.com/yourPage');
|
||||||
|
|
||||||
// validates a twitter url correctly
|
// // validates a twitter url correctly
|
||||||
|
|
||||||
// loads fixtures and performs transform
|
// // loads fixtures and performs transform
|
||||||
expect(find('[data-test-twitter-input]').value, 'initial twitter value')
|
// expect(find('[data-test-twitter-input]').value, 'initial twitter value')
|
||||||
.to.equal('https://twitter.com/test');
|
// .to.equal('https://twitter.com/test');
|
||||||
|
|
||||||
await focus('[data-test-twitter-input]');
|
// await focus('[data-test-twitter-input]');
|
||||||
await blur('[data-test-twitter-input]');
|
// await blur('[data-test-twitter-input]');
|
||||||
|
|
||||||
// regression test: we still have a value after the input is
|
// // regression test: we still have a value after the input is
|
||||||
// focused and then blurred without any changes
|
// // focused and then blurred without any changes
|
||||||
expect(find('[data-test-twitter-input]').value, 'twitter value after blur with no change')
|
// expect(find('[data-test-twitter-input]').value, 'twitter value after blur with no change')
|
||||||
.to.equal('https://twitter.com/test');
|
// .to.equal('https://twitter.com/test');
|
||||||
|
|
||||||
await testTwitterValidation(
|
// await testTwitterValidation(
|
||||||
'twitter.com/username',
|
// 'twitter.com/username',
|
||||||
'https://twitter.com/username');
|
// 'https://twitter.com/username');
|
||||||
|
|
||||||
await testTwitterValidation(
|
// await testTwitterValidation(
|
||||||
'testuser',
|
// 'testuser',
|
||||||
'https://twitter.com/testuser');
|
// 'https://twitter.com/testuser');
|
||||||
|
|
||||||
await testTwitterValidation(
|
// await testTwitterValidation(
|
||||||
'http://github.com/username',
|
// 'http://github.com/username',
|
||||||
'https://twitter.com/username');
|
// 'https://twitter.com/username');
|
||||||
|
|
||||||
await testTwitterValidation(
|
// await testTwitterValidation(
|
||||||
'*(&*(%%))',
|
// '*(&*(%%))',
|
||||||
'*(&*(%%))',
|
// '*(&*(%%))',
|
||||||
'The URL must be in a format like https://twitter.com/yourUsername');
|
// 'The URL must be in a format like https://twitter.com/yourUsername');
|
||||||
|
|
||||||
await testTwitterValidation(
|
// await testTwitterValidation(
|
||||||
'thisusernamehasmorethan15characters',
|
// 'thisusernamehasmorethan15characters',
|
||||||
'thisusernamehasmorethan15characters',
|
// 'thisusernamehasmorethan15characters',
|
||||||
'Your Username is not a valid Twitter Username');
|
// 'Your Username is not a valid Twitter Username');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('warns when leaving without saving', async function () {
|
// it('warns when leaving without saving', async function () {
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-private-checkbox]').checked,
|
// find('[data-test-private-checkbox]').checked,
|
||||||
'private blog checkbox'
|
// 'private blog checkbox'
|
||||||
).to.be.false;
|
// ).to.be.false;
|
||||||
|
|
||||||
await click('[data-test-toggle-pub-info]');
|
// await click('[data-test-toggle-pub-info]');
|
||||||
await fillIn('[data-test-title-input]', 'New Blog Title');
|
// await fillIn('[data-test-title-input]', 'New Blog Title');
|
||||||
|
|
||||||
await click('[data-test-private-checkbox]');
|
// await click('[data-test-private-checkbox]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-private-checkbox]').checked,
|
// find('[data-test-private-checkbox]').checked,
|
||||||
'private blog checkbox'
|
// 'private blog checkbox'
|
||||||
).to.be.true;
|
// ).to.be.true;
|
||||||
|
|
||||||
await visit('/settings/staff');
|
// await visit('/settings/staff');
|
||||||
|
|
||||||
expect(findAll('[data-test-modal="unsaved-settings"]').length, 'modal exists').to.equal(1);
|
// expect(findAll('[data-test-modal="unsaved-settings"]').length, 'modal exists').to.equal(1);
|
||||||
|
|
||||||
// Leave without saving
|
// // Leave without saving
|
||||||
await click('[data-test-leave-button]');
|
// await click('[data-test-leave-button]');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/staff');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/staff');
|
||||||
|
|
||||||
await visit('/settings/general');
|
// await visit('/settings/general');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/general');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/general');
|
||||||
|
|
||||||
// settings were not saved
|
// // settings were not saved
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-private-checkbox]').checked,
|
// find('[data-test-private-checkbox]').checked,
|
||||||
'private blog checkbox'
|
// 'private blog checkbox'
|
||||||
).to.be.false;
|
// ).to.be.false;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-title-input]').textContent.trim(),
|
// find('[data-test-title-input]').textContent.trim(),
|
||||||
'Blog title'
|
// 'Blog title'
|
||||||
).to.equal('');
|
// ).to.equal('');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,512 +1,512 @@
|
|||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {beforeEach, describe, it} from 'mocha';
|
// import {beforeEach, describe, it} from 'mocha';
|
||||||
import {blur, click, currentRouteName, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
|
// import {blur, click, currentRouteName, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Integrations - Custom', function () {
|
// describe('Acceptance: Settings - Integrations - Custom', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
describe('access permissions', function () {
|
// describe('access permissions', function () {
|
||||||
beforeEach(function () {
|
// beforeEach(function () {
|
||||||
this.server.create('integration', {name: 'Test'});
|
// this.server.create('integration', {name: 'Test'});
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects /integrations/ to signin when not authenticated', async function () {
|
// it('redirects /integrations/ to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/integrations');
|
// await visit('/settings/integrations');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects /integrations/ to home page when authenticated as contributor', async function () {
|
// it('redirects /integrations/ to home page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
// let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations');
|
// await visit('/settings/integrations');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/posts');
|
// expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects /integrations/ to home page when authenticated as author', async function () {
|
// it('redirects /integrations/ to home page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
// let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations');
|
// await visit('/settings/integrations');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects /integrations/ to home page when authenticated as editor', async function () {
|
// it('redirects /integrations/ to home page when authenticated as editor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Editor'});
|
// let role = this.server.create('role', {name: 'Editor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects /integrations/:id/ to signin when not authenticated', async function () {
|
// it('redirects /integrations/:id/ to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects /integrations/:id/ to home page when authenticated as contributor', async function () {
|
// it('redirects /integrations/:id/ to home page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
// let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/posts');
|
// expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects /integrations/:id/ to home page when authenticated as author', async function () {
|
// it('redirects /integrations/:id/ to home page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
// let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects /integrations/:id/ to home page when authenticated as editor', async function () {
|
// it('redirects /integrations/:id/ to home page when authenticated as editor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Editor'});
|
// let role = this.server.create('role', {name: 'Editor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('navigation', function () {
|
// describe('navigation', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
this.server.loadFixtures('settings');
|
// this.server.loadFixtures('settings');
|
||||||
|
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('renders defaults correctly', async function () {
|
// it('renders defaults correctly', async function () {
|
||||||
await visit('/settings/integrations');
|
// await visit('/settings/integrations');
|
||||||
|
|
||||||
// slack is not configured in the fixtures
|
// // slack is not configured in the fixtures
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-app="slack"] [data-test-app-status]').textContent.trim(),
|
// find('[data-test-app="slack"] [data-test-app-status]').textContent.trim(),
|
||||||
'slack app status'
|
// 'slack app status'
|
||||||
).to.equal('Configure');
|
// ).to.equal('Configure');
|
||||||
|
|
||||||
// amp is disabled in the fixtures
|
// // amp is disabled in the fixtures
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-app="amp"] [data-test-app-status]').textContent.trim(),
|
// find('[data-test-app="amp"] [data-test-app-status]').textContent.trim(),
|
||||||
'amp app status'
|
// 'amp app status'
|
||||||
).to.equal('Configure');
|
// ).to.equal('Configure');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('renders AMP active state', async function () {
|
// it('renders AMP active state', async function () {
|
||||||
this.server.db.settings.update({key: 'amp', value: true});
|
// this.server.db.settings.update({key: 'amp', value: true});
|
||||||
await visit('/settings/integrations');
|
// await visit('/settings/integrations');
|
||||||
|
|
||||||
// amp switches to active when enabled
|
// // amp switches to active when enabled
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-app="amp"] [data-test-app-status]').textContent.trim(),
|
// find('[data-test-app="amp"] [data-test-app-status]').textContent.trim(),
|
||||||
'amp app status'
|
// 'amp app status'
|
||||||
).to.equal('Active');
|
// ).to.equal('Active');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it redirects to Slack when clicking on the grid', async function () {
|
// it('it redirects to Slack when clicking on the grid', async function () {
|
||||||
await visit('/settings/integrations');
|
// await visit('/settings/integrations');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
|
||||||
|
|
||||||
await click('[data-test-link="slack"]');
|
// await click('[data-test-link="slack"]');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it redirects to AMP when clicking on the grid', async function () {
|
// it('it redirects to AMP when clicking on the grid', async function () {
|
||||||
await visit('/settings/integrations');
|
// await visit('/settings/integrations');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
|
||||||
|
|
||||||
await click('[data-test-link="amp"]');
|
// await click('[data-test-link="amp"]');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it redirects to Unsplash when clicking on the grid', async function () {
|
// it('it redirects to Unsplash when clicking on the grid', async function () {
|
||||||
await visit('/settings/integrations');
|
// await visit('/settings/integrations');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
|
||||||
|
|
||||||
await click('[data-test-link="unsplash"]');
|
// await click('[data-test-link="unsplash"]');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('custom integrations', function () {
|
// describe('custom integrations', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
this.server.loadFixtures('configs');
|
// this.server.loadFixtures('configs');
|
||||||
let config = this.server.schema.configs.first();
|
// let config = this.server.schema.configs.first();
|
||||||
config.update({
|
// config.update({
|
||||||
enableDeveloperExperiments: true
|
// enableDeveloperExperiments: true
|
||||||
});
|
// });
|
||||||
|
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('handles 404', async function () {
|
// it('handles 404', async function () {
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
expect(currentRouteName()).to.equal('error404');
|
// expect(currentRouteName()).to.equal('error404');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can add new integration', async function () {
|
// it('can add new integration', async function () {
|
||||||
// sanity check
|
// // sanity check
|
||||||
expect(
|
// expect(
|
||||||
this.server.db.integrations.length,
|
// this.server.db.integrations.length,
|
||||||
'number of integrations in db at start'
|
// 'number of integrations in db at start'
|
||||||
).to.equal(0);
|
// ).to.equal(0);
|
||||||
expect(
|
// expect(
|
||||||
this.server.db.apiKeys.length,
|
// this.server.db.apiKeys.length,
|
||||||
'number of apiKeys in db at start'
|
// 'number of apiKeys in db at start'
|
||||||
).to.equal(0);
|
// ).to.equal(0);
|
||||||
|
|
||||||
// blank slate
|
// // blank slate
|
||||||
await visit('/settings/integrations');
|
// await visit('/settings/integrations');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-blank="custom-integrations"]'),
|
// find('[data-test-blank="custom-integrations"]'),
|
||||||
'initial blank slate'
|
// 'initial blank slate'
|
||||||
).to.exist;
|
// ).to.exist;
|
||||||
|
|
||||||
// new integration modal opens/closes
|
// // new integration modal opens/closes
|
||||||
await click('[data-test-button="new-integration"]');
|
// await click('[data-test-button="new-integration"]');
|
||||||
|
|
||||||
expect(currentURL(), 'url after clicking new').to.equal('/settings/integrations/new');
|
// expect(currentURL(), 'url after clicking new').to.equal('/settings/integrations/new');
|
||||||
expect(find('[data-test-modal="new-integration"]'), 'modal after clicking new').to.exist;
|
// expect(find('[data-test-modal="new-integration"]'), 'modal after clicking new').to.exist;
|
||||||
|
|
||||||
await click('[data-test-button="cancel-new-integration"]');
|
// await click('[data-test-button="cancel-new-integration"]');
|
||||||
|
|
||||||
expect(find('[data-test-modal="new-integration"]'), 'modal after clicking cancel')
|
// expect(find('[data-test-modal="new-integration"]'), 'modal after clicking cancel')
|
||||||
.to.not.exist;
|
// .to.not.exist;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-blank="custom-integrations"]'),
|
// find('[data-test-blank="custom-integrations"]'),
|
||||||
'blank slate after cancelled creation'
|
// 'blank slate after cancelled creation'
|
||||||
).to.exist;
|
// ).to.exist;
|
||||||
|
|
||||||
// new integration validations
|
// // new integration validations
|
||||||
await click('[data-test-button="new-integration"]');
|
// await click('[data-test-button="new-integration"]');
|
||||||
await click('[data-test-button="create-integration"]');
|
// await click('[data-test-button="create-integration"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-error="new-integration-name"]').textContent,
|
// find('[data-test-error="new-integration-name"]').textContent,
|
||||||
'name error after create with blank field'
|
// 'name error after create with blank field'
|
||||||
).to.have.string('enter a name');
|
// ).to.have.string('enter a name');
|
||||||
|
|
||||||
await fillIn('[data-test-input="new-integration-name"]', 'Duplicate');
|
// await fillIn('[data-test-input="new-integration-name"]', 'Duplicate');
|
||||||
await click('[data-test-button="create-integration"]');
|
// await click('[data-test-button="create-integration"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-error="new-integration-name"]').textContent,
|
// find('[data-test-error="new-integration-name"]').textContent,
|
||||||
'name error after create with duplicate name'
|
// 'name error after create with duplicate name'
|
||||||
).to.have.string('already been used');
|
// ).to.have.string('already been used');
|
||||||
|
|
||||||
// successful creation
|
// // successful creation
|
||||||
await fillIn('[data-test-input="new-integration-name"]', 'Test');
|
// await fillIn('[data-test-input="new-integration-name"]', 'Test');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-error="new-integration-name"]').textContent.trim(),
|
// find('[data-test-error="new-integration-name"]').textContent.trim(),
|
||||||
'name error after typing in field'
|
// 'name error after typing in field'
|
||||||
).to.be.empty;
|
// ).to.be.empty;
|
||||||
|
|
||||||
await click('[data-test-button="create-integration"]');
|
// await click('[data-test-button="create-integration"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-modal="new-integration"]'),
|
// find('[data-test-modal="new-integration"]'),
|
||||||
'modal after successful create'
|
// 'modal after successful create'
|
||||||
).to.not.exist;
|
// ).to.not.exist;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
this.server.db.integrations.length,
|
// this.server.db.integrations.length,
|
||||||
'number of integrations in db after create'
|
// 'number of integrations in db after create'
|
||||||
).to.equal(1);
|
// ).to.equal(1);
|
||||||
// mirage sanity check
|
// // mirage sanity check
|
||||||
expect(
|
// expect(
|
||||||
this.server.db.apiKeys.length,
|
// this.server.db.apiKeys.length,
|
||||||
'number of api keys in db after create'
|
// 'number of api keys in db after create'
|
||||||
).to.equal(2);
|
// ).to.equal(2);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
currentURL(),
|
// currentURL(),
|
||||||
'url after integration creation'
|
// 'url after integration creation'
|
||||||
).to.equal('/settings/integrations/1');
|
// ).to.equal('/settings/integrations/1');
|
||||||
|
|
||||||
// test navigation back to list then back to new integration
|
// // test navigation back to list then back to new integration
|
||||||
await click('[data-test-link="integrations-back"]');
|
// await click('[data-test-link="integrations-back"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
currentURL(),
|
// currentURL(),
|
||||||
'url after clicking "Back"'
|
// 'url after clicking "Back"'
|
||||||
).to.equal('/settings/integrations');
|
// ).to.equal('/settings/integrations');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-blank="custom-integrations"]'),
|
// find('[data-test-blank="custom-integrations"]'),
|
||||||
'blank slate after creation'
|
// 'blank slate after creation'
|
||||||
).to.not.exist;
|
// ).to.not.exist;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
findAll('[data-test-custom-integration]').length,
|
// findAll('[data-test-custom-integration]').length,
|
||||||
'number of custom integrations after creation'
|
// 'number of custom integrations after creation'
|
||||||
).to.equal(1);
|
// ).to.equal(1);
|
||||||
|
|
||||||
await click(`[data-test-integration="1"]`);
|
// await click(`[data-test-integration="1"]`);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
currentURL(),
|
// currentURL(),
|
||||||
'url after clicking integration in list'
|
// 'url after clicking integration in list'
|
||||||
).to.equal('/settings/integrations/1');
|
// ).to.equal('/settings/integrations/1');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can manage an integration', async function () {
|
// it('can manage an integration', async function () {
|
||||||
this.server.create('integration');
|
// this.server.create('integration');
|
||||||
|
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
currentURL(),
|
// currentURL(),
|
||||||
'initial URL'
|
// 'initial URL'
|
||||||
).to.equal('/settings/integrations/1');
|
// ).to.equal('/settings/integrations/1');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-screen-title]').textContent,
|
// find('[data-test-screen-title]').textContent,
|
||||||
'screen title'
|
// 'screen title'
|
||||||
).to.have.string('Integration 1');
|
// ).to.have.string('Integration 1');
|
||||||
|
|
||||||
// fields have expected values
|
// // fields have expected values
|
||||||
// TODO: add test for logo
|
// // TODO: add test for logo
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-input="name"]').value,
|
// find('[data-test-input="name"]').value,
|
||||||
'initial name value'
|
// 'initial name value'
|
||||||
).to.equal('Integration 1');
|
// ).to.equal('Integration 1');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-input="description"]').value,
|
// find('[data-test-input="description"]').value,
|
||||||
'initial description value'
|
// 'initial description value'
|
||||||
).to.equal('');
|
// ).to.equal('');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-text="content-key"]'),
|
// find('[data-test-text="content-key"]'),
|
||||||
'content key text'
|
// 'content key text'
|
||||||
).to.have.trimmed.text('integration-1_content_key-12345');
|
// ).to.have.trimmed.text('integration-1_content_key-12345');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-text="admin-key"]'),
|
// find('[data-test-text="admin-key"]'),
|
||||||
'admin key text'
|
// 'admin key text'
|
||||||
).to.have.trimmed.text('integration-1_admin_key-12345');
|
// ).to.have.trimmed.text('integration-1_admin_key-12345');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-text="api-url"]'),
|
// find('[data-test-text="api-url"]'),
|
||||||
'api url text'
|
// 'api url text'
|
||||||
).to.have.trimmed.text(window.location.origin);
|
// ).to.have.trimmed.text(window.location.origin);
|
||||||
|
|
||||||
// it can modify integration fields and has validation
|
// // it can modify integration fields and has validation
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-error="name"]').textContent.trim(),
|
// find('[data-test-error="name"]').textContent.trim(),
|
||||||
'initial name error'
|
// 'initial name error'
|
||||||
).to.be.empty;
|
// ).to.be.empty;
|
||||||
|
|
||||||
await fillIn('[data-test-input="name"]', '');
|
// await fillIn('[data-test-input="name"]', '');
|
||||||
await await blur('[data-test-input="name"]');
|
// await await blur('[data-test-input="name"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-error="name"]').textContent,
|
// find('[data-test-error="name"]').textContent,
|
||||||
'name validation for blank string'
|
// 'name validation for blank string'
|
||||||
).to.have.string('enter a name');
|
// ).to.have.string('enter a name');
|
||||||
|
|
||||||
await click('[data-test-button="save"]');
|
// await click('[data-test-button="save"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
this.server.schema.integrations.first().name,
|
// this.server.schema.integrations.first().name,
|
||||||
'db integration name after failed save'
|
// 'db integration name after failed save'
|
||||||
).to.equal('Integration 1');
|
// ).to.equal('Integration 1');
|
||||||
|
|
||||||
await fillIn('[data-test-input="name"]', 'Test Integration');
|
// await fillIn('[data-test-input="name"]', 'Test Integration');
|
||||||
await await blur('[data-test-input="name"]');
|
// await await blur('[data-test-input="name"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-error="name"]').textContent.trim(),
|
// find('[data-test-error="name"]').textContent.trim(),
|
||||||
'name error after valid entry'
|
// 'name error after valid entry'
|
||||||
).to.be.empty;
|
// ).to.be.empty;
|
||||||
|
|
||||||
await fillIn('[data-test-input="description"]', 'Description for Test Integration');
|
// await fillIn('[data-test-input="description"]', 'Description for Test Integration');
|
||||||
await await blur('[data-test-input="description"]');
|
// await await blur('[data-test-input="description"]');
|
||||||
await click('[data-test-button="save"]');
|
// await click('[data-test-button="save"]');
|
||||||
|
|
||||||
// changes are reflected in the integrations list
|
// // changes are reflected in the integrations list
|
||||||
|
|
||||||
await click('[data-test-link="integrations-back"]');
|
// await click('[data-test-link="integrations-back"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
currentURL(),
|
// currentURL(),
|
||||||
'url after saving and clicking "back"'
|
// 'url after saving and clicking "back"'
|
||||||
).to.equal('/settings/integrations');
|
// ).to.equal('/settings/integrations');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-integration="1"] [data-test-text="name"]').textContent.trim(),
|
// find('[data-test-integration="1"] [data-test-text="name"]').textContent.trim(),
|
||||||
'integration name after save'
|
// 'integration name after save'
|
||||||
).to.equal('Test Integration');
|
// ).to.equal('Test Integration');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-integration="1"] [data-test-text="description"]').textContent.trim(),
|
// find('[data-test-integration="1"] [data-test-text="description"]').textContent.trim(),
|
||||||
'integration description after save'
|
// 'integration description after save'
|
||||||
).to.equal('Description for Test Integration');
|
// ).to.equal('Description for Test Integration');
|
||||||
|
|
||||||
await click('[data-test-integration="1"]');
|
// await click('[data-test-integration="1"]');
|
||||||
|
|
||||||
// warns of unsaved changes when leaving
|
// // warns of unsaved changes when leaving
|
||||||
|
|
||||||
await fillIn('[data-test-input="name"]', 'Unsaved test');
|
// await fillIn('[data-test-input="name"]', 'Unsaved test');
|
||||||
await click('[data-test-link="integrations-back"]');
|
// await click('[data-test-link="integrations-back"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-modal="unsaved-settings"]'),
|
// find('[data-test-modal="unsaved-settings"]'),
|
||||||
'modal shown when navigating with unsaved changes'
|
// 'modal shown when navigating with unsaved changes'
|
||||||
).to.exist;
|
// ).to.exist;
|
||||||
|
|
||||||
await click('[data-test-stay-button]');
|
// await click('[data-test-stay-button]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-modal="unsaved-settings"]'),
|
// find('[data-test-modal="unsaved-settings"]'),
|
||||||
'modal is closed after clicking "stay"'
|
// 'modal is closed after clicking "stay"'
|
||||||
).to.not.exist;
|
// ).to.not.exist;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
currentURL(),
|
// currentURL(),
|
||||||
'url after clicking "stay"'
|
// 'url after clicking "stay"'
|
||||||
).to.equal('/settings/integrations/1');
|
// ).to.equal('/settings/integrations/1');
|
||||||
|
|
||||||
await click('[data-test-link="integrations-back"]');
|
// await click('[data-test-link="integrations-back"]');
|
||||||
await click('[data-test-leave-button]');
|
// await click('[data-test-leave-button]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-modal="unsaved-settings"]'),
|
// find('[data-test-modal="unsaved-settings"]'),
|
||||||
'modal is closed after clicking "leave"'
|
// 'modal is closed after clicking "leave"'
|
||||||
).to.not.exist;
|
// ).to.not.exist;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
currentURL(),
|
// currentURL(),
|
||||||
'url after clicking "leave"'
|
// 'url after clicking "leave"'
|
||||||
).to.equal('/settings/integrations');
|
// ).to.equal('/settings/integrations');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-integration="1"] [data-test-text="name"]').textContent.trim(),
|
// find('[data-test-integration="1"] [data-test-text="name"]').textContent.trim(),
|
||||||
'integration name after leaving unsaved changes'
|
// 'integration name after leaving unsaved changes'
|
||||||
).to.equal('Test Integration');
|
// ).to.equal('Test Integration');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can manage an integration\'s webhooks', async function () {
|
// it('can manage an integration\'s webhooks', async function () {
|
||||||
this.server.create('integration');
|
// this.server.create('integration');
|
||||||
|
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
|
|
||||||
expect(find('[data-test-webhooks-blank-slate]')).to.exist;
|
// expect(find('[data-test-webhooks-blank-slate]')).to.exist;
|
||||||
|
|
||||||
// open new webhook modal
|
// // open new webhook modal
|
||||||
await click('[data-test-link="add-webhook"]');
|
// await click('[data-test-link="add-webhook"]');
|
||||||
expect(find('[data-test-modal="webhook-form"]')).to.exist;
|
// expect(find('[data-test-modal="webhook-form"]')).to.exist;
|
||||||
expect(find('[data-test-modal="webhook-form"] [data-test-text="title"]').textContent)
|
// expect(find('[data-test-modal="webhook-form"] [data-test-text="title"]').textContent)
|
||||||
.to.have.string('New webhook');
|
// .to.have.string('New webhook');
|
||||||
|
|
||||||
// can cancel new webhook
|
// // can cancel new webhook
|
||||||
await click('[data-test-button="cancel-webhook"]');
|
// await click('[data-test-button="cancel-webhook"]');
|
||||||
expect(find('[data-test-modal="webhook-form"]')).to.not.exist;
|
// expect(find('[data-test-modal="webhook-form"]')).to.not.exist;
|
||||||
|
|
||||||
// create new webhook
|
// // create new webhook
|
||||||
await click('[data-test-link="add-webhook"]');
|
// await click('[data-test-link="add-webhook"]');
|
||||||
await fillIn('[data-test-input="webhook-name"]', 'First webhook');
|
// await fillIn('[data-test-input="webhook-name"]', 'First webhook');
|
||||||
await fillIn('[data-test-select="webhook-event"]', 'site.changed');
|
// await fillIn('[data-test-select="webhook-event"]', 'site.changed');
|
||||||
await fillIn('[data-test-input="webhook-targetUrl"]', 'https://example.com/first-webhook');
|
// await fillIn('[data-test-input="webhook-targetUrl"]', 'https://example.com/first-webhook');
|
||||||
await click('[data-test-button="save-webhook"]');
|
// await click('[data-test-button="save-webhook"]');
|
||||||
|
|
||||||
// modal closed and 1 webhook listed with correct details
|
// // modal closed and 1 webhook listed with correct details
|
||||||
expect(find('[data-test-modal="webhook-form"]')).to.not.exist;
|
// expect(find('[data-test-modal="webhook-form"]')).to.not.exist;
|
||||||
expect(find('[data-test-webhook-row]')).to.exist;
|
// expect(find('[data-test-webhook-row]')).to.exist;
|
||||||
let row = find('[data-test-webhook-row="1"]');
|
// let row = find('[data-test-webhook-row="1"]');
|
||||||
expect(row.querySelector('[data-test-text="name"]').textContent)
|
// expect(row.querySelector('[data-test-text="name"]').textContent)
|
||||||
.to.have.string('First webhook');
|
// .to.have.string('First webhook');
|
||||||
expect(row.querySelector('[data-test-text="event"]').textContent)
|
// expect(row.querySelector('[data-test-text="event"]').textContent)
|
||||||
.to.have.string('Site changed (rebuild)');
|
// .to.have.string('Site changed (rebuild)');
|
||||||
expect(row.querySelector('[data-test-text="targetUrl"]').textContent)
|
// expect(row.querySelector('[data-test-text="targetUrl"]').textContent)
|
||||||
.to.have.string('https://example.com/first-webhook');
|
// .to.have.string('https://example.com/first-webhook');
|
||||||
expect(row.querySelector('[data-test-text="last-triggered"]').textContent)
|
// expect(row.querySelector('[data-test-text="last-triggered"]').textContent)
|
||||||
.to.have.string('Not triggered');
|
// .to.have.string('Not triggered');
|
||||||
|
|
||||||
// click edit webhook link
|
// // click edit webhook link
|
||||||
await click('[data-test-webhook-row="1"] [data-test-newsletter-menu-trigger]');
|
// await click('[data-test-webhook-row="1"] [data-test-newsletter-menu-trigger]');
|
||||||
await click('[data-test-link="edit-webhook"]');
|
// await click('[data-test-link="edit-webhook"]');
|
||||||
|
|
||||||
// modal appears and has correct title
|
// // modal appears and has correct title
|
||||||
expect(find('[data-test-modal="webhook-form"]')).to.exist;
|
// expect(find('[data-test-modal="webhook-form"]')).to.exist;
|
||||||
expect(find('[data-test-modal="webhook-form"] [data-test-text="title"]').textContent)
|
// expect(find('[data-test-modal="webhook-form"] [data-test-text="title"]').textContent)
|
||||||
.to.have.string('Edit webhook');
|
// .to.have.string('Edit webhook');
|
||||||
});
|
// });
|
||||||
|
|
||||||
// test to ensure the `value=description` passed to `gh-text-input` is `readonly`
|
// // test to ensure the `value=description` passed to `gh-text-input` is `readonly`
|
||||||
it('doesn\'t show unsaved changes modal after placing focus on description field', async function () {
|
// it('doesn\'t show unsaved changes modal after placing focus on description field', async function () {
|
||||||
this.server.create('integration');
|
// this.server.create('integration');
|
||||||
|
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
await click('[data-test-input="description"]');
|
// await click('[data-test-input="description"]');
|
||||||
await blur('[data-test-input="description"]');
|
// await blur('[data-test-input="description"]');
|
||||||
await click('[data-test-link="integrations-back"]');
|
// await click('[data-test-link="integrations-back"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-modal="unsaved-settings"]'),
|
// find('[data-test-modal="unsaved-settings"]'),
|
||||||
'unsaved changes modal is not shown'
|
// 'unsaved changes modal is not shown'
|
||||||
).to.not.exist;
|
// ).to.not.exist;
|
||||||
|
|
||||||
expect(currentURL()).to.equal('/settings/integrations');
|
// expect(currentURL()).to.equal('/settings/integrations');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can delete integration', async function () {
|
// it('can delete integration', async function () {
|
||||||
this.server.create('integration');
|
// this.server.create('integration');
|
||||||
|
|
||||||
await visit('/settings/integrations/1');
|
// await visit('/settings/integrations/1');
|
||||||
await click('[data-test-button="delete-integration"]');
|
// await click('[data-test-button="delete-integration"]');
|
||||||
|
|
||||||
expect(find('[data-test-modal="delete-integration"]')).to.exist;
|
// expect(find('[data-test-modal="delete-integration"]')).to.exist;
|
||||||
|
|
||||||
await click('[data-test-modal="delete-integration"] [data-test-button="confirm"]');
|
// await click('[data-test-modal="delete-integration"] [data-test-button="confirm"]');
|
||||||
|
|
||||||
expect(find('[data-test-modal="delete-integration"]')).to.not.exist;
|
// expect(find('[data-test-modal="delete-integration"]')).to.not.exist;
|
||||||
expect(currentURL()).to.equal('/settings/integrations');
|
// expect(currentURL()).to.equal('/settings/integrations');
|
||||||
expect(find('[data-test-custom-integration]')).to.not.exist;
|
// expect(find('[data-test-custom-integration]')).to.not.exist;
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,339 +1,338 @@
|
|||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {beforeEach, describe, it} from 'mocha';
|
// import {beforeEach, describe, it} from 'mocha';
|
||||||
import {click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
|
// import {click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {fileUpload} from '../../helpers/file-upload';
|
// import {fileUpload} from '../../helpers/file-upload';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Labs', function () {
|
// describe('Acceptance: Settings - Labs', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
it('redirects to signin when not authenticated', async function () {
|
// it('redirects to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/labs');
|
// await visit('/settings/labs');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as contributor', async function () {
|
// it('redirects to home page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
// let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/labs');
|
// await visit('/settings/labs');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/posts');
|
// expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as author', async function () {
|
// it('redirects to home page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
// let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/labs');
|
// await visit('/settings/labs');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as editor', async function () {
|
// it('redirects to home page when authenticated as editor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Editor'});
|
// let role = this.server.create('role', {name: 'Editor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/labs');
|
// await visit('/settings/labs');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('when logged in', function () {
|
// describe('when logged in', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it renders', async function () {
|
// it('it renders', async function () {
|
||||||
await visit('/settings/labs');
|
// await visit('/settings/labs');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/labs');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/labs');
|
||||||
|
|
||||||
// has correct page title
|
// // has correct page title
|
||||||
expect(document.title, 'page title').to.equal('Settings - Labs - Test Blog');
|
// expect(document.title, 'page title').to.equal('Settings - Labs - Test Blog');
|
||||||
|
|
||||||
// highlights nav menu
|
// // highlights nav menu
|
||||||
expect(find('[data-test-nav="settings"]'), 'highlights nav menu item')
|
// expect(find('[data-test-nav="settings"]'), 'highlights nav menu item')
|
||||||
.to.have.class('active');
|
// .to.have.class('active');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can delete all content', async function () {
|
// it('can delete all content', async function () {
|
||||||
await visit('/settings/labs');
|
// await visit('/settings/labs');
|
||||||
await click('[data-test-button="delete-all"]');
|
// await click('[data-test-button="delete-all"]');
|
||||||
|
|
||||||
const modal = '[data-test-modal="confirm-delete-all"]';
|
// const modal = '[data-test-modal="confirm-delete-all"]';
|
||||||
expect(find(modal)).to.exist;
|
// expect(find(modal)).to.exist;
|
||||||
|
|
||||||
await click(`${modal} [data-test-button="confirm"]`);
|
// await click(`${modal} [data-test-button="confirm"]`);
|
||||||
|
|
||||||
// API request is correct
|
// // API request is correct
|
||||||
const [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
// const [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
expect(lastRequest.url).to.equal('/ghost/api/admin/db/');
|
// expect(lastRequest.url).to.equal('/ghost/api/admin/db/');
|
||||||
expect(lastRequest.method).to.equal('DELETE');
|
// expect(lastRequest.method).to.equal('DELETE');
|
||||||
|
|
||||||
expect(find(modal)).to.not.exist;
|
// expect(find(modal)).to.not.exist;
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can upload/download redirects', async function () {
|
// it('can upload/download redirects', async function () {
|
||||||
await visit('/settings/labs');
|
// await visit('/settings/labs');
|
||||||
|
|
||||||
// successful upload
|
// // successful upload
|
||||||
this.server.post('/redirects/upload/', {}, 200);
|
// this.server.post('/redirects/upload/', {}, 200);
|
||||||
|
|
||||||
await fileUpload(
|
// await fileUpload(
|
||||||
'[data-test-file-input="redirects"] input',
|
// '[data-test-file-input="redirects"] input',
|
||||||
['test'],
|
// ['test'],
|
||||||
{name: 'redirects.json', type: 'application/json'}
|
// {name: 'redirects.json', type: 'application/json'}
|
||||||
);
|
// );
|
||||||
|
|
||||||
// TODO: tests for the temporary success/failure state have been
|
// // TODO: tests for the temporary success/failure state have been
|
||||||
// disabled because they were randomly failing
|
// // disabled because they were randomly failing
|
||||||
|
|
||||||
// this should be half-way through button reset timeout
|
// // this should be half-way through button reset timeout
|
||||||
// await timeout(50);
|
// // await timeout(50);
|
||||||
//
|
// //
|
||||||
// // shows success button
|
// // // shows success button
|
||||||
// let buttons = findAll('[data-test-button="upload-redirects"]');
|
// // let buttons = findAll('[data-test-button="upload-redirects"]');
|
||||||
// expect(buttons.length, 'no of success buttons').to.equal(1);
|
// // expect(buttons.length, 'no of success buttons').to.equal(1);
|
||||||
// expect(
|
// // expect(
|
||||||
// buttons[0],
|
// // buttons[0],
|
||||||
// 'success button is green'
|
// // 'success button is green'
|
||||||
// ).to.have.class('gh-btn-green);
|
// // ).to.have.class('gh-btn-green);
|
||||||
// expect(
|
// // expect(
|
||||||
// button.textContent,
|
// // button.textContent,
|
||||||
// 'success button text'
|
// // 'success button text'
|
||||||
// ).to.have.string('Uploaded');
|
// // ).to.have.string('Uploaded');
|
||||||
//
|
// //
|
||||||
// await wait();
|
// // await wait();
|
||||||
|
|
||||||
// returned to normal button
|
// // returned to normal button
|
||||||
let buttons = findAll('[data-test-button="upload-redirects"]');
|
// let buttons = findAll('[data-test-button="upload-redirects"]');
|
||||||
expect(buttons.length, 'no of post-success buttons').to.equal(1);
|
// expect(buttons.length, 'no of post-success buttons').to.equal(1);
|
||||||
expect(
|
// expect(
|
||||||
buttons[0],
|
// buttons[0],
|
||||||
'post-success button doesn\'t have success class'
|
// 'post-success button doesn\'t have success class'
|
||||||
).to.not.have.class('gh-btn-green');
|
// ).to.not.have.class('gh-btn-green');
|
||||||
expect(
|
// expect(
|
||||||
buttons[0].textContent,
|
// buttons[0].textContent,
|
||||||
'post-success button text'
|
// 'post-success button text'
|
||||||
).to.have.string('Upload redirects');
|
// ).to.have.string('Upload redirects');
|
||||||
|
|
||||||
// failed upload
|
// // failed upload
|
||||||
this.server.post('/redirects/upload/', {
|
// this.server.post('/redirects/upload/', {
|
||||||
errors: [{
|
// errors: [{
|
||||||
type: 'BadRequestError',
|
// type: 'BadRequestError',
|
||||||
message: 'Test failure message'
|
// message: 'Test failure message'
|
||||||
}]
|
// }]
|
||||||
}, 400);
|
// }, 400);
|
||||||
|
|
||||||
await fileUpload(
|
// await fileUpload(
|
||||||
'[data-test-file-input="redirects"] input',
|
// '[data-test-file-input="redirects"] input',
|
||||||
['test'],
|
// ['test'],
|
||||||
{name: 'redirects-bad.json', type: 'application/json'}
|
// {name: 'redirects-bad.json', type: 'application/json'}
|
||||||
);
|
// );
|
||||||
|
|
||||||
// TODO: tests for the temporary success/failure state have been
|
// // TODO: tests for the temporary success/failure state have been
|
||||||
// disabled because they were randomly failing
|
// // disabled because they were randomly failing
|
||||||
|
|
||||||
// this should be half-way through button reset timeout
|
// // this should be half-way through button reset timeout
|
||||||
// await timeout(50);
|
// // await timeout(50);
|
||||||
//
|
// //
|
||||||
// shows failure button
|
// // shows failure button
|
||||||
// buttons = findAll('[data-test-button="upload-redirects"]');
|
// // buttons = findAll('[data-test-button="upload-redirects"]');
|
||||||
// expect(buttons.length, 'no of failure buttons').to.equal(1);
|
// // expect(buttons.length, 'no of failure buttons').to.equal(1);
|
||||||
// expect(
|
// // expect(
|
||||||
// buttons[0],
|
// // buttons[0],
|
||||||
// 'failure button is red'
|
// // 'failure button is red'
|
||||||
// ).to.have.class('gh-btn-red);
|
// // ).to.have.class('gh-btn-red);
|
||||||
// expect(
|
// // expect(
|
||||||
// buttons[0].textContent,
|
// // buttons[0].textContent,
|
||||||
// 'failure button text'
|
// // 'failure button text'
|
||||||
// ).to.have.string('Upload Failed');
|
// // ).to.have.string('Upload Failed');
|
||||||
//
|
// //
|
||||||
// await wait();
|
// // await wait();
|
||||||
|
|
||||||
// shows error message
|
// // shows error message
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-error="redirects"]').textContent.trim(),
|
// find('[data-test-error="redirects"]').textContent.trim(),
|
||||||
'upload error text'
|
// 'upload error text'
|
||||||
).to.have.string('Test failure message');
|
// ).to.have.string('Test failure message');
|
||||||
|
|
||||||
// returned to normal button
|
// // returned to normal button
|
||||||
buttons = findAll('[data-test-button="upload-redirects"]');
|
// buttons = findAll('[data-test-button="upload-redirects"]');
|
||||||
expect(buttons.length, 'no of post-failure buttons').to.equal(1);
|
// expect(buttons.length, 'no of post-failure buttons').to.equal(1);
|
||||||
expect(
|
// expect(
|
||||||
buttons[0],
|
// buttons[0],
|
||||||
'post-failure button doesn\'t have failure class'
|
// 'post-failure button doesn\'t have failure class'
|
||||||
).to.not.have.class('gh-btn-red');
|
// ).to.not.have.class('gh-btn-red');
|
||||||
expect(
|
// expect(
|
||||||
buttons[0].textContent,
|
// buttons[0].textContent,
|
||||||
'post-failure button text'
|
// 'post-failure button text'
|
||||||
).to.have.string('Upload redirects');
|
// ).to.have.string('Upload redirects');
|
||||||
|
|
||||||
// successful upload clears error
|
// // successful upload clears error
|
||||||
this.server.post('/redirects/upload/', {}, 200);
|
// this.server.post('/redirects/upload/', {}, 200);
|
||||||
await fileUpload(
|
// await fileUpload(
|
||||||
'[data-test-file-input="redirects"] input',
|
// '[data-test-file-input="redirects"] input',
|
||||||
['test'],
|
// ['test'],
|
||||||
{name: 'redirects-bad.json', type: 'application/json'}
|
// {name: 'redirects-bad.json', type: 'application/json'}
|
||||||
);
|
// );
|
||||||
|
|
||||||
expect(find('[data-test-error="redirects"]')).to.not.exist;
|
// expect(find('[data-test-error="redirects"]')).to.not.exist;
|
||||||
|
|
||||||
// can download redirects.json
|
// // can download redirects.json
|
||||||
await click('[data-test-link="download-redirects"]');
|
// await click('[data-test-link="download-redirects"]');
|
||||||
|
|
||||||
let iframe = document.querySelector('#iframeDownload');
|
// let iframe = document.querySelector('#iframeDownload');
|
||||||
expect(iframe.getAttribute('src')).to.have.string('/redirects/download/');
|
// expect(iframe.getAttribute('src')).to.have.string('/redirects/download/');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can upload/download routes.yaml', async function () {
|
// it('can upload/download routes.yaml', async function () {
|
||||||
await visit('/settings/labs');
|
// await visit('/settings/labs');
|
||||||
|
|
||||||
// successful upload
|
// // successful upload
|
||||||
this.server.post('/settings/routes/yaml/', {}, 200);
|
// this.server.post('/settings/routes/yaml/', {}, 200);
|
||||||
|
|
||||||
await fileUpload(
|
// await fileUpload(
|
||||||
'[data-test-file-input="routes"] input',
|
// '[data-test-file-input="routes"] input',
|
||||||
['test'],
|
// ['test'],
|
||||||
{name: 'routes.yaml', type: 'application/x-yaml'}
|
// {name: 'routes.yaml', type: 'application/x-yaml'}
|
||||||
);
|
// );
|
||||||
|
|
||||||
// TODO: tests for the temporary success/failure state have been
|
// // TODO: tests for the temporary success/failure state have been
|
||||||
// disabled because they were randomly failing
|
// // disabled because they were randomly failing
|
||||||
|
|
||||||
// this should be half-way through button reset timeout
|
// // this should be half-way through button reset timeout
|
||||||
// await timeout(50);
|
// // await timeout(50);
|
||||||
//
|
// //
|
||||||
// // shows success button
|
// // // shows success button
|
||||||
// let button = find('[data-test-button="upload-routes"]');
|
// // let button = find('[data-test-button="upload-routes"]');
|
||||||
// expect(button.length, 'no of success buttons').to.equal(1);
|
// // expect(button.length, 'no of success buttons').to.equal(1);
|
||||||
// expect(
|
// // expect(
|
||||||
// button.hasClass('gh-btn-green'),
|
// // button.hasClass('gh-btn-green'),
|
||||||
// 'success button is green'
|
// // 'success button is green'
|
||||||
// ).to.be.true;
|
// // ).to.be.true;
|
||||||
// expect(
|
// // expect(
|
||||||
// button.text().trim(),
|
// // button.text().trim(),
|
||||||
// 'success button text'
|
// // 'success button text'
|
||||||
// ).to.have.string('Uploaded');
|
// // ).to.have.string('Uploaded');
|
||||||
//
|
// //
|
||||||
// await wait();
|
// // await wait();
|
||||||
|
|
||||||
// returned to normal button
|
// // returned to normal button
|
||||||
let buttons = findAll('[data-test-button="upload-routes"]');
|
// let buttons = findAll('[data-test-button="upload-routes"]');
|
||||||
expect(buttons.length, 'no of post-success buttons').to.equal(1);
|
// expect(buttons.length, 'no of post-success buttons').to.equal(1);
|
||||||
expect(
|
// expect(
|
||||||
buttons[0],
|
// buttons[0],
|
||||||
'routes post-success button doesn\'t have success class'
|
// 'routes post-success button doesn\'t have success class'
|
||||||
).to.not.have.class('gh-btn-green');
|
// ).to.not.have.class('gh-btn-green');
|
||||||
expect(
|
// expect(
|
||||||
buttons[0].textContent,
|
// buttons[0].textContent,
|
||||||
'routes post-success button text'
|
// 'routes post-success button text'
|
||||||
).to.have.string('Upload routes YAML');
|
// ).to.have.string('Upload routes YAML');
|
||||||
|
|
||||||
// failed upload
|
// // failed upload
|
||||||
this.server.post('/settings/routes/yaml/', {
|
// this.server.post('/settings/routes/yaml/', {
|
||||||
errors: [{
|
// errors: [{
|
||||||
type: 'BadRequestError',
|
// type: 'BadRequestError',
|
||||||
message: 'Test failure message'
|
// message: 'Test failure message'
|
||||||
}]
|
// }]
|
||||||
}, 400);
|
// }, 400);
|
||||||
|
|
||||||
await fileUpload(
|
// await fileUpload(
|
||||||
'[data-test-file-input="routes"] input',
|
// '[data-test-file-input="routes"] input',
|
||||||
['test'],
|
// ['test'],
|
||||||
{name: 'routes-bad.yaml', type: 'application/x-yaml'}
|
// {name: 'routes-bad.yaml', type: 'application/x-yaml'}
|
||||||
);
|
// );
|
||||||
|
|
||||||
// TODO: tests for the temporary success/failure state have been
|
// // TODO: tests for the temporary success/failure state have been
|
||||||
// disabled because they were randomly failing
|
// // disabled because they were randomly failing
|
||||||
|
|
||||||
// this should be half-way through button reset timeout
|
// // this should be half-way through button reset timeout
|
||||||
// await timeout(50);
|
// // await timeout(50);
|
||||||
//
|
// //
|
||||||
// shows failure button
|
// // shows failure button
|
||||||
// button = find('[data-test-button="upload-routes"]');
|
// // button = find('[data-test-button="upload-routes"]');
|
||||||
// expect(button.length, 'no of failure buttons').to.equal(1);
|
// // expect(button.length, 'no of failure buttons').to.equal(1);
|
||||||
// expect(
|
// // expect(
|
||||||
// button.hasClass('gh-btn-red'),
|
// // button.hasClass('gh-btn-red'),
|
||||||
// 'failure button is red'
|
// // 'failure button is red'
|
||||||
// ).to.be.true;
|
// // ).to.be.true;
|
||||||
// expect(
|
// // expect(
|
||||||
// button.text().trim(),
|
// // button.text().trim(),
|
||||||
// 'failure button text'
|
// // 'failure button text'
|
||||||
// ).to.have.string('Upload Failed');
|
// // ).to.have.string('Upload Failed');
|
||||||
//
|
// //
|
||||||
// await wait();
|
// // await wait();
|
||||||
|
|
||||||
// shows error message
|
// // shows error message
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-error="routes"]').textContent,
|
// find('[data-test-error="routes"]').textContent,
|
||||||
'routes upload error text'
|
// 'routes upload error text'
|
||||||
).to.have.string('Test failure message');
|
// ).to.have.string('Test failure message');
|
||||||
|
|
||||||
// returned to normal button
|
// // returned to normal button
|
||||||
buttons = findAll('[data-test-button="upload-routes"]');
|
// buttons = findAll('[data-test-button="upload-routes"]');
|
||||||
expect(buttons.length, 'no of post-failure buttons').to.equal(1);
|
// expect(buttons.length, 'no of post-failure buttons').to.equal(1);
|
||||||
expect(
|
// expect(
|
||||||
buttons[0],
|
// buttons[0],
|
||||||
'routes post-failure button doesn\'t have failure class'
|
// 'routes post-failure button doesn\'t have failure class'
|
||||||
).to.not.have.class('gh-btn-red');
|
// ).to.not.have.class('gh-btn-red');
|
||||||
expect(
|
// expect(
|
||||||
buttons[0].textContent,
|
// buttons[0].textContent,
|
||||||
'routes post-failure button text'
|
// 'routes post-failure button text'
|
||||||
).to.have.string('Upload routes YAML');
|
// ).to.have.string('Upload routes YAML');
|
||||||
|
|
||||||
// successful upload clears error
|
// // successful upload clears error
|
||||||
this.server.post('/settings/routes/yaml/', {}, 200);
|
// this.server.post('/settings/routes/yaml/', {}, 200);
|
||||||
await fileUpload(
|
// await fileUpload(
|
||||||
'[data-test-file-input="routes"] input',
|
// '[data-test-file-input="routes"] input',
|
||||||
['test'],
|
// ['test'],
|
||||||
{name: 'routes-good.yaml', type: 'application/x-yaml'}
|
// {name: 'routes-good.yaml', type: 'application/x-yaml'}
|
||||||
);
|
// );
|
||||||
|
|
||||||
expect(find('[data-test-error="routes"]')).to.not.exist;
|
// expect(find('[data-test-error="routes"]')).to.not.exist;
|
||||||
|
|
||||||
// can download redirects.json
|
// // can download redirects.json
|
||||||
await click('[data-test-link="download-routes"]');
|
// await click('[data-test-link="download-routes"]');
|
||||||
|
|
||||||
let iframe = document.querySelector('#iframeDownload');
|
// let iframe = document.querySelector('#iframeDownload');
|
||||||
expect(iframe.getAttribute('src')).to.have.string('/settings/routes/yaml/');
|
// expect(iframe.getAttribute('src')).to.have.string('/settings/routes/yaml/');
|
||||||
});
|
// });
|
||||||
});
|
|
||||||
|
|
||||||
describe('When logged in as Owner', function () {
|
// describe('When logged in as Owner', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Owner'});
|
// let role = this.server.create('role', {name: 'Owner'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it.skip('sets the mailgunBaseUrl to the default', async function () {
|
// it.skip('sets the mailgunBaseUrl to the default', async function () {
|
||||||
await visit('/settings/members');
|
// await visit('/settings/members');
|
||||||
|
|
||||||
await fillIn('[data-test-mailgun-api-key-input]', 'i_am_an_api_key');
|
// await fillIn('[data-test-mailgun-api-key-input]', 'i_am_an_api_key');
|
||||||
await fillIn('[data-test-mailgun-domain-input]', 'https://domain.tld');
|
// await fillIn('[data-test-mailgun-domain-input]', 'https://domain.tld');
|
||||||
|
|
||||||
await click('[data-test-button="save-members-settings"]');
|
// await click('[data-test-button="save-members-settings"]');
|
||||||
|
|
||||||
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
let params = JSON.parse(lastRequest.requestBody);
|
// let params = JSON.parse(lastRequest.requestBody);
|
||||||
|
|
||||||
expect(params.settings.findBy('key', 'mailgun_base_url').value).not.to.equal(null);
|
// expect(params.settings.findBy('key', 'mailgun_base_url').value).not.to.equal(null);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,292 +1,292 @@
|
|||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {blur, click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
|
// import {blur, click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Membership', function () {
|
// describe('Acceptance: Settings - Membership', function () {
|
||||||
const hooks = setupApplicationTest();
|
// const hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
beforeEach(function () {
|
// beforeEach(function () {
|
||||||
});
|
// });
|
||||||
|
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
this.server.loadFixtures('configs');
|
// this.server.loadFixtures('configs');
|
||||||
this.server.loadFixtures('tiers');
|
// this.server.loadFixtures('tiers');
|
||||||
|
|
||||||
this.server.db.configs.update(1, {blogUrl: 'http://localhost:2368'});
|
// this.server.db.configs.update(1, {blogUrl: 'http://localhost:2368'});
|
||||||
|
|
||||||
const role = this.server.create('role', {name: 'Owner'});
|
// const role = this.server.create('role', {name: 'Owner'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('permissions', function () {
|
// describe('permissions', function () {
|
||||||
let visitAs;
|
// let visitAs;
|
||||||
|
|
||||||
before(function () {
|
// before(function () {
|
||||||
visitAs = async (roleName) => {
|
// visitAs = async (roleName) => {
|
||||||
const role = this.server.create('role', {name: roleName});
|
// const role = this.server.create('role', {name: roleName});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/members');
|
// await visit('/settings/members');
|
||||||
};
|
// };
|
||||||
});
|
// });
|
||||||
|
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
this.server.db.users.remove();
|
// this.server.db.users.remove();
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('allows Owners', async function () {
|
// it('allows Owners', async function () {
|
||||||
await visitAs('Owner');
|
// await visitAs('Owner');
|
||||||
expect(currentURL()).to.equal('/settings/members');
|
// expect(currentURL()).to.equal('/settings/members');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('allows Administrators', async function () {
|
// it('allows Administrators', async function () {
|
||||||
await visitAs('Administrator');
|
// await visitAs('Administrator');
|
||||||
expect(currentURL()).to.equal('/settings/members');
|
// expect(currentURL()).to.equal('/settings/members');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('disallows Editors', async function () {
|
// it('disallows Editors', async function () {
|
||||||
await visitAs('Editor');
|
// await visitAs('Editor');
|
||||||
expect(currentURL()).to.not.equal('/settings/members');
|
// expect(currentURL()).to.not.equal('/settings/members');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('disallows Authors', async function () {
|
// it('disallows Authors', async function () {
|
||||||
await visitAs('Author');
|
// await visitAs('Author');
|
||||||
expect(currentURL()).to.not.equal('/settings/members');
|
// expect(currentURL()).to.not.equal('/settings/members');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('disallows Contributors', async function () {
|
// it('disallows Contributors', async function () {
|
||||||
await visitAs('Contributor');
|
// await visitAs('Contributor');
|
||||||
expect(currentURL()).to.not.equal('/settings/members');
|
// expect(currentURL()).to.not.equal('/settings/members');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can change subscription access', async function () {
|
// it('can change subscription access', async function () {
|
||||||
await visit('/settings/members');
|
// await visit('/settings/members');
|
||||||
|
|
||||||
expect(this.server.db.settings.findBy({key: 'members_signup_access'}).value).to.equal('all');
|
// expect(this.server.db.settings.findBy({key: 'members_signup_access'}).value).to.equal('all');
|
||||||
expect(find('[data-test-members-subscription-option="all"]'), 'initial selection is "all"').to.exist;
|
// expect(find('[data-test-members-subscription-option="all"]'), 'initial selection is "all"').to.exist;
|
||||||
expect(find('[data-test-iframe="portal-preview"]'), 'initial preview src matches "all"')
|
// expect(find('[data-test-iframe="portal-preview"]'), 'initial preview src matches "all"')
|
||||||
.to.have.attribute('src').match(/membersSignupAccess=all/);
|
// .to.have.attribute('src').match(/membersSignupAccess=all/);
|
||||||
|
|
||||||
// open dropdown
|
// // open dropdown
|
||||||
await click('[data-test-members-subscription-option="all"]');
|
// await click('[data-test-members-subscription-option="all"]');
|
||||||
|
|
||||||
// all settings exist in dropdown
|
// // all settings exist in dropdown
|
||||||
expect(find('.ember-power-select-options [data-test-members-subscription-option="all"]'), 'all option').to.exist;
|
// expect(find('.ember-power-select-options [data-test-members-subscription-option="all"]'), 'all option').to.exist;
|
||||||
expect(find('.ember-power-select-options [data-test-members-subscription-option="invite"]'), 'invite option').to.exist;
|
// expect(find('.ember-power-select-options [data-test-members-subscription-option="invite"]'), 'invite option').to.exist;
|
||||||
expect(find('.ember-power-select-options [data-test-members-subscription-option="none"]'), 'none option').to.exist;
|
// expect(find('.ember-power-select-options [data-test-members-subscription-option="none"]'), 'none option').to.exist;
|
||||||
|
|
||||||
// switch to invite
|
// // switch to invite
|
||||||
await click('.ember-power-select-options [data-test-members-subscription-option="invite"]');
|
// await click('.ember-power-select-options [data-test-members-subscription-option="invite"]');
|
||||||
|
|
||||||
expect(find('.ember-power-select-options'), 'dropdown closes').to.not.exist;
|
// expect(find('.ember-power-select-options'), 'dropdown closes').to.not.exist;
|
||||||
expect(find('[data-test-members-subscription-option="invite"]'), 'invite option shown after selected').to.exist;
|
// expect(find('[data-test-members-subscription-option="invite"]'), 'invite option shown after selected').to.exist;
|
||||||
expect(find('[data-test-iframe="portal-preview"]'))
|
// expect(find('[data-test-iframe="portal-preview"]'))
|
||||||
.to.have.attribute('src').match(/membersSignupAccess=invite/);
|
// .to.have.attribute('src').match(/membersSignupAccess=invite/);
|
||||||
|
|
||||||
await click('[data-test-button="save-settings"]');
|
// await click('[data-test-button="save-settings"]');
|
||||||
|
|
||||||
expect(this.server.db.settings.findBy({key: 'members_signup_access'}).value).to.equal('invite');
|
// expect(this.server.db.settings.findBy({key: 'members_signup_access'}).value).to.equal('invite');
|
||||||
|
|
||||||
// switch to nobody
|
// // switch to nobody
|
||||||
await click('[data-test-members-subscription-option="invite"]');
|
// await click('[data-test-members-subscription-option="invite"]');
|
||||||
await click('.ember-power-select-options [data-test-members-subscription-option="none"]');
|
// await click('.ember-power-select-options [data-test-members-subscription-option="none"]');
|
||||||
|
|
||||||
expect(find('.ember-power-select-options'), 'dropdown closes').to.not.exist;
|
// expect(find('.ember-power-select-options'), 'dropdown closes').to.not.exist;
|
||||||
expect(find('[data-test-members-subscription-option="none"]'), 'none option shown after selected').to.exist;
|
// expect(find('[data-test-members-subscription-option="none"]'), 'none option shown after selected').to.exist;
|
||||||
expect(find('[data-test-iframe="portal-preview"]')).to.not.exist;
|
// expect(find('[data-test-iframe="portal-preview"]')).to.not.exist;
|
||||||
expect(find('[data-test-portal-preview-disabled]')).to.exist;
|
// expect(find('[data-test-portal-preview-disabled]')).to.exist;
|
||||||
|
|
||||||
expect(find('[data-test-default-post-access] .ember-basic-dropdown-trigger')).to.have.attribute('aria-disabled', 'true');
|
// expect(find('[data-test-default-post-access] .ember-basic-dropdown-trigger')).to.have.attribute('aria-disabled', 'true');
|
||||||
|
|
||||||
await click('[data-test-button="save-settings"]');
|
// await click('[data-test-button="save-settings"]');
|
||||||
|
|
||||||
expect(this.server.db.settings.findBy({key: 'members_signup_access'}).value).to.equal('none');
|
// expect(this.server.db.settings.findBy({key: 'members_signup_access'}).value).to.equal('none');
|
||||||
|
|
||||||
// automatically saves when switching back off nobody
|
// // automatically saves when switching back off nobody
|
||||||
await click('[data-test-members-subscription-option="none"]');
|
// await click('[data-test-members-subscription-option="none"]');
|
||||||
await click('.ember-power-select-options [data-test-members-subscription-option="invite"]');
|
// await click('.ember-power-select-options [data-test-members-subscription-option="invite"]');
|
||||||
expect(this.server.db.settings.findBy({key: 'members_signup_access'}).value).to.equal('invite');
|
// expect(this.server.db.settings.findBy({key: 'members_signup_access'}).value).to.equal('invite');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can change default post access', async function () {
|
// it('can change default post access', async function () {
|
||||||
await visit('/settings/members');
|
// await visit('/settings/members');
|
||||||
|
|
||||||
// fixtures match what we expect
|
// // fixtures match what we expect
|
||||||
expect(this.server.db.settings.findBy({key: 'default_content_visibility'}).value).to.equal('public');
|
// expect(this.server.db.settings.findBy({key: 'default_content_visibility'}).value).to.equal('public');
|
||||||
expect(this.server.db.settings.findBy({key: 'default_content_visibility_tiers'}).value).to.equal('[]');
|
// expect(this.server.db.settings.findBy({key: 'default_content_visibility_tiers'}).value).to.equal('[]');
|
||||||
|
|
||||||
expect(find('[data-test-default-post-access-option="public"]'), 'initial selection is "public"').to.exist;
|
// expect(find('[data-test-default-post-access-option="public"]'), 'initial selection is "public"').to.exist;
|
||||||
expect(find('[data-test-default-post-access-tiers]')).to.not.exist;
|
// expect(find('[data-test-default-post-access-tiers]')).to.not.exist;
|
||||||
|
|
||||||
// open dropdown
|
// // open dropdown
|
||||||
await click('[data-test-default-post-access-option="public"]');
|
// await click('[data-test-default-post-access-option="public"]');
|
||||||
|
|
||||||
// all settings exist in dropdown
|
// // all settings exist in dropdown
|
||||||
expect(find('.ember-power-select-options [data-test-default-post-access-option="public"]'), 'public option').to.exist;
|
// expect(find('.ember-power-select-options [data-test-default-post-access-option="public"]'), 'public option').to.exist;
|
||||||
expect(find('.ember-power-select-options [data-test-default-post-access-option="members"]'), 'members-only option').to.exist;
|
// expect(find('.ember-power-select-options [data-test-default-post-access-option="members"]'), 'members-only option').to.exist;
|
||||||
expect(find('.ember-power-select-options [data-test-default-post-access-option="paid"]'), 'paid-only option').to.exist;
|
// expect(find('.ember-power-select-options [data-test-default-post-access-option="paid"]'), 'paid-only option').to.exist;
|
||||||
expect(find('.ember-power-select-options [data-test-default-post-access-option="tiers"]'), 'specific tiers option').to.exist;
|
// expect(find('.ember-power-select-options [data-test-default-post-access-option="tiers"]'), 'specific tiers option').to.exist;
|
||||||
|
|
||||||
// switch to members only
|
// // switch to members only
|
||||||
await click('.ember-power-select-options [data-test-default-post-access-option="members"]');
|
// await click('.ember-power-select-options [data-test-default-post-access-option="members"]');
|
||||||
await click('[data-test-button="save-settings"]');
|
// await click('[data-test-button="save-settings"]');
|
||||||
|
|
||||||
expect(this.server.db.settings.findBy({key: 'default_content_visibility'}).value).to.equal('members');
|
// expect(this.server.db.settings.findBy({key: 'default_content_visibility'}).value).to.equal('members');
|
||||||
expect(this.server.db.settings.findBy({key: 'default_content_visibility_tiers'}).value).to.equal('[]');
|
// expect(this.server.db.settings.findBy({key: 'default_content_visibility_tiers'}).value).to.equal('[]');
|
||||||
|
|
||||||
expect(find('[data-test-default-post-access-option="members"]'), 'post-members selection is "members"').to.exist;
|
// expect(find('[data-test-default-post-access-option="members"]'), 'post-members selection is "members"').to.exist;
|
||||||
expect(find('[data-test-default-post-access-tiers]')).to.not.exist;
|
// expect(find('[data-test-default-post-access-tiers]')).to.not.exist;
|
||||||
|
|
||||||
// can switch to specific tiers
|
// // can switch to specific tiers
|
||||||
await click('[data-test-default-post-access-option="members"]');
|
// await click('[data-test-default-post-access-option="members"]');
|
||||||
await click('.ember-power-select-options [data-test-default-post-access-option="tiers"]');
|
// await click('.ember-power-select-options [data-test-default-post-access-option="tiers"]');
|
||||||
|
|
||||||
// tiers input is shown
|
// // tiers input is shown
|
||||||
expect(find('[data-test-default-post-access-tiers]')).to.exist;
|
// expect(find('[data-test-default-post-access-tiers]')).to.exist;
|
||||||
|
|
||||||
// open tiers dropdown
|
// // open tiers dropdown
|
||||||
await click('[data-test-default-post-access-tiers] .ember-basic-dropdown-trigger');
|
// await click('[data-test-default-post-access-tiers] .ember-basic-dropdown-trigger');
|
||||||
|
|
||||||
// paid tiers are available in tiers input
|
// // paid tiers are available in tiers input
|
||||||
expect(find('[data-test-default-post-access-tiers] [data-test-visibility-segment-option="Default Tier"]')).to.exist;
|
// expect(find('[data-test-default-post-access-tiers] [data-test-visibility-segment-option="Default Tier"]')).to.exist;
|
||||||
|
|
||||||
// select tier
|
// // select tier
|
||||||
await click('[data-test-default-post-access-tiers] [data-test-visibility-segment-option="Default Tier"]');
|
// await click('[data-test-default-post-access-tiers] [data-test-visibility-segment-option="Default Tier"]');
|
||||||
|
|
||||||
// save
|
// // save
|
||||||
await click('[data-test-button="save-settings"]');
|
// await click('[data-test-button="save-settings"]');
|
||||||
expect(this.server.db.settings.findBy({key: 'default_content_visibility'}).value).to.equal('tiers');
|
// expect(this.server.db.settings.findBy({key: 'default_content_visibility'}).value).to.equal('tiers');
|
||||||
expect(this.server.db.settings.findBy({key: 'default_content_visibility_tiers'}).value).to.equal('["2"]');
|
// expect(this.server.db.settings.findBy({key: 'default_content_visibility_tiers'}).value).to.equal('["2"]');
|
||||||
|
|
||||||
// switch back to non-tiers option
|
// // switch back to non-tiers option
|
||||||
await click('[data-test-default-post-access-option="tiers"]');
|
// await click('[data-test-default-post-access-option="tiers"]');
|
||||||
await click('.ember-power-select-options [data-test-default-post-access-option="paid"]');
|
// await click('.ember-power-select-options [data-test-default-post-access-option="paid"]');
|
||||||
|
|
||||||
expect(find('[data-test-default-post-access-tiers]')).to.not.exist;
|
// expect(find('[data-test-default-post-access-tiers]')).to.not.exist;
|
||||||
|
|
||||||
await click('[data-test-button="save-settings"]');
|
// await click('[data-test-button="save-settings"]');
|
||||||
expect(this.server.db.settings.findBy({key: 'default_content_visibility'}).value).to.equal('paid');
|
// expect(this.server.db.settings.findBy({key: 'default_content_visibility'}).value).to.equal('paid');
|
||||||
expect(this.server.db.settings.findBy({key: 'default_content_visibility_tiers'}).value).to.equal('["2"]');
|
// expect(this.server.db.settings.findBy({key: 'default_content_visibility_tiers'}).value).to.equal('["2"]');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can manage free tier', async function () {
|
// it('can manage free tier', async function () {
|
||||||
await visit('/settings/members');
|
// await visit('/settings/members');
|
||||||
await click('[data-test-button="toggle-free-settings"]');
|
// await click('[data-test-button="toggle-free-settings"]');
|
||||||
expect(find('[data-test-free-settings-expanded]'), 'expanded free settings').to.exist;
|
// expect(find('[data-test-free-settings-expanded]'), 'expanded free settings').to.exist;
|
||||||
|
|
||||||
// we aren't viewing the non-labs-flag input
|
// // we aren't viewing the non-labs-flag input
|
||||||
expect(find('[data-test-input="old-free-welcome-page"]')).to.not.exist;
|
// expect(find('[data-test-input="old-free-welcome-page"]')).to.not.exist;
|
||||||
|
|
||||||
// it can set free signup welcome page
|
// // it can set free signup welcome page
|
||||||
|
|
||||||
// initial value
|
// // initial value
|
||||||
expect(find('[data-test-input="free-welcome-page"]')).to.exist;
|
// expect(find('[data-test-input="free-welcome-page"]')).to.exist;
|
||||||
expect(find('[data-test-input="free-welcome-page"]')).to.have.value('');
|
// expect(find('[data-test-input="free-welcome-page"]')).to.have.value('');
|
||||||
|
|
||||||
// saving
|
// // saving
|
||||||
await fillIn('[data-test-input="free-welcome-page"]', 'not a url');
|
// await fillIn('[data-test-input="free-welcome-page"]', 'not a url');
|
||||||
await blur('[data-test-input="free-welcome-page"]');
|
// await blur('[data-test-input="free-welcome-page"]');
|
||||||
await click('[data-test-button="save-settings"]');
|
// await click('[data-test-button="save-settings"]');
|
||||||
|
|
||||||
expect(this.server.db.tiers.findBy({slug: 'free'}).welcomePageUrl)
|
// expect(this.server.db.tiers.findBy({slug: 'free'}).welcomePageUrl)
|
||||||
.to.equal('/not%20a%20url');
|
// .to.equal('/not%20a%20url');
|
||||||
|
|
||||||
// re-rendering will insert full URL in welcome page input
|
// // re-rendering will insert full URL in welcome page input
|
||||||
await visit('/settings');
|
// await visit('/settings');
|
||||||
await visit('/settings/members');
|
// await visit('/settings/members');
|
||||||
|
|
||||||
expect(find('[data-test-input="free-welcome-page"]')).to.exist;
|
// expect(find('[data-test-input="free-welcome-page"]')).to.exist;
|
||||||
expect(find('[data-test-input="free-welcome-page"]'))
|
// expect(find('[data-test-input="free-welcome-page"]'))
|
||||||
.to.have.value('http://localhost:2368/not%20a%20url');
|
// .to.have.value('http://localhost:2368/not%20a%20url');
|
||||||
|
|
||||||
// it can manage free tier description and benefits
|
// // it can manage free tier description and benefits
|
||||||
|
|
||||||
// initial free tier details are as expected
|
// // initial free tier details are as expected
|
||||||
expect(find('[data-test-tier-card="free"]')).to.exist;
|
// expect(find('[data-test-tier-card="free"]')).to.exist;
|
||||||
expect(find('[data-test-tier-card="free"] [data-test-name]')).to.contain.text('Free');
|
// expect(find('[data-test-tier-card="free"] [data-test-name]')).to.contain.text('Free');
|
||||||
expect(find('[data-test-tier-card="free"] [data-test-description]')).to.contain.text('No description');
|
// expect(find('[data-test-tier-card="free"] [data-test-description]')).to.contain.text('No description');
|
||||||
expect(find('[data-test-tier-card="free"] [data-test-benefits]')).to.contain.text('No benefits');
|
// expect(find('[data-test-tier-card="free"] [data-test-benefits]')).to.contain.text('No benefits');
|
||||||
expect(find('[data-test-tier-card="free"] [data-test-free-price]')).to.exist;
|
// expect(find('[data-test-tier-card="free"] [data-test-free-price]')).to.exist;
|
||||||
|
|
||||||
// open modal
|
// // open modal
|
||||||
await click('[data-test-tier-card="free"] [data-test-button="edit-tier"]');
|
// await click('[data-test-tier-card="free"] [data-test-button="edit-tier"]');
|
||||||
|
|
||||||
// initial modal state is as expected
|
// // initial modal state is as expected
|
||||||
const modal = '[data-test-modal="edit-tier"]';
|
// const modal = '[data-test-modal="edit-tier"]';
|
||||||
expect(find(modal)).to.exist;
|
// expect(find(modal)).to.exist;
|
||||||
expect(find(`${modal} [data-test-input="tier-name"]`)).to.not.exist;
|
// expect(find(`${modal} [data-test-input="tier-name"]`)).to.not.exist;
|
||||||
expect(find(`${modal} [data-test-input="tier-description"]`)).to.not.exist;
|
// expect(find(`${modal} [data-test-input="tier-description"]`)).to.not.exist;
|
||||||
expect(find(`${modal} [data-test-input="free-tier-description"]`)).to.exist;
|
// expect(find(`${modal} [data-test-input="free-tier-description"]`)).to.exist;
|
||||||
expect(find(`${modal} [data-test-input="free-tier-description"]`)).to.have.value('');
|
// expect(find(`${modal} [data-test-input="free-tier-description"]`)).to.have.value('');
|
||||||
expect(find(`${modal} [data-test-formgroup="prices"]`)).to.not.exist;
|
// expect(find(`${modal} [data-test-formgroup="prices"]`)).to.not.exist;
|
||||||
expect(find(`${modal} [data-test-benefit-item="new"]`)).to.exist;
|
// expect(find(`${modal} [data-test-benefit-item="new"]`)).to.exist;
|
||||||
expect(findAll(`${modal} [data-test-benefit-item]`).length).to.equal(1);
|
// expect(findAll(`${modal} [data-test-benefit-item]`).length).to.equal(1);
|
||||||
|
|
||||||
expect(find(`${modal} [data-test-tierpreview-title]`)).to.contain.text('Free Membership Preview');
|
// expect(find(`${modal} [data-test-tierpreview-title]`)).to.contain.text('Free Membership Preview');
|
||||||
expect(find(`${modal} [data-test-tierpreview-description]`)).to.contain.text('Free preview of');
|
// expect(find(`${modal} [data-test-tierpreview-description]`)).to.contain.text('Free preview of');
|
||||||
expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.contain.text('Access to all public posts');
|
// expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.contain.text('Access to all public posts');
|
||||||
expect(find(`${modal} [data-test-tierpreview-price]`).textContent).to.match(/\$\s+0/);
|
// expect(find(`${modal} [data-test-tierpreview-price]`).textContent).to.match(/\$\s+0/);
|
||||||
|
|
||||||
// can change description
|
// // can change description
|
||||||
await fillIn(`${modal} [data-test-input="free-tier-description"]`, 'Test description');
|
// await fillIn(`${modal} [data-test-input="free-tier-description"]`, 'Test description');
|
||||||
expect(find(`${modal} [data-test-tierpreview-description]`)).to.contain.text('Test description');
|
// expect(find(`${modal} [data-test-tierpreview-description]`)).to.contain.text('Test description');
|
||||||
|
|
||||||
// can manage benefits
|
// // can manage benefits
|
||||||
const newBenefit = `${modal} [data-test-benefit-item="new"]`;
|
// const newBenefit = `${modal} [data-test-benefit-item="new"]`;
|
||||||
await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'First benefit');
|
// await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'First benefit');
|
||||||
await click(`${newBenefit} [data-test-button="add-benefit"]`);
|
// await click(`${newBenefit} [data-test-button="add-benefit"]`);
|
||||||
|
|
||||||
expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.contain.text('First benefit');
|
// expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.contain.text('First benefit');
|
||||||
|
|
||||||
expect(find(`${modal} [data-test-benefit-item="0"]`)).to.exist;
|
// expect(find(`${modal} [data-test-benefit-item="0"]`)).to.exist;
|
||||||
expect(find(`${modal} [data-test-benefit-item="new"]`)).to.exist;
|
// expect(find(`${modal} [data-test-benefit-item="new"]`)).to.exist;
|
||||||
|
|
||||||
await click(`${newBenefit} [data-test-button="add-benefit"]`);
|
// await click(`${newBenefit} [data-test-button="add-benefit"]`);
|
||||||
expect(find(`${newBenefit}`)).to.contain.text('Please enter a benefit');
|
// expect(find(`${newBenefit}`)).to.contain.text('Please enter a benefit');
|
||||||
|
|
||||||
await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'Second benefit');
|
// await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'Second benefit');
|
||||||
await click(`${newBenefit} [data-test-button="add-benefit"]`);
|
// await click(`${newBenefit} [data-test-button="add-benefit"]`);
|
||||||
|
|
||||||
expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.contain.text('Second benefit');
|
// expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.contain.text('Second benefit');
|
||||||
expect(findAll(`${modal} [data-test-tierpreview-benefits] div`).length).to.equal(4);
|
// expect(findAll(`${modal} [data-test-tierpreview-benefits] div`).length).to.equal(4);
|
||||||
|
|
||||||
await click(`${modal} [data-test-benefit-item="0"] [data-test-button="delete-benefit"]`);
|
// await click(`${modal} [data-test-benefit-item="0"] [data-test-button="delete-benefit"]`);
|
||||||
|
|
||||||
expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.not.contain.text('First benefit');
|
// expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.not.contain.text('First benefit');
|
||||||
expect(findAll(`${modal} [data-test-tierpreview-benefits] div`).length).to.equal(2);
|
// expect(findAll(`${modal} [data-test-tierpreview-benefits] div`).length).to.equal(2);
|
||||||
|
|
||||||
// Add a new benefit that we will later rename to an empty name
|
// // Add a new benefit that we will later rename to an empty name
|
||||||
await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'Third benefit');
|
// await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'Third benefit');
|
||||||
await click(`${newBenefit} [data-test-button="add-benefit"]`);
|
// await click(`${newBenefit} [data-test-button="add-benefit"]`);
|
||||||
|
|
||||||
expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.contain.text('Third benefit');
|
// expect(find(`${modal} [data-test-tierpreview-benefits]`)).to.contain.text('Third benefit');
|
||||||
expect(findAll(`${modal} [data-test-tierpreview-benefits] div`).length).to.equal(4);
|
// expect(findAll(`${modal} [data-test-tierpreview-benefits] div`).length).to.equal(4);
|
||||||
|
|
||||||
// Clear the second benefit's name (it should get removed after saving)
|
// // Clear the second benefit's name (it should get removed after saving)
|
||||||
const secondBenefitItem = `${modal} [data-test-benefit-item="1"]`;
|
// const secondBenefitItem = `${modal} [data-test-benefit-item="1"]`;
|
||||||
await fillIn(`${secondBenefitItem} [data-test-input="benefit-label"]`, '');
|
// await fillIn(`${secondBenefitItem} [data-test-input="benefit-label"]`, '');
|
||||||
|
|
||||||
await click('[data-test-button="save-tier"]');
|
// await click('[data-test-button="save-tier"]');
|
||||||
|
|
||||||
expect(find(`${modal}`)).to.not.exist;
|
// expect(find(`${modal}`)).to.not.exist;
|
||||||
expect(find('[data-test-tier-card="free"] [data-test-name]')).to.contain.text('Free');
|
// expect(find('[data-test-tier-card="free"] [data-test-name]')).to.contain.text('Free');
|
||||||
expect(find('[data-test-tier-card="free"] [data-test-description]')).to.contain.text('Test description');
|
// expect(find('[data-test-tier-card="free"] [data-test-description]')).to.contain.text('Test description');
|
||||||
expect(find('[data-test-tier-card="free"] [data-test-benefits]')).to.contain.text('Benefits (1)');
|
// expect(find('[data-test-tier-card="free"] [data-test-benefits]')).to.contain.text('Benefits (1)');
|
||||||
expect(find('[data-test-tier-card="free"] [data-test-benefits] li:nth-of-type(1)')).to.contain.text('Second benefit');
|
// expect(find('[data-test-tier-card="free"] [data-test-benefits] li:nth-of-type(1)')).to.contain.text('Second benefit');
|
||||||
expect(findAll(`[data-test-tier-card="free"] [data-test-benefits] li`).length).to.equal(1);
|
// expect(findAll(`[data-test-tier-card="free"] [data-test-benefits] li`).length).to.equal(1);
|
||||||
|
|
||||||
const freeTier = this.server.db.tiers.findBy({slug: 'free'});
|
// const freeTier = this.server.db.tiers.findBy({slug: 'free'});
|
||||||
expect(freeTier.description).to.equal('Test description');
|
// expect(freeTier.description).to.equal('Test description');
|
||||||
expect(freeTier.welcomePageUrl).to.equal('/not%20a%20url');
|
// expect(freeTier.welcomePageUrl).to.equal('/not%20a%20url');
|
||||||
expect(freeTier.benefits.length).to.equal(1);
|
// expect(freeTier.benefits.length).to.equal(1);
|
||||||
expect(freeTier.benefits[0]).to.equal('Second benefit');
|
// expect(freeTier.benefits[0]).to.equal('Second benefit');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,252 +1,252 @@
|
|||||||
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
||||||
import {authenticateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession} from 'ember-simple-auth/test-support';
|
||||||
import {beforeEach, describe, it} from 'mocha';
|
// import {beforeEach, describe, it} from 'mocha';
|
||||||
import {blur, click, currentRouteName, currentURL, fillIn, find, findAll, triggerEvent, typeIn} from '@ember/test-helpers';
|
// import {blur, click, currentRouteName, currentURL, fillIn, find, findAll, triggerEvent, typeIn} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
// simulate jQuery's `:visible` pseudo-selector
|
// // simulate jQuery's `:visible` pseudo-selector
|
||||||
function withText(elements) {
|
// function withText(elements) {
|
||||||
return Array.from(elements).filter(elem => elem.textContent.trim() !== '');
|
// return Array.from(elements).filter(elem => elem.textContent.trim() !== '');
|
||||||
}
|
// }
|
||||||
|
|
||||||
describe('Acceptance: Settings - Navigation', function () {
|
// describe('Acceptance: Settings - Navigation', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
describe('when logged in', function () {
|
// describe('when logged in', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can visit /settings/navigation', async function () {
|
// it('can visit /settings/navigation', async function () {
|
||||||
await visit('/settings/navigation');
|
// await visit('/settings/navigation');
|
||||||
|
|
||||||
expect(currentRouteName()).to.equal('settings.navigation');
|
// expect(currentRouteName()).to.equal('settings.navigation');
|
||||||
expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
// expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
|
||||||
|
|
||||||
// fixtures contain two nav items, check for four rows as we
|
// // fixtures contain two nav items, check for four rows as we
|
||||||
// should have one extra that's blank for each navigation section
|
// // should have one extra that's blank for each navigation section
|
||||||
expect(
|
// expect(
|
||||||
findAll('[data-test-navitem]').length,
|
// findAll('[data-test-navitem]').length,
|
||||||
'navigation items count'
|
// 'navigation items count'
|
||||||
).to.equal(4);
|
// ).to.equal(4);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('saves navigation settings', async function () {
|
// it('saves navigation settings', async function () {
|
||||||
await visit('/settings/navigation');
|
// await visit('/settings/navigation');
|
||||||
await fillIn('#settings-navigation [data-test-navitem="0"] [data-test-input="label"]', 'Test');
|
// await fillIn('#settings-navigation [data-test-navitem="0"] [data-test-input="label"]', 'Test');
|
||||||
await typeIn('#settings-navigation [data-test-navitem="0"] [data-test-input="url"]', '/test');
|
// await typeIn('#settings-navigation [data-test-navitem="0"] [data-test-input="url"]', '/test');
|
||||||
await click('[data-test-save-button]');
|
// await click('[data-test-save-button]');
|
||||||
|
|
||||||
let [navSetting] = this.server.db.settings.where({key: 'navigation'});
|
// let [navSetting] = this.server.db.settings.where({key: 'navigation'});
|
||||||
|
|
||||||
expect(navSetting.value).to.equal('[{"label":"Test","url":"/test/"},{"label":"About","url":"/about"}]');
|
// expect(navSetting.value).to.equal('[{"label":"Test","url":"/test/"},{"label":"About","url":"/about"}]');
|
||||||
|
|
||||||
// don't test against .error directly as it will pick up failed
|
// // don't test against .error directly as it will pick up failed
|
||||||
// tests "pre.error" elements
|
// // tests "pre.error" elements
|
||||||
expect(findAll('span.error').length, 'error messages count').to.equal(0);
|
// expect(findAll('span.error').length, 'error messages count').to.equal(0);
|
||||||
expect(findAll('.gh-alert').length, 'alerts count').to.equal(0);
|
// expect(findAll('.gh-alert').length, 'alerts count').to.equal(0);
|
||||||
expect(withText(findAll('[data-test-error]')).length, 'validation errors count')
|
// expect(withText(findAll('[data-test-error]')).length, 'validation errors count')
|
||||||
.to.equal(0);
|
// .to.equal(0);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('validates new item correctly on save', async function () {
|
// it('validates new item correctly on save', async function () {
|
||||||
await visit('/settings/navigation');
|
// await visit('/settings/navigation');
|
||||||
await click('[data-test-save-button]');
|
// await click('[data-test-save-button]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
findAll('#settings-navigation [data-test-navitem]').length,
|
// findAll('#settings-navigation [data-test-navitem]').length,
|
||||||
'number of nav items after saving with blank new item'
|
// 'number of nav items after saving with blank new item'
|
||||||
).to.equal(3);
|
// ).to.equal(3);
|
||||||
|
|
||||||
await fillIn('#settings-navigation [data-test-navitem="new"] [data-test-input="label"]', 'Test');
|
// await fillIn('#settings-navigation [data-test-navitem="new"] [data-test-input="label"]', 'Test');
|
||||||
await fillIn('#settings-navigation [data-test-navitem="new"] [data-test-input="url"]', '');
|
// await fillIn('#settings-navigation [data-test-navitem="new"] [data-test-input="url"]', '');
|
||||||
await typeIn('#settings-navigation [data-test-navitem="new"] [data-test-input="url"]', 'http://invalid domain/');
|
// await typeIn('#settings-navigation [data-test-navitem="new"] [data-test-input="url"]', 'http://invalid domain/');
|
||||||
|
|
||||||
await click('[data-test-save-button]');
|
// await click('[data-test-save-button]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
findAll('#settings-navigation [data-test-navitem]').length,
|
// findAll('#settings-navigation [data-test-navitem]').length,
|
||||||
'number of nav items after saving with invalid new item'
|
// 'number of nav items after saving with invalid new item'
|
||||||
).to.equal(3);
|
// ).to.equal(3);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
withText(findAll('#settings-navigation [data-test-navitem="new"] [data-test-error]')).length,
|
// withText(findAll('#settings-navigation [data-test-navitem="new"] [data-test-error]')).length,
|
||||||
'number of invalid fields in new item'
|
// 'number of invalid fields in new item'
|
||||||
).to.equal(1);
|
// ).to.equal(1);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('clears unsaved settings when navigating away but warns with a confirmation dialog', async function () {
|
// it('clears unsaved settings when navigating away but warns with a confirmation dialog', async function () {
|
||||||
await visit('/settings/navigation');
|
// await visit('/settings/navigation');
|
||||||
await fillIn('[data-test-navitem="0"] [data-test-input="label"]', 'Test');
|
// await fillIn('[data-test-navitem="0"] [data-test-input="label"]', 'Test');
|
||||||
await blur('[data-test-navitem="0"] [data-test-input="label"]');
|
// await blur('[data-test-navitem="0"] [data-test-input="label"]');
|
||||||
|
|
||||||
expect(find('[data-test-navitem="0"] [data-test-input="label"]').value).to.equal('Test');
|
// expect(find('[data-test-navitem="0"] [data-test-input="label"]').value).to.equal('Test');
|
||||||
|
|
||||||
await visit('/settings/code-injection');
|
// await visit('/settings/code-injection');
|
||||||
|
|
||||||
expect(findAll('[data-test-modal="unsaved-settings"]').length, 'modal exists').to.equal(1);
|
// expect(findAll('[data-test-modal="unsaved-settings"]').length, 'modal exists').to.equal(1);
|
||||||
|
|
||||||
// Leave without saving
|
// // Leave without saving
|
||||||
await click('[data-test-leave-button]'), 'leave without saving';
|
// await click('[data-test-leave-button]'), 'leave without saving';
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/code-injection');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/code-injection');
|
||||||
|
|
||||||
await visit('/settings/navigation');
|
// await visit('/settings/navigation');
|
||||||
|
|
||||||
expect(find('[data-test-navitem="0"] [data-test-input="label"]').value).to.equal('Home');
|
// expect(find('[data-test-navitem="0"] [data-test-input="label"]').value).to.equal('Home');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can add and remove items', async function () {
|
// it('can add and remove items', async function () {
|
||||||
await visit('/settings/navigation');
|
// await visit('/settings/navigation');
|
||||||
await click('#settings-navigation .gh-blognav-add');
|
// await click('#settings-navigation .gh-blognav-add');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
|
// find('[data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
|
||||||
'blank label has validation error'
|
// 'blank label has validation error'
|
||||||
).to.not.be.empty;
|
// ).to.not.be.empty;
|
||||||
|
|
||||||
await fillIn('[data-test-navitem="new"] [data-test-input="label"]', '');
|
// await fillIn('[data-test-navitem="new"] [data-test-input="label"]', '');
|
||||||
await typeIn('[data-test-navitem="new"] [data-test-input="label"]', 'New');
|
// await typeIn('[data-test-navitem="new"] [data-test-input="label"]', 'New');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
|
// find('[data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
|
||||||
'label validation is visible after typing'
|
// 'label validation is visible after typing'
|
||||||
).to.be.empty;
|
// ).to.be.empty;
|
||||||
|
|
||||||
await fillIn('[data-test-navitem="new"] [data-test-input="url"]', '');
|
// await fillIn('[data-test-navitem="new"] [data-test-input="url"]', '');
|
||||||
await typeIn('[data-test-navitem="new"] [data-test-input="url"]', '/new');
|
// await typeIn('[data-test-navitem="new"] [data-test-input="url"]', '/new');
|
||||||
await blur('[data-test-navitem="new"] [data-test-input="url"]');
|
// await blur('[data-test-navitem="new"] [data-test-input="url"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-navitem="new"] [data-test-error="url"]').textContent.trim(),
|
// find('[data-test-navitem="new"] [data-test-error="url"]').textContent.trim(),
|
||||||
'url validation is visible after typing'
|
// 'url validation is visible after typing'
|
||||||
).to.be.empty;
|
// ).to.be.empty;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-navitem="new"] [data-test-input="url"]').value
|
// find('[data-test-navitem="new"] [data-test-input="url"]').value
|
||||||
).to.equal(`${window.location.origin}/new/`);
|
// ).to.equal(`${window.location.origin}/new/`);
|
||||||
|
|
||||||
await click('.gh-blognav-add');
|
// await click('.gh-blognav-add');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
findAll('#settings-navigation [data-test-navitem]').length,
|
// findAll('#settings-navigation [data-test-navitem]').length,
|
||||||
'number of nav items after successful add'
|
// 'number of nav items after successful add'
|
||||||
).to.equal(4);
|
// ).to.equal(4);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('#settings-navigation [data-test-navitem="new"] [data-test-input="label"]').value,
|
// find('#settings-navigation [data-test-navitem="new"] [data-test-input="label"]').value,
|
||||||
'new item label value after successful add'
|
// 'new item label value after successful add'
|
||||||
).to.be.empty;
|
// ).to.be.empty;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('#settings-navigation [data-test-navitem="new"] [data-test-input="url"]').value,
|
// find('#settings-navigation [data-test-navitem="new"] [data-test-input="url"]').value,
|
||||||
'new item url value after successful add'
|
// 'new item url value after successful add'
|
||||||
).to.equal(`${window.location.origin}/`);
|
// ).to.equal(`${window.location.origin}/`);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
withText(findAll('[data-test-navitem] [data-test-error]')).length,
|
// withText(findAll('[data-test-navitem] [data-test-error]')).length,
|
||||||
'number or validation errors shown after successful add'
|
// 'number or validation errors shown after successful add'
|
||||||
).to.equal(0);
|
// ).to.equal(0);
|
||||||
|
|
||||||
await click('#settings-navigation [data-test-navitem="0"] .gh-blognav-delete');
|
// await click('#settings-navigation [data-test-navitem="0"] .gh-blognav-delete');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
findAll('#settings-navigation [data-test-navitem]').length,
|
// findAll('#settings-navigation [data-test-navitem]').length,
|
||||||
'number of nav items after successful remove'
|
// 'number of nav items after successful remove'
|
||||||
).to.equal(3);
|
// ).to.equal(3);
|
||||||
|
|
||||||
// CMD-S shortcut works
|
// // CMD-S shortcut works
|
||||||
await triggerEvent('.gh-app', 'keydown', {
|
// await triggerEvent('.gh-app', 'keydown', {
|
||||||
keyCode: 83, // s
|
// keyCode: 83, // s
|
||||||
metaKey: ctrlOrCmd === 'command',
|
// metaKey: ctrlOrCmd === 'command',
|
||||||
ctrlKey: ctrlOrCmd === 'ctrl'
|
// ctrlKey: ctrlOrCmd === 'ctrl'
|
||||||
});
|
// });
|
||||||
|
|
||||||
let [navSetting] = this.server.db.settings.where({key: 'navigation'});
|
// let [navSetting] = this.server.db.settings.where({key: 'navigation'});
|
||||||
|
|
||||||
expect(navSetting.value).to.equal('[{"label":"About","url":"/about"},{"label":"New","url":"/new/"}]');
|
// expect(navSetting.value).to.equal('[{"label":"About","url":"/about"},{"label":"New","url":"/new/"}]');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('can also add and remove items from seconday nav', async function () {
|
// it('can also add and remove items from seconday nav', async function () {
|
||||||
await visit('/settings/navigation');
|
// await visit('/settings/navigation');
|
||||||
await click('#secondary-navigation .gh-blognav-add');
|
// await click('#secondary-navigation .gh-blognav-add');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('#secondary-navigation [data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
|
// find('#secondary-navigation [data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
|
||||||
'blank label has validation error'
|
// 'blank label has validation error'
|
||||||
).to.not.be.empty;
|
// ).to.not.be.empty;
|
||||||
|
|
||||||
await fillIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]', '');
|
// await fillIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]', '');
|
||||||
await typeIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]', 'Foo');
|
// await typeIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]', 'Foo');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('#secondary-navigation [data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
|
// find('#secondary-navigation [data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
|
||||||
'label validation is visible after typing'
|
// 'label validation is visible after typing'
|
||||||
).to.be.empty;
|
// ).to.be.empty;
|
||||||
|
|
||||||
await fillIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]', '');
|
// await fillIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]', '');
|
||||||
await typeIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]', '/bar');
|
// await typeIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]', '/bar');
|
||||||
await blur('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]');
|
// await blur('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('#secondary-navigation [data-test-navitem="new"] [data-test-error="url"]').textContent.trim(),
|
// find('#secondary-navigation [data-test-navitem="new"] [data-test-error="url"]').textContent.trim(),
|
||||||
'url validation is visible after typing'
|
// 'url validation is visible after typing'
|
||||||
).to.be.empty;
|
// ).to.be.empty;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]').value
|
// find('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]').value
|
||||||
).to.equal(`${window.location.origin}/bar/`);
|
// ).to.equal(`${window.location.origin}/bar/`);
|
||||||
|
|
||||||
await click('[data-test-save-button]');
|
// await click('[data-test-save-button]');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
findAll('#secondary-navigation [data-test-navitem]').length,
|
// findAll('#secondary-navigation [data-test-navitem]').length,
|
||||||
'number of nav items after successful add'
|
// 'number of nav items after successful add'
|
||||||
).to.equal(2);
|
// ).to.equal(2);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]').value,
|
// find('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]').value,
|
||||||
'new item label value after successful add'
|
// 'new item label value after successful add'
|
||||||
).to.be.empty;
|
// ).to.be.empty;
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
find('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]').value,
|
// find('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]').value,
|
||||||
'new item url value after successful add'
|
// 'new item url value after successful add'
|
||||||
).to.equal(`${window.location.origin}/`);
|
// ).to.equal(`${window.location.origin}/`);
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
withText(findAll('#secondary-navigation [data-test-navitem] [data-test-error]')).length,
|
// withText(findAll('#secondary-navigation [data-test-navitem] [data-test-error]')).length,
|
||||||
'number or validation errors shown after successful add'
|
// 'number or validation errors shown after successful add'
|
||||||
).to.equal(0);
|
// ).to.equal(0);
|
||||||
|
|
||||||
let [navSetting] = this.server.db.settings.where({key: 'secondary_navigation'});
|
// let [navSetting] = this.server.db.settings.where({key: 'secondary_navigation'});
|
||||||
|
|
||||||
expect(navSetting.value).to.equal('[{"label":"Foo","url":"/bar/"}]');
|
// expect(navSetting.value).to.equal('[{"label":"Foo","url":"/bar/"}]');
|
||||||
|
|
||||||
await click('#secondary-navigation [data-test-navitem="0"] .gh-blognav-delete');
|
// await click('#secondary-navigation [data-test-navitem="0"] .gh-blognav-delete');
|
||||||
|
|
||||||
expect(
|
// expect(
|
||||||
findAll('#secondary-navigation [data-test-navitem]').length,
|
// findAll('#secondary-navigation [data-test-navitem]').length,
|
||||||
'number of nav items after successful remove'
|
// 'number of nav items after successful remove'
|
||||||
).to.equal(1);
|
// ).to.equal(1);
|
||||||
|
|
||||||
// CMD-S shortcut works
|
// // CMD-S shortcut works
|
||||||
await triggerEvent('.gh-app', 'keydown', {
|
// await triggerEvent('.gh-app', 'keydown', {
|
||||||
keyCode: 83, // s
|
// keyCode: 83, // s
|
||||||
metaKey: ctrlOrCmd === 'command',
|
// metaKey: ctrlOrCmd === 'command',
|
||||||
ctrlKey: ctrlOrCmd === 'ctrl'
|
// ctrlKey: ctrlOrCmd === 'ctrl'
|
||||||
});
|
// });
|
||||||
|
|
||||||
[navSetting] = this.server.db.settings.where({key: 'secondary_navigation'});
|
// [navSetting] = this.server.db.settings.where({key: 'secondary_navigation'});
|
||||||
|
|
||||||
expect(navSetting.value).to.equal('[]');
|
// expect(navSetting.value).to.equal('[]');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,151 +1,151 @@
|
|||||||
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
||||||
import {Response} from 'miragejs';
|
// import {Response} from 'miragejs';
|
||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {beforeEach, describe, it} from 'mocha';
|
// import {beforeEach, describe, it} from 'mocha';
|
||||||
import {blur, click, currentURL, fillIn, find, findAll, triggerEvent} from '@ember/test-helpers';
|
// import {blur, click, currentURL, fillIn, find, findAll, triggerEvent} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Integrations - Slack', function () {
|
// describe('Acceptance: Settings - Integrations - Slack', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
it('redirects to signin when not authenticated', async function () {
|
// it('redirects to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/integrations/slack');
|
// await visit('/settings/integrations/slack');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as contributor', async function () {
|
// it('redirects to home page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
// let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/slack');
|
// await visit('/settings/integrations/slack');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/posts');
|
// expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as author', async function () {
|
// it('redirects to home page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
// let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/slack');
|
// await visit('/settings/integrations/slack');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as editor', async function () {
|
// it('redirects to home page when authenticated as editor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Editor'});
|
// let role = this.server.create('role', {name: 'Editor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/slack');
|
// await visit('/settings/integrations/slack');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('when logged in', function () {
|
// describe('when logged in', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it validates and saves slack settings properly', async function () {
|
// it('it validates and saves slack settings properly', async function () {
|
||||||
await visit('/settings/integrations/slack');
|
// await visit('/settings/integrations/slack');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
|
||||||
|
|
||||||
await fillIn('[data-test-slack-url-input]', 'notacorrecturl');
|
// await fillIn('[data-test-slack-url-input]', 'notacorrecturl');
|
||||||
await click('[data-test-save-button]');
|
// await click('[data-test-save-button]');
|
||||||
|
|
||||||
expect(find('[data-test-error="slack-url"]').textContent.trim(), 'inline validation response')
|
// expect(find('[data-test-error="slack-url"]').textContent.trim(), 'inline validation response')
|
||||||
.to.equal('The URL must be in a format like https://hooks.slack.com/services/<your personal key>');
|
// .to.equal('The URL must be in a format like https://hooks.slack.com/services/<your personal key>');
|
||||||
|
|
||||||
// CMD-S shortcut works
|
// // CMD-S shortcut works
|
||||||
await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
|
// await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
|
||||||
await fillIn('[data-test-slack-username-input]', 'SlackBot');
|
// await fillIn('[data-test-slack-username-input]', 'SlackBot');
|
||||||
await triggerEvent('.gh-app', 'keydown', {
|
// await triggerEvent('.gh-app', 'keydown', {
|
||||||
keyCode: 83, // s
|
// keyCode: 83, // s
|
||||||
metaKey: ctrlOrCmd === 'command',
|
// metaKey: ctrlOrCmd === 'command',
|
||||||
ctrlKey: ctrlOrCmd === 'ctrl'
|
// ctrlKey: ctrlOrCmd === 'ctrl'
|
||||||
});
|
// });
|
||||||
|
|
||||||
let [newRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [newRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
let params = JSON.parse(newRequest.requestBody);
|
// let params = JSON.parse(newRequest.requestBody);
|
||||||
|
|
||||||
let urlResult = params.settings.findBy('key', 'slack_url').value;
|
// let urlResult = params.settings.findBy('key', 'slack_url').value;
|
||||||
let usernameResult = params.settings.findBy('key', 'slack_username').value;
|
// let usernameResult = params.settings.findBy('key', 'slack_username').value;
|
||||||
|
|
||||||
expect(urlResult).to.equal('https://hooks.slack.com/services/1275958430');
|
// expect(urlResult).to.equal('https://hooks.slack.com/services/1275958430');
|
||||||
expect(usernameResult).to.equal('SlackBot');
|
// expect(usernameResult).to.equal('SlackBot');
|
||||||
expect(find('[data-test-error="slack-url"]'), 'inline validation response')
|
// expect(find('[data-test-error="slack-url"]'), 'inline validation response')
|
||||||
.to.not.exist;
|
// .to.not.exist;
|
||||||
|
|
||||||
await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
|
// await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
|
||||||
await click('[data-test-send-notification-button]');
|
// await click('[data-test-send-notification-button]');
|
||||||
|
|
||||||
expect(findAll('.gh-notification').length, 'number of notifications').to.equal(1);
|
// expect(findAll('.gh-notification').length, 'number of notifications').to.equal(1);
|
||||||
expect(find('[data-test-error="slack-url"]'), 'inline validation response')
|
// expect(find('[data-test-error="slack-url"]'), 'inline validation response')
|
||||||
.to.not.exist;
|
// .to.not.exist;
|
||||||
|
|
||||||
// modify model data or there will be no api call
|
// // modify model data or there will be no api call
|
||||||
await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958431');
|
// await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958431');
|
||||||
|
|
||||||
this.server.put('/settings/', function () {
|
// this.server.put('/settings/', function () {
|
||||||
return new Response(422, {}, {
|
// return new Response(422, {}, {
|
||||||
errors: [
|
// errors: [
|
||||||
{
|
// {
|
||||||
type: 'ValidationError',
|
// type: 'ValidationError',
|
||||||
message: 'Test error'
|
// message: 'Test error'
|
||||||
}
|
// }
|
||||||
]
|
// ]
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
await click('.gh-notification .gh-notification-close');
|
// await click('.gh-notification .gh-notification-close');
|
||||||
await click('[data-test-send-notification-button]');
|
// await click('[data-test-send-notification-button]');
|
||||||
|
|
||||||
// we shouldn't try to send the test request if the save fails
|
// // we shouldn't try to send the test request if the save fails
|
||||||
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
expect(lastRequest.url).to.not.match(/\/slack\/test/);
|
// expect(lastRequest.url).to.not.match(/\/slack\/test/);
|
||||||
expect(findAll('.gh-notification').length, 'check slack notification after api validation error').to.equal(0);
|
// expect(findAll('.gh-notification').length, 'check slack notification after api validation error').to.equal(0);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('warns when leaving without saving', async function () {
|
// it('warns when leaving without saving', async function () {
|
||||||
await visit('/settings/integrations/slack');
|
// await visit('/settings/integrations/slack');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
|
||||||
|
|
||||||
await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
|
// await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
|
||||||
await blur('[data-test-slack-url-input]');
|
// await blur('[data-test-slack-url-input]');
|
||||||
|
|
||||||
await visit('/settings');
|
// await visit('/settings');
|
||||||
|
|
||||||
expect(findAll('[data-test-modal="unsaved-settings"]').length, 'modal exists').to.equal(1);
|
// expect(findAll('[data-test-modal="unsaved-settings"]').length, 'modal exists').to.equal(1);
|
||||||
|
|
||||||
// Leave without saving
|
// // Leave without saving
|
||||||
await click('[data-test-modal="unsaved-settings"] [data-test-leave-button]');
|
// await click('[data-test-modal="unsaved-settings"] [data-test-leave-button]');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings');
|
// expect(currentURL(), 'currentURL').to.equal('/settings');
|
||||||
|
|
||||||
await visit('/settings/integrations/slack');
|
// await visit('/settings/integrations/slack');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
|
||||||
|
|
||||||
// settings were not saved
|
// // settings were not saved
|
||||||
expect(
|
// expect(
|
||||||
find('[data-test-slack-url-input]').textContent.trim(),
|
// find('[data-test-slack-url-input]').textContent.trim(),
|
||||||
'Slack Webhook URL'
|
// 'Slack Webhook URL'
|
||||||
).to.equal('');
|
// ).to.equal('');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -18,24 +18,24 @@ describe('Acceptance: Tags', function () {
|
|||||||
expect(currentURL()).to.equal('/signin');
|
expect(currentURL()).to.equal('/signin');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('redirects to staff page when authenticated as contributor', async function () {
|
it('redirects to posts page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
await authenticateSession();
|
||||||
await visit('/settings/design');
|
await visit('/tags');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/staff/test-user');
|
expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('redirects to staff page when authenticated as author', async function () {
|
it('redirects to site page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
await authenticateSession();
|
||||||
await visit('/settings/design');
|
await visit('/tags');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/staff/test-user');
|
expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when logged in', function () {
|
describe('when logged in', function () {
|
||||||
|
@ -1,132 +1,132 @@
|
|||||||
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
|
||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {
|
// import {
|
||||||
beforeEach,
|
// beforeEach,
|
||||||
describe,
|
// describe,
|
||||||
it
|
// it
|
||||||
} from 'mocha';
|
// } from 'mocha';
|
||||||
import {click, currentURL, find, findAll, triggerEvent} from '@ember/test-helpers';
|
// import {click, currentURL, find, findAll, triggerEvent} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Integrations - Unsplash', function () {
|
// describe('Acceptance: Settings - Integrations - Unsplash', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
it('redirects to signin when not authenticated', async function () {
|
// it('redirects to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/integrations/unsplash');
|
// await visit('/settings/integrations/unsplash');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as contributor', async function () {
|
// it('redirects to home page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
// let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/unsplash');
|
// await visit('/settings/integrations/unsplash');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/posts');
|
// expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as author', async function () {
|
// it('redirects to home page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
// let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/unsplash');
|
// await visit('/settings/integrations/unsplash');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as editor', async function () {
|
// it('redirects to home page when authenticated as editor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Editor'});
|
// let role = this.server.create('role', {name: 'Editor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/unsplash');
|
// await visit('/settings/integrations/unsplash');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('when logged in', function () {
|
// describe('when logged in', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it can activate/deactivate', async function () {
|
// it('it can activate/deactivate', async function () {
|
||||||
await visit('/settings/integrations/unsplash');
|
// await visit('/settings/integrations/unsplash');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
|
||||||
|
|
||||||
// it's enabled by default when settings is empty
|
// // it's enabled by default when settings is empty
|
||||||
expect(find('[data-test-unsplash-checkbox]').checked, 'checked by default').to.be.true;
|
// expect(find('[data-test-unsplash-checkbox]').checked, 'checked by default').to.be.true;
|
||||||
|
|
||||||
await click('[data-test-unsplash-checkbox]');
|
// await click('[data-test-unsplash-checkbox]');
|
||||||
|
|
||||||
expect(find('[data-test-unsplash-checkbox]').checked, 'unsplash checkbox').to.be.false;
|
// expect(find('[data-test-unsplash-checkbox]').checked, 'unsplash checkbox').to.be.false;
|
||||||
|
|
||||||
// trigger a save
|
// // trigger a save
|
||||||
await click('[data-test-save-button]');
|
// await click('[data-test-save-button]');
|
||||||
|
|
||||||
// server should now have an unsplash setting
|
// // server should now have an unsplash setting
|
||||||
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
let params = JSON.parse(lastRequest.requestBody);
|
// let params = JSON.parse(lastRequest.requestBody);
|
||||||
|
|
||||||
expect(params.settings.findBy('key', 'unsplash').value).to.equal(false);
|
// expect(params.settings.findBy('key', 'unsplash').value).to.equal(false);
|
||||||
|
|
||||||
// save via CMD-S shortcut
|
// // save via CMD-S shortcut
|
||||||
await click('[data-test-unsplash-checkbox]');
|
// await click('[data-test-unsplash-checkbox]');
|
||||||
await triggerEvent('.gh-app', 'keydown', {
|
// await triggerEvent('.gh-app', 'keydown', {
|
||||||
keyCode: 83, // s
|
// keyCode: 83, // s
|
||||||
metaKey: ctrlOrCmd === 'command',
|
// metaKey: ctrlOrCmd === 'command',
|
||||||
ctrlKey: ctrlOrCmd === 'ctrl'
|
// ctrlKey: ctrlOrCmd === 'ctrl'
|
||||||
});
|
// });
|
||||||
|
|
||||||
// we've already saved in this test so there's no on-screen indication
|
// // we've already saved in this test so there's no on-screen indication
|
||||||
// that we've had another save, check the request was fired instead
|
// // that we've had another save, check the request was fired instead
|
||||||
let [newRequest] = this.server.pretender.handledRequests.slice(-1);
|
// let [newRequest] = this.server.pretender.handledRequests.slice(-1);
|
||||||
params = JSON.parse(newRequest.requestBody);
|
// params = JSON.parse(newRequest.requestBody);
|
||||||
|
|
||||||
expect(find('[data-test-unsplash-checkbox]').checked, 'AMP checkbox').to.be.true;
|
// expect(find('[data-test-unsplash-checkbox]').checked, 'AMP checkbox').to.be.true;
|
||||||
expect(params.settings.findBy('key', 'unsplash').value).to.equal(true);
|
// expect(params.settings.findBy('key', 'unsplash').value).to.equal(true);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('warns when leaving without saving', async function () {
|
// it('warns when leaving without saving', async function () {
|
||||||
await visit('/settings/integrations/unsplash');
|
// await visit('/settings/integrations/unsplash');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
|
||||||
|
|
||||||
// AMP is enabled by default
|
// // AMP is enabled by default
|
||||||
expect(find('[data-test-unsplash-checkbox]').checked, 'AMP checkbox default').to.be.true;
|
// expect(find('[data-test-unsplash-checkbox]').checked, 'AMP checkbox default').to.be.true;
|
||||||
|
|
||||||
await click('[data-test-unsplash-checkbox]');
|
// await click('[data-test-unsplash-checkbox]');
|
||||||
|
|
||||||
expect(find('[data-test-unsplash-checkbox]').checked, 'Unsplash checkbox').to.be.false;
|
// expect(find('[data-test-unsplash-checkbox]').checked, 'Unsplash checkbox').to.be.false;
|
||||||
|
|
||||||
await visit('/settings/labs');
|
// await visit('/settings/labs');
|
||||||
|
|
||||||
expect(findAll('[data-test-modal="unsaved-settings"]').length, 'unsaved changes modal exists').to.equal(1);
|
// expect(findAll('[data-test-modal="unsaved-settings"]').length, 'unsaved changes modal exists').to.equal(1);
|
||||||
|
|
||||||
// Leave without saving
|
// // Leave without saving
|
||||||
await click('[data-test-modal="unsaved-settings"] [data-test-leave-button]');
|
// await click('[data-test-modal="unsaved-settings"] [data-test-leave-button]');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL after leave without saving').to.equal('/settings/labs');
|
// expect(currentURL(), 'currentURL after leave without saving').to.equal('/settings/labs');
|
||||||
|
|
||||||
await visit('/settings/integrations/unsplash');
|
// await visit('/settings/integrations/unsplash');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
|
||||||
|
|
||||||
// settings were not saved
|
// // settings were not saved
|
||||||
expect(find('[data-test-unsplash-checkbox]').checked, 'Unsplash checkbox').to.be.true;
|
// expect(find('[data-test-unsplash-checkbox]').checked, 'Unsplash checkbox').to.be.true;
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,69 +1,69 @@
|
|||||||
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
|
||||||
import {
|
// import {
|
||||||
beforeEach,
|
// beforeEach,
|
||||||
describe,
|
// describe,
|
||||||
it
|
// it
|
||||||
} from 'mocha';
|
// } from 'mocha';
|
||||||
import {currentURL} from '@ember/test-helpers';
|
// import {currentURL} from '@ember/test-helpers';
|
||||||
import {expect} from 'chai';
|
// import {expect} from 'chai';
|
||||||
import {setupApplicationTest} from 'ember-mocha';
|
// import {setupApplicationTest} from 'ember-mocha';
|
||||||
import {setupMirage} from 'ember-cli-mirage/test-support';
|
// import {setupMirage} from 'ember-cli-mirage/test-support';
|
||||||
import {visit} from '../../helpers/visit';
|
// import {visit} from '../../helpers/visit';
|
||||||
|
|
||||||
describe('Acceptance: Settings - Integrations - Zapier', function () {
|
// describe('Acceptance: Settings - Integrations - Zapier', function () {
|
||||||
let hooks = setupApplicationTest();
|
// let hooks = setupApplicationTest();
|
||||||
setupMirage(hooks);
|
// setupMirage(hooks);
|
||||||
|
|
||||||
it('redirects to signin when not authenticated', async function () {
|
// it('redirects to signin when not authenticated', async function () {
|
||||||
await invalidateSession();
|
// await invalidateSession();
|
||||||
await visit('/settings/integrations/zapier');
|
// await visit('/settings/integrations/zapier');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/signin');
|
// expect(currentURL(), 'currentURL').to.equal('/signin');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as contributor', async function () {
|
// it('redirects to home page when authenticated as contributor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Contributor'});
|
// let role = this.server.create('role', {name: 'Contributor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/zapier');
|
// await visit('/settings/integrations/zapier');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/posts');
|
// expect(currentURL(), 'currentURL').to.equal('/posts');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as author', async function () {
|
// it('redirects to home page when authenticated as author', async function () {
|
||||||
let role = this.server.create('role', {name: 'Author'});
|
// let role = this.server.create('role', {name: 'Author'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/zapier');
|
// await visit('/settings/integrations/zapier');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('redirects to home page when authenticated as editor', async function () {
|
// it('redirects to home page when authenticated as editor', async function () {
|
||||||
let role = this.server.create('role', {name: 'Editor'});
|
// let role = this.server.create('role', {name: 'Editor'});
|
||||||
this.server.create('user', {roles: [role], slug: 'test-user'});
|
// this.server.create('user', {roles: [role], slug: 'test-user'});
|
||||||
|
|
||||||
await authenticateSession();
|
// await authenticateSession();
|
||||||
await visit('/settings/integrations/zapier');
|
// await visit('/settings/integrations/zapier');
|
||||||
|
|
||||||
expect(currentURL(), 'currentURL').to.equal('/site');
|
// expect(currentURL(), 'currentURL').to.equal('/site');
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('when logged in', function () {
|
// describe('when logged in', function () {
|
||||||
beforeEach(async function () {
|
// beforeEach(async function () {
|
||||||
let role = this.server.create('role', {name: 'Administrator'});
|
// let role = this.server.create('role', {name: 'Administrator'});
|
||||||
this.server.create('user', {roles: [role]});
|
// this.server.create('user', {roles: [role]});
|
||||||
|
|
||||||
return await authenticateSession();
|
// return await authenticateSession();
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('it loads', async function () {
|
// it('it loads', async function () {
|
||||||
await visit('/settings/integrations/zapier');
|
// await visit('/settings/integrations/zapier');
|
||||||
|
|
||||||
// has correct url
|
// // has correct url
|
||||||
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/zapier');
|
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/zapier');
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,40 +6,38 @@ test.describe('Announcement Bar Settings', () => {
|
|||||||
await goToAnnouncementBarSettings(page);
|
await goToAnnouncementBarSettings(page);
|
||||||
|
|
||||||
await test.step('Bar should be hidden', async () => {
|
await test.step('Bar should be hidden', async () => {
|
||||||
const htmlFrame = await getPreviewFrame(page);
|
const htmlFrame = getPreviewFrame(page);
|
||||||
await expect(await htmlFrame.locator('#announcement-bar-root')).toHaveCount(0);
|
await expect(await htmlFrame.locator('#announcement-bar-root')).toHaveCount(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Show/hide bar if visibility checked/unchecked and text filled', async ({page}) => {
|
test('Show/hide bar if visibility checked/unchecked and text filled', async ({page}) => {
|
||||||
await page.goto('/ghost');
|
await page.goto('/ghost');
|
||||||
await goToAnnouncementBarSettings(page);
|
const modal = await goToAnnouncementBarSettings(page);
|
||||||
|
|
||||||
await test.step('Check free members', async () => {
|
await test.step('Check free members', async () => {
|
||||||
const freeMembersCheckbox = await page.getByTestId('announcement-bar-free-member-input');
|
const freeMembersCheckbox = modal.getByLabel('Free members');
|
||||||
await expect(await freeMembersCheckbox.isChecked()).toBeFalsy();
|
await expect(freeMembersCheckbox).not.toBeChecked();
|
||||||
await page.getByTestId('announcement-bar-free-member-label').click();
|
await freeMembersCheckbox.check();
|
||||||
await expect(await freeMembersCheckbox.isChecked()).toBeTruthy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Fill announcement text', async () => {
|
await test.step('Fill announcement text', async () => {
|
||||||
await page.locator('.koenig-react-editor').click();
|
await modal.locator('.koenig-react-editor').click();
|
||||||
await expect(await page.locator('[contenteditable="true"]')).toBeVisible({timeout: 30000}); // add timeout as lexical module loading can take time
|
await expect(await modal.locator('[contenteditable="true"]')).toBeVisible({timeout: 30000}); // add timeout as lexical module loading can take time
|
||||||
await page.keyboard.type('Announcement text');
|
await page.keyboard.type('Announcement text');
|
||||||
await page.getByTestId('announcement-bar-title').click();
|
await modal.getByText('Announcement').first().click(); // defocus the editor
|
||||||
});
|
});
|
||||||
|
|
||||||
const htmlFrame = await getPreviewFrame(page);
|
const htmlFrame = getPreviewFrame(page);
|
||||||
await test.step('Announcement bar should be visible', async () => {
|
await test.step('Announcement bar should be visible', async () => {
|
||||||
await expect(await htmlFrame.getByText('Announcement text')).toBeVisible();
|
await expect(await htmlFrame.getByText('Announcement text')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Disable free members', async () => {
|
await test.step('Disable free members', async () => {
|
||||||
const freeMembersCheckbox = await page.getByTestId('announcement-bar-free-member-input');
|
const freeMembersCheckbox = modal.getByLabel('Free members');
|
||||||
await expect(await freeMembersCheckbox.isChecked()).toBeTruthy();
|
await expect(freeMembersCheckbox).toBeChecked();
|
||||||
await page.getByTestId('announcement-bar-free-member-label').click();
|
await freeMembersCheckbox.uncheck();
|
||||||
await expect(await freeMembersCheckbox.isChecked()).toBeFalsy();
|
await modal.locator('.koenig-react-editor').click();
|
||||||
await page.locator('.koenig-react-editor').click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Announcement bar should be hidden', async () => {
|
await test.step('Announcement bar should be hidden', async () => {
|
||||||
@ -49,13 +47,15 @@ test.describe('Announcement Bar Settings', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function goToAnnouncementBarSettings(page) {
|
async function goToAnnouncementBarSettings(page) {
|
||||||
return await test.step('Navigate to the announcement bar settings', async () => {
|
await test.step('Navigate to the announcement bar settings', async () => {
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
await page.locator('[data-test-nav="settings"]').click();
|
||||||
await page.locator('[data-test-nav="announcement-bar"]').click();
|
await page.getByTestId('announcement-bar').getByRole('button', {name: 'Customize'}).click();
|
||||||
await expect(await page.getByTestId('announcement-bar-title')).toBeVisible();
|
// Wait for the preview to load
|
||||||
|
await getPreviewFrame(page).locator('body *:visible').first().waitFor();
|
||||||
});
|
});
|
||||||
|
return page.getByTestId('announcement-bar-modal');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPreviewFrame(page) {
|
function getPreviewFrame(page) {
|
||||||
return page.frameLocator('[data-testid="iframe-html"]:visible');
|
return page.frameLocator('[data-testid="announcement-bar-preview-iframe"] > iframe[data-visible=true]');
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,11 @@ test.describe('Membership Settings', () => {
|
|||||||
// Open Portal settings
|
// Open Portal settings
|
||||||
await page.goto('/ghost');
|
await page.goto('/ghost');
|
||||||
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
||||||
await page.locator('.gh-setting-group').filter({hasText: 'Membership'}).click();
|
await page.getByTestId('portal').getByRole('button', {name: 'Customize'}).click();
|
||||||
await page.locator('[data-test-toggle="portal-settings"]').click();
|
|
||||||
|
const modal = page.getByTestId('portal-modal');
|
||||||
// Check free tier toggle is visible
|
// Check free tier toggle is visible
|
||||||
await expect(page.locator('label').filter({hasText: 'Free'}).first()).toBeVisible();
|
await expect(modal.locator('label').filter({hasText: 'Free'}).first()).toBeVisible();
|
||||||
|
|
||||||
// Reconnect Stripe for other tests
|
// Reconnect Stripe for other tests
|
||||||
const stripeToken = await generateStripeIntegrationToken();
|
const stripeToken = await generateStripeIntegrationToken();
|
||||||
|
@ -2,20 +2,24 @@ const {expect, test} = require('@playwright/test');
|
|||||||
|
|
||||||
test.describe('Portal Settings', () => {
|
test.describe('Portal Settings', () => {
|
||||||
test.describe('Links', () => {
|
test.describe('Links', () => {
|
||||||
test('can open portal on default page', async ({page}) => {
|
const openPortalLinks = async (page) => {
|
||||||
await page.goto('/ghost');
|
await page.goto('/ghost');
|
||||||
// Navigate to the member settings
|
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
await page.locator('[data-test-nav="settings"]').click();
|
||||||
await page.locator('[data-test-nav="members-membership"]').click();
|
|
||||||
|
|
||||||
// open portal settings
|
await page.getByTestId('portal').getByRole('button', {name: 'Customize'}).click();
|
||||||
await page.locator('[data-test-toggle="portal-settings"]').click();
|
|
||||||
|
|
||||||
// open links preview page
|
const modal = page.getByTestId('portal-modal');
|
||||||
await page.locator('[data-test-select="page-selector"]').first().selectOption('links');
|
|
||||||
|
await modal.getByRole('tab', {name: 'Links'}).click();
|
||||||
|
|
||||||
|
return modal;
|
||||||
|
};
|
||||||
|
|
||||||
|
test('can open portal on default page', async ({page}) => {
|
||||||
|
const modal = await openPortalLinks(page);
|
||||||
|
|
||||||
// fetch portal default url from input
|
// fetch portal default url from input
|
||||||
const portalUrl = await page.locator('[data-test-input="portal-link-default"]').inputValue();
|
const portalUrl = await modal.getByLabel('Default').inputValue();
|
||||||
await page.goto(portalUrl);
|
await page.goto(portalUrl);
|
||||||
|
|
||||||
const portalFrame = page.locator('[data-testid="portal-popup-frame"]');
|
const portalFrame = page.locator('[data-testid="portal-popup-frame"]');
|
||||||
@ -25,19 +29,10 @@ test.describe('Portal Settings', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can open portal on signin page', async ({page}) => {
|
test('can open portal on signin page', async ({page}) => {
|
||||||
await page.goto('/ghost');
|
const modal = await openPortalLinks(page);
|
||||||
// Navigate to the member settings
|
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
|
||||||
await page.locator('[data-test-nav="members-membership"]').click();
|
|
||||||
|
|
||||||
// open portal settings
|
|
||||||
await page.locator('[data-test-toggle="portal-settings"]').click();
|
|
||||||
|
|
||||||
// open links preview page
|
|
||||||
await page.locator('[data-test-select="page-selector"]').first().selectOption('links');
|
|
||||||
|
|
||||||
// fetch portal signin url from input
|
// fetch portal signin url from input
|
||||||
const portalUrl = await page.locator('[data-test-input="portal-link-signin"]').inputValue();
|
const portalUrl = await modal.getByLabel('Sign in').inputValue();
|
||||||
await page.goto(portalUrl);
|
await page.goto(portalUrl);
|
||||||
|
|
||||||
const portalFrame = page.locator('[data-testid="portal-popup-frame"]');
|
const portalFrame = page.locator('[data-testid="portal-popup-frame"]');
|
||||||
@ -50,19 +45,10 @@ test.describe('Portal Settings', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can open portal on signup page', async ({page}) => {
|
test('can open portal on signup page', async ({page}) => {
|
||||||
await page.goto('/ghost');
|
const modal = await openPortalLinks(page);
|
||||||
// Navigate to the member settings
|
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
|
||||||
await page.locator('[data-test-nav="members-membership"]').click();
|
|
||||||
|
|
||||||
// open portal settings
|
|
||||||
await page.locator('[data-test-toggle="portal-settings"]').click();
|
|
||||||
|
|
||||||
// open links preview page
|
|
||||||
await page.locator('[data-test-select="page-selector"]').first().selectOption('links');
|
|
||||||
|
|
||||||
// fetch portal signup url from input
|
// fetch portal signup url from input
|
||||||
const portalUrl = await page.locator('[data-test-input="portal-link-signup"]').inputValue();
|
const portalUrl = await modal.getByLabel('Sign up').inputValue();
|
||||||
await page.goto(portalUrl);
|
await page.goto(portalUrl);
|
||||||
|
|
||||||
const portalFrame = page.locator('[data-testid="portal-popup-frame"]');
|
const portalFrame = page.locator('[data-testid="portal-popup-frame"]');
|
||||||
@ -75,19 +61,10 @@ test.describe('Portal Settings', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can open portal directly on monthly signup', async ({page}) => {
|
test('can open portal directly on monthly signup', async ({page}) => {
|
||||||
await page.goto('/ghost');
|
const modal = await openPortalLinks(page);
|
||||||
// Navigate to the member settings
|
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
|
||||||
await page.locator('[data-test-nav="members-membership"]').click();
|
|
||||||
|
|
||||||
// open portal settings
|
|
||||||
await page.locator('[data-test-toggle="portal-settings"]').click();
|
|
||||||
|
|
||||||
// open links preview page
|
|
||||||
await page.locator('[data-test-select="page-selector"]').first().selectOption('links');
|
|
||||||
|
|
||||||
// fetch and go to portal directly monthly signup url
|
// fetch and go to portal directly monthly signup url
|
||||||
const portalUrl = await page.locator('[data-test-input="portal-tier-link-monthly"]').inputValue();
|
const portalUrl = await modal.getByLabel('Signup / Monthly').inputValue();
|
||||||
await page.goto(portalUrl);
|
await page.goto(portalUrl);
|
||||||
|
|
||||||
// expect stripe checkout to have opeened
|
// expect stripe checkout to have opeened
|
||||||
@ -95,19 +72,10 @@ test.describe('Portal Settings', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can open portal directly on yearly signup', async ({page}) => {
|
test('can open portal directly on yearly signup', async ({page}) => {
|
||||||
await page.goto('/ghost');
|
const modal = await openPortalLinks(page);
|
||||||
// Navigate to the member settings
|
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
|
||||||
await page.locator('[data-test-nav="members-membership"]').click();
|
|
||||||
|
|
||||||
// open portal settings
|
// fetch and go to portal directly yearly signup url
|
||||||
await page.locator('[data-test-toggle="portal-settings"]').click();
|
const portalUrl = await modal.getByLabel('Signup / Yearly').inputValue();
|
||||||
|
|
||||||
// open links preview page
|
|
||||||
await page.locator('[data-test-select="page-selector"]').first().selectOption('links');
|
|
||||||
|
|
||||||
// fetch and go to portal directly monthly signup url
|
|
||||||
const portalUrl = await page.locator('[data-test-input="portal-tier-link-yearly"]').inputValue();
|
|
||||||
await page.goto(portalUrl);
|
await page.goto(portalUrl);
|
||||||
|
|
||||||
// expect stripe checkout to have opeened
|
// expect stripe checkout to have opeened
|
||||||
|
@ -7,17 +7,17 @@ test.describe('Site Settings', () => {
|
|||||||
await page.goto('/ghost');
|
await page.goto('/ghost');
|
||||||
|
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
await page.locator('[data-test-nav="settings"]').click();
|
||||||
await page.locator('[data-test-nav="general"]').click();
|
|
||||||
|
|
||||||
// @NOTE: needs a data-test selector
|
const section = page.getByTestId('locksite');
|
||||||
await page.locator('label.switch span').click();
|
|
||||||
|
await section.getByRole('button', {name: 'Edit'}).click();
|
||||||
|
|
||||||
|
await section.getByLabel(/Enable password protection/).check();
|
||||||
|
await section.getByLabel('Site password').fill('password');
|
||||||
|
|
||||||
// save changes
|
// save changes
|
||||||
await page.locator('[data-test-button="save"]').click();
|
await section.getByRole('button', {name: 'Save'}).click();
|
||||||
await page.getByRole('button', {name: 'Saved'}).waitFor({
|
await expect(section.getByLabel('Site password')).toHaveCount(0);
|
||||||
state: 'visible',
|
|
||||||
timeout: 1000
|
|
||||||
});
|
|
||||||
|
|
||||||
// copy site password
|
// copy site password
|
||||||
//const passwordInput = await page.locator('[data-test-password-input]');
|
//const passwordInput = await page.locator('[data-test-password-input]');
|
||||||
@ -40,20 +40,20 @@ test.describe('Site Settings', () => {
|
|||||||
// await frontendPage.waitForSelector('.site-title');
|
// await frontendPage.waitForSelector('.site-title');
|
||||||
// await expect(frontendPage.locator('.site-title')).toHaveText('The Local Test');
|
// await expect(frontendPage.locator('.site-title')).toHaveText('The Local Test');
|
||||||
|
|
||||||
// // set private mode in admin "off"
|
// set private mode in admin "off"
|
||||||
// @NOTE: needs a data-test selector
|
await section.getByRole('button', {name: 'Edit'}).click();
|
||||||
await page.locator('label.switch span').click();
|
|
||||||
|
await section.getByLabel(/Enable password protection/).uncheck();
|
||||||
|
|
||||||
// save changes
|
// save changes
|
||||||
await page.locator('[data-test-button="save"]').click();
|
await section.getByRole('button', {name: 'Save'}).click();
|
||||||
await page.getByRole('button', {name: 'Saved'}).waitFor({
|
await expect(section.getByLabel('Site password')).toHaveCount(0);
|
||||||
state: 'visible',
|
|
||||||
timeout: 1000
|
|
||||||
});
|
|
||||||
|
|
||||||
// check the site is publicly accessible
|
// check the site is publicly accessible
|
||||||
await frontendPage.goto('/');
|
await expect(async () => {
|
||||||
await expect(frontendPage.locator('.gh-navigation-brand')).toHaveText('The Local Test');
|
await frontendPage.goto('/');
|
||||||
|
await expect(frontendPage.locator('.gh-navigation-brand')).toHaveText('The Local Test');
|
||||||
|
}).toPass();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,22 +2,18 @@ const {expect, test} = require('@playwright/test');
|
|||||||
const {createPostDraft, createTier, disconnectStripe, generateStripeIntegrationToken, setupStripe} = require('../utils');
|
const {createPostDraft, createTier, disconnectStripe, generateStripeIntegrationToken, setupStripe} = require('../utils');
|
||||||
|
|
||||||
const changeSubscriptionAccess = async (page, access) => {
|
const changeSubscriptionAccess = async (page, access) => {
|
||||||
// Go to settings page
|
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
await page.locator('[data-test-nav="settings"]').click();
|
||||||
|
|
||||||
// Go to members settings page
|
const section = page.getByTestId('access');
|
||||||
await page.locator('[data-test-nav="members-membership"]').click();
|
await section.getByRole('button', {name: 'Edit'}).click();
|
||||||
|
|
||||||
// Change subscription access
|
const select = section.getByTestId('subscription-access-select');
|
||||||
await page.locator('[data-test-members-subscription-access] [data-test-members-subscription-option]').click();
|
await select.click();
|
||||||
await page.locator(`[data-test-members-subscription-option="${access}"]`).click();
|
await page.locator(`[data-testid="select-option"][data-value="${access}"]`).click();
|
||||||
|
|
||||||
// Save settings
|
// Save settings
|
||||||
await page.locator('[data-test-button="save-settings"]').click();
|
await section.getByRole('button', {name: 'Save'}).click();
|
||||||
await page.getByRole('button', {name: 'Saved'}).waitFor({
|
await expect(select).not.toBeVisible();
|
||||||
state: 'visible',
|
|
||||||
timeout: 1000
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkPortalScriptLoaded = async (page, loaded = true) => {
|
const checkPortalScriptLoaded = async (page, loaded = true) => {
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
const {expect, test} = require('@playwright/test');
|
const {expect, test} = require('@playwright/test');
|
||||||
const {createTier, createOffer, getUniqueName, getSlug, goToMembershipPage, getTierCardById} = require('../utils');
|
const {createTier, createOffer, getUniqueName, getSlug, goToMembershipPage, openTierModal} = require('../utils');
|
||||||
|
|
||||||
test.describe('Admin', () => {
|
test.describe('Admin', () => {
|
||||||
test.describe('Tiers', () => {
|
test.describe('Tiers', () => {
|
||||||
test('Default tier should be $5mo / $50yr', async ({page}) => {
|
test('Default tier should be $5mo / $50yr', async ({page}) => {
|
||||||
const defaultTierId = 'default-product';
|
const defaultTier = 'default-product';
|
||||||
await goToMembershipPage(page);
|
await goToMembershipPage(page);
|
||||||
const tierCard = await getTierCardById(page, {id: defaultTierId});
|
const tierModal = await openTierModal(page, {slug: defaultTier});
|
||||||
|
|
||||||
await test.step('Default tier should be $5mo / $50yr', async () => {
|
await test.step('Default tier should be $5mo / $50yr', async () => {
|
||||||
await expect(tierCard.locator('[data-test-amount-monthly-price]')).toHaveText('5');
|
await expect(tierModal.getByLabel('Monthly price')).toHaveValue('5');
|
||||||
await expect(tierCard.locator('[data-test-amount-yearly-price]')).toHaveText('50');
|
await expect(tierModal.getByLabel('Yearly price')).toHaveValue('50');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -50,18 +50,20 @@ test.describe('Admin', () => {
|
|||||||
await goToMembershipPage(page);
|
await goToMembershipPage(page);
|
||||||
|
|
||||||
await test.step('Created tier should be in Portal settings and not selected', async () => {
|
await test.step('Created tier should be in Portal settings and not selected', async () => {
|
||||||
await page.locator('[data-test-toggle="portal-settings"]').click();
|
await page.getByTestId('portal').getByRole('button', {name: 'Customize'}).click();
|
||||||
// Wait until the list of tiers available at signup is visible
|
|
||||||
await page.waitForSelector('[data-test-tiers-at-signup]');
|
const portalSettings = page.getByTestId('portal-modal');
|
||||||
await page.locator(`[data-test-settings-tier-label="${tierName}"]`);
|
|
||||||
expect(await page.locator(`[data-test-settings-tier-input="${tierName}"]`).isChecked()).toBeFalsy();
|
await portalSettings.getByLabel(tierName).first().waitFor();
|
||||||
|
|
||||||
|
await expect(portalSettings.getByLabel(tierName).first()).not.toBeChecked();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Can update Tier', async ({page}) => {
|
test('Can update Tier', async ({page}) => {
|
||||||
await page.goto('/ghost');
|
await page.goto('/ghost');
|
||||||
const tierName = getUniqueName('New Test Tier');
|
const tierName = getUniqueName('New Test Tier');
|
||||||
const tierId = getSlug(tierName);
|
const slug = getSlug(tierName);
|
||||||
const updatedTierName = getUniqueName('Updated Test Tier Name');
|
const updatedTierName = getUniqueName('Updated Test Tier Name');
|
||||||
const updatedMonthlyPrice = '66';
|
const updatedMonthlyPrice = '66';
|
||||||
const updatedYearlyPrice = '666';
|
const updatedYearlyPrice = '666';
|
||||||
@ -73,18 +75,14 @@ test.describe('Admin', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await goToMembershipPage(page);
|
await goToMembershipPage(page);
|
||||||
const tierCard = await getTierCardById(page, {id: tierId});
|
const tierModal = await openTierModal(page, {slug});
|
||||||
|
|
||||||
await test.step('Open modal and edit tier information', async () => {
|
await test.step('Open modal and edit tier information', async () => {
|
||||||
await tierCard.locator('[data-test-button="tiers-actions"]').click();
|
await tierModal.getByLabel('Name').fill(updatedTierName);
|
||||||
await tierCard.locator('[data-test-button="edit-tier"]').click();
|
await tierModal.getByLabel('Description').fill(updatedDescription);
|
||||||
const modal = page.locator('[data-test-modal="edit-tier"]');
|
await tierModal.getByLabel('Monthly price').fill(updatedMonthlyPrice);
|
||||||
|
await tierModal.getByLabel('Yearly price').fill(updatedYearlyPrice);
|
||||||
await modal.locator('[data-test-input="tier-name"]').first().fill(updatedTierName);
|
await tierModal.getByRole('button', {name: 'Save & close'}).click();
|
||||||
await modal.locator('[data-test-input="tier-description"]').first().fill(updatedDescription);
|
|
||||||
await modal.locator('[data-test-input="monthly-price"]').fill(updatedMonthlyPrice);
|
|
||||||
await modal.locator('[data-test-input="yearly-price"]').fill(updatedYearlyPrice);
|
|
||||||
await page.locator('[data-test-button="save-tier"]').click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const portalFrame = await test.step('Go to website and open portal', async () => {
|
const portalFrame = await test.step('Go to website and open portal', async () => {
|
||||||
@ -111,15 +109,16 @@ test.describe('Admin', () => {
|
|||||||
|
|
||||||
await test.step('Check monthly price', async () => {
|
await test.step('Check monthly price', async () => {
|
||||||
await portalFrame.locator('[data-test-button="switch-monthly"]').click();
|
await portalFrame.locator('[data-test-button="switch-monthly"]').click();
|
||||||
await expect(await portalTierCard.getByText('/month')).toBeVisible();
|
await expect(portalTierCard.getByText('/month')).toBeVisible();
|
||||||
await expect(portalTierCard.locator('.amount').first()).toHaveText(updatedMonthlyPrice);
|
await expect(portalTierCard.locator('.amount').first()).toHaveText(updatedMonthlyPrice);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: Add something more useful to this, e.g. checking in the portal
|
||||||
test('Can archive and unarchive a Tier', async ({page}) => {
|
test('Can archive and unarchive a Tier', async ({page}) => {
|
||||||
await page.goto('/ghost');
|
await page.goto('/ghost');
|
||||||
const tierName = getUniqueName('Archive Tier');
|
const tierName = getUniqueName('Archive Tier');
|
||||||
const tierId = getSlug(tierName);
|
const slug = getSlug(tierName);
|
||||||
await createTier(page, {
|
await createTier(page, {
|
||||||
name: tierName,
|
name: tierName,
|
||||||
monthlyPrice: 5,
|
monthlyPrice: 5,
|
||||||
@ -127,50 +126,56 @@ test.describe('Admin', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await goToMembershipPage(page);
|
await goToMembershipPage(page);
|
||||||
const tierCard = await getTierCardById(page, {id: tierId});
|
|
||||||
|
|
||||||
await test.step('Archive tier', async () => {
|
await test.step('Archive tier', async () => {
|
||||||
await tierCard.locator('[data-test-button="tiers-actions"]').click();
|
const tierModal = await openTierModal(page, {slug});
|
||||||
await tierCard.locator('[data-test-button="archive-tier"]').click();
|
await tierModal.getByRole('button', {name: 'Archive tier'}).click();
|
||||||
const modal = page.locator('[data-test-modal="archive-tier"]');
|
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Archive'}).click();
|
||||||
await modal.locator('[data-test-button="archive-tier"]').click();
|
await tierModal.getByRole('button', {name: 'Save & close'}).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Archived tier should not be available in active tiers', async () => {
|
await test.step('Archived tier should not be available in active tiers', async () => {
|
||||||
await expect(page.locator(`[data-test-tier-card="${tierId}"]`)).toBeHidden();
|
await expect(page.locator(`[data-testid="tier-card"][data-tier="${slug}"]`)).toBeHidden();
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Archived tier should be available in archived tiers', async () => {
|
await test.step('Archived tier should be available in archived tiers', async () => {
|
||||||
const tiersSelect = await page.locator('[data-test-select-tiers-list]');
|
await page.getByTestId('tiers').getByRole('tab', {name: 'Archived'}).click();
|
||||||
await tiersSelect.click();
|
await expect(page.locator(`[data-testid="tier-card"][data-tier="${slug}"]`)).toBeVisible();
|
||||||
await page.getByRole('option', {name: 'Archived'}).click();
|
|
||||||
await expect(page.locator(`[data-test-tier-card="${tierId}"]`)).toBeVisible();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Archived tier should not be available in portal settings', async () => {
|
await test.step('Archived tier should not be available in portal settings', async () => {
|
||||||
await expect(page.locator(`[data-test-settings-tier-label="${tierName}"]`)).toBeHidden();
|
await page.getByTestId('portal').getByRole('button', {name: 'Customize'}).click();
|
||||||
|
|
||||||
|
const portalSettings = page.getByTestId('portal-modal');
|
||||||
|
|
||||||
|
await portalSettings.locator('input[type=checkbox]').first().waitFor();
|
||||||
|
|
||||||
|
await expect(portalSettings.getByLabel(tierName).first()).toBeHidden();
|
||||||
|
|
||||||
|
await portalSettings.getByRole('button', {name: 'Close'}).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Unarchive tier', async () => {
|
await test.step('Unarchive tier', async () => {
|
||||||
await tierCard.locator('[data-test-button="tiers-actions"]').click();
|
const tierModal = await openTierModal(page, {slug});
|
||||||
await tierCard.locator('[data-test-button="unarchive-tier"]').click();
|
await tierModal.getByRole('button', {name: 'Reactivate tier'}).click();
|
||||||
const modal = page.locator('[data-test-modal="unarchive-tier"]');
|
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Reactivate'}).click();
|
||||||
await modal.locator('[data-test-button="unarchive-tier"]').click();
|
await tierModal.getByRole('button', {name: 'Save & close'}).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Unarchived tier should be available in active tiers', async () => {
|
await test.step('Unarchived tier should be available in active tiers', async () => {
|
||||||
await expect(page.locator(`[data-test-tier-card="${tierId}"]`)).toBeVisible();
|
await page.getByTestId('tiers').getByRole('tab', {name: 'Active'}).click();
|
||||||
});
|
await expect(page.locator(`[data-testid="tier-card"][data-tier="${slug}"]`)).toBeVisible();
|
||||||
|
|
||||||
await test.step('Open Portal settings', async () => {
|
|
||||||
await page.locator('[data-test-toggle="portal-settings"]').click();
|
|
||||||
// Wait until the list of tiers available at signup is visible
|
|
||||||
await page.waitForSelector('[data-test-tiers-at-signup]');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Unarchived tier should be available in portal settings', async () => {
|
await test.step('Unarchived tier should be available in portal settings', async () => {
|
||||||
await page.locator(`[data-test-settings-tier-label="${tierName}"]`);
|
await page.getByTestId('portal').getByRole('button', {name: 'Customize'}).click();
|
||||||
expect(await page.locator(`[data-test-settings-tier-input="${tierName}"]`).isChecked()).toBeFalsy();
|
|
||||||
|
const portalSettings = page.getByTestId('portal-modal');
|
||||||
|
|
||||||
|
await portalSettings.locator('input[type=checkbox]').first().waitFor();
|
||||||
|
|
||||||
|
await expect(portalSettings.getByLabel(tierName).first()).toBeVisible();
|
||||||
|
|
||||||
|
await portalSettings.getByRole('button', {name: 'Close'}).click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -40,11 +40,17 @@ test.describe('Portal', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Can donate with a fixed amount set and different currency', async ({page}) => {
|
test('Can donate with a fixed amount set and different currency', async ({page}) => {
|
||||||
await page.goto('/ghost/#/settings/members');
|
await page.goto('/ghost/#/settings');
|
||||||
await page.getByTestId('expand-tips-and-donations').click();
|
|
||||||
await page.getByTestId('tips-and-donations-amount').fill('98');
|
const section = page.getByTestId('tips-or-donations');
|
||||||
await page.locator('#gh-tips-and-donations-currency').selectOption('EUR');
|
|
||||||
await page.locator('[data-test-button="save-settings"]').click();
|
await section.getByRole('button', {name: 'Edit'}).click();
|
||||||
|
await section.getByLabel('Suggested amount').fill('98');
|
||||||
|
const select = section.getByLabel('Currency');
|
||||||
|
await select.click();
|
||||||
|
await page.locator(`[data-testid="select-option"][data-value="EUR"]`).click();
|
||||||
|
await section.getByRole('button', {name: 'Save'}).click();
|
||||||
|
await expect(select).not.toBeVisible();
|
||||||
|
|
||||||
// go to website and open portal
|
// go to website and open portal
|
||||||
await page.goto('/#/portal/support');
|
await page.goto('/#/portal/support');
|
||||||
|
@ -1,26 +1,29 @@
|
|||||||
const {expect, test} = require('@playwright/test');
|
const {expect, test} = require('@playwright/test');
|
||||||
const {createMember, impersonateMember} = require('../utils');
|
const {createMember, impersonateMember} = require('../utils');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import('@playwright/test').Page} page
|
||||||
|
*/
|
||||||
const addNewsletter = async (page) => {
|
const addNewsletter = async (page) => {
|
||||||
// go to email settings
|
|
||||||
await page.goto('/ghost');
|
await page.goto('/ghost');
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
await page.locator('[data-test-nav="settings"]').click();
|
||||||
await page.locator('[data-test-nav="members-email"]').click();
|
|
||||||
|
|
||||||
// create newsletter
|
// create newsletter
|
||||||
await page.locator('[data-test-button="add-newsletter"]').click();
|
const section = page.getByTestId('newsletters');
|
||||||
await page.locator('[data-test-newsletter-title-input]').click();
|
await section.getByRole('button', {name: 'Add newsletter'}).click();
|
||||||
await page.locator('[data-test-newsletter-title-input]').fill('One more newsletter');
|
|
||||||
await page.locator('[data-test-button="save-newsletter"]').click();
|
const modal = page.getByTestId('add-newsletter-modal');
|
||||||
|
await modal.getByLabel('Name').fill('One more newsletter');
|
||||||
|
await modal.getByRole('button', {name: 'Create'}).click();
|
||||||
|
|
||||||
// check that newsletter was added
|
// check that newsletter was added
|
||||||
await page.waitForSelector('[data-test-newsletter="one-more-newsletter"]');
|
await section.locator('*', {hasText: 'One more newsletter'}).first().waitFor();
|
||||||
};
|
};
|
||||||
|
|
||||||
test.describe('Portal', () => {
|
test.describe('Portal', () => {
|
||||||
test.describe('Member actions', () => {
|
test.describe('Member actions', () => {
|
||||||
test.describe.configure({retries: 1});
|
test.describe.configure({retries: 1});
|
||||||
|
|
||||||
test('can log out', async ({page}) => {
|
test('can log out', async ({page}) => {
|
||||||
// create a new free member
|
// create a new free member
|
||||||
await createMember(page, {
|
await createMember(page, {
|
||||||
|
@ -74,54 +74,49 @@ const setupGhost = async (page) => {
|
|||||||
const disconnectStripe = async (page) => {
|
const disconnectStripe = async (page) => {
|
||||||
await deleteAllMembers(page);
|
await deleteAllMembers(page);
|
||||||
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
||||||
await page.locator('.gh-setting-group').filter({hasText: 'Membership'}).click();
|
await page.getByTestId('tiers').waitFor();
|
||||||
if (await page.isVisible('.gh-btn-stripe-status.connected')) {
|
if (await page.isVisible('[data-testid="stripe-connected"]')) {
|
||||||
// Disconnect if already connected
|
await page.getByTestId('stripe-connected').first().click();
|
||||||
await page.locator('.gh-btn-stripe-status.connected').click();
|
await page.getByTestId('stripe-modal').getByRole('button', {name: 'Disconnect'}).click();
|
||||||
await page.locator('.modal-content .gh-btn-stripe-disconnect').first().click();
|
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Disconnect'}).click();
|
||||||
await page
|
|
||||||
.locator('.modal-content')
|
|
||||||
.filter({hasText: 'Are you sure you want to disconnect?'})
|
|
||||||
.first()
|
|
||||||
.getByRole('button', {name: 'Disconnect'})
|
|
||||||
.click();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const setupStripe = async (page, stripConnectIntegrationToken) => {
|
const setupStripe = async (page, stripConnectIntegrationToken) => {
|
||||||
await deleteAllMembers(page);
|
await deleteAllMembers(page);
|
||||||
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
||||||
await page.locator('.gh-setting-group').filter({hasText: 'Membership'}).click();
|
await page.getByTestId('tiers').waitFor();
|
||||||
if (await page.isVisible('.gh-btn-stripe-status.connected')) {
|
if (await page.isVisible('[data-testid="stripe-connected"]')) {
|
||||||
// Disconnect if already connected
|
// Disconnect if already connected
|
||||||
await page.locator('.gh-btn-stripe-status.connected').click();
|
await page.getByTestId('stripe-connected').first().click();
|
||||||
await page.locator('.modal-content .gh-btn-stripe-disconnect').first().click();
|
await page.getByTestId('stripe-modal').getByRole('button', {name: 'Disconnect'}).click();
|
||||||
await page
|
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Disconnect'}).click();
|
||||||
.locator('.modal-content')
|
|
||||||
.filter({hasText: 'Are you sure you want to disconnect?'})
|
|
||||||
.first()
|
|
||||||
.getByRole('button', {name: 'Disconnect'})
|
|
||||||
.click();
|
|
||||||
} else {
|
} else {
|
||||||
await page.locator('.gh-setting-members-tierscontainer .stripe-connect').click();
|
await page.getByRole('button', {name: 'Connect with Stripe'}).click();
|
||||||
}
|
}
|
||||||
await page.getByPlaceholder('Paste your secure key here').first().fill(stripConnectIntegrationToken);
|
const modal = page.getByTestId('stripe-modal');
|
||||||
await page.getByRole('button', {name: 'Save Stripe settings'}).click();
|
await modal.getByRole('button', {name: /I have a Stripe account/}).click();
|
||||||
|
await modal.getByPlaceholder('Paste your secure key here').first().fill(stripConnectIntegrationToken);
|
||||||
|
await modal.getByRole('button', {name: 'Save Stripe settings'}).click();
|
||||||
// We need to wait for the saving to succeed
|
// We need to wait for the saving to succeed
|
||||||
await expect(page.locator('[data-test-button="stripe-disconnect"]')).toBeVisible();
|
await expect(modal.getByRole('button', {name: 'Disconnect'})).toBeVisible();
|
||||||
await page.locator('[data-test-button="close-stripe-connect"]').click();
|
await modal.getByRole('button', {name: 'Close'}).click();
|
||||||
|
|
||||||
|
await page.getByRole('button', {name: '← Done'}).click();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup Mailgun with fake data, for Ghost Admin to allow bulk sending
|
// Setup Mailgun with fake data, for Ghost Admin to allow bulk sending
|
||||||
const setupMailgun = async (page) => {
|
const setupMailgun = async (page) => {
|
||||||
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
||||||
await page.locator('.gh-setting-group').filter({hasText: 'Email newsletter'}).click();
|
const section = page.getByTestId('mailgun');
|
||||||
await page.locator('.gh-expandable-block').filter({hasText: 'Mailgun configuration'}).getByRole('button', {name: 'Expand'}).click();
|
|
||||||
|
|
||||||
await page.locator('[data-test-mailgun-domain-input]').fill('api.testgun.com');
|
await section.getByRole('button', {name: 'Edit'}).click();
|
||||||
await page.locator('[data-test-mailgun-api-key-input]').fill('Not an API key');
|
await section.getByLabel('Mailgun domain').fill('api.testgun.com');
|
||||||
await page.locator('[data-test-button="save-members-settings"]').click();
|
await section.getByLabel('Mailgun private API key').fill('Not an API key');
|
||||||
await page.waitForSelector('[data-test-button="save-members-settings"] [data-test-task-button-state="success"]');
|
await section.getByRole('button', {name: 'Save'}).click();
|
||||||
|
await section.getByText('Mailgun is set up').waitFor();
|
||||||
|
|
||||||
|
await page.getByRole('button', {name: '← Done'}).click();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -130,10 +125,15 @@ const setupMailgun = async (page) => {
|
|||||||
*/
|
*/
|
||||||
const enableLabs = async (page) => {
|
const enableLabs = async (page) => {
|
||||||
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
await page.locator('.gh-nav a[href="#/settings/"]').click();
|
||||||
await page.locator('.gh-setting-group').filter({hasText: 'Labs'}).click();
|
|
||||||
const alphaList = page.locator('.gh-main-section').filter({hasText: 'Alpha Features'});
|
const section = page.getByTestId('labs');
|
||||||
await alphaList.locator('label[for="labs-webmentions"]').click();
|
await section.getByRole('button', {name: 'Open'}).click();
|
||||||
await alphaList.locator('label[for="labs-tipsAndDonations"]').click();
|
|
||||||
|
await section.getByRole('tab', {name: 'Alpha features'}).click();
|
||||||
|
await section.getByLabel('Webmentions').click();
|
||||||
|
await section.getByLabel('Tips & donations').click();
|
||||||
|
|
||||||
|
await page.getByRole('button', {name: '← Done'}).click();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,62 +213,59 @@ const impersonateMember = async (page) => {
|
|||||||
* @param {number} [tier.trialDays]
|
* @param {number} [tier.trialDays]
|
||||||
*/
|
*/
|
||||||
const createTier = async (page, {name, monthlyPrice, yearlyPrice, trialDays}, enableInPortal = true) => {
|
const createTier = async (page, {name, monthlyPrice, yearlyPrice, trialDays}, enableInPortal = true) => {
|
||||||
|
await test.step('Create a tier', async () => {
|
||||||
// Navigate to the member settings
|
// Navigate to the member settings
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
await page.locator('[data-test-nav="settings"]').click();
|
||||||
await page.locator('[data-test-nav="members-membership"]').click();
|
|
||||||
|
|
||||||
// Tiers request can take time, so waiting until there is no connections before interacting with them
|
// Tiers request can take time, so waiting until there is no connections before interacting with them
|
||||||
await page.waitForLoadState('networkidle');
|
await page.waitForLoadState('networkidle');
|
||||||
|
|
||||||
// Expand the premium tier list
|
// Archive if already exists
|
||||||
await page.locator('[data-test-toggle-pub-info]').click();
|
while (await page.getByTestId('tier-card').filter({hasText: name}).first().isVisible()) {
|
||||||
|
await page.getByTestId('tier-card').filter({hasText: name}).first().click();
|
||||||
// Archive if already exists
|
await page.getByTestId('tier-detail-modal').getByRole('button', {name: 'Archive tier'}).click();
|
||||||
while (await page.locator('.gh-tier-card').filter({hasText: name}).first().isVisible()) {
|
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Archive'}).click();
|
||||||
const tierCard = page.locator('.gh-tier-card').filter({hasText: name}).first();
|
await page.getByTestId('tier-detail-modal').getByRole('button', {name: 'Reactivate tier'}).waitFor();
|
||||||
await tierCard.locator('.gh-tier-card-actions-button').click();
|
await page.getByTestId('tier-detail-modal').getByRole('button', {name: 'Save & close'}).click();
|
||||||
await tierCard.getByRole('button', {name: 'Archive'}).click();
|
|
||||||
await page.locator('.modal-content').getByRole('button', {name: 'Archive'}).click();
|
|
||||||
await page.locator('.modal-content').waitFor({state: 'detached', timeout: 1000});
|
|
||||||
}
|
|
||||||
if (!await page.locator('.gh-btn-add-tier').isVisible()) {
|
|
||||||
await page.locator('[data-test-toggle-pub-info]').click();
|
|
||||||
}
|
|
||||||
// Add the tier
|
|
||||||
await page.locator('.gh-btn-add-tier').click();
|
|
||||||
const modal = page.locator('.modal-content');
|
|
||||||
await modal.locator('input#name').first().fill(name);
|
|
||||||
await modal.locator('#monthlyPrice').fill(`${monthlyPrice}`);
|
|
||||||
await modal.locator('#yearlyPrice').fill(`${yearlyPrice}`);
|
|
||||||
if (trialDays) {
|
|
||||||
await modal.locator('[data-test-toggle="free-trial"]').click();
|
|
||||||
await modal.locator('#trial').fill(`${trialDays}`);
|
|
||||||
}
|
|
||||||
await modal.getByRole('button', {name: 'Add tier'}).click();
|
|
||||||
await page.waitForSelector('.modal-content input#name', {state: 'detached'});
|
|
||||||
|
|
||||||
// Close the premium tier list
|
|
||||||
await page.locator('[data-test-toggle-pub-info]').click();
|
|
||||||
|
|
||||||
// Enable the tier in portal
|
|
||||||
if (enableInPortal) {
|
|
||||||
await page.getByRole('button', {name: 'Customize Portal'}).click();
|
|
||||||
const portalSettings = page.locator('.modal-content').filter({hasText: 'Portal settings'});
|
|
||||||
if (!await portalSettings.locator('label').filter({hasText: name}).locator('input').first().isChecked()) {
|
|
||||||
await portalSettings.locator('label').filter({hasText: name}).locator('span').first().click();
|
|
||||||
}
|
}
|
||||||
if (!await portalSettings.locator('label').filter({hasText: 'Monthly'}).locator('input').first().isChecked()) {
|
|
||||||
await portalSettings.locator('label').filter({hasText: 'Monthly'}).locator('span').first().click();
|
|
||||||
}
|
|
||||||
if (!await portalSettings.locator('label').filter({hasText: 'Yearly'}).locator('input').first().isChecked()) {
|
|
||||||
await portalSettings.locator('label').filter({hasText: 'Yearly'}).locator('span').first().click();
|
|
||||||
}
|
|
||||||
await portalSettings.getByRole('button', {name: 'Save and close'}).click();
|
|
||||||
await page.waitForSelector('.gh-portal-settings', {state: 'detached'});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Navigate back to the dashboard
|
// Add the tier
|
||||||
await page.goto('/ghost');
|
await page.getByTestId('tiers').getByRole('button', {name: 'Add tier'}).click();
|
||||||
|
|
||||||
|
const modal = page.getByTestId('tier-detail-modal');
|
||||||
|
await modal.getByLabel('Name').fill(name);
|
||||||
|
await modal.getByLabel('Monthly price').fill(`${monthlyPrice}`);
|
||||||
|
await modal.getByLabel('Yearly price').fill(`${yearlyPrice}`);
|
||||||
|
if (trialDays) {
|
||||||
|
await modal.getByLabel('Add a free trial').check();
|
||||||
|
await modal.getByLabel('Trial days').fill(`${trialDays}`);
|
||||||
|
}
|
||||||
|
await modal.getByRole('button', {name: 'Save & close'}).click();
|
||||||
|
await page.locator('[data-testid="tier-card"]:visible').filter({hasText: name}).waitFor();
|
||||||
|
|
||||||
|
// Enable the tier in portal
|
||||||
|
if (enableInPortal) {
|
||||||
|
await page.getByTestId('portal').getByRole('button', {name: 'Customize'}).click();
|
||||||
|
|
||||||
|
const portalSettings = page.getByTestId('portal-modal');
|
||||||
|
|
||||||
|
if (!await portalSettings.getByLabel(name).first().isChecked()) {
|
||||||
|
await portalSettings.getByLabel(name).first().check();
|
||||||
|
}
|
||||||
|
if (!await portalSettings.getByLabel('Monthly').first().isChecked()) {
|
||||||
|
await portalSettings.getByLabel('Monthly').first().check();
|
||||||
|
}
|
||||||
|
if (!await portalSettings.getByLabel('Yearly').first().isChecked()) {
|
||||||
|
await portalSettings.getByLabel('Yearly').first().check();
|
||||||
|
}
|
||||||
|
await portalSettings.getByRole('button', {name: 'Save'}).click();
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
await portalSettings.getByRole('button', {name: 'Close'}).click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate back to the dashboard
|
||||||
|
await page.goto('/ghost');
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -453,7 +450,6 @@ const goToMembershipPage = async (page) => {
|
|||||||
return await test.step('Open Membership settings', async () => {
|
return await test.step('Open Membership settings', async () => {
|
||||||
await page.goto('/ghost');
|
await page.goto('/ghost');
|
||||||
await page.locator('[data-test-nav="settings"]').click();
|
await page.locator('[data-test-nav="settings"]').click();
|
||||||
await page.locator('[data-test-nav="members-membership"]').click();
|
|
||||||
// Tiers request can take time, so waiting until there is no connections before interacting with UI
|
// Tiers request can take time, so waiting until there is no connections before interacting with UI
|
||||||
await page.waitForLoadState('networkidle');
|
await page.waitForLoadState('networkidle');
|
||||||
});
|
});
|
||||||
@ -463,14 +459,13 @@ const goToMembershipPage = async (page) => {
|
|||||||
* Get tier card from membership page
|
* Get tier card from membership page
|
||||||
* @param {import('@playwright/test').Page} page
|
* @param {import('@playwright/test').Page} page
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @param {String} [options.id]
|
* @param {String} [options.slug]
|
||||||
*/
|
*/
|
||||||
const getTierCardById = async (page, {id}) => {
|
const openTierModal = async (page, {slug}) => {
|
||||||
return await test.step('Expand the premium tier list and find the tier', async () => {
|
return await test.step('Open the tier modal', async () => {
|
||||||
await page.locator('[data-test-toggle-pub-info]').click();
|
await page.getByTestId('tiers').locator(`[data-testid="tier-card"][data-tier="${slug}"]`).click();
|
||||||
await page.waitForSelector(`[data-test-tier-card="${id}"]`);
|
|
||||||
|
|
||||||
return page.locator(`[data-test-tier-card="${id}"]`);
|
return page.getByTestId('tier-detail-modal');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -522,5 +517,5 @@ module.exports = {
|
|||||||
completeStripeSubscription,
|
completeStripeSubscription,
|
||||||
impersonateMember,
|
impersonateMember,
|
||||||
goToMembershipPage,
|
goToMembershipPage,
|
||||||
getTierCardById
|
openTierModal
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,10 @@ let uniqueId = 0;
|
|||||||
|
|
||||||
const getUniqueName = (prefix = 'id') => {
|
const getUniqueName = (prefix = 'id') => {
|
||||||
uniqueId += 1;
|
uniqueId += 1;
|
||||||
return `${prefix} ${uniqueId}`;
|
// uniqueId is incremented to avoid conflicts when running tests in parallel,
|
||||||
|
// while Date.now() is used to avoid conflicts when running tests locally in
|
||||||
|
// the same session (e.g. using the Playwright UI)
|
||||||
|
return `${prefix} ${Date.now()}${uniqueId}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSlug = str => str.toLowerCase().split(' ').join('-');
|
const getSlug = str => str.toLowerCase().split(' ').join('-');
|
||||||
|
Loading…
Reference in New Issue
Block a user