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:
Peter Zimon 2023-10-09 09:12:46 +02:00 committed by GitHub
parent 741a00fe05
commit e68db848dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 3844 additions and 3971 deletions

View File

@ -77,8 +77,7 @@ jobs:
- name: Build Admin
if: env.ENVIRONMENT == 'browser-tests-local'
working-directory: ghost/admin
run: yarn build:dev
run: yarn nx run ghost-admin:build:dev
- name: Run Playwright tests on a remote site
if: env.ENVIRONMENT == 'browser-tests-staging'

View File

@ -26,8 +26,8 @@ const MainContent: React.FC = () => {
const {route, updateRoute, loadingModal} = useRouting();
useEffect(() => {
if (!canAccessSettings(currentUser) && route !== `users/show/${currentUser.slug}`) {
updateRoute(`users/show/${currentUser.slug}`);
if (!canAccessSettings(currentUser) && route !== `staff/${currentUser.slug}`) {
updateRoute(`staff/${currentUser.slug}`);
}
}, [currentUser, route, updateRoute]);

View File

@ -82,7 +82,7 @@ const ClearIndicator: React.FC<ClearIndicatorProps<SelectOption, false>> = props
const Option: React.FC<OptionProps<SelectOption, false>> = ({children, ...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>}
</components.Option>
);

View File

@ -97,13 +97,13 @@ export const getActorLinkTarget = (action: Action): InternalLink | ExternalLink
return;
}
return {route: `integrations/show/${action.actor.id}`};
return {route: `integrations/${action.actor.id}`};
case 'user':
if (!action.actor.slug) {
return;
}
return {route: `users/show/${action.actor.slug}`};
return {route: `staff/${action.actor.slug}`};
}
return;
@ -136,7 +136,7 @@ export const getLinkTarget = (action: Action): InternalLink | ExternalLink | und
return;
}
return {route: `integrations/show/${action.resource.id}`};
return {route: `integrations/${action.resource.id}`};
case 'offer':
if (!action.resource || !action.resource.id) {
return;
@ -164,7 +164,7 @@ export const getLinkTarget = (action: Action): InternalLink | ExternalLink | und
return;
}
return {route: `users/show/${action.resource.slug}`};
return {route: `staff/${action.resource.slug}`};
}
}

View File

@ -15,9 +15,6 @@ const Settings: React.FC = () => {
<MembershipSettings />
<EmailSettings />
<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>
</>
);

View File

@ -75,7 +75,7 @@ const Sidebar: React.FC = () => {
</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'>
<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.publicationLanguage} navid='publication-language' title="Publication language" 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.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.users} navid='users' title="Staff" onClick={handleSectionClick} />
<SettingNavItem keywords={generalSearchKeywords.users} navid='staff' title="Staff" onClick={handleSectionClick} />
</SettingNavSection>
<SettingNavSection keywords={Object.values(siteSearchKeywords).flat()} title="Site">
@ -93,7 +93,7 @@ const Sidebar: React.FC = () => {
</SettingNavSection>
<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.tiers} navid='tiers' title="Tiers" onClick={handleSectionClick} />
{hasTipsAndDonations && <SettingNavItem keywords={membershipSearchKeywords.tips} navid='tips-or-donations' title="Tips or donations" onClick={handleSectionClick} />}

View File

@ -35,19 +35,19 @@ export type RoutingModalProps = {
}
const modalPaths: {[key: string]: ModalName} = {
'design/edit/themes': 'DesignAndThemeModal',
'design/change-theme': 'DesignAndThemeModal',
'design/edit': 'DesignAndThemeModal',
// this is a special route, because it can install a theme directly from the Ghost Marketplace
'design/change-theme/install': 'DesignAndThemeModal',
'navigation/edit': 'NavigationModal',
'users/invite': 'InviteUserModal',
'users/show/:slug': 'UserDetailModal',
'staff/invite': 'InviteUserModal',
'staff/:slug': 'UserDetailModal',
'portal/edit': 'PortalModal',
'tiers/add': 'TierDetailModal',
'tiers/show/:id': 'TierDetailModal',
'tiers/:id': 'TierDetailModal',
'stripe-connect': 'StripeConnectModal',
'newsletters/add': 'AddNewsletterModal',
'newsletters/show/:id': 'NewsletterDetailModal',
'newsletters/new': 'AddNewsletterModal',
'newsletters/:id': 'NewsletterDetailModal',
'history/view': 'HistoryModal',
'history/view/:user': 'HistoryModal',
'integrations/zapier': 'ZapierModal',
@ -56,8 +56,8 @@ const modalPaths: {[key: string]: ModalName} = {
'integrations/unsplash': 'UnsplashModal',
'integrations/firstpromoter': 'FirstpromoterModal',
'integrations/pintura': 'PinturaModal',
'integrations/add': 'AddIntegrationModal',
'integrations/show/:id': 'CustomIntegrationModal',
'integrations/new': 'AddIntegrationModal',
'integrations/:id': 'CustomIntegrationModal',
'recommendations/add': 'AddRecommendationModal',
'recommendations/edit': 'EditRecommendationModal',
'announcement-bar/edit': 'AnnouncementBarModal',
@ -68,7 +68,7 @@ function getHashPath(urlPath: string | undefined) {
if (!urlPath) {
return null;
}
const regex = /\/settings-x\/(.*)/;
const regex = /\/settings\/(.*)/;
const match = urlPath?.match(regex);
if (match) {
@ -142,9 +142,9 @@ const RoutingProvider: React.FC<RouteProviderProps> = ({externalNavigate, childr
const newPath = options.route;
if (newPath) {
window.location.hash = `/settings-x/${newPath}`;
window.location.hash = `/settings/${newPath}`;
} else {
window.location.hash = `/settings-x`;
window.location.hash = `/settings`;
}
}, [externalNavigate]);

View File

@ -158,7 +158,7 @@ const CustomIntegrations: React.FC<{integrations: Integration[]}> = ({integratio
<List borderTop={false}>
{integrations.map(integration => (
<IntegrationItem
action={() => updateRoute({route: `integrations/show/${integration.id}`})}
action={() => updateRoute({route: `integrations/${integration.id}`})}
detail={integration.description || 'No description'}
icon={
integration.icon_image ?
@ -218,7 +218,7 @@ const Integrations: React.FC<{ keywords: string[] }> = ({keywords}) => {
const buttons = (
<Button className='hidden md:!visible md:!block' color='green' label='Add custom integration' link linkWithPadding onClick={() => {
updateRoute('integrations/add');
updateRoute('integrations/new');
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'>
<Button color='green' label='Add custom integration' link onClick={() => {
updateRoute('integrations/add');
updateRoute('integrations/new');
setSelectedTab('custom');
}} />
</div>

View File

@ -51,7 +51,7 @@ const AddIntegrationModal: React.FC<RoutingModalProps> = () => {
try {
const data = await createIntegration({name});
modal.remove();
updateRoute({route: `integrations/show/${data.integrations[0].id}`});
updateRoute({route: `integrations/${data.integrations[0].id}`});
} catch (e) {
handleError(e);
}

View File

@ -62,7 +62,7 @@ const AlphaFeatures: React.FC = () => {
<List titleSeparator={false}>
{features.map(feature => (
<LabItem
action={<FeatureToggle flag={feature.flag} />}
action={<FeatureToggle flag={feature.flag} label={feature.title} />}
detail={feature.description}
title={feature.title} />
))}

View File

@ -6,14 +6,14 @@ import {getSettingValue, useEditSettings} from '../../../../api/settings';
import {useGlobalData} from '../../../providers/GlobalDataProvider';
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 labs = JSON.parse(getSettingValue<string>(settings, 'labs') || '{}');
const {mutateAsync: editSettings} = useEditSettings();
const client = useQueryClient();
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];
try {
await editSettings([{

View File

@ -10,7 +10,7 @@ import {withErrorBoundary} from '../../../admin-x-ds/global/ErrorBoundary';
const Newsletters: React.FC<{ keywords: string[] }> = ({keywords}) => {
const {updateRoute} = useRouting();
const openNewsletterModal = () => {
updateRoute('newsletters/add');
updateRoute('newsletters/new');
};
const [selectedTab, setSelectedTab] = useState('active-newsletters');
const {data: {newsletters, meta, isEnd} = {}, fetchNextPage} = useBrowseNewsletters();

View File

@ -40,7 +40,7 @@ const AddNewsletterModal: React.FC<RoutingModalProps> = () => {
feedback_enabled: true
});
updateRoute({route: `newsletters/show/${response.newsletters[0].id}`});
updateRoute({route: `newsletters/${response.newsletters[0].id}`});
},
onSaveError: handleError,
onValidate: () => {

View File

@ -16,7 +16,7 @@ const NewsletterItem: React.FC<{newsletter: Newsletter}> = ({newsletter}) => {
const {updateRoute} = useRouting();
const showDetails = () => {
updateRoute({route: `newsletters/show/${newsletter.id}`});
updateRoute({route: `newsletters/${newsletter.id}`});
};
return (

View File

@ -130,7 +130,7 @@ const InviteUserModal = NiceModal.create(() => {
});
modal.remove();
updateRoute('users');
updateRoute('staff');
} catch (e) {
setSaveState('error');
@ -175,7 +175,7 @@ const InviteUserModal = NiceModal.create(() => {
return (
<Modal
afterClose={() => {
updateRoute('users');
updateRoute('staff');
}}
cancelLabel=''
okLabel={okLabel}

View File

@ -70,7 +70,7 @@ const TitleAndDescription: React.FC<{ keywords: string[] }> = ({keywords}) => {
description='The details used to identify your publication around the web'
isEditing={isEditing}
keywords={keywords}
navid='title-and-description'
navid='general'
saveState={saveState}
testId='title-and-description'
title='Title & description'

View File

@ -80,7 +80,7 @@ const UserDetailModalContent: React.FC<{user: User}> = ({user}) => {
const navigateOnClose = useCallback(() => {
if (canAccessSettings(currentUser)) {
updateRoute('users');
updateRoute('staff');
} else {
updateRoute({isExternal: true, route: 'dashboard'});
}

View File

@ -39,7 +39,7 @@ const Owner: React.FC<OwnerProps> = ({user}) => {
const showDetailModal = () => {
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 showDetailModal = (user: User) => {
updateRoute({route: `users/show/${user.slug}`});
updateRoute({route: `staff/${user.slug}`});
};
if (!users || !users.length) {
@ -221,7 +221,7 @@ const Users: React.FC<{ keywords: string[], highlight?: boolean }> = ({keywords,
const {updateRoute} = useRouting();
const showInviteModal = () => {
updateRoute('users/invite');
updateRoute('staff/invite');
};
const buttons = (
@ -265,7 +265,7 @@ const Users: React.FC<{ keywords: string[], highlight?: boolean }> = ({keywords,
customButtons={buttons}
highlightOnModalClose={highlight}
keywords={keywords}
navid='users'
navid='staff'
testId='users'
title='Staff'
>

View File

@ -182,7 +182,7 @@ const Access: React.FC<{ keywords: string[] }> = ({keywords}) => {
description='Set up default access options for subscription and posts'
isEditing={isEditing}
keywords={keywords}
navid='access'
navid='members'
saveState={saveState}
testId='access'
title='Access'

View File

@ -17,7 +17,7 @@ const StripeConnectedButton: React.FC<{className?: string; onClick: () => void;}
className
);
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='ml-2'>Connected to Stripe</span>
</button>

View File

@ -103,6 +103,8 @@ const TipsOrDonations: React.FC<{ keywords: string[] }> = ({keywords}) => {
fullWidth={false}
options={currencySelectGroups()}
selectedOption={currencySelectGroups().flatMap(group => group.options).find(option => option.value === donationsCurrency)}
title='Currency'
hideTitle
isSearchable
onSelect={option => updateSetting('donations_currency', option?.value || 'USD')}
/>

View File

@ -2,7 +2,7 @@ import Button from '../../../../admin-x-ds/global/Button';
import List from '../../../../admin-x-ds/global/List';
import ListItem from '../../../../admin-x-ds/global/ListItem';
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 TextField from '../../../../admin-x-ds/global/form/TextField';
import {getHomepageUrl} from '../../../../api/site';
@ -15,6 +15,8 @@ interface PortalLinkPrefs {
}
const PortalLink: React.FC<PortalLinkPrefs> = ({name, value}) => {
const id = useId();
return (
<ListItem
action={<Button color='black' label='Copy' link onClick={(e) => {
@ -29,8 +31,8 @@ const PortalLink: React.FC<PortalLinkPrefs> = ({name, value}) => {
separator
>
<div className='flex w-full grow items-center gap-5 py-3'>
<span className='inline-block w-[240px] whitespace-nowrap'>{name}</span>
<TextField className='border-b-500 grow bg-transparent p-1 text-grey-700' value={value} disabled unstyled />
<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' id={id} value={value} disabled unstyled />
</div>
</ListItem>
);

View File

@ -52,7 +52,8 @@ const TierDetailModalContent: React.FC<{tier?: Tier}> = ({tier}) => {
initialState: {
...(tier || {}),
trial_days: tier?.trial_days?.toString() || '',
currency: tier?.currency || currencies[0].isoCode
currency: tier?.currency || currencies[0].isoCode,
visibility: tier?.visibility || 'none'
},
onSave: async () => {
const {trial_days: trialDays, currency, ...rest} = formState;

View File

@ -27,9 +27,9 @@ const TierCard: React.FC<TierCardProps> = ({tier}) => {
const currencySymbol = currency ? getSymbol(currency) : '$';
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={() => {
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='mt-2 flex items-baseline'>

View File

@ -8,7 +8,7 @@ const DesignAndThemeModal: React.FC<RoutingModalProps> = ({pathName}) => {
if (pathName === 'design/edit') {
return <DesignModal />;
} else if (pathName === 'design/edit/themes') {
} else if (pathName === 'design/change-theme') {
return <ChangeThemeModal />;
} else if (pathName === 'design/change-theme/install') {
const url = window.location.href;

View File

@ -66,7 +66,7 @@ const Sidebar: React.FC<{
<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 () => {
await handleSave();
updateRoute('design/edit/themes');
updateRoute('design/change-theme');
}}>
<div className='text-left'>
<div className='font-semibold'>Change theme</div>

View File

@ -1,5 +1,5 @@
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 params = new URLSearchParams();
@ -19,7 +19,10 @@ type AnnouncementBarSettings = {
};
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) {
return;
}
@ -31,7 +34,7 @@ const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcement
'x-ghost-preview': getPreviewData(
announcementBackgroundColor,
announcementContent,
visibility
visibilityMemo
),
Accept: 'text/plain',
mode: 'cors',
@ -63,7 +66,7 @@ const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcement
.catch(() => {
// handle error in fetching data
});
};
}, [announcementBackgroundColor, announcementContent, url, visibilityMemo]);
return (
<IframeBuffering
@ -78,43 +81,4 @@ const AnnouncementBarPreview: React.FC<AnnouncementBarSettings> = ({announcement
);
};
function arraysAreEqual(arr1: string[], arr2: string[]) {
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;
});
export default AnnouncementBarPreview;

View File

@ -89,9 +89,15 @@ const useSettingGroup = ({onValidate}: {onValidate?: () => ErrorMessages} = {}):
// function to update the local state
const updateSetting = (key: string, value: SettingValue) => {
updateForm(state => state.map(setting => (
setting.key === key ? {...setting, value, dirty: true} : setting
)));
updateForm((state) => {
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 {

View File

@ -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
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-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|785|168|785|168|0145b67f0faef0aad141c6a4269c35c6ef8f0a47|1696204800000|1706576400000|1711760400000|app/components/gh-post-settings-menu.hbs

View File

@ -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>
{{else}}
<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">
<span>Membership settings</span>
</LinkTo>
{{else}}
<LinkTo @route="settings.membership" class="gh-btn gh-btn-green">
<span>Membership settings</span>
</LinkTo>
{{/if}}
<LinkTo @route="settings-x.settings-x" @model="access" class="gh-btn gh-btn-green">
<span>Membership settings</span>
</LinkTo>
{{/if}}
</div>

View File

@ -55,15 +55,9 @@
{{/if}}
<li>
{{#if (feature "adminXSettings")}}
<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
</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}}
<LinkTo @route="settings-x.settings-x" @model="staff/{{this.session.user.slug}}" class="dropdown-item" @role="menuitem" tabindex="-1" data-test-nav="user-profile">
Your profile
</LinkTo>
</li>
{{#unless this.session.user.isContributor}}
@ -106,11 +100,7 @@
</div>
<div class="flex items-center pe-all">
{{#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>
{{else}}
<LinkTo class="gh-nav-bottom-tabicon" @route="settings" @current-when={{this.isSettingsRoute}} data-test-nav="settings">{{svg-jar "settings"}}</LinkTo>
{{/if}}
<LinkTo class="gh-nav-bottom-tabicon" @route="settings-x" @current-when={{this.isSettingsRoute}} data-test-nav="settings">{{svg-jar "settings"}}</LinkTo>
{{/if}}
<div class="nightshift-toggle-container">
<div class="nightshift-toggle {{if this.feature.nightShift "on"}}" {{action (toggle "nightShift" this.feature)}}>

View File

@ -64,7 +64,7 @@ export default class GhSearchInputComponent extends Component {
if (selected.searchable === 'Users') {
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') {

View File

@ -53,41 +53,13 @@ Router.map(function () {
this.route('collection.new', {path: '/collections/new'});
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');
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
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 () {
// actual Ember route, not rendered in iframe
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('members', function () {

View File

@ -7,14 +7,6 @@ export default class SettingsXRoute extends AuthenticatedRoute {
@service ui;
@service modals;
beforeModel() {
super.beforeModel(...arguments);
if (!this.feature.adminXSettings) {
return this.router.transitionTo('settings');
}
}
activate() {
super.activate(...arguments);
this.ui.set('isFullScreen', true);

View File

@ -4,6 +4,7 @@ import {inject as service} from '@ember/service';
// need this to be authenticated
export default class WebsocketRoute extends AuthenticatedRoute {
@service session;
@service router;
beforeModel() {
super.beforeModel(...arguments);
@ -11,7 +12,7 @@ export default class WebsocketRoute extends AuthenticatedRoute {
const user = this.session.user;
if (!user.isAdmin) {
return this.transitionTo('settings.staff.user', user);
return this.router.transitionTo('settings-x.settings-x', `staff/${user.slug}`);
}
}
}

View File

@ -30,15 +30,9 @@
<div class="gh-offers-list-cta missing-tiers">
{{svg-jar "discount-bubble" class="discount-bubble"}}
<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">
<span>Manage tiers</span>
</LinkTo>
{{else}}
<LinkTo @route="settings.membership" class="gh-btn gh-btn-green">
<span>Manage tiers</span>
</LinkTo>
{{/if}}
<LinkTo @route="settings-x.settings-x" @model="tiers" class="gh-btn gh-btn-green">
<span>Manage tiers</span>
</LinkTo>
</div>
{{else if (and this.offersExist this.filteredOffers.length)}}
<table class="gh-list gh-offers-list" data-test-offers-list>

View File

@ -16,7 +16,7 @@
<h6>Write your first post</h6>
<p>Test out the editor and get a feel for creating content inside Ghost.</p>
</LinkTo>
<LinkTo class="gh-done-green" @route="settings">
<LinkTo class="gh-done-green" @route="settings-x">
<span>{{svg-jar "paint-palette"}}</span>
<h6>Customize your site</h6>
<p>Review your settings and tweak the design to make your site just right.</p>

View File

@ -61,7 +61,7 @@ describe('Acceptance: Authentication', function () {
}));
await authenticateSession();
await visit('/settings/staff');
await visit('/members');
// running `visit(url)` inside windowProxy.replaceLocation breaks
// the async behaviour so we need to run `visit` here to simulate
@ -82,7 +82,7 @@ describe('Acceptance: Authentication', function () {
}));
await authenticateSession();
await visit('/settings/staff');
await visit('/members');
// running `visit(url)` inside windowProxy.replaceLocation breaks
// the async behaviour so we need to run `visit` here to simulate

View File

@ -125,100 +125,101 @@ describe('Acceptance: Editor', function () {
});
describe('post settings menu', function () {
it('can set publish date', async function () {
let [post1] = this.server.createList('post', 2, {authors: [author]});
let futureTime = moment().tz('Etc/UTC').add(10, 'minutes');
// TODO: Convert to E2E test
// it('can set publish date', async function () {
// let [post1] = this.server.createList('post', 2, {authors: [author]});
// let futureTime = moment().tz('Etc/UTC').add(10, 'minutes');
// sanity check
expect(
moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD HH:mm:ss'),
'initial publishedAt sanity check')
.to.equal('2015-12-19 16:25:07');
// // sanity check
// expect(
// moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD HH:mm:ss'),
// 'initial publishedAt sanity check')
// .to.equal('2015-12-19 16:25:07');
// post id 1 is a draft, checking for draft behaviour now
await visit('/editor/post/1');
// // post id 1 is a draft, checking for draft behaviour now
// await visit('/editor/post/1');
// open post settings menu
await click('[data-test-psm-trigger]');
// // open post settings menu
// await click('[data-test-psm-trigger]');
// should error, if the publish time is in the wrong format
await fillIn('[data-test-date-time-picker-time-input]', 'foo');
await blur('[data-test-date-time-picker-time-input]');
// // should error, if the publish time is in the wrong format
// await fillIn('[data-test-date-time-picker-time-input]', 'foo');
// 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')
.to.equal('Must be in format: "15:00"');
// expect(find('[data-test-date-time-picker-error]').textContent.trim(), 'inline error response for invalid time')
// .to.equal('Must be in format: "15:00"');
// should error, if the publish time is in the future
// NOTE: date must be selected first, changing the time first will save
// 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 blur('[data-test-date-time-picker-datepicker] input');
await fillIn('[data-test-date-time-picker-time-input]', futureTime.format('HH:mm'));
await blur('[data-test-date-time-picker-time-input]');
// // should error, if the publish time is in the future
// // NOTE: date must be selected first, changing the time first will save
// // 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 blur('[data-test-date-time-picker-datepicker] input');
// await fillIn('[data-test-date-time-picker-time-input]', futureTime.format('HH:mm'));
// 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')
.to.equal('Must be in the past');
// expect(find('[data-test-date-time-picker-error]').textContent.trim(), 'inline error response for future time')
// .to.equal('Must be in the past');
// closing the PSM will reset the invalid date/time
await click('[data-test-psm-trigger]');
await click('[data-test-psm-trigger]');
// // closing the PSM will reset the invalid date/time
// await click('[data-test-psm-trigger]');
// await click('[data-test-psm-trigger]');
expect(
find('[data-test-date-time-picker-error]'),
'date picker error after closing PSM'
).to.not.exist;
// expect(
// find('[data-test-date-time-picker-error]'),
// 'date picker error after closing PSM'
// ).to.not.exist;
expect(
find('[data-test-date-time-picker-date-input]').value,
'PSM date value after closing with invalid date'
).to.equal(moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD'));
// expect(
// find('[data-test-date-time-picker-date-input]').value,
// 'PSM date value after closing with invalid date'
// ).to.equal(moment(post1.publishedAt).tz('Etc/UTC').format('YYYY-MM-DD'));
expect(
find('[data-test-date-time-picker-time-input]').value,
'PSM time value after closing with invalid date'
).to.equal(moment(post1.publishedAt).tz('Etc/UTC').format('HH:mm'));
// expect(
// find('[data-test-date-time-picker-time-input]').value,
// 'PSM time value after closing with invalid date'
// ).to.equal(moment(post1.publishedAt).tz('Etc/UTC').format('HH:mm'));
// saves the post with the new date
let validTime = moment('2017-04-09 12:00');
await fillIn('[data-test-date-time-picker-time-input]', validTime.format('HH:mm'));
await blur('[data-test-date-time-picker-time-input]');
await datepickerSelect('[data-test-date-time-picker-datepicker]', validTime.toDate());
// // saves the post with the new date
// let validTime = moment('2017-04-09 12:00');
// await fillIn('[data-test-date-time-picker-time-input]', validTime.format('HH:mm'));
// await blur('[data-test-date-time-picker-time-input]');
// 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
await visit('/settings/general');
await click('[data-test-toggle-timezone]');
// // go to settings to change the timezone
// await visit('/settings/general');
// await click('[data-test-toggle-timezone]');
expect(currentURL(), 'currentURL for settings')
.to.equal('/settings/general');
expect(find('#timezone option:checked').textContent.trim(), 'default timezone')
.to.equal('(GMT) UTC');
// expect(currentURL(), 'currentURL for settings')
// .to.equal('/settings/general');
// expect(find('#timezone option:checked').textContent.trim(), 'default timezone')
// .to.equal('(GMT) UTC');
// select a new timezone
find('#timezone option[value="Pacific/Kwajalein"]').selected = true;
// // select a new timezone
// find('#timezone option[value="Pacific/Kwajalein"]').selected = true;
await triggerEvent('#timezone', 'change');
// save the settings
await click('[data-test-button="save"]');
// await triggerEvent('#timezone', 'change');
// // save the settings
// await click('[data-test-button="save"]');
expect(find('#timezone option:checked').textContent.trim(), 'new timezone after saving')
.to.equal('(GMT +12:00) International Date Line West');
// expect(find('#timezone option:checked').textContent.trim(), 'new timezone after saving')
// .to.equal('(GMT +12:00) International Date Line West');
// and now go back to the editor
await visit('/editor/post/1');
// // and now go back to the editor
// await visit('/editor/post/1');
await click('[data-test-psm-trigger]');
expect(
find('[data-test-date-time-picker-date-input]').value,
'date after timezone change'
).to.equal('2017-04-10');
// await click('[data-test-psm-trigger]');
// expect(
// find('[data-test-date-time-picker-date-input]').value,
// 'date after timezone change'
// ).to.equal('2017-04-10');
expect(
find('[data-test-date-time-picker-time-input]').value,
'time after timezone change'
).to.equal('00:00');
});
// expect(
// find('[data-test-date-time-picker-time-input]').value,
// 'time after timezone change'
// ).to.equal('00:00');
// });
});
it.skip('handles validation errors when scheduling', async function () {

View File

@ -431,39 +431,40 @@ describe('Acceptance: Publish flow', function () {
it('can publish');
it('can schedule publish');
it('respects default recipient settings - usually nobody', async function () {
// switch to "usually nobody" setting
// - doing it this way so we're not testing potentially stale mocked setting keys/values
await loginAsRole('Administrator', this.server);
await visit('/settings/newsletters');
await click('[data-test-toggle-membersemail]');
await selectChoose('[data-test-select="default-recipients"]', 'Usually nobody');
await click('[data-test-button="save-members-settings"]');
// TODO: Update to E2E test
// it('respects default recipient settings - usually nobody', async function () {
// // switch to "usually nobody" setting
// // - doing it this way so we're not testing potentially stale mocked setting keys/values
// await loginAsRole('Administrator', this.server);
// await visit('/settings/newsletters');
// await click('[data-test-toggle-membersemail]');
// 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'});
await visit(`/editor/post/${post.id}`);
await click('[data-test-button="publish-flow"]');
// const post = this.server.create('post', {status: 'draft'});
// await visit(`/editor/post/${post.id}`);
// await click('[data-test-button="publish-flow"]');
expect(
find('[data-test-setting="publish-type"] [data-test-setting-title]'), 'publish type title'
).to.have.trimmed.rendered.text('Publish');
// expect(
// find('[data-test-setting="publish-type"] [data-test-setting-title]'), 'publish type title'
// ).to.have.trimmed.rendered.text('Publish');
expect(
find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
).to.have.trimmed.rendered.text('Not sent as newsletter');
// expect(
// find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
// ).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
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');
// // email-related options are enabled
// 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');
await click('[data-test-publish-type="publish+send"]');
// await click('[data-test-publish-type="publish+send"]');
expect(
find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
).to.have.trimmed.rendered.text('All 7 subscribers');
});
// expect(
// find('[data-test-setting="email-recipients"] [data-test-setting-title]'), 'recipients title'
// ).to.have.trimmed.rendered.text('All 7 subscribers');
// });
it('handles Mailgun not being set up', async function () {
disableMailgun(this.server);

View File

@ -107,14 +107,14 @@ describe('Acceptance: Error Handling', 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 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-modal="delete-theme"] [data-test-button="confirm"]');
await visit('/tags/test');
await click('[data-test-button="delete-tag"]');
await click('[data-test-modal="confirm-delete-tag"] [data-test-button="confirm"]');
expect(findAll('.gh-alert').length).to.equal(1);
expect(find('.gh-alert').textContent).to.not.match(/html>/);

View File

@ -1,130 +1,130 @@
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {
beforeEach,
describe,
it
} from 'mocha';
import {click, currentURL, find, findAll, triggerEvent} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {
// beforeEach,
// describe,
// it
// } from 'mocha';
// import {click, currentURL, find, findAll, triggerEvent} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Integrations - AMP', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Integrations - AMP', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
it('redirects to signin when not authenticated', async function () {
await invalidateSession();
await visit('/settings/integrations/amp');
// it('redirects to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
let role = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as contributor', async function () {
// let role = this.server.create('role', {name: 'Contributor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/amp');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Author'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as author', async function () {
// let role = this.server.create('role', {name: 'Author'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/amp');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Editor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as editor', async function () {
// let role = this.server.create('role', {name: 'Editor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/amp');
// await authenticateSession();
// await visit('/settings/integrations/amp');
expect(currentURL(), 'currentURL').to.equal('/site');
});
// expect(currentURL(), 'currentURL').to.equal('/site');
// });
describe('when logged in', function () {
beforeEach(async function () {
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// describe('when logged in', function () {
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it('it enables or disables AMP properly and saves it', async function () {
await visit('/settings/integrations/amp');
// it('it enables or disables AMP properly and saves it', async function () {
// await visit('/settings/integrations/amp');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
// AMP is disabled by default
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
// // AMP is disabled by default
// 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 params = JSON.parse(lastRequest.requestBody);
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
// 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
await click('[data-test-amp-checkbox]');
await triggerEvent('.gh-app', 'keydown', {
keyCode: 83, // s
metaKey: ctrlOrCmd === 'command',
ctrlKey: ctrlOrCmd === 'ctrl'
});
// // CMD-S shortcut works
// await click('[data-test-amp-checkbox]');
// await triggerEvent('.gh-app', 'keydown', {
// keyCode: 83, // s
// metaKey: ctrlOrCmd === 'command',
// ctrlKey: ctrlOrCmd === 'ctrl'
// });
// 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
let [newRequest] = this.server.pretender.handledRequests.slice(-1);
params = JSON.parse(newRequest.requestBody);
// // 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
// let [newRequest] = this.server.pretender.handledRequests.slice(-1);
// params = JSON.parse(newRequest.requestBody);
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
expect(params.settings.findBy('key', 'amp').value).to.equal(false);
});
// expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
// expect(params.settings.findBy('key', 'amp').value).to.equal(false);
// });
it('warns when leaving without saving', async function () {
await visit('/settings/integrations/amp');
// it('warns when leaving without saving', async function () {
// await visit('/settings/integrations/amp');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
// AMP is disabled by default
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox default').to.be.false;
// // AMP is disabled by default
// 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
await click('[data-test-leave-button]');
// // Leave without saving
// 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
expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
});
});
});
// // settings were not saved
// expect(find('[data-test-amp-checkbox]').checked, 'AMP checkbox').to.be.false;
// });
// });
// });

View File

@ -1,80 +1,80 @@
import {authenticateSession} from 'ember-simple-auth/test-support';
import {click, find} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import {authenticateSession} from 'ember-simple-auth/test-support';
// import {click, find} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Analytics', function () {
const hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Analytics', function () {
// const hooks = setupApplicationTest();
// setupMirage(hooks);
beforeEach(async function () {
this.server.loadFixtures('configs', 'newsletters');
// beforeEach(async function () {
// this.server.loadFixtures('configs', 'newsletters');
const role = this.server.create('role', {name: 'Owner'});
this.server.create('user', {roles: [role]});
// const role = this.server.create('role', {name: 'Owner'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it('can manage open rate tracking', async function () {
this.server.db.settings.update({key: 'email_track_opens'}, {value: 'true'});
// it('can manage open rate tracking', async function () {
// 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"]');
expect(find('[data-test-checkbox="email-track-opens"]')).to.not.be.checked;
// await click('[data-test-label="email-track-opens"]');
// 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 () {
this.server.db.settings.update({key: 'email_track_clicks'}, {value: 'true'});
// it('can manage click tracking', async function () {
// 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"]');
expect(find('[data-test-checkbox="email-track-clicks"]')).to.not.be.checked;
// await click('[data-test-label="email-track-clicks"]');
// 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 () {
this.server.db.settings.update({key: 'members_track_sources'}, {value: 'true'});
// it('can manage source tracking', async function () {
// 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"]');
expect(find('[data-test-checkbox="members-track-sources"]')).to.not.be.checked;
// await click('[data-test-label="members-track-sources"]');
// 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 () {
this.server.db.settings.update({key: 'outbound_link_tagging'}, {value: 'true'});
// it('can manage outbound link tagging', async function () {
// 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"]');
expect(find('[data-test-checkbox="outbound-link-tagging"]')).to.not.be.checked;
// await click('[data-test-label="outbound-link-tagging"]');
// 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);
// });
// });

View File

@ -1,113 +1,113 @@
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {
beforeEach,
describe,
it
} from 'mocha';
import {click, currentURL, fillIn, find, findAll, triggerEvent} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {
// beforeEach,
// describe,
// it
// } from 'mocha';
// import {click, currentURL, fillIn, find, findAll, triggerEvent} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Code-Injection', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Code-Injection', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
it('redirects to signin when not authenticated', async function () {
await invalidateSession();
await visit('/settings/code-injection');
// it('redirects to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
let role = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as contributor', async function () {
// let role = this.server.create('role', {name: 'Contributor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/code-injection');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Author'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to staff page when authenticated as author', async function () {
// let role = this.server.create('role', {name: 'Author'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/code-injection');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Editor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as editor', async function () {
// let role = this.server.create('role', {name: 'Editor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/code-injection');
// await authenticateSession();
// await visit('/settings/code-injection');
expect(currentURL(), 'currentURL').to.equal('/site');
});
// expect(currentURL(), 'currentURL').to.equal('/site');
// });
describe('when logged in', function () {
beforeEach(async function () {
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// describe('when logged in', function () {
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it('it renders, loads and saves editors correctly', async function () {
await visit('/settings/code-injection');
// it('it renders, loads and saves editors correctly', async function () {
// await visit('/settings/code-injection');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/code-injection');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/code-injection');
// has correct page title
expect(document.title, 'page title').to.equal('Settings - Code injection - Test Blog');
// // has correct page title
// 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(find('#ghost-head .CodeMirror'), 'ghost head editor theme').to.have.class('cm-s-xq-light');
// 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(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(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');
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 params = JSON.parse(lastRequest.requestBody);
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
// let params = JSON.parse(lastRequest.requestBody);
expect(params.settings.findBy('key', 'codeinjection_head').value).to.equal('Test');
// update should have been partial
expect(params.settings.findBy('key', 'navigation')).to.be.undefined;
expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
// expect(params.settings.findBy('key', 'codeinjection_head').value).to.equal('Test');
// // update should have been partial
// expect(params.settings.findBy('key', 'navigation')).to.be.undefined;
// 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
await triggerEvent('.gh-app', 'keydown', {
keyCode: 83, // s
metaKey: ctrlOrCmd === 'command',
ctrlKey: ctrlOrCmd === 'ctrl'
});
// // CMD-S shortcut works
// await triggerEvent('.gh-app', 'keydown', {
// keyCode: 83, // s
// metaKey: ctrlOrCmd === 'command',
// ctrlKey: ctrlOrCmd === 'ctrl'
// });
let [newRequest] = this.server.pretender.handledRequests.slice(-1);
params = JSON.parse(newRequest.requestBody);
// let [newRequest] = this.server.pretender.handledRequests.slice(-1);
// params = JSON.parse(newRequest.requestBody);
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(params.settings.findBy('key', 'codeinjection_head').value).to.equal('');
// expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
// Saving when no changed have been made should work
// (although no api request is expected)
await click('[data-test-save-button]');
expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
});
});
});
// // Saving when no changed have been made should work
// // (although no api request is expected)
// await click('[data-test-save-button]');
// expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
// });
// });
// });

View File

@ -1,159 +1,159 @@
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
import {expect} from 'chai';
import {fileUpload} from '../../helpers/file-upload';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {fileUpload} from '../../helpers/file-upload';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Design', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Design', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
beforeEach(async function () {
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Administrator'});
// 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 () {
await invalidateSession();
await visit('/settings/general');
// it('redirects to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
await visit('/settings');
await click('[data-test-nav="design"]');
// it('renders with no custom theme settings', async function () {
// await visit('/settings');
// await click('[data-test-nav="design"]');
expect(currentURL(), 'currentURL').to.equal('/settings/design');
expect(document.title, 'page title').to.equal('Settings - Design - Test Blog');
// expect(currentURL(), 'currentURL').to.equal('/settings/design');
// expect(document.title, 'page title').to.equal('Settings - Design - Test Blog');
// side nav menu changes
expect(find('[data-test-nav-menu="design"]'), 'design menu').to.exist;
expect(find('[data-test-nav-menu="main"]'), 'main menu').to.not.exist;
// // side nav menu changes
// expect(find('[data-test-nav-menu="design"]'), 'design menu').to.exist;
// expect(find('[data-test-nav-menu="main"]'), 'main menu').to.not.exist;
// side nav defaults to general group open
expect(find('[data-test-nav-toggle="general"]'), 'general toggle').to.exist;
expect(find('[data-test-nav-group="general"]'), 'general form').to.exist;
// // side nav defaults to general group open
// expect(find('[data-test-nav-toggle="general"]'), 'general toggle').to.exist;
// expect(find('[data-test-nav-group="general"]'), 'general form').to.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-group]'), 'no of groups open').to.have.lengthOf(1);
// // 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-group]'), 'no of groups open').to.have.lengthOf(1);
// current theme is shown in nav menu
expect(find('[data-test-text="current-theme"]')).to.contain.text('source - v1.0');
// // current theme is shown in nav menu
// expect(find('[data-test-text="current-theme"]')).to.contain.text('source - v1.0');
// defaults to "home" desktop preview
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');
});
// // defaults to "home" desktop preview
// 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');
// });
it('has unsaved-changes confirmation', async function () {
await visit('/settings/design');
await fillIn('[data-test-input="siteDescription"]', 'Changed');
await click('[data-test-link="back-to-settings"]');
// it('has unsaved-changes confirmation', async function () {
// await visit('/settings/design');
// await fillIn('[data-test-input="siteDescription"]', 'Changed');
// 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-modal="unsaved-settings"] [data-test-leave-button]');
// await click('[data-test-link="back-to-settings"]');
// 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 () {
await visit('/settings/design');
await click('[data-test-nav="change-theme"]');
expect(currentURL(), 'currentURL').to.equal('/settings/design/change-theme');
// it('can install an official theme', async function () {
// await visit('/settings/design');
// await click('[data-test-nav="change-theme"]');
// expect(currentURL(), 'currentURL').to.equal('/settings/design/change-theme');
await click('[data-test-theme-link="Journal"]');
expect(currentURL(), 'currentURL').to.equal('/settings/design/change-theme/Journal');
// await click('[data-test-theme-link="Journal"]');
// expect(currentURL(), 'currentURL').to.equal('/settings/design/change-theme/Journal');
await click('[data-test-button="install-theme"]');
expect(find('[data-test-modal="install-theme"]'), 'install-theme modal').to.exist;
expect(find('[data-test-state="confirm"]'), 'confirm state').to.exist;
expect(findAll('[data-test-state]').length, 'state count').to.equal(1);
// await click('[data-test-button="install-theme"]');
// expect(find('[data-test-modal="install-theme"]'), 'install-theme modal').to.exist;
// expect(find('[data-test-state="confirm"]'), 'confirm state').to.exist;
// expect(findAll('[data-test-state]').length, 'state count').to.equal(1);
await click('[data-test-button="confirm-install"]');
expect(find('[data-test-state="installed-no-notes"]'), 'success state').to.exist;
expect(findAll('[data-test-state]').length, 'state count').to.equal(1);
// await click('[data-test-button="confirm-install"]');
// expect(find('[data-test-state="installed-no-notes"]'), 'success state').to.exist;
// expect(findAll('[data-test-state]').length, 'state count').to.equal(1);
// navigates back to design screen in background
expect(currentURL(), 'currentURL').to.equal('/settings/design');
// // navigates back to design screen in background
// expect(currentURL(), 'currentURL').to.equal('/settings/design');
await click('[data-test-button="cancel"]');
expect(find('[data-test-modal="install-theme"]')).to.not.exist;
// await click('[data-test-button="cancel"]');
// expect(find('[data-test-modal="install-theme"]')).to.not.exist;
// nav menu shows current theme
expect(find('[data-test-text="current-theme"]')).to.contain.text('Journal - v0.1');
});
// // nav menu shows current theme
// expect(find('[data-test-text="current-theme"]')).to.contain.text('Journal - v0.1');
// });
it('can upload custom theme', async function () {
this.server.post('/themes/upload/', function ({themes}) {
const theme = themes.create({
name: 'custom',
package: {
name: 'Custom',
version: '1.0'
}
});
// it('can upload custom theme', async function () {
// this.server.post('/themes/upload/', function ({themes}) {
// const theme = themes.create({
// name: 'custom',
// package: {
// name: 'Custom',
// version: '1.0'
// }
// });
return {themes: [theme]};
});
// return {themes: [theme]};
// });
await visit('/settings/design/change-theme');
await click('[data-test-button="upload-theme"]');
// await visit('/settings/design/change-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(currentURL(), 'url after upload').to.equal('/settings/design/change-theme');
// expect(find('[data-test-state="installed-no-notes"]'), 'success state').to.exist;
// 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(find('[data-test-modal="install-theme"]')).to.not.exist;
expect(find('[data-test-text="current-theme"]')).to.contain.text('custom - v1.0');
});
// expect(currentURL(), 'url after activate').to.equal('/settings/design');
// expect(find('[data-test-modal="install-theme"]')).to.not.exist;
// expect(find('[data-test-text="current-theme"]')).to.contain.text('custom - v1.0');
// });
it('can change between installed themes');
it('can delete installed theme');
// it('can change between installed themes');
// it('can delete installed theme');
describe('limits', function () {
it('displays upgrade notice when custom themes are not allowed', async function () {
this.server.loadFixtures('configs');
const config = this.server.db.configs.find(1);
config.hostSettings = {
limits: {
customThemes: {
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.'
}
}
};
this.server.db.configs.update(1, config);
// describe('limits', function () {
// it('displays upgrade notice when custom themes are not allowed', async function () {
// this.server.loadFixtures('configs');
// const config = this.server.db.configs.find(1);
// config.hostSettings = {
// limits: {
// customThemes: {
// 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.'
// }
// }
// };
// this.server.db.configs.update(1, config);
await visit('/settings/design/change-theme');
await click('[data-test-button="upload-theme"]');
// await visit('/settings/design/change-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;
// });
// });
// });

View File

@ -1,291 +1,291 @@
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {beforeEach, describe, it} from 'mocha';
import {blur, click, currentURL, fillIn, find, findAll, focus, triggerEvent} from '@ember/test-helpers';
import {expect} from 'chai';
import {keyDown} from 'ember-keyboard/test-support/test-helpers';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - General', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {beforeEach, describe, it} from 'mocha';
// import {blur, click, currentURL, fillIn, find, findAll, focus, triggerEvent} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {keyDown} from 'ember-keyboard/test-support/test-helpers';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
// describe('Acceptance: Settings - General', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
it('redirects to signin when not authenticated', async function () {
await invalidateSession();
await visit('/settings/general');
// it('redirects to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
let role = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as contributor', async function () {
// let role = this.server.create('role', {name: 'Contributor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/general');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Author'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as author', async function () {
// let role = this.server.create('role', {name: 'Author'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/general');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Editor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as editor', async function () {
// let role = this.server.create('role', {name: 'Editor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/general');
// await authenticateSession();
// await visit('/settings/general');
expect(currentURL(), 'currentURL').to.equal('/site');
});
// expect(currentURL(), 'currentURL').to.equal('/site');
// });
describe('when logged in', function () {
beforeEach(async function () {
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// describe('when logged in', function () {
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it('it renders, handles image uploads', async function () {
await visit('/settings/general');
// it('it renders, handles image uploads', async function () {
// await visit('/settings/general');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/general');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/general');
// has correct page title
expect(document.title, 'page title').to.equal('Settings - General - Test Blog');
// // has correct page title
// expect(document.title, 'page title').to.equal('Settings - General - Test Blog');
// highlights nav menu
expect(find('[data-test-nav="settings"]'), 'highlights nav menu item')
.to.have.class('active');
// // highlights nav menu
// expect(find('[data-test-nav="settings"]'), 'highlights nav menu item')
// .to.have.class('active');
expect(
find('[data-test-button="save"]').textContent.trim(),
'save button text'
).to.equal('Save');
// expect(
// find('[data-test-button="save"]').textContent.trim(),
// 'save button text'
// ).to.equal('Save');
await click('[data-test-toggle-pub-info]');
await fillIn('[data-test-title-input]', 'New Blog Title');
await click('[data-test-button="save"]');
expect(document.title, 'page title').to.equal('Settings - General - New Blog Title');
// await click('[data-test-toggle-pub-info]');
// await fillIn('[data-test-title-input]', 'New Blog Title');
// await click('[data-test-button="save"]');
// expect(document.title, 'page title').to.equal('Settings - General - New Blog Title');
// CMD-S shortcut works
// -------------------------------------------------------------- //
await fillIn('[data-test-title-input]', 'CMD-S Test');
await keyDown('cmd+s');
// 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
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
let params = JSON.parse(lastRequest.requestBody);
expect(params.settings.findBy('key', 'title').value).to.equal('CMD-S Test');
});
// // CMD-S shortcut works
// // -------------------------------------------------------------- //
// await fillIn('[data-test-title-input]', 'CMD-S Test');
// await keyDown('cmd+s');
// // 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
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
// let params = JSON.parse(lastRequest.requestBody);
// expect(params.settings.findBy('key', 'title').value).to.equal('CMD-S Test');
// });
it('renders timezone selector correctly', async function () {
await visit('/settings/general');
await click('[data-test-toggle-timezone]');
// it('renders timezone selector correctly', async function () {
// await visit('/settings/general');
// 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(find('#timezone option:checked').textContent.trim()).to.equal('(GMT) UTC');
find('#timezone option[value="Africa/Cairo"]').selected = true;
// expect(findAll('#timezone option').length, 'available timezones').to.equal(66);
// expect(find('#timezone option:checked').textContent.trim()).to.equal('(GMT) UTC');
// find('#timezone option[value="Africa/Cairo"]').selected = true;
await triggerEvent('#timezone', 'change');
await click('[data-test-button="save"]');
expect(find('#timezone option:checked').textContent.trim()).to.equal('(GMT +2:00) Cairo, Egypt');
});
// await triggerEvent('#timezone', 'change');
// await click('[data-test-button="save"]');
// expect(find('#timezone option:checked').textContent.trim()).to.equal('(GMT +2:00) Cairo, Egypt');
// });
it('handles private blog settings correctly', async function () {
await visit('/settings/general');
// it('handles private blog settings correctly', async function () {
// await visit('/settings/general');
// handles private blog settings correctly
expect(find('[data-test-private-checkbox]').checked, 'isPrivate checkbox').to.be.false;
// // handles private blog settings correctly
// 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(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-private-checkbox]').checked, 'isPrivate checkbox').to.be.true;
// 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('');
await fillIn('[data-test-password-input]', '');
await blur('[data-test-password-input]');
// await fillIn('[data-test-password-input]', '');
// await blur('[data-test-password-input]');
expect(find('[data-test-password-error]').textContent.trim(), 'empty password error')
.to.equal('Password must be supplied');
// expect(find('[data-test-password-error]').textContent.trim(), 'empty password error')
// .to.equal('Password must be supplied');
await fillIn('[data-test-password-input]', 'asdfg');
await blur('[data-test-password-input]');
// await fillIn('[data-test-password-input]', 'asdfg');
// await blur('[data-test-password-input]');
expect(find('[data-test-password-error]').textContent.trim(), 'present password error')
.to.equal('');
});
// expect(find('[data-test-password-error]').textContent.trim(), 'present password error')
// .to.equal('');
// });
it('handles social blog settings correctly', async function () {
let testSocialInput = async function (type, input, expectedValue, expectedError = '') {
await fillIn(`[data-test-${type}-input]`, input);
await blur(`[data-test-${type}-input]`);
// it('handles social blog settings correctly', async function () {
// let testSocialInput = async function (type, input, expectedValue, expectedError = '') {
// await fillIn(`[data-test-${type}-input]`, input);
// await blur(`[data-test-${type}-input]`);
expect(
find(`[data-test-${type}-input]`).value,
`${type} value for ${input}`
).to.equal(expectedValue);
// expect(
// find(`[data-test-${type}-input]`).value,
// `${type} value for ${input}`
// ).to.equal(expectedValue);
expect(
find(`[data-test-${type}-error]`).textContent.trim(),
`${type} validation response for ${input}`
).to.equal(expectedError);
// expect(
// find(`[data-test-${type}-error]`).textContent.trim(),
// `${type} validation response for ${input}`
// ).to.equal(expectedError);
expect(
find(`[data-test-${type}-input]`).closest('.form-group').classList.contains('error'),
`${type} input should be in error state with '${input}'`
).to.equal(!!expectedError);
};
let testFacebookValidation = async (...args) => testSocialInput('facebook', ...args);
let testTwitterValidation = async (...args) => testSocialInput('twitter', ...args);
await visit('/settings/general');
await click('[data-test-toggle-social]');
// validates a facebook url correctly
// loads fixtures and performs transform
expect(find('[data-test-facebook-input]').value, 'initial facebook value')
.to.equal('https://www.facebook.com/test');
await focus('[data-test-facebook-input]');
await blur('[data-test-facebook-input]');
// expect(
// find(`[data-test-${type}-input]`).closest('.form-group').classList.contains('error'),
// `${type} input should be in error state with '${input}'`
// ).to.equal(!!expectedError);
// };
// let testFacebookValidation = async (...args) => testSocialInput('facebook', ...args);
// let testTwitterValidation = async (...args) => testSocialInput('twitter', ...args);
// await visit('/settings/general');
// await click('[data-test-toggle-social]');
// // validates a facebook url correctly
// // loads fixtures and performs transform
// expect(find('[data-test-facebook-input]').value, 'initial facebook value')
// .to.equal('https://www.facebook.com/test');
// await focus('[data-test-facebook-input]');
// await blur('[data-test-facebook-input]');
// regression test: we still have a value after the input is
// focused and then blurred without any changes
expect(find('[data-test-facebook-input]').value, 'facebook value after blur with no change')
.to.equal('https://www.facebook.com/test');
// // regression test: we still have a value after the input is
// // focused and then blurred without any changes
// expect(find('[data-test-facebook-input]').value, 'facebook value after blur with no change')
// .to.equal('https://www.facebook.com/test');
await testFacebookValidation(
'facebook.com/username',
'https://www.facebook.com/username');
// await testFacebookValidation(
// 'facebook.com/username',
// 'https://www.facebook.com/username');
await testFacebookValidation(
'testuser',
'https://www.facebook.com/testuser');
// await testFacebookValidation(
// 'testuser',
// 'https://www.facebook.com/testuser');
await testFacebookValidation(
'ab99',
'https://www.facebook.com/ab99');
// await testFacebookValidation(
// 'ab99',
// 'https://www.facebook.com/ab99');
await testFacebookValidation(
'page/ab99',
'https://www.facebook.com/page/ab99');
// await testFacebookValidation(
// 'page/ab99',
// 'https://www.facebook.com/page/ab99');
await testFacebookValidation(
'page/*(&*(%%))',
'https://www.facebook.com/page/*(&*(%%))');
// await testFacebookValidation(
// 'page/*(&*(%%))',
// 'https://www.facebook.com/page/*(&*(%%))');
await testFacebookValidation(
'facebook.com/pages/some-facebook-page/857469375913?ref=ts',
'https://www.facebook.com/pages/some-facebook-page/857469375913?ref=ts');
// await testFacebookValidation(
// 'facebook.com/pages/some-facebook-page/857469375913?ref=ts',
// 'https://www.facebook.com/pages/some-facebook-page/857469375913?ref=ts');
await testFacebookValidation(
'https://www.facebook.com/groups/savethecrowninn',
'https://www.facebook.com/groups/savethecrowninn');
// await testFacebookValidation(
// 'https://www.facebook.com/groups/savethecrowninn',
// 'https://www.facebook.com/groups/savethecrowninn');
await testFacebookValidation(
'http://github.com/username',
'http://github.com/username',
'The URL must be in a format like https://www.facebook.com/yourPage');
// await testFacebookValidation(
// 'http://github.com/username',
// 'http://github.com/username',
// 'The URL must be in a format like https://www.facebook.com/yourPage');
await testFacebookValidation(
'http://github.com/pages/username',
'http://github.com/pages/username',
'The URL must be in a format like https://www.facebook.com/yourPage');
// await testFacebookValidation(
// 'http://github.com/pages/username',
// 'http://github.com/pages/username',
// '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
expect(find('[data-test-twitter-input]').value, 'initial twitter value')
.to.equal('https://twitter.com/test');
// // loads fixtures and performs transform
// expect(find('[data-test-twitter-input]').value, 'initial twitter value')
// .to.equal('https://twitter.com/test');
await focus('[data-test-twitter-input]');
await blur('[data-test-twitter-input]');
// await focus('[data-test-twitter-input]');
// await blur('[data-test-twitter-input]');
// regression test: we still have a value after the input is
// focused and then blurred without any changes
expect(find('[data-test-twitter-input]').value, 'twitter value after blur with no change')
.to.equal('https://twitter.com/test');
// // regression test: we still have a value after the input is
// // focused and then blurred without any changes
// expect(find('[data-test-twitter-input]').value, 'twitter value after blur with no change')
// .to.equal('https://twitter.com/test');
await testTwitterValidation(
'twitter.com/username',
'https://twitter.com/username');
// await testTwitterValidation(
// 'twitter.com/username',
// 'https://twitter.com/username');
await testTwitterValidation(
'testuser',
'https://twitter.com/testuser');
// await testTwitterValidation(
// 'testuser',
// 'https://twitter.com/testuser');
await testTwitterValidation(
'http://github.com/username',
'https://twitter.com/username');
// await testTwitterValidation(
// 'http://github.com/username',
// 'https://twitter.com/username');
await testTwitterValidation(
'*(&*(%%))',
'*(&*(%%))',
'The URL must be in a format like https://twitter.com/yourUsername');
// await testTwitterValidation(
// '*(&*(%%))',
// '*(&*(%%))',
// 'The URL must be in a format like https://twitter.com/yourUsername');
await testTwitterValidation(
'thisusernamehasmorethan15characters',
'thisusernamehasmorethan15characters',
'Your Username is not a valid Twitter Username');
});
// await testTwitterValidation(
// 'thisusernamehasmorethan15characters',
// 'thisusernamehasmorethan15characters',
// 'Your Username is not a valid Twitter Username');
// });
it('warns when leaving without saving', async function () {
await visit('/settings/general');
// it('warns when leaving without saving', async function () {
// await visit('/settings/general');
expect(
find('[data-test-private-checkbox]').checked,
'private blog checkbox'
).to.be.false;
// expect(
// find('[data-test-private-checkbox]').checked,
// 'private blog checkbox'
// ).to.be.false;
await click('[data-test-toggle-pub-info]');
await fillIn('[data-test-title-input]', 'New Blog Title');
// await click('[data-test-toggle-pub-info]');
// await fillIn('[data-test-title-input]', 'New Blog Title');
await click('[data-test-private-checkbox]');
// await click('[data-test-private-checkbox]');
expect(
find('[data-test-private-checkbox]').checked,
'private blog checkbox'
).to.be.true;
// expect(
// find('[data-test-private-checkbox]').checked,
// 'private blog checkbox'
// ).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
await click('[data-test-leave-button]');
// // Leave without saving
// 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
expect(
find('[data-test-private-checkbox]').checked,
'private blog checkbox'
).to.be.false;
// // settings were not saved
// expect(
// find('[data-test-private-checkbox]').checked,
// 'private blog checkbox'
// ).to.be.false;
expect(
find('[data-test-title-input]').textContent.trim(),
'Blog title'
).to.equal('');
});
});
});
// expect(
// find('[data-test-title-input]').textContent.trim(),
// 'Blog title'
// ).to.equal('');
// });
// });
// });

View File

@ -1,512 +1,512 @@
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {beforeEach, describe, it} from 'mocha';
import {blur, click, currentRouteName, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {beforeEach, describe, it} from 'mocha';
// import {blur, click, currentRouteName, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Integrations - Custom', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Integrations - Custom', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
describe('access permissions', function () {
beforeEach(function () {
this.server.create('integration', {name: 'Test'});
});
// describe('access permissions', function () {
// beforeEach(function () {
// this.server.create('integration', {name: 'Test'});
// });
it('redirects /integrations/ to signin when not authenticated', async function () {
await invalidateSession();
await visit('/settings/integrations');
// it('redirects /integrations/ to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
let role = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects /integrations/ to home page when authenticated as contributor', async function () {
// let role = this.server.create('role', {name: 'Contributor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Author'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects /integrations/ to home page when authenticated as author', async function () {
// let role = this.server.create('role', {name: 'Author'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Editor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects /integrations/ to home page when authenticated as editor', async function () {
// let role = this.server.create('role', {name: 'Editor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/1');
// await authenticateSession();
// 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 () {
await invalidateSession();
await visit('/settings/integrations/1');
// it('redirects /integrations/:id/ to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
let role = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects /integrations/:id/ to home page when authenticated as contributor', async function () {
// let role = this.server.create('role', {name: 'Contributor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/1');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Author'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects /integrations/:id/ to home page when authenticated as author', async function () {
// let role = this.server.create('role', {name: 'Author'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/1');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Editor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects /integrations/:id/ to home page when authenticated as editor', async function () {
// let role = this.server.create('role', {name: 'Editor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/1');
// await authenticateSession();
// await visit('/settings/integrations/1');
expect(currentURL(), 'currentURL').to.equal('/site');
});
});
// expect(currentURL(), 'currentURL').to.equal('/site');
// });
// });
describe('navigation', function () {
beforeEach(async function () {
this.server.loadFixtures('settings');
// describe('navigation', function () {
// beforeEach(async function () {
// this.server.loadFixtures('settings');
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it('renders defaults correctly', async function () {
await visit('/settings/integrations');
// it('renders defaults correctly', async function () {
// await visit('/settings/integrations');
// slack is not configured in the fixtures
expect(
find('[data-test-app="slack"] [data-test-app-status]').textContent.trim(),
'slack app status'
).to.equal('Configure');
// // slack is not configured in the fixtures
// expect(
// find('[data-test-app="slack"] [data-test-app-status]').textContent.trim(),
// 'slack app status'
// ).to.equal('Configure');
// amp is disabled in the fixtures
expect(
find('[data-test-app="amp"] [data-test-app-status]').textContent.trim(),
'amp app status'
).to.equal('Configure');
});
// // amp is disabled in the fixtures
// expect(
// find('[data-test-app="amp"] [data-test-app-status]').textContent.trim(),
// 'amp app status'
// ).to.equal('Configure');
// });
it('renders AMP active state', async function () {
this.server.db.settings.update({key: 'amp', value: true});
await visit('/settings/integrations');
// it('renders AMP active state', async function () {
// this.server.db.settings.update({key: 'amp', value: true});
// await visit('/settings/integrations');
// amp switches to active when enabled
expect(
find('[data-test-app="amp"] [data-test-app-status]').textContent.trim(),
'amp app status'
).to.equal('Active');
});
// // amp switches to active when enabled
// expect(
// find('[data-test-app="amp"] [data-test-app-status]').textContent.trim(),
// 'amp app status'
// ).to.equal('Active');
// });
it('it redirects to Slack when clicking on the grid', async function () {
await visit('/settings/integrations');
// it('it redirects to Slack when clicking on the grid', async function () {
// await visit('/settings/integrations');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
await click('[data-test-link="slack"]');
// await click('[data-test-link="slack"]');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
});
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
// });
it('it redirects to AMP when clicking on the grid', async function () {
await visit('/settings/integrations');
// it('it redirects to AMP when clicking on the grid', async function () {
// await visit('/settings/integrations');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
await click('[data-test-link="amp"]');
// await click('[data-test-link="amp"]');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
});
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/amp');
// });
it('it redirects to Unsplash when clicking on the grid', async function () {
await visit('/settings/integrations');
// it('it redirects to Unsplash when clicking on the grid', async function () {
// await visit('/settings/integrations');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations');
await click('[data-test-link="unsplash"]');
// await click('[data-test-link="unsplash"]');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
});
});
describe('custom integrations', function () {
beforeEach(async function () {
this.server.loadFixtures('configs');
let config = this.server.schema.configs.first();
config.update({
enableDeveloperExperiments: true
});
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
return await authenticateSession();
});
it('handles 404', async function () {
await visit('/settings/integrations/1');
expect(currentRouteName()).to.equal('error404');
});
it('can add new integration', async function () {
// sanity check
expect(
this.server.db.integrations.length,
'number of integrations in db at start'
).to.equal(0);
expect(
this.server.db.apiKeys.length,
'number of apiKeys in db at start'
).to.equal(0);
// blank slate
await visit('/settings/integrations');
expect(
find('[data-test-blank="custom-integrations"]'),
'initial blank slate'
).to.exist;
// new integration modal opens/closes
await click('[data-test-button="new-integration"]');
expect(currentURL(), 'url after clicking new').to.equal('/settings/integrations/new');
expect(find('[data-test-modal="new-integration"]'), 'modal after clicking new').to.exist;
await click('[data-test-button="cancel-new-integration"]');
expect(find('[data-test-modal="new-integration"]'), 'modal after clicking cancel')
.to.not.exist;
expect(
find('[data-test-blank="custom-integrations"]'),
'blank slate after cancelled creation'
).to.exist;
// new integration validations
await click('[data-test-button="new-integration"]');
await click('[data-test-button="create-integration"]');
expect(
find('[data-test-error="new-integration-name"]').textContent,
'name error after create with blank field'
).to.have.string('enter a name');
await fillIn('[data-test-input="new-integration-name"]', 'Duplicate');
await click('[data-test-button="create-integration"]');
expect(
find('[data-test-error="new-integration-name"]').textContent,
'name error after create with duplicate name'
).to.have.string('already been used');
// successful creation
await fillIn('[data-test-input="new-integration-name"]', 'Test');
expect(
find('[data-test-error="new-integration-name"]').textContent.trim(),
'name error after typing in field'
).to.be.empty;
await click('[data-test-button="create-integration"]');
expect(
find('[data-test-modal="new-integration"]'),
'modal after successful create'
).to.not.exist;
expect(
this.server.db.integrations.length,
'number of integrations in db after create'
).to.equal(1);
// mirage sanity check
expect(
this.server.db.apiKeys.length,
'number of api keys in db after create'
).to.equal(2);
expect(
currentURL(),
'url after integration creation'
).to.equal('/settings/integrations/1');
// test navigation back to list then back to new integration
await click('[data-test-link="integrations-back"]');
expect(
currentURL(),
'url after clicking "Back"'
).to.equal('/settings/integrations');
expect(
find('[data-test-blank="custom-integrations"]'),
'blank slate after creation'
).to.not.exist;
expect(
findAll('[data-test-custom-integration]').length,
'number of custom integrations after creation'
).to.equal(1);
await click(`[data-test-integration="1"]`);
expect(
currentURL(),
'url after clicking integration in list'
).to.equal('/settings/integrations/1');
});
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
// });
// });
// describe('custom integrations', function () {
// beforeEach(async function () {
// this.server.loadFixtures('configs');
// let config = this.server.schema.configs.first();
// config.update({
// enableDeveloperExperiments: true
// });
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
// return await authenticateSession();
// });
// it('handles 404', async function () {
// await visit('/settings/integrations/1');
// expect(currentRouteName()).to.equal('error404');
// });
// it('can add new integration', async function () {
// // sanity check
// expect(
// this.server.db.integrations.length,
// 'number of integrations in db at start'
// ).to.equal(0);
// expect(
// this.server.db.apiKeys.length,
// 'number of apiKeys in db at start'
// ).to.equal(0);
// // blank slate
// await visit('/settings/integrations');
// expect(
// find('[data-test-blank="custom-integrations"]'),
// 'initial blank slate'
// ).to.exist;
// // new integration modal opens/closes
// await click('[data-test-button="new-integration"]');
// expect(currentURL(), 'url after clicking new').to.equal('/settings/integrations/new');
// expect(find('[data-test-modal="new-integration"]'), 'modal after clicking new').to.exist;
// await click('[data-test-button="cancel-new-integration"]');
// expect(find('[data-test-modal="new-integration"]'), 'modal after clicking cancel')
// .to.not.exist;
// expect(
// find('[data-test-blank="custom-integrations"]'),
// 'blank slate after cancelled creation'
// ).to.exist;
// // new integration validations
// await click('[data-test-button="new-integration"]');
// await click('[data-test-button="create-integration"]');
// expect(
// find('[data-test-error="new-integration-name"]').textContent,
// 'name error after create with blank field'
// ).to.have.string('enter a name');
// await fillIn('[data-test-input="new-integration-name"]', 'Duplicate');
// await click('[data-test-button="create-integration"]');
// expect(
// find('[data-test-error="new-integration-name"]').textContent,
// 'name error after create with duplicate name'
// ).to.have.string('already been used');
// // successful creation
// await fillIn('[data-test-input="new-integration-name"]', 'Test');
// expect(
// find('[data-test-error="new-integration-name"]').textContent.trim(),
// 'name error after typing in field'
// ).to.be.empty;
// await click('[data-test-button="create-integration"]');
// expect(
// find('[data-test-modal="new-integration"]'),
// 'modal after successful create'
// ).to.not.exist;
// expect(
// this.server.db.integrations.length,
// 'number of integrations in db after create'
// ).to.equal(1);
// // mirage sanity check
// expect(
// this.server.db.apiKeys.length,
// 'number of api keys in db after create'
// ).to.equal(2);
// expect(
// currentURL(),
// 'url after integration creation'
// ).to.equal('/settings/integrations/1');
// // test navigation back to list then back to new integration
// await click('[data-test-link="integrations-back"]');
// expect(
// currentURL(),
// 'url after clicking "Back"'
// ).to.equal('/settings/integrations');
// expect(
// find('[data-test-blank="custom-integrations"]'),
// 'blank slate after creation'
// ).to.not.exist;
// expect(
// findAll('[data-test-custom-integration]').length,
// 'number of custom integrations after creation'
// ).to.equal(1);
// await click(`[data-test-integration="1"]`);
// expect(
// currentURL(),
// 'url after clicking integration in list'
// ).to.equal('/settings/integrations/1');
// });
it('can manage an integration', async function () {
this.server.create('integration');
// it('can manage an integration', async function () {
// this.server.create('integration');
await visit('/settings/integrations/1');
// await visit('/settings/integrations/1');
expect(
currentURL(),
'initial URL'
).to.equal('/settings/integrations/1');
// expect(
// currentURL(),
// 'initial URL'
// ).to.equal('/settings/integrations/1');
expect(
find('[data-test-screen-title]').textContent,
'screen title'
).to.have.string('Integration 1');
// expect(
// find('[data-test-screen-title]').textContent,
// 'screen title'
// ).to.have.string('Integration 1');
// fields have expected values
// TODO: add test for logo
expect(
find('[data-test-input="name"]').value,
'initial name value'
).to.equal('Integration 1');
expect(
find('[data-test-input="description"]').value,
'initial description value'
).to.equal('');
expect(
find('[data-test-text="content-key"]'),
'content key text'
).to.have.trimmed.text('integration-1_content_key-12345');
expect(
find('[data-test-text="admin-key"]'),
'admin key text'
).to.have.trimmed.text('integration-1_admin_key-12345');
expect(
find('[data-test-text="api-url"]'),
'api url text'
).to.have.trimmed.text(window.location.origin);
// it can modify integration fields and has validation
expect(
find('[data-test-error="name"]').textContent.trim(),
'initial name error'
).to.be.empty;
await fillIn('[data-test-input="name"]', '');
await await blur('[data-test-input="name"]');
expect(
find('[data-test-error="name"]').textContent,
'name validation for blank string'
).to.have.string('enter a name');
await click('[data-test-button="save"]');
expect(
this.server.schema.integrations.first().name,
'db integration name after failed save'
).to.equal('Integration 1');
await fillIn('[data-test-input="name"]', 'Test Integration');
await await blur('[data-test-input="name"]');
expect(
find('[data-test-error="name"]').textContent.trim(),
'name error after valid entry'
).to.be.empty;
await fillIn('[data-test-input="description"]', 'Description for Test Integration');
await await blur('[data-test-input="description"]');
await click('[data-test-button="save"]');
// changes are reflected in the integrations list
await click('[data-test-link="integrations-back"]');
expect(
currentURL(),
'url after saving and clicking "back"'
).to.equal('/settings/integrations');
expect(
find('[data-test-integration="1"] [data-test-text="name"]').textContent.trim(),
'integration name after save'
).to.equal('Test Integration');
expect(
find('[data-test-integration="1"] [data-test-text="description"]').textContent.trim(),
'integration description after save'
).to.equal('Description for Test Integration');
await click('[data-test-integration="1"]');
// warns of unsaved changes when leaving
await fillIn('[data-test-input="name"]', 'Unsaved test');
await click('[data-test-link="integrations-back"]');
expect(
find('[data-test-modal="unsaved-settings"]'),
'modal shown when navigating with unsaved changes'
).to.exist;
await click('[data-test-stay-button]');
expect(
find('[data-test-modal="unsaved-settings"]'),
'modal is closed after clicking "stay"'
).to.not.exist;
expect(
currentURL(),
'url after clicking "stay"'
).to.equal('/settings/integrations/1');
await click('[data-test-link="integrations-back"]');
await click('[data-test-leave-button]');
expect(
find('[data-test-modal="unsaved-settings"]'),
'modal is closed after clicking "leave"'
).to.not.exist;
expect(
currentURL(),
'url after clicking "leave"'
).to.equal('/settings/integrations');
expect(
find('[data-test-integration="1"] [data-test-text="name"]').textContent.trim(),
'integration name after leaving unsaved changes'
).to.equal('Test Integration');
});
it('can manage an integration\'s webhooks', async function () {
this.server.create('integration');
await visit('/settings/integrations/1');
expect(find('[data-test-webhooks-blank-slate]')).to.exist;
// open new webhook modal
await click('[data-test-link="add-webhook"]');
expect(find('[data-test-modal="webhook-form"]')).to.exist;
expect(find('[data-test-modal="webhook-form"] [data-test-text="title"]').textContent)
.to.have.string('New webhook');
// can cancel new webhook
await click('[data-test-button="cancel-webhook"]');
expect(find('[data-test-modal="webhook-form"]')).to.not.exist;
// create new webhook
await click('[data-test-link="add-webhook"]');
await fillIn('[data-test-input="webhook-name"]', 'First webhook');
await fillIn('[data-test-select="webhook-event"]', 'site.changed');
await fillIn('[data-test-input="webhook-targetUrl"]', 'https://example.com/first-webhook');
await click('[data-test-button="save-webhook"]');
// modal closed and 1 webhook listed with correct details
expect(find('[data-test-modal="webhook-form"]')).to.not.exist;
expect(find('[data-test-webhook-row]')).to.exist;
let row = find('[data-test-webhook-row="1"]');
expect(row.querySelector('[data-test-text="name"]').textContent)
.to.have.string('First webhook');
expect(row.querySelector('[data-test-text="event"]').textContent)
.to.have.string('Site changed (rebuild)');
expect(row.querySelector('[data-test-text="targetUrl"]').textContent)
.to.have.string('https://example.com/first-webhook');
expect(row.querySelector('[data-test-text="last-triggered"]').textContent)
.to.have.string('Not triggered');
// click edit webhook link
await click('[data-test-webhook-row="1"] [data-test-newsletter-menu-trigger]');
await click('[data-test-link="edit-webhook"]');
// modal appears and has correct title
expect(find('[data-test-modal="webhook-form"]')).to.exist;
expect(find('[data-test-modal="webhook-form"] [data-test-text="title"]').textContent)
.to.have.string('Edit webhook');
});
// 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 () {
this.server.create('integration');
await visit('/settings/integrations/1');
await click('[data-test-input="description"]');
await blur('[data-test-input="description"]');
await click('[data-test-link="integrations-back"]');
expect(
find('[data-test-modal="unsaved-settings"]'),
'unsaved changes modal is not shown'
).to.not.exist;
expect(currentURL()).to.equal('/settings/integrations');
});
it('can delete integration', async function () {
this.server.create('integration');
await visit('/settings/integrations/1');
await click('[data-test-button="delete-integration"]');
expect(find('[data-test-modal="delete-integration"]')).to.exist;
await click('[data-test-modal="delete-integration"] [data-test-button="confirm"]');
expect(find('[data-test-modal="delete-integration"]')).to.not.exist;
expect(currentURL()).to.equal('/settings/integrations');
expect(find('[data-test-custom-integration]')).to.not.exist;
});
});
});
// // fields have expected values
// // TODO: add test for logo
// expect(
// find('[data-test-input="name"]').value,
// 'initial name value'
// ).to.equal('Integration 1');
// expect(
// find('[data-test-input="description"]').value,
// 'initial description value'
// ).to.equal('');
// expect(
// find('[data-test-text="content-key"]'),
// 'content key text'
// ).to.have.trimmed.text('integration-1_content_key-12345');
// expect(
// find('[data-test-text="admin-key"]'),
// 'admin key text'
// ).to.have.trimmed.text('integration-1_admin_key-12345');
// expect(
// find('[data-test-text="api-url"]'),
// 'api url text'
// ).to.have.trimmed.text(window.location.origin);
// // it can modify integration fields and has validation
// expect(
// find('[data-test-error="name"]').textContent.trim(),
// 'initial name error'
// ).to.be.empty;
// await fillIn('[data-test-input="name"]', '');
// await await blur('[data-test-input="name"]');
// expect(
// find('[data-test-error="name"]').textContent,
// 'name validation for blank string'
// ).to.have.string('enter a name');
// await click('[data-test-button="save"]');
// expect(
// this.server.schema.integrations.first().name,
// 'db integration name after failed save'
// ).to.equal('Integration 1');
// await fillIn('[data-test-input="name"]', 'Test Integration');
// await await blur('[data-test-input="name"]');
// expect(
// find('[data-test-error="name"]').textContent.trim(),
// 'name error after valid entry'
// ).to.be.empty;
// await fillIn('[data-test-input="description"]', 'Description for Test Integration');
// await await blur('[data-test-input="description"]');
// await click('[data-test-button="save"]');
// // changes are reflected in the integrations list
// await click('[data-test-link="integrations-back"]');
// expect(
// currentURL(),
// 'url after saving and clicking "back"'
// ).to.equal('/settings/integrations');
// expect(
// find('[data-test-integration="1"] [data-test-text="name"]').textContent.trim(),
// 'integration name after save'
// ).to.equal('Test Integration');
// expect(
// find('[data-test-integration="1"] [data-test-text="description"]').textContent.trim(),
// 'integration description after save'
// ).to.equal('Description for Test Integration');
// await click('[data-test-integration="1"]');
// // warns of unsaved changes when leaving
// await fillIn('[data-test-input="name"]', 'Unsaved test');
// await click('[data-test-link="integrations-back"]');
// expect(
// find('[data-test-modal="unsaved-settings"]'),
// 'modal shown when navigating with unsaved changes'
// ).to.exist;
// await click('[data-test-stay-button]');
// expect(
// find('[data-test-modal="unsaved-settings"]'),
// 'modal is closed after clicking "stay"'
// ).to.not.exist;
// expect(
// currentURL(),
// 'url after clicking "stay"'
// ).to.equal('/settings/integrations/1');
// await click('[data-test-link="integrations-back"]');
// await click('[data-test-leave-button]');
// expect(
// find('[data-test-modal="unsaved-settings"]'),
// 'modal is closed after clicking "leave"'
// ).to.not.exist;
// expect(
// currentURL(),
// 'url after clicking "leave"'
// ).to.equal('/settings/integrations');
// expect(
// find('[data-test-integration="1"] [data-test-text="name"]').textContent.trim(),
// 'integration name after leaving unsaved changes'
// ).to.equal('Test Integration');
// });
// it('can manage an integration\'s webhooks', async function () {
// this.server.create('integration');
// await visit('/settings/integrations/1');
// expect(find('[data-test-webhooks-blank-slate]')).to.exist;
// // open new webhook modal
// await click('[data-test-link="add-webhook"]');
// expect(find('[data-test-modal="webhook-form"]')).to.exist;
// expect(find('[data-test-modal="webhook-form"] [data-test-text="title"]').textContent)
// .to.have.string('New webhook');
// // can cancel new webhook
// await click('[data-test-button="cancel-webhook"]');
// expect(find('[data-test-modal="webhook-form"]')).to.not.exist;
// // create new webhook
// await click('[data-test-link="add-webhook"]');
// await fillIn('[data-test-input="webhook-name"]', 'First webhook');
// await fillIn('[data-test-select="webhook-event"]', 'site.changed');
// await fillIn('[data-test-input="webhook-targetUrl"]', 'https://example.com/first-webhook');
// await click('[data-test-button="save-webhook"]');
// // modal closed and 1 webhook listed with correct details
// expect(find('[data-test-modal="webhook-form"]')).to.not.exist;
// expect(find('[data-test-webhook-row]')).to.exist;
// let row = find('[data-test-webhook-row="1"]');
// expect(row.querySelector('[data-test-text="name"]').textContent)
// .to.have.string('First webhook');
// expect(row.querySelector('[data-test-text="event"]').textContent)
// .to.have.string('Site changed (rebuild)');
// expect(row.querySelector('[data-test-text="targetUrl"]').textContent)
// .to.have.string('https://example.com/first-webhook');
// expect(row.querySelector('[data-test-text="last-triggered"]').textContent)
// .to.have.string('Not triggered');
// // click edit webhook link
// await click('[data-test-webhook-row="1"] [data-test-newsletter-menu-trigger]');
// await click('[data-test-link="edit-webhook"]');
// // modal appears and has correct title
// expect(find('[data-test-modal="webhook-form"]')).to.exist;
// expect(find('[data-test-modal="webhook-form"] [data-test-text="title"]').textContent)
// .to.have.string('Edit webhook');
// });
// // 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 () {
// this.server.create('integration');
// await visit('/settings/integrations/1');
// await click('[data-test-input="description"]');
// await blur('[data-test-input="description"]');
// await click('[data-test-link="integrations-back"]');
// expect(
// find('[data-test-modal="unsaved-settings"]'),
// 'unsaved changes modal is not shown'
// ).to.not.exist;
// expect(currentURL()).to.equal('/settings/integrations');
// });
// it('can delete integration', async function () {
// this.server.create('integration');
// await visit('/settings/integrations/1');
// await click('[data-test-button="delete-integration"]');
// expect(find('[data-test-modal="delete-integration"]')).to.exist;
// await click('[data-test-modal="delete-integration"] [data-test-button="confirm"]');
// expect(find('[data-test-modal="delete-integration"]')).to.not.exist;
// expect(currentURL()).to.equal('/settings/integrations');
// expect(find('[data-test-custom-integration]')).to.not.exist;
// });
// });
// });

View File

@ -1,339 +1,338 @@
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {beforeEach, describe, it} from 'mocha';
import {click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
import {expect} from 'chai';
import {fileUpload} from '../../helpers/file-upload';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {beforeEach, describe, it} from 'mocha';
// import {click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {fileUpload} from '../../helpers/file-upload';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Labs', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Labs', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
it('redirects to signin when not authenticated', async function () {
await invalidateSession();
await visit('/settings/labs');
// it('redirects to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
let role = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as contributor', async function () {
// let role = this.server.create('role', {name: 'Contributor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/labs');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Author'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as author', async function () {
// let role = this.server.create('role', {name: 'Author'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/labs');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Editor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as editor', async function () {
// let role = this.server.create('role', {name: 'Editor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/labs');
// await authenticateSession();
// await visit('/settings/labs');
expect(currentURL(), 'currentURL').to.equal('/site');
});
// expect(currentURL(), 'currentURL').to.equal('/site');
// });
describe('when logged in', function () {
beforeEach(async function () {
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// describe('when logged in', function () {
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it('it renders', async function () {
await visit('/settings/labs');
// it('it renders', async function () {
// await visit('/settings/labs');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/labs');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/labs');
// has correct page title
expect(document.title, 'page title').to.equal('Settings - Labs - Test Blog');
// // has correct page title
// expect(document.title, 'page title').to.equal('Settings - Labs - Test Blog');
// highlights nav menu
expect(find('[data-test-nav="settings"]'), 'highlights nav menu item')
.to.have.class('active');
});
// // highlights nav menu
// expect(find('[data-test-nav="settings"]'), 'highlights nav menu item')
// .to.have.class('active');
// });
it('can delete all content', async function () {
await visit('/settings/labs');
await click('[data-test-button="delete-all"]');
// it('can delete all content', async function () {
// await visit('/settings/labs');
// await click('[data-test-button="delete-all"]');
const modal = '[data-test-modal="confirm-delete-all"]';
expect(find(modal)).to.exist;
// const modal = '[data-test-modal="confirm-delete-all"]';
// expect(find(modal)).to.exist;
await click(`${modal} [data-test-button="confirm"]`);
// await click(`${modal} [data-test-button="confirm"]`);
// API request is correct
const [lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.url).to.equal('/ghost/api/admin/db/');
expect(lastRequest.method).to.equal('DELETE');
// // API request is correct
// const [lastRequest] = this.server.pretender.handledRequests.slice(-1);
// expect(lastRequest.url).to.equal('/ghost/api/admin/db/');
// 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 () {
await visit('/settings/labs');
// it('can upload/download redirects', async function () {
// await visit('/settings/labs');
// successful upload
this.server.post('/redirects/upload/', {}, 200);
// // successful upload
// this.server.post('/redirects/upload/', {}, 200);
await fileUpload(
'[data-test-file-input="redirects"] input',
['test'],
{name: 'redirects.json', type: 'application/json'}
);
// await fileUpload(
// '[data-test-file-input="redirects"] input',
// ['test'],
// {name: 'redirects.json', type: 'application/json'}
// );
// TODO: tests for the temporary success/failure state have been
// disabled because they were randomly failing
// // TODO: tests for the temporary success/failure state have been
// // disabled because they were randomly failing
// this should be half-way through button reset timeout
// await timeout(50);
//
// // shows success button
// let buttons = findAll('[data-test-button="upload-redirects"]');
// expect(buttons.length, 'no of success buttons').to.equal(1);
// expect(
// buttons[0],
// 'success button is green'
// ).to.have.class('gh-btn-green);
// expect(
// button.textContent,
// 'success button text'
// ).to.have.string('Uploaded');
//
// await wait();
// // this should be half-way through button reset timeout
// // await timeout(50);
// //
// // // shows success button
// // let buttons = findAll('[data-test-button="upload-redirects"]');
// // expect(buttons.length, 'no of success buttons').to.equal(1);
// // expect(
// // buttons[0],
// // 'success button is green'
// // ).to.have.class('gh-btn-green);
// // expect(
// // button.textContent,
// // 'success button text'
// // ).to.have.string('Uploaded');
// //
// // await wait();
// returned to normal button
let buttons = findAll('[data-test-button="upload-redirects"]');
expect(buttons.length, 'no of post-success buttons').to.equal(1);
expect(
buttons[0],
'post-success button doesn\'t have success class'
).to.not.have.class('gh-btn-green');
expect(
buttons[0].textContent,
'post-success button text'
).to.have.string('Upload redirects');
// // returned to normal button
// let buttons = findAll('[data-test-button="upload-redirects"]');
// expect(buttons.length, 'no of post-success buttons').to.equal(1);
// expect(
// buttons[0],
// 'post-success button doesn\'t have success class'
// ).to.not.have.class('gh-btn-green');
// expect(
// buttons[0].textContent,
// 'post-success button text'
// ).to.have.string('Upload redirects');
// failed upload
this.server.post('/redirects/upload/', {
errors: [{
type: 'BadRequestError',
message: 'Test failure message'
}]
}, 400);
// // failed upload
// this.server.post('/redirects/upload/', {
// errors: [{
// type: 'BadRequestError',
// message: 'Test failure message'
// }]
// }, 400);
await fileUpload(
'[data-test-file-input="redirects"] input',
['test'],
{name: 'redirects-bad.json', type: 'application/json'}
);
// await fileUpload(
// '[data-test-file-input="redirects"] input',
// ['test'],
// {name: 'redirects-bad.json', type: 'application/json'}
// );
// TODO: tests for the temporary success/failure state have been
// disabled because they were randomly failing
// // TODO: tests for the temporary success/failure state have been
// // disabled because they were randomly failing
// this should be half-way through button reset timeout
// await timeout(50);
//
// shows failure button
// buttons = findAll('[data-test-button="upload-redirects"]');
// expect(buttons.length, 'no of failure buttons').to.equal(1);
// expect(
// buttons[0],
// 'failure button is red'
// ).to.have.class('gh-btn-red);
// expect(
// buttons[0].textContent,
// 'failure button text'
// ).to.have.string('Upload Failed');
//
// await wait();
// // this should be half-way through button reset timeout
// // await timeout(50);
// //
// // shows failure button
// // buttons = findAll('[data-test-button="upload-redirects"]');
// // expect(buttons.length, 'no of failure buttons').to.equal(1);
// // expect(
// // buttons[0],
// // 'failure button is red'
// // ).to.have.class('gh-btn-red);
// // expect(
// // buttons[0].textContent,
// // 'failure button text'
// // ).to.have.string('Upload Failed');
// //
// // await wait();
// shows error message
expect(
find('[data-test-error="redirects"]').textContent.trim(),
'upload error text'
).to.have.string('Test failure message');
// // shows error message
// expect(
// find('[data-test-error="redirects"]').textContent.trim(),
// 'upload error text'
// ).to.have.string('Test failure message');
// returned to normal button
buttons = findAll('[data-test-button="upload-redirects"]');
expect(buttons.length, 'no of post-failure buttons').to.equal(1);
expect(
buttons[0],
'post-failure button doesn\'t have failure class'
).to.not.have.class('gh-btn-red');
expect(
buttons[0].textContent,
'post-failure button text'
).to.have.string('Upload redirects');
// // returned to normal button
// buttons = findAll('[data-test-button="upload-redirects"]');
// expect(buttons.length, 'no of post-failure buttons').to.equal(1);
// expect(
// buttons[0],
// 'post-failure button doesn\'t have failure class'
// ).to.not.have.class('gh-btn-red');
// expect(
// buttons[0].textContent,
// 'post-failure button text'
// ).to.have.string('Upload redirects');
// successful upload clears error
this.server.post('/redirects/upload/', {}, 200);
await fileUpload(
'[data-test-file-input="redirects"] input',
['test'],
{name: 'redirects-bad.json', type: 'application/json'}
);
// // successful upload clears error
// this.server.post('/redirects/upload/', {}, 200);
// await fileUpload(
// '[data-test-file-input="redirects"] input',
// ['test'],
// {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
await click('[data-test-link="download-redirects"]');
// // can download redirects.json
// await click('[data-test-link="download-redirects"]');
let iframe = document.querySelector('#iframeDownload');
expect(iframe.getAttribute('src')).to.have.string('/redirects/download/');
});
// let iframe = document.querySelector('#iframeDownload');
// expect(iframe.getAttribute('src')).to.have.string('/redirects/download/');
// });
it('can upload/download routes.yaml', async function () {
await visit('/settings/labs');
// it('can upload/download routes.yaml', async function () {
// await visit('/settings/labs');
// successful upload
this.server.post('/settings/routes/yaml/', {}, 200);
// // successful upload
// this.server.post('/settings/routes/yaml/', {}, 200);
await fileUpload(
'[data-test-file-input="routes"] input',
['test'],
{name: 'routes.yaml', type: 'application/x-yaml'}
);
// await fileUpload(
// '[data-test-file-input="routes"] input',
// ['test'],
// {name: 'routes.yaml', type: 'application/x-yaml'}
// );
// TODO: tests for the temporary success/failure state have been
// disabled because they were randomly failing
// // TODO: tests for the temporary success/failure state have been
// // disabled because they were randomly failing
// this should be half-way through button reset timeout
// await timeout(50);
//
// // shows success button
// let button = find('[data-test-button="upload-routes"]');
// expect(button.length, 'no of success buttons').to.equal(1);
// expect(
// button.hasClass('gh-btn-green'),
// 'success button is green'
// ).to.be.true;
// expect(
// button.text().trim(),
// 'success button text'
// ).to.have.string('Uploaded');
//
// await wait();
// // this should be half-way through button reset timeout
// // await timeout(50);
// //
// // // shows success button
// // let button = find('[data-test-button="upload-routes"]');
// // expect(button.length, 'no of success buttons').to.equal(1);
// // expect(
// // button.hasClass('gh-btn-green'),
// // 'success button is green'
// // ).to.be.true;
// // expect(
// // button.text().trim(),
// // 'success button text'
// // ).to.have.string('Uploaded');
// //
// // await wait();
// returned to normal button
let buttons = findAll('[data-test-button="upload-routes"]');
expect(buttons.length, 'no of post-success buttons').to.equal(1);
expect(
buttons[0],
'routes post-success button doesn\'t have success class'
).to.not.have.class('gh-btn-green');
expect(
buttons[0].textContent,
'routes post-success button text'
).to.have.string('Upload routes YAML');
// // returned to normal button
// let buttons = findAll('[data-test-button="upload-routes"]');
// expect(buttons.length, 'no of post-success buttons').to.equal(1);
// expect(
// buttons[0],
// 'routes post-success button doesn\'t have success class'
// ).to.not.have.class('gh-btn-green');
// expect(
// buttons[0].textContent,
// 'routes post-success button text'
// ).to.have.string('Upload routes YAML');
// failed upload
this.server.post('/settings/routes/yaml/', {
errors: [{
type: 'BadRequestError',
message: 'Test failure message'
}]
}, 400);
// // failed upload
// this.server.post('/settings/routes/yaml/', {
// errors: [{
// type: 'BadRequestError',
// message: 'Test failure message'
// }]
// }, 400);
await fileUpload(
'[data-test-file-input="routes"] input',
['test'],
{name: 'routes-bad.yaml', type: 'application/x-yaml'}
);
// await fileUpload(
// '[data-test-file-input="routes"] input',
// ['test'],
// {name: 'routes-bad.yaml', type: 'application/x-yaml'}
// );
// TODO: tests for the temporary success/failure state have been
// disabled because they were randomly failing
// // TODO: tests for the temporary success/failure state have been
// // disabled because they were randomly failing
// this should be half-way through button reset timeout
// await timeout(50);
//
// shows failure button
// button = find('[data-test-button="upload-routes"]');
// expect(button.length, 'no of failure buttons').to.equal(1);
// expect(
// button.hasClass('gh-btn-red'),
// 'failure button is red'
// ).to.be.true;
// expect(
// button.text().trim(),
// 'failure button text'
// ).to.have.string('Upload Failed');
//
// await wait();
// // this should be half-way through button reset timeout
// // await timeout(50);
// //
// // shows failure button
// // button = find('[data-test-button="upload-routes"]');
// // expect(button.length, 'no of failure buttons').to.equal(1);
// // expect(
// // button.hasClass('gh-btn-red'),
// // 'failure button is red'
// // ).to.be.true;
// // expect(
// // button.text().trim(),
// // 'failure button text'
// // ).to.have.string('Upload Failed');
// //
// // await wait();
// shows error message
expect(
find('[data-test-error="routes"]').textContent,
'routes upload error text'
).to.have.string('Test failure message');
// // shows error message
// expect(
// find('[data-test-error="routes"]').textContent,
// 'routes upload error text'
// ).to.have.string('Test failure message');
// returned to normal button
buttons = findAll('[data-test-button="upload-routes"]');
expect(buttons.length, 'no of post-failure buttons').to.equal(1);
expect(
buttons[0],
'routes post-failure button doesn\'t have failure class'
).to.not.have.class('gh-btn-red');
expect(
buttons[0].textContent,
'routes post-failure button text'
).to.have.string('Upload routes YAML');
// // returned to normal button
// buttons = findAll('[data-test-button="upload-routes"]');
// expect(buttons.length, 'no of post-failure buttons').to.equal(1);
// expect(
// buttons[0],
// 'routes post-failure button doesn\'t have failure class'
// ).to.not.have.class('gh-btn-red');
// expect(
// buttons[0].textContent,
// 'routes post-failure button text'
// ).to.have.string('Upload routes YAML');
// successful upload clears error
this.server.post('/settings/routes/yaml/', {}, 200);
await fileUpload(
'[data-test-file-input="routes"] input',
['test'],
{name: 'routes-good.yaml', type: 'application/x-yaml'}
);
// // successful upload clears error
// this.server.post('/settings/routes/yaml/', {}, 200);
// await fileUpload(
// '[data-test-file-input="routes"] input',
// ['test'],
// {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
await click('[data-test-link="download-routes"]');
// // can download redirects.json
// await click('[data-test-link="download-routes"]');
let iframe = document.querySelector('#iframeDownload');
expect(iframe.getAttribute('src')).to.have.string('/settings/routes/yaml/');
});
});
// let iframe = document.querySelector('#iframeDownload');
// expect(iframe.getAttribute('src')).to.have.string('/settings/routes/yaml/');
// });
describe('When logged in as Owner', function () {
beforeEach(async function () {
let role = this.server.create('role', {name: 'Owner'});
this.server.create('user', {roles: [role]});
// describe('When logged in as Owner', function () {
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Owner'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it.skip('sets the mailgunBaseUrl to the default', async function () {
await visit('/settings/members');
// it.skip('sets the mailgunBaseUrl to the default', async function () {
// await visit('/settings/members');
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-api-key-input]', 'i_am_an_api_key');
// 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 params = JSON.parse(lastRequest.requestBody);
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
// 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);
// });
// });
// });

View File

@ -1,292 +1,292 @@
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {blur, click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Membership', function () {
const hooks = setupApplicationTest();
setupMirage(hooks);
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {blur, click, currentURL, fillIn, find, findAll} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
// describe('Acceptance: Settings - Membership', function () {
// const hooks = setupApplicationTest();
// setupMirage(hooks);
beforeEach(function () {
});
// beforeEach(function () {
// });
beforeEach(async function () {
this.server.loadFixtures('configs');
this.server.loadFixtures('tiers');
// beforeEach(async function () {
// this.server.loadFixtures('configs');
// this.server.loadFixtures('tiers');
this.server.db.configs.update(1, {blogUrl: 'http://localhost:2368'});
const role = this.server.create('role', {name: 'Owner'});
this.server.create('user', {roles: [role]});
// this.server.db.configs.update(1, {blogUrl: 'http://localhost:2368'});
// const role = this.server.create('role', {name: 'Owner'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
describe('permissions', function () {
let visitAs;
// describe('permissions', function () {
// let visitAs;
before(function () {
visitAs = async (roleName) => {
const role = this.server.create('role', {name: roleName});
this.server.create('user', {roles: [role]});
await authenticateSession();
await visit('/settings/members');
};
});
// before(function () {
// visitAs = async (roleName) => {
// const role = this.server.create('role', {name: roleName});
// this.server.create('user', {roles: [role]});
// await authenticateSession();
// await visit('/settings/members');
// };
// });
beforeEach(async function () {
this.server.db.users.remove();
await invalidateSession();
});
// beforeEach(async function () {
// this.server.db.users.remove();
// await invalidateSession();
// });
it('allows Owners', async function () {
await visitAs('Owner');
expect(currentURL()).to.equal('/settings/members');
});
// it('allows Owners', async function () {
// await visitAs('Owner');
// expect(currentURL()).to.equal('/settings/members');
// });
it('allows Administrators', async function () {
await visitAs('Administrator');
expect(currentURL()).to.equal('/settings/members');
});
// it('allows Administrators', async function () {
// await visitAs('Administrator');
// expect(currentURL()).to.equal('/settings/members');
// });
it('disallows Editors', async function () {
await visitAs('Editor');
expect(currentURL()).to.not.equal('/settings/members');
});
// it('disallows Editors', async function () {
// await visitAs('Editor');
// expect(currentURL()).to.not.equal('/settings/members');
// });
it('disallows Authors', async function () {
await visitAs('Author');
expect(currentURL()).to.not.equal('/settings/members');
});
// it('disallows Authors', async function () {
// await visitAs('Author');
// expect(currentURL()).to.not.equal('/settings/members');
// });
it('disallows Contributors', async function () {
await visitAs('Contributor');
expect(currentURL()).to.not.equal('/settings/members');
});
});
// it('disallows Contributors', async function () {
// await visitAs('Contributor');
// expect(currentURL()).to.not.equal('/settings/members');
// });
// });
it('can change subscription access', async function () {
await visit('/settings/members');
// it('can change subscription access', async function () {
// await visit('/settings/members');
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-iframe="portal-preview"]'), 'initial preview src matches "all"')
.to.have.attribute('src').match(/membersSignupAccess=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-iframe="portal-preview"]'), 'initial preview src matches "all"')
// .to.have.attribute('src').match(/membersSignupAccess=all/);
// open dropdown
await click('[data-test-members-subscription-option="all"]');
// // open dropdown
// await click('[data-test-members-subscription-option="all"]');
// 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="invite"]'), 'invite option').to.exist;
expect(find('.ember-power-select-options [data-test-members-subscription-option="none"]'), 'none option').to.exist;
// // 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="invite"]'), 'invite option').to.exist;
// expect(find('.ember-power-select-options [data-test-members-subscription-option="none"]'), 'none option').to.exist;
// switch to invite
await click('.ember-power-select-options [data-test-members-subscription-option="invite"]');
// // switch to 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('[data-test-members-subscription-option="invite"]'), 'invite option shown after selected').to.exist;
expect(find('[data-test-iframe="portal-preview"]'))
.to.have.attribute('src').match(/membersSignupAccess=invite/);
// 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-iframe="portal-preview"]'))
// .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
await click('[data-test-members-subscription-option="invite"]');
await click('.ember-power-select-options [data-test-members-subscription-option="none"]');
// // switch to nobody
// await click('[data-test-members-subscription-option="invite"]');
// 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('[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-portal-preview-disabled]')).to.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-iframe="portal-preview"]')).to.not.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
await click('[data-test-members-subscription-option="none"]');
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');
});
// // automatically saves when switching back off nobody
// await click('[data-test-members-subscription-option="none"]');
// 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');
// });
it('can change default post access', async function () {
await visit('/settings/members');
// it('can change default post access', async function () {
// await visit('/settings/members');
// 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_tiers'}).value).to.equal('[]');
// // 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_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-tiers]')).to.not.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;
// open dropdown
await click('[data-test-default-post-access-option="public"]');
// 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="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="tiers"]'), 'specific tiers option').to.exist;
// // open dropdown
// await click('[data-test-default-post-access-option="public"]');
// // 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="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="tiers"]'), 'specific tiers option').to.exist;
// switch to members only
await click('.ember-power-select-options [data-test-default-post-access-option="members"]');
await click('[data-test-button="save-settings"]');
// // switch to members only
// await click('.ember-power-select-options [data-test-default-post-access-option="members"]');
// 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_tiers'}).value).to.equal('[]');
// 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(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-option="members"]'), 'post-members selection is "members"').to.exist;
// expect(find('[data-test-default-post-access-tiers]')).to.not.exist;
// can switch to specific tiers
await click('[data-test-default-post-access-option="members"]');
await click('.ember-power-select-options [data-test-default-post-access-option="tiers"]');
// // can switch to specific tiers
// await click('[data-test-default-post-access-option="members"]');
// await click('.ember-power-select-options [data-test-default-post-access-option="tiers"]');
// tiers input is shown
expect(find('[data-test-default-post-access-tiers]')).to.exist;
// // tiers input is shown
// expect(find('[data-test-default-post-access-tiers]')).to.exist;
// open tiers dropdown
await click('[data-test-default-post-access-tiers] .ember-basic-dropdown-trigger');
// // open tiers dropdown
// await click('[data-test-default-post-access-tiers] .ember-basic-dropdown-trigger');
// paid tiers are available in tiers input
expect(find('[data-test-default-post-access-tiers] [data-test-visibility-segment-option="Default Tier"]')).to.exist;
// // paid tiers are available in tiers input
// expect(find('[data-test-default-post-access-tiers] [data-test-visibility-segment-option="Default Tier"]')).to.exist;
// select tier
await click('[data-test-default-post-access-tiers] [data-test-visibility-segment-option="Default Tier"]');
// // select tier
// await click('[data-test-default-post-access-tiers] [data-test-visibility-segment-option="Default Tier"]');
// save
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_tiers'}).value).to.equal('["2"]');
// // save
// 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_tiers'}).value).to.equal('["2"]');
// switch back to non-tiers option
await click('[data-test-default-post-access-option="tiers"]');
await click('.ember-power-select-options [data-test-default-post-access-option="paid"]');
// // switch back to non-tiers option
// await click('[data-test-default-post-access-option="tiers"]');
// 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"]');
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"]');
});
// 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_tiers'}).value).to.equal('["2"]');
// });
it('can manage free tier', async function () {
await visit('/settings/members');
await click('[data-test-button="toggle-free-settings"]');
expect(find('[data-test-free-settings-expanded]'), 'expanded free settings').to.exist;
// it('can manage free tier', async function () {
// await visit('/settings/members');
// await click('[data-test-button="toggle-free-settings"]');
// expect(find('[data-test-free-settings-expanded]'), 'expanded free settings').to.exist;
// we aren't viewing the non-labs-flag input
expect(find('[data-test-input="old-free-welcome-page"]')).to.not.exist;
// // we aren't viewing the non-labs-flag input
// 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
expect(find('[data-test-input="free-welcome-page"]')).to.exist;
expect(find('[data-test-input="free-welcome-page"]')).to.have.value('');
// // initial value
// expect(find('[data-test-input="free-welcome-page"]')).to.exist;
// expect(find('[data-test-input="free-welcome-page"]')).to.have.value('');
// saving
await fillIn('[data-test-input="free-welcome-page"]', 'not a url');
await blur('[data-test-input="free-welcome-page"]');
await click('[data-test-button="save-settings"]');
// // saving
// await fillIn('[data-test-input="free-welcome-page"]', 'not a url');
// await blur('[data-test-input="free-welcome-page"]');
// await click('[data-test-button="save-settings"]');
expect(this.server.db.tiers.findBy({slug: 'free'}).welcomePageUrl)
.to.equal('/not%20a%20url');
// expect(this.server.db.tiers.findBy({slug: 'free'}).welcomePageUrl)
// .to.equal('/not%20a%20url');
// re-rendering will insert full URL in welcome page input
await visit('/settings');
await visit('/settings/members');
// // re-rendering will insert full URL in welcome page input
// await visit('/settings');
// await visit('/settings/members');
expect(find('[data-test-input="free-welcome-page"]')).to.exist;
expect(find('[data-test-input="free-welcome-page"]'))
.to.have.value('http://localhost:2368/not%20a%20url');
// expect(find('[data-test-input="free-welcome-page"]')).to.exist;
// expect(find('[data-test-input="free-welcome-page"]'))
// .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
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-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-free-price]')).to.exist;
// // initial free tier details are as expected
// 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-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-free-price]')).to.exist;
// open modal
await click('[data-test-tier-card="free"] [data-test-button="edit-tier"]');
// // open modal
// await click('[data-test-tier-card="free"] [data-test-button="edit-tier"]');
// initial modal state is as expected
const modal = '[data-test-modal="edit-tier"]';
expect(find(modal)).to.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="free-tier-description"]`)).to.exist;
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-benefit-item="new"]`)).to.exist;
expect(findAll(`${modal} [data-test-benefit-item]`).length).to.equal(1);
// // initial modal state is as expected
// const modal = '[data-test-modal="edit-tier"]';
// expect(find(modal)).to.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="free-tier-description"]`)).to.exist;
// 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-benefit-item="new"]`)).to.exist;
// 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-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-price]`).textContent).to.match(/\$\s+0/);
// 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-benefits]`)).to.contain.text('Access to all public posts');
// expect(find(`${modal} [data-test-tierpreview-price]`).textContent).to.match(/\$\s+0/);
// can change description
await fillIn(`${modal} [data-test-input="free-tier-description"]`, 'Test description');
expect(find(`${modal} [data-test-tierpreview-description]`)).to.contain.text('Test description');
// // can change description
// await fillIn(`${modal} [data-test-input="free-tier-description"]`, 'Test description');
// expect(find(`${modal} [data-test-tierpreview-description]`)).to.contain.text('Test description');
// can manage benefits
const newBenefit = `${modal} [data-test-benefit-item="new"]`;
await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'First benefit');
await click(`${newBenefit} [data-test-button="add-benefit"]`);
// // can manage benefits
// const newBenefit = `${modal} [data-test-benefit-item="new"]`;
// await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'First 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="new"]`)).to.exist;
// expect(find(`${modal} [data-test-benefit-item="0"]`)).to.exist;
// expect(find(`${modal} [data-test-benefit-item="new"]`)).to.exist;
await click(`${newBenefit} [data-test-button="add-benefit"]`);
expect(find(`${newBenefit}`)).to.contain.text('Please enter a benefit');
// await click(`${newBenefit} [data-test-button="add-benefit"]`);
// expect(find(`${newBenefit}`)).to.contain.text('Please enter a benefit');
await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'Second benefit');
await click(`${newBenefit} [data-test-button="add-benefit"]`);
// await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'Second benefit');
// await click(`${newBenefit} [data-test-button="add-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(find(`${modal} [data-test-tierpreview-benefits]`)).to.contain.text('Second benefit');
// 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(findAll(`${modal} [data-test-tierpreview-benefits] div`).length).to.equal(2);
// Add a new benefit that we will later rename to an empty name
await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'Third benefit');
await click(`${newBenefit} [data-test-button="add-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(find(`${modal} [data-test-tierpreview-benefits]`)).to.not.contain.text('First benefit');
// 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
// await fillIn(`${newBenefit} [data-test-input="benefit-label"]`, 'Third benefit');
// await click(`${newBenefit} [data-test-button="add-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);
// Clear the second benefit's name (it should get removed after saving)
const secondBenefitItem = `${modal} [data-test-benefit-item="1"]`;
await fillIn(`${secondBenefitItem} [data-test-input="benefit-label"]`, '');
await click('[data-test-button="save-tier"]');
// // Clear the second benefit's name (it should get removed after saving)
// const secondBenefitItem = `${modal} [data-test-benefit-item="1"]`;
// await fillIn(`${secondBenefitItem} [data-test-input="benefit-label"]`, '');
// await click('[data-test-button="save-tier"]');
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-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] 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);
const freeTier = this.server.db.tiers.findBy({slug: 'free'});
expect(freeTier.description).to.equal('Test description');
expect(freeTier.welcomePageUrl).to.equal('/not%20a%20url');
expect(freeTier.benefits.length).to.equal(1);
expect(freeTier.benefits[0]).to.equal('Second benefit');
});
});
// 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-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] 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);
// const freeTier = this.server.db.tiers.findBy({slug: 'free'});
// expect(freeTier.description).to.equal('Test description');
// expect(freeTier.welcomePageUrl).to.equal('/not%20a%20url');
// expect(freeTier.benefits.length).to.equal(1);
// expect(freeTier.benefits[0]).to.equal('Second benefit');
// });
// });

View File

@ -1,252 +1,252 @@
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import {authenticateSession} from 'ember-simple-auth/test-support';
import {beforeEach, describe, it} from 'mocha';
import {blur, click, currentRouteName, currentURL, fillIn, find, findAll, triggerEvent, typeIn} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
// import {authenticateSession} from 'ember-simple-auth/test-support';
// import {beforeEach, describe, it} from 'mocha';
// import {blur, click, currentRouteName, currentURL, fillIn, find, findAll, triggerEvent, typeIn} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
// simulate jQuery's `:visible` pseudo-selector
function withText(elements) {
return Array.from(elements).filter(elem => elem.textContent.trim() !== '');
}
// // simulate jQuery's `:visible` pseudo-selector
// function withText(elements) {
// return Array.from(elements).filter(elem => elem.textContent.trim() !== '');
// }
describe('Acceptance: Settings - Navigation', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Navigation', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
describe('when logged in', function () {
beforeEach(async function () {
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// describe('when logged in', function () {
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
await authenticateSession();
});
// await authenticateSession();
// });
it('can visit /settings/navigation', async function () {
await visit('/settings/navigation');
// it('can visit /settings/navigation', async function () {
// await visit('/settings/navigation');
expect(currentRouteName()).to.equal('settings.navigation');
expect(find('[data-test-save-button]').textContent.trim(), 'save button text').to.equal('Save');
// expect(currentRouteName()).to.equal('settings.navigation');
// 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
// should have one extra that's blank for each navigation section
expect(
findAll('[data-test-navitem]').length,
'navigation items count'
).to.equal(4);
});
// // fixtures contain two nav items, check for four rows as we
// // should have one extra that's blank for each navigation section
// expect(
// findAll('[data-test-navitem]').length,
// 'navigation items count'
// ).to.equal(4);
// });
it('saves navigation settings', async function () {
await visit('/settings/navigation');
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 click('[data-test-save-button]');
// it('saves navigation settings', async function () {
// await visit('/settings/navigation');
// 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 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
// tests "pre.error" elements
expect(findAll('span.error').length, 'error messages count').to.equal(0);
expect(findAll('.gh-alert').length, 'alerts count').to.equal(0);
expect(withText(findAll('[data-test-error]')).length, 'validation errors count')
.to.equal(0);
});
// // don't test against .error directly as it will pick up failed
// // tests "pre.error" elements
// expect(findAll('span.error').length, 'error messages count').to.equal(0);
// expect(findAll('.gh-alert').length, 'alerts count').to.equal(0);
// expect(withText(findAll('[data-test-error]')).length, 'validation errors count')
// .to.equal(0);
// });
it('validates new item correctly on save', async function () {
await visit('/settings/navigation');
await click('[data-test-save-button]');
// it('validates new item correctly on save', async function () {
// await visit('/settings/navigation');
// await click('[data-test-save-button]');
expect(
findAll('#settings-navigation [data-test-navitem]').length,
'number of nav items after saving with blank new item'
).to.equal(3);
// expect(
// findAll('#settings-navigation [data-test-navitem]').length,
// 'number of nav items after saving with blank new item'
// ).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="url"]', '');
await typeIn('#settings-navigation [data-test-navitem="new"] [data-test-input="url"]', 'http://invalid domain/');
// 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 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(
findAll('#settings-navigation [data-test-navitem]').length,
'number of nav items after saving with invalid new item'
).to.equal(3);
// expect(
// findAll('#settings-navigation [data-test-navitem]').length,
// 'number of nav items after saving with invalid new item'
// ).to.equal(3);
expect(
withText(findAll('#settings-navigation [data-test-navitem="new"] [data-test-error]')).length,
'number of invalid fields in new item'
).to.equal(1);
});
// expect(
// withText(findAll('#settings-navigation [data-test-navitem="new"] [data-test-error]')).length,
// 'number of invalid fields in new item'
// ).to.equal(1);
// });
it('clears unsaved settings when navigating away but warns with a confirmation dialog', async function () {
await visit('/settings/navigation');
await fillIn('[data-test-navitem="0"] [data-test-input="label"]', 'Test');
await blur('[data-test-navitem="0"] [data-test-input="label"]');
// it('clears unsaved settings when navigating away but warns with a confirmation dialog', async function () {
// await visit('/settings/navigation');
// await fillIn('[data-test-navitem="0"] [data-test-input="label"]', 'Test');
// 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
await click('[data-test-leave-button]'), 'leave without saving';
// // 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 () {
await visit('/settings/navigation');
await click('#settings-navigation .gh-blognav-add');
// it('can add and remove items', async function () {
// await visit('/settings/navigation');
// await click('#settings-navigation .gh-blognav-add');
expect(
find('[data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
'blank label has validation error'
).to.not.be.empty;
// expect(
// find('[data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
// 'blank label has validation error'
// ).to.not.be.empty;
await fillIn('[data-test-navitem="new"] [data-test-input="label"]', '');
await typeIn('[data-test-navitem="new"] [data-test-input="label"]', 'New');
// await fillIn('[data-test-navitem="new"] [data-test-input="label"]', '');
// await typeIn('[data-test-navitem="new"] [data-test-input="label"]', 'New');
expect(
find('[data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
'label validation is visible after typing'
).to.be.empty;
// expect(
// find('[data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
// 'label validation is visible after typing'
// ).to.be.empty;
await fillIn('[data-test-navitem="new"] [data-test-input="url"]', '');
await typeIn('[data-test-navitem="new"] [data-test-input="url"]', '/new');
await blur('[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 blur('[data-test-navitem="new"] [data-test-input="url"]');
expect(
find('[data-test-navitem="new"] [data-test-error="url"]').textContent.trim(),
'url validation is visible after typing'
).to.be.empty;
// expect(
// find('[data-test-navitem="new"] [data-test-error="url"]').textContent.trim(),
// 'url validation is visible after typing'
// ).to.be.empty;
expect(
find('[data-test-navitem="new"] [data-test-input="url"]').value
).to.equal(`${window.location.origin}/new/`);
// expect(
// find('[data-test-navitem="new"] [data-test-input="url"]').value
// ).to.equal(`${window.location.origin}/new/`);
await click('.gh-blognav-add');
// await click('.gh-blognav-add');
expect(
findAll('#settings-navigation [data-test-navitem]').length,
'number of nav items after successful add'
).to.equal(4);
// expect(
// findAll('#settings-navigation [data-test-navitem]').length,
// 'number of nav items after successful add'
// ).to.equal(4);
expect(
find('#settings-navigation [data-test-navitem="new"] [data-test-input="label"]').value,
'new item label value after successful add'
).to.be.empty;
// expect(
// find('#settings-navigation [data-test-navitem="new"] [data-test-input="label"]').value,
// 'new item label value after successful add'
// ).to.be.empty;
expect(
find('#settings-navigation [data-test-navitem="new"] [data-test-input="url"]').value,
'new item url value after successful add'
).to.equal(`${window.location.origin}/`);
// expect(
// find('#settings-navigation [data-test-navitem="new"] [data-test-input="url"]').value,
// 'new item url value after successful add'
// ).to.equal(`${window.location.origin}/`);
expect(
withText(findAll('[data-test-navitem] [data-test-error]')).length,
'number or validation errors shown after successful add'
).to.equal(0);
// expect(
// withText(findAll('[data-test-navitem] [data-test-error]')).length,
// 'number or validation errors shown after successful add'
// ).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(
findAll('#settings-navigation [data-test-navitem]').length,
'number of nav items after successful remove'
).to.equal(3);
// expect(
// findAll('#settings-navigation [data-test-navitem]').length,
// 'number of nav items after successful remove'
// ).to.equal(3);
// CMD-S shortcut works
await triggerEvent('.gh-app', 'keydown', {
keyCode: 83, // s
metaKey: ctrlOrCmd === 'command',
ctrlKey: ctrlOrCmd === 'ctrl'
});
// // CMD-S shortcut works
// await triggerEvent('.gh-app', 'keydown', {
// keyCode: 83, // s
// metaKey: ctrlOrCmd === 'command',
// 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 () {
await visit('/settings/navigation');
await click('#secondary-navigation .gh-blognav-add');
// it('can also add and remove items from seconday nav', async function () {
// await visit('/settings/navigation');
// await click('#secondary-navigation .gh-blognav-add');
expect(
find('#secondary-navigation [data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
'blank label has validation error'
).to.not.be.empty;
// expect(
// find('#secondary-navigation [data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
// 'blank label has validation error'
// ).to.not.be.empty;
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 fillIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]', '');
// await typeIn('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]', 'Foo');
expect(
find('#secondary-navigation [data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
'label validation is visible after typing'
).to.be.empty;
// expect(
// find('#secondary-navigation [data-test-navitem="new"] [data-test-error="label"]').textContent.trim(),
// 'label validation is visible after typing'
// ).to.be.empty;
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 blur('#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 blur('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]');
expect(
find('#secondary-navigation [data-test-navitem="new"] [data-test-error="url"]').textContent.trim(),
'url validation is visible after typing'
).to.be.empty;
// expect(
// find('#secondary-navigation [data-test-navitem="new"] [data-test-error="url"]').textContent.trim(),
// 'url validation is visible after typing'
// ).to.be.empty;
expect(
find('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]').value
).to.equal(`${window.location.origin}/bar/`);
// expect(
// find('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]').value
// ).to.equal(`${window.location.origin}/bar/`);
await click('[data-test-save-button]');
// await click('[data-test-save-button]');
expect(
findAll('#secondary-navigation [data-test-navitem]').length,
'number of nav items after successful add'
).to.equal(2);
// expect(
// findAll('#secondary-navigation [data-test-navitem]').length,
// 'number of nav items after successful add'
// ).to.equal(2);
expect(
find('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]').value,
'new item label value after successful add'
).to.be.empty;
// expect(
// find('#secondary-navigation [data-test-navitem="new"] [data-test-input="label"]').value,
// 'new item label value after successful add'
// ).to.be.empty;
expect(
find('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]').value,
'new item url value after successful add'
).to.equal(`${window.location.origin}/`);
// expect(
// find('#secondary-navigation [data-test-navitem="new"] [data-test-input="url"]').value,
// 'new item url value after successful add'
// ).to.equal(`${window.location.origin}/`);
expect(
withText(findAll('#secondary-navigation [data-test-navitem] [data-test-error]')).length,
'number or validation errors shown after successful add'
).to.equal(0);
// expect(
// withText(findAll('#secondary-navigation [data-test-navitem] [data-test-error]')).length,
// 'number or validation errors shown after successful add'
// ).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(
findAll('#secondary-navigation [data-test-navitem]').length,
'number of nav items after successful remove'
).to.equal(1);
// expect(
// findAll('#secondary-navigation [data-test-navitem]').length,
// 'number of nav items after successful remove'
// ).to.equal(1);
// CMD-S shortcut works
await triggerEvent('.gh-app', 'keydown', {
keyCode: 83, // s
metaKey: ctrlOrCmd === 'command',
ctrlKey: ctrlOrCmd === 'ctrl'
});
// // CMD-S shortcut works
// await triggerEvent('.gh-app', 'keydown', {
// keyCode: 83, // s
// metaKey: ctrlOrCmd === 'command',
// 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

View File

@ -1,151 +1,151 @@
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import {Response} from 'miragejs';
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {beforeEach, describe, it} from 'mocha';
import {blur, click, currentURL, fillIn, find, findAll, triggerEvent} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
// import {Response} from 'miragejs';
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {beforeEach, describe, it} from 'mocha';
// import {blur, click, currentURL, fillIn, find, findAll, triggerEvent} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Integrations - Slack', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Integrations - Slack', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
it('redirects to signin when not authenticated', async function () {
await invalidateSession();
await visit('/settings/integrations/slack');
// it('redirects to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
let role = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as contributor', async function () {
// let role = this.server.create('role', {name: 'Contributor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/slack');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Author'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as author', async function () {
// let role = this.server.create('role', {name: 'Author'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/slack');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Editor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as editor', async function () {
// let role = this.server.create('role', {name: 'Editor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/slack');
// await authenticateSession();
// await visit('/settings/integrations/slack');
expect(currentURL(), 'currentURL').to.equal('/site');
});
// expect(currentURL(), 'currentURL').to.equal('/site');
// });
describe('when logged in', function () {
beforeEach(async function () {
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// describe('when logged in', function () {
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it('it validates and saves slack settings properly', async function () {
await visit('/settings/integrations/slack');
// it('it validates and saves slack settings properly', async function () {
// await visit('/settings/integrations/slack');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
await fillIn('[data-test-slack-url-input]', 'notacorrecturl');
await click('[data-test-save-button]');
// await fillIn('[data-test-slack-url-input]', 'notacorrecturl');
// await click('[data-test-save-button]');
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>');
// 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>');
// CMD-S shortcut works
await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
await fillIn('[data-test-slack-username-input]', 'SlackBot');
await triggerEvent('.gh-app', 'keydown', {
keyCode: 83, // s
metaKey: ctrlOrCmd === 'command',
ctrlKey: ctrlOrCmd === 'ctrl'
});
// // CMD-S shortcut works
// await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
// await fillIn('[data-test-slack-username-input]', 'SlackBot');
// await triggerEvent('.gh-app', 'keydown', {
// keyCode: 83, // s
// metaKey: ctrlOrCmd === 'command',
// ctrlKey: ctrlOrCmd === 'ctrl'
// });
let [newRequest] = this.server.pretender.handledRequests.slice(-1);
let params = JSON.parse(newRequest.requestBody);
// let [newRequest] = this.server.pretender.handledRequests.slice(-1);
// let params = JSON.parse(newRequest.requestBody);
let urlResult = params.settings.findBy('key', 'slack_url').value;
let usernameResult = params.settings.findBy('key', 'slack_username').value;
// let urlResult = params.settings.findBy('key', 'slack_url').value;
// let usernameResult = params.settings.findBy('key', 'slack_username').value;
expect(urlResult).to.equal('https://hooks.slack.com/services/1275958430');
expect(usernameResult).to.equal('SlackBot');
expect(find('[data-test-error="slack-url"]'), 'inline validation response')
.to.not.exist;
// expect(urlResult).to.equal('https://hooks.slack.com/services/1275958430');
// expect(usernameResult).to.equal('SlackBot');
// expect(find('[data-test-error="slack-url"]'), 'inline validation response')
// .to.not.exist;
await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
await click('[data-test-send-notification-button]');
// await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
// await click('[data-test-send-notification-button]');
expect(findAll('.gh-notification').length, 'number of notifications').to.equal(1);
expect(find('[data-test-error="slack-url"]'), 'inline validation response')
.to.not.exist;
// expect(findAll('.gh-notification').length, 'number of notifications').to.equal(1);
// expect(find('[data-test-error="slack-url"]'), 'inline validation response')
// .to.not.exist;
// modify model data or there will be no api call
await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958431');
// // modify model data or there will be no api call
// await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958431');
this.server.put('/settings/', function () {
return new Response(422, {}, {
errors: [
{
type: 'ValidationError',
message: 'Test error'
}
]
});
});
// this.server.put('/settings/', function () {
// return new Response(422, {}, {
// errors: [
// {
// type: 'ValidationError',
// message: 'Test error'
// }
// ]
// });
// });
await click('.gh-notification .gh-notification-close');
await click('[data-test-send-notification-button]');
// await click('.gh-notification .gh-notification-close');
// await click('[data-test-send-notification-button]');
// we shouldn't try to send the test request if the save fails
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
expect(lastRequest.url).to.not.match(/\/slack\/test/);
expect(findAll('.gh-notification').length, 'check slack notification after api validation error').to.equal(0);
});
// // we shouldn't try to send the test request if the save fails
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
// expect(lastRequest.url).to.not.match(/\/slack\/test/);
// expect(findAll('.gh-notification').length, 'check slack notification after api validation error').to.equal(0);
// });
it('warns when leaving without saving', async function () {
await visit('/settings/integrations/slack');
// it('warns when leaving without saving', async function () {
// await visit('/settings/integrations/slack');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/slack');
await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
await blur('[data-test-slack-url-input]');
// await fillIn('[data-test-slack-url-input]', 'https://hooks.slack.com/services/1275958430');
// 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
await click('[data-test-modal="unsaved-settings"] [data-test-leave-button]');
// // Leave without saving
// 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
expect(
find('[data-test-slack-url-input]').textContent.trim(),
'Slack Webhook URL'
).to.equal('');
});
});
});
// // settings were not saved
// expect(
// find('[data-test-slack-url-input]').textContent.trim(),
// 'Slack Webhook URL'
// ).to.equal('');
// });
// });
// });

View File

@ -18,24 +18,24 @@ describe('Acceptance: Tags', function () {
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'});
this.server.create('user', {roles: [role], slug: 'test-user'});
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'});
this.server.create('user', {roles: [role], slug: 'test-user'});
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 () {

View File

@ -1,132 +1,132 @@
import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {
beforeEach,
describe,
it
} from 'mocha';
import {click, currentURL, find, findAll, triggerEvent} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd';
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {
// beforeEach,
// describe,
// it
// } from 'mocha';
// import {click, currentURL, find, findAll, triggerEvent} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Integrations - Unsplash', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Integrations - Unsplash', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
it('redirects to signin when not authenticated', async function () {
await invalidateSession();
await visit('/settings/integrations/unsplash');
// it('redirects to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
let role = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as contributor', async function () {
// let role = this.server.create('role', {name: 'Contributor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/unsplash');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Author'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as author', async function () {
// let role = this.server.create('role', {name: 'Author'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/unsplash');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Editor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as editor', async function () {
// let role = this.server.create('role', {name: 'Editor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/unsplash');
// await authenticateSession();
// await visit('/settings/integrations/unsplash');
expect(currentURL(), 'currentURL').to.equal('/site');
});
// expect(currentURL(), 'currentURL').to.equal('/site');
// });
describe('when logged in', function () {
beforeEach(async function () {
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// describe('when logged in', function () {
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it('it can activate/deactivate', async function () {
await visit('/settings/integrations/unsplash');
// it('it can activate/deactivate', async function () {
// await visit('/settings/integrations/unsplash');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
// it's enabled by default when settings is empty
expect(find('[data-test-unsplash-checkbox]').checked, 'checked by default').to.be.true;
// // it's enabled by default when settings is empty
// 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
await click('[data-test-save-button]');
// // trigger a save
// await click('[data-test-save-button]');
// server should now have an unsplash setting
let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
let params = JSON.parse(lastRequest.requestBody);
// // server should now have an unsplash setting
// let [lastRequest] = this.server.pretender.handledRequests.slice(-1);
// 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
await click('[data-test-unsplash-checkbox]');
await triggerEvent('.gh-app', 'keydown', {
keyCode: 83, // s
metaKey: ctrlOrCmd === 'command',
ctrlKey: ctrlOrCmd === 'ctrl'
});
// // save via CMD-S shortcut
// await click('[data-test-unsplash-checkbox]');
// await triggerEvent('.gh-app', 'keydown', {
// keyCode: 83, // s
// metaKey: ctrlOrCmd === 'command',
// ctrlKey: ctrlOrCmd === 'ctrl'
// });
// 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
let [newRequest] = this.server.pretender.handledRequests.slice(-1);
params = JSON.parse(newRequest.requestBody);
// // 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
// let [newRequest] = this.server.pretender.handledRequests.slice(-1);
// params = JSON.parse(newRequest.requestBody);
expect(find('[data-test-unsplash-checkbox]').checked, 'AMP checkbox').to.be.true;
expect(params.settings.findBy('key', 'unsplash').value).to.equal(true);
});
// expect(find('[data-test-unsplash-checkbox]').checked, 'AMP checkbox').to.be.true;
// expect(params.settings.findBy('key', 'unsplash').value).to.equal(true);
// });
it('warns when leaving without saving', async function () {
await visit('/settings/integrations/unsplash');
// it('warns when leaving without saving', async function () {
// await visit('/settings/integrations/unsplash');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/unsplash');
// AMP is enabled by default
expect(find('[data-test-unsplash-checkbox]').checked, 'AMP checkbox default').to.be.true;
// // AMP is enabled by default
// 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
await click('[data-test-modal="unsaved-settings"] [data-test-leave-button]');
// // Leave without saving
// 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
expect(find('[data-test-unsplash-checkbox]').checked, 'Unsplash checkbox').to.be.true;
});
});
});
// // settings were not saved
// expect(find('[data-test-unsplash-checkbox]').checked, 'Unsplash checkbox').to.be.true;
// });
// });
// });

View File

@ -1,69 +1,69 @@
import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
import {
beforeEach,
describe,
it
} from 'mocha';
import {currentURL} from '@ember/test-helpers';
import {expect} from 'chai';
import {setupApplicationTest} from 'ember-mocha';
import {setupMirage} from 'ember-cli-mirage/test-support';
import {visit} from '../../helpers/visit';
// import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support';
// import {
// beforeEach,
// describe,
// it
// } from 'mocha';
// import {currentURL} from '@ember/test-helpers';
// import {expect} from 'chai';
// import {setupApplicationTest} from 'ember-mocha';
// import {setupMirage} from 'ember-cli-mirage/test-support';
// import {visit} from '../../helpers/visit';
describe('Acceptance: Settings - Integrations - Zapier', function () {
let hooks = setupApplicationTest();
setupMirage(hooks);
// describe('Acceptance: Settings - Integrations - Zapier', function () {
// let hooks = setupApplicationTest();
// setupMirage(hooks);
it('redirects to signin when not authenticated', async function () {
await invalidateSession();
await visit('/settings/integrations/zapier');
// it('redirects to signin when not authenticated', async function () {
// await invalidateSession();
// 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 () {
let role = this.server.create('role', {name: 'Contributor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as contributor', async function () {
// let role = this.server.create('role', {name: 'Contributor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/zapier');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Author'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as author', async function () {
// let role = this.server.create('role', {name: 'Author'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/zapier');
// await authenticateSession();
// 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 () {
let role = this.server.create('role', {name: 'Editor'});
this.server.create('user', {roles: [role], slug: 'test-user'});
// it('redirects to home page when authenticated as editor', async function () {
// let role = this.server.create('role', {name: 'Editor'});
// this.server.create('user', {roles: [role], slug: 'test-user'});
await authenticateSession();
await visit('/settings/integrations/zapier');
// await authenticateSession();
// await visit('/settings/integrations/zapier');
expect(currentURL(), 'currentURL').to.equal('/site');
});
// expect(currentURL(), 'currentURL').to.equal('/site');
// });
describe('when logged in', function () {
beforeEach(async function () {
let role = this.server.create('role', {name: 'Administrator'});
this.server.create('user', {roles: [role]});
// describe('when logged in', function () {
// beforeEach(async function () {
// let role = this.server.create('role', {name: 'Administrator'});
// this.server.create('user', {roles: [role]});
return await authenticateSession();
});
// return await authenticateSession();
// });
it('it loads', async function () {
await visit('/settings/integrations/zapier');
// it('it loads', async function () {
// await visit('/settings/integrations/zapier');
// has correct url
expect(currentURL(), 'currentURL').to.equal('/settings/integrations/zapier');
});
});
});
// // has correct url
// expect(currentURL(), 'currentURL').to.equal('/settings/integrations/zapier');
// });
// });
// });

File diff suppressed because it is too large Load Diff

View File

@ -6,40 +6,38 @@ test.describe('Announcement Bar Settings', () => {
await goToAnnouncementBarSettings(page);
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);
});
});
test('Show/hide bar if visibility checked/unchecked and text filled', async ({page}) => {
await page.goto('/ghost');
await goToAnnouncementBarSettings(page);
const modal = await goToAnnouncementBarSettings(page);
await test.step('Check free members', async () => {
const freeMembersCheckbox = await page.getByTestId('announcement-bar-free-member-input');
await expect(await freeMembersCheckbox.isChecked()).toBeFalsy();
await page.getByTestId('announcement-bar-free-member-label').click();
await expect(await freeMembersCheckbox.isChecked()).toBeTruthy();
const freeMembersCheckbox = modal.getByLabel('Free members');
await expect(freeMembersCheckbox).not.toBeChecked();
await freeMembersCheckbox.check();
});
await test.step('Fill announcement text', async () => {
await page.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 modal.locator('.koenig-react-editor').click();
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.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 expect(await htmlFrame.getByText('Announcement text')).toBeVisible();
});
await test.step('Disable free members', async () => {
const freeMembersCheckbox = await page.getByTestId('announcement-bar-free-member-input');
await expect(await freeMembersCheckbox.isChecked()).toBeTruthy();
await page.getByTestId('announcement-bar-free-member-label').click();
await expect(await freeMembersCheckbox.isChecked()).toBeFalsy();
await page.locator('.koenig-react-editor').click();
const freeMembersCheckbox = modal.getByLabel('Free members');
await expect(freeMembersCheckbox).toBeChecked();
await freeMembersCheckbox.uncheck();
await modal.locator('.koenig-react-editor').click();
});
await test.step('Announcement bar should be hidden', async () => {
@ -49,13 +47,15 @@ test.describe('Announcement Bar Settings', () => {
});
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="announcement-bar"]').click();
await expect(await page.getByTestId('announcement-bar-title')).toBeVisible();
await page.getByTestId('announcement-bar').getByRole('button', {name: 'Customize'}).click();
// Wait for the preview to load
await getPreviewFrame(page).locator('body *:visible').first().waitFor();
});
return page.getByTestId('announcement-bar-modal');
}
async function getPreviewFrame(page) {
return page.frameLocator('[data-testid="iframe-html"]:visible');
function getPreviewFrame(page) {
return page.frameLocator('[data-testid="announcement-bar-preview-iframe"] > iframe[data-visible=true]');
}

View File

@ -11,10 +11,11 @@ test.describe('Membership Settings', () => {
// Open Portal settings
await page.goto('/ghost');
await page.locator('.gh-nav a[href="#/settings/"]').click();
await page.locator('.gh-setting-group').filter({hasText: 'Membership'}).click();
await page.locator('[data-test-toggle="portal-settings"]').click();
await page.getByTestId('portal').getByRole('button', {name: 'Customize'}).click();
const modal = page.getByTestId('portal-modal');
// 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
const stripeToken = await generateStripeIntegrationToken();

View File

@ -2,20 +2,24 @@ const {expect, test} = require('@playwright/test');
test.describe('Portal Settings', () => {
test.describe('Links', () => {
test('can open portal on default page', async ({page}) => {
const openPortalLinks = async (page) => {
await page.goto('/ghost');
// 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();
await page.getByTestId('portal').getByRole('button', {name: 'Customize'}).click();
// open links preview page
await page.locator('[data-test-select="page-selector"]').first().selectOption('links');
const modal = page.getByTestId('portal-modal');
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
const portalUrl = await page.locator('[data-test-input="portal-link-default"]').inputValue();
const portalUrl = await modal.getByLabel('Default').inputValue();
await page.goto(portalUrl);
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}) => {
await page.goto('/ghost');
// 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');
const modal = await openPortalLinks(page);
// 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);
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}) => {
await page.goto('/ghost');
// 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');
const modal = await openPortalLinks(page);
// 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);
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}) => {
await page.goto('/ghost');
// 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');
const modal = await openPortalLinks(page);
// 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);
// expect stripe checkout to have opeened
@ -95,19 +72,10 @@ test.describe('Portal Settings', () => {
});
test('can open portal directly on yearly signup', async ({page}) => {
await page.goto('/ghost');
// Navigate to the member settings
await page.locator('[data-test-nav="settings"]').click();
await page.locator('[data-test-nav="members-membership"]').click();
const modal = await openPortalLinks(page);
// 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
const portalUrl = await page.locator('[data-test-input="portal-tier-link-yearly"]').inputValue();
// fetch and go to portal directly yearly signup url
const portalUrl = await modal.getByLabel('Signup / Yearly').inputValue();
await page.goto(portalUrl);
// expect stripe checkout to have opeened

View File

@ -7,17 +7,17 @@ test.describe('Site Settings', () => {
await page.goto('/ghost');
await page.locator('[data-test-nav="settings"]').click();
await page.locator('[data-test-nav="general"]').click();
// @NOTE: needs a data-test selector
await page.locator('label.switch span').click();
const section = page.getByTestId('locksite');
await section.getByRole('button', {name: 'Edit'}).click();
await section.getByLabel(/Enable password protection/).check();
await section.getByLabel('Site password').fill('password');
// save changes
await page.locator('[data-test-button="save"]').click();
await page.getByRole('button', {name: 'Saved'}).waitFor({
state: 'visible',
timeout: 1000
});
await section.getByRole('button', {name: 'Save'}).click();
await expect(section.getByLabel('Site password')).toHaveCount(0);
// copy site password
//const passwordInput = await page.locator('[data-test-password-input]');
@ -40,20 +40,20 @@ test.describe('Site Settings', () => {
// await frontendPage.waitForSelector('.site-title');
// await expect(frontendPage.locator('.site-title')).toHaveText('The Local Test');
// // set private mode in admin "off"
// @NOTE: needs a data-test selector
await page.locator('label.switch span').click();
// set private mode in admin "off"
await section.getByRole('button', {name: 'Edit'}).click();
await section.getByLabel(/Enable password protection/).uncheck();
// save changes
await page.locator('[data-test-button="save"]').click();
await page.getByRole('button', {name: 'Saved'}).waitFor({
state: 'visible',
timeout: 1000
});
await section.getByRole('button', {name: 'Save'}).click();
await expect(section.getByLabel('Site password')).toHaveCount(0);
// check the site is publicly accessible
await frontendPage.goto('/');
await expect(frontendPage.locator('.gh-navigation-brand')).toHaveText('The Local Test');
await expect(async () => {
await frontendPage.goto('/');
await expect(frontendPage.locator('.gh-navigation-brand')).toHaveText('The Local Test');
}).toPass();
});
});
});

View File

@ -2,22 +2,18 @@ const {expect, test} = require('@playwright/test');
const {createPostDraft, createTier, disconnectStripe, generateStripeIntegrationToken, setupStripe} = require('../utils');
const changeSubscriptionAccess = async (page, access) => {
// Go to settings page
await page.locator('[data-test-nav="settings"]').click();
// Go to members settings page
await page.locator('[data-test-nav="members-membership"]').click();
const section = page.getByTestId('access');
await section.getByRole('button', {name: 'Edit'}).click();
// Change subscription access
await page.locator('[data-test-members-subscription-access] [data-test-members-subscription-option]').click();
await page.locator(`[data-test-members-subscription-option="${access}"]`).click();
const select = section.getByTestId('subscription-access-select');
await select.click();
await page.locator(`[data-testid="select-option"][data-value="${access}"]`).click();
// Save settings
await page.locator('[data-test-button="save-settings"]').click();
await page.getByRole('button', {name: 'Saved'}).waitFor({
state: 'visible',
timeout: 1000
});
await section.getByRole('button', {name: 'Save'}).click();
await expect(select).not.toBeVisible();
};
const checkPortalScriptLoaded = async (page, loaded = true) => {

View File

@ -1,16 +1,16 @@
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('Tiers', () => {
test('Default tier should be $5mo / $50yr', async ({page}) => {
const defaultTierId = 'default-product';
const defaultTier = 'default-product';
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 expect(tierCard.locator('[data-test-amount-monthly-price]')).toHaveText('5');
await expect(tierCard.locator('[data-test-amount-yearly-price]')).toHaveText('50');
await expect(tierModal.getByLabel('Monthly price')).toHaveValue('5');
await expect(tierModal.getByLabel('Yearly price')).toHaveValue('50');
});
});
@ -50,18 +50,20 @@ test.describe('Admin', () => {
await goToMembershipPage(page);
await test.step('Created tier should be in Portal settings and not selected', 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 page.locator(`[data-test-settings-tier-label="${tierName}"]`);
expect(await page.locator(`[data-test-settings-tier-input="${tierName}"]`).isChecked()).toBeFalsy();
await page.getByTestId('portal').getByRole('button', {name: 'Customize'}).click();
const portalSettings = page.getByTestId('portal-modal');
await portalSettings.getByLabel(tierName).first().waitFor();
await expect(portalSettings.getByLabel(tierName).first()).not.toBeChecked();
});
});
test('Can update Tier', async ({page}) => {
await page.goto('/ghost');
const tierName = getUniqueName('New Test Tier');
const tierId = getSlug(tierName);
const slug = getSlug(tierName);
const updatedTierName = getUniqueName('Updated Test Tier Name');
const updatedMonthlyPrice = '66';
const updatedYearlyPrice = '666';
@ -73,18 +75,14 @@ test.describe('Admin', () => {
});
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 tierCard.locator('[data-test-button="tiers-actions"]').click();
await tierCard.locator('[data-test-button="edit-tier"]').click();
const modal = page.locator('[data-test-modal="edit-tier"]');
await modal.locator('[data-test-input="tier-name"]').first().fill(updatedTierName);
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();
await tierModal.getByLabel('Name').fill(updatedTierName);
await tierModal.getByLabel('Description').fill(updatedDescription);
await tierModal.getByLabel('Monthly price').fill(updatedMonthlyPrice);
await tierModal.getByLabel('Yearly price').fill(updatedYearlyPrice);
await tierModal.getByRole('button', {name: 'Save & close'}).click();
});
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 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);
});
});
// TODO: Add something more useful to this, e.g. checking in the portal
test('Can archive and unarchive a Tier', async ({page}) => {
await page.goto('/ghost');
const tierName = getUniqueName('Archive Tier');
const tierId = getSlug(tierName);
const slug = getSlug(tierName);
await createTier(page, {
name: tierName,
monthlyPrice: 5,
@ -127,50 +126,56 @@ test.describe('Admin', () => {
});
await goToMembershipPage(page);
const tierCard = await getTierCardById(page, {id: tierId});
await test.step('Archive tier', async () => {
await tierCard.locator('[data-test-button="tiers-actions"]').click();
await tierCard.locator('[data-test-button="archive-tier"]').click();
const modal = page.locator('[data-test-modal="archive-tier"]');
await modal.locator('[data-test-button="archive-tier"]').click();
const tierModal = await openTierModal(page, {slug});
await tierModal.getByRole('button', {name: 'Archive tier'}).click();
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Archive'}).click();
await tierModal.getByRole('button', {name: 'Save & close'}).click();
});
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 () => {
const tiersSelect = await page.locator('[data-test-select-tiers-list]');
await tiersSelect.click();
await page.getByRole('option', {name: 'Archived'}).click();
await expect(page.locator(`[data-test-tier-card="${tierId}"]`)).toBeVisible();
await page.getByTestId('tiers').getByRole('tab', {name: 'Archived'}).click();
await expect(page.locator(`[data-testid="tier-card"][data-tier="${slug}"]`)).toBeVisible();
});
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 tierCard.locator('[data-test-button="tiers-actions"]').click();
await tierCard.locator('[data-test-button="unarchive-tier"]').click();
const modal = page.locator('[data-test-modal="unarchive-tier"]');
await modal.locator('[data-test-button="unarchive-tier"]').click();
const tierModal = await openTierModal(page, {slug});
await tierModal.getByRole('button', {name: 'Reactivate tier'}).click();
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Reactivate'}).click();
await tierModal.getByRole('button', {name: 'Save & close'}).click();
});
await test.step('Unarchived tier should be available in active tiers', async () => {
await expect(page.locator(`[data-test-tier-card="${tierId}"]`)).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 page.getByTestId('tiers').getByRole('tab', {name: 'Active'}).click();
await expect(page.locator(`[data-testid="tier-card"][data-tier="${slug}"]`)).toBeVisible();
});
await test.step('Unarchived tier should be available in portal settings', async () => {
await page.locator(`[data-test-settings-tier-label="${tierName}"]`);
expect(await page.locator(`[data-test-settings-tier-input="${tierName}"]`).isChecked()).toBeFalsy();
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()).toBeVisible();
await portalSettings.getByRole('button', {name: 'Close'}).click();
});
});
});

View File

@ -40,11 +40,17 @@ test.describe('Portal', () => {
});
test('Can donate with a fixed amount set and different currency', async ({page}) => {
await page.goto('/ghost/#/settings/members');
await page.getByTestId('expand-tips-and-donations').click();
await page.getByTestId('tips-and-donations-amount').fill('98');
await page.locator('#gh-tips-and-donations-currency').selectOption('EUR');
await page.locator('[data-test-button="save-settings"]').click();
await page.goto('/ghost/#/settings');
const section = page.getByTestId('tips-or-donations');
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
await page.goto('/#/portal/support');

View File

@ -1,26 +1,29 @@
const {expect, test} = require('@playwright/test');
const {createMember, impersonateMember} = require('../utils');
/**
* @param {import('@playwright/test').Page} page
*/
const addNewsletter = async (page) => {
// go to email settings
await page.goto('/ghost');
await page.locator('[data-test-nav="settings"]').click();
await page.locator('[data-test-nav="members-email"]').click();
// create newsletter
await page.locator('[data-test-button="add-newsletter"]').click();
await page.locator('[data-test-newsletter-title-input]').click();
await page.locator('[data-test-newsletter-title-input]').fill('One more newsletter');
await page.locator('[data-test-button="save-newsletter"]').click();
const section = page.getByTestId('newsletters');
await section.getByRole('button', {name: 'Add 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
await page.waitForSelector('[data-test-newsletter="one-more-newsletter"]');
await section.locator('*', {hasText: 'One more newsletter'}).first().waitFor();
};
test.describe('Portal', () => {
test.describe('Member actions', () => {
test.describe.configure({retries: 1});
test('can log out', async ({page}) => {
// create a new free member
await createMember(page, {

View File

@ -74,54 +74,49 @@ const setupGhost = async (page) => {
const disconnectStripe = async (page) => {
await deleteAllMembers(page);
await page.locator('.gh-nav a[href="#/settings/"]').click();
await page.locator('.gh-setting-group').filter({hasText: 'Membership'}).click();
if (await page.isVisible('.gh-btn-stripe-status.connected')) {
// Disconnect if already connected
await page.locator('.gh-btn-stripe-status.connected').click();
await page.locator('.modal-content .gh-btn-stripe-disconnect').first().click();
await page
.locator('.modal-content')
.filter({hasText: 'Are you sure you want to disconnect?'})
.first()
.getByRole('button', {name: 'Disconnect'})
.click();
await page.getByTestId('tiers').waitFor();
if (await page.isVisible('[data-testid="stripe-connected"]')) {
await page.getByTestId('stripe-connected').first().click();
await page.getByTestId('stripe-modal').getByRole('button', {name: 'Disconnect'}).click();
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Disconnect'}).click();
}
};
const setupStripe = async (page, stripConnectIntegrationToken) => {
await deleteAllMembers(page);
await page.locator('.gh-nav a[href="#/settings/"]').click();
await page.locator('.gh-setting-group').filter({hasText: 'Membership'}).click();
if (await page.isVisible('.gh-btn-stripe-status.connected')) {
await page.getByTestId('tiers').waitFor();
if (await page.isVisible('[data-testid="stripe-connected"]')) {
// Disconnect if already connected
await page.locator('.gh-btn-stripe-status.connected').click();
await page.locator('.modal-content .gh-btn-stripe-disconnect').first().click();
await page
.locator('.modal-content')
.filter({hasText: 'Are you sure you want to disconnect?'})
.first()
.getByRole('button', {name: 'Disconnect'})
.click();
await page.getByTestId('stripe-connected').first().click();
await page.getByTestId('stripe-modal').getByRole('button', {name: 'Disconnect'}).click();
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Disconnect'}).click();
} 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);
await page.getByRole('button', {name: 'Save Stripe settings'}).click();
const modal = page.getByTestId('stripe-modal');
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
await expect(page.locator('[data-test-button="stripe-disconnect"]')).toBeVisible();
await page.locator('[data-test-button="close-stripe-connect"]').click();
await expect(modal.getByRole('button', {name: 'Disconnect'})).toBeVisible();
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
const setupMailgun = async (page) => {
await page.locator('.gh-nav a[href="#/settings/"]').click();
await page.locator('.gh-setting-group').filter({hasText: 'Email newsletter'}).click();
await page.locator('.gh-expandable-block').filter({hasText: 'Mailgun configuration'}).getByRole('button', {name: 'Expand'}).click();
const section = page.getByTestId('mailgun');
await page.locator('[data-test-mailgun-domain-input]').fill('api.testgun.com');
await page.locator('[data-test-mailgun-api-key-input]').fill('Not an API key');
await page.locator('[data-test-button="save-members-settings"]').click();
await page.waitForSelector('[data-test-button="save-members-settings"] [data-test-task-button-state="success"]');
await section.getByRole('button', {name: 'Edit'}).click();
await section.getByLabel('Mailgun domain').fill('api.testgun.com');
await section.getByLabel('Mailgun private API key').fill('Not an API key');
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) => {
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'});
await alphaList.locator('label[for="labs-webmentions"]').click();
await alphaList.locator('label[for="labs-tipsAndDonations"]').click();
const section = page.getByTestId('labs');
await section.getByRole('button', {name: 'Open'}).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]
*/
const createTier = async (page, {name, monthlyPrice, yearlyPrice, trialDays}, enableInPortal = true) => {
await test.step('Create a tier', async () => {
// Navigate to the member settings
await page.locator('[data-test-nav="settings"]').click();
await page.locator('[data-test-nav="members-membership"]').click();
await page.locator('[data-test-nav="settings"]').click();
// Tiers request can take time, so waiting until there is no connections before interacting with them
await page.waitForLoadState('networkidle');
// Tiers request can take time, so waiting until there is no connections before interacting with them
await page.waitForLoadState('networkidle');
// Expand the premium tier list
await page.locator('[data-test-toggle-pub-info]').click();
// Archive if already exists
while (await page.locator('.gh-tier-card').filter({hasText: name}).first().isVisible()) {
const tierCard = page.locator('.gh-tier-card').filter({hasText: name}).first();
await tierCard.locator('.gh-tier-card-actions-button').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();
// Archive if already exists
while (await page.getByTestId('tier-card').filter({hasText: name}).first().isVisible()) {
await page.getByTestId('tier-card').filter({hasText: name}).first().click();
await page.getByTestId('tier-detail-modal').getByRole('button', {name: 'Archive tier'}).click();
await page.getByTestId('confirmation-modal').getByRole('button', {name: 'Archive'}).click();
await page.getByTestId('tier-detail-modal').getByRole('button', {name: 'Reactivate tier'}).waitFor();
await page.getByTestId('tier-detail-modal').getByRole('button', {name: 'Save & close'}).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
await page.goto('/ghost');
// Add the tier
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 () => {
await page.goto('/ghost');
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
await page.waitForLoadState('networkidle');
});
@ -463,14 +459,13 @@ const goToMembershipPage = async (page) => {
* Get tier card from membership page
* @param {import('@playwright/test').Page} page
* @param {Object} options
* @param {String} [options.id]
* @param {String} [options.slug]
*/
const getTierCardById = async (page, {id}) => {
return await test.step('Expand the premium tier list and find the tier', async () => {
await page.locator('[data-test-toggle-pub-info]').click();
await page.waitForSelector(`[data-test-tier-card="${id}"]`);
const openTierModal = async (page, {slug}) => {
return await test.step('Open the tier modal', async () => {
await page.getByTestId('tiers').locator(`[data-testid="tier-card"][data-tier="${slug}"]`).click();
return page.locator(`[data-test-tier-card="${id}"]`);
return page.getByTestId('tier-detail-modal');
});
};
@ -522,5 +517,5 @@ module.exports = {
completeStripeSubscription,
impersonateMember,
goToMembershipPage,
getTierCardById
openTierModal
};

View File

@ -2,7 +2,10 @@ let uniqueId = 0;
const getUniqueName = (prefix = 'id') => {
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('-');