mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-25 02:31:59 -05:00
Added functional tests for member sign-in flow
closes https://github.com/TryGhost/Team/issues/1347
This commit is contained in:
parent
6be29d900c
commit
4c15ecacd8
1 changed files with 290 additions and 0 deletions
290
ghost/portal/src/tests/SigninFlow.test.js
Normal file
290
ghost/portal/src/tests/SigninFlow.test.js
Normal file
|
@ -0,0 +1,290 @@
|
||||||
|
import React from 'react';
|
||||||
|
import App from '../App.js';
|
||||||
|
import {fireEvent, appRender, within, waitFor, prettyDOM} from '../utils/test-utils';
|
||||||
|
import {offer as FixtureOffer, site as FixtureSite} from '../utils/test-fixtures';
|
||||||
|
import setupGhostApi from '../utils/api.js';
|
||||||
|
|
||||||
|
const setup = async ({site, member = null}) => {
|
||||||
|
const ghostApi = setupGhostApi({siteUrl: 'https://example.com'});
|
||||||
|
ghostApi.init = jest.fn(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
site,
|
||||||
|
member
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ghostApi.member.sendMagicLink = jest.fn(() => {
|
||||||
|
return Promise.resolve('success');
|
||||||
|
});
|
||||||
|
|
||||||
|
ghostApi.member.checkoutPlan = jest.fn(() => {
|
||||||
|
return Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
const utils = appRender(
|
||||||
|
<App api={ghostApi} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const triggerButtonFrame = await utils.findByTitle(/portal-trigger/i);
|
||||||
|
const popupFrame = utils.queryByTitle(/portal-popup/i);
|
||||||
|
const popupIframeDocument = popupFrame.contentDocument;
|
||||||
|
const emailInput = within(popupIframeDocument).queryByLabelText(/email/i);
|
||||||
|
const nameInput = within(popupIframeDocument).queryByLabelText(/name/i);
|
||||||
|
const submitButton = within(popupIframeDocument).queryByRole('button', {name: 'Continue'});
|
||||||
|
const signinButton = within(popupIframeDocument).queryByRole('button', {name: 'Sign in'});
|
||||||
|
const siteTitle = within(popupIframeDocument).queryByText(site.title);
|
||||||
|
const freePlanTitle = within(popupIframeDocument).queryByText('Free');
|
||||||
|
const monthlyPlanTitle = within(popupIframeDocument).queryByText('Monthly');
|
||||||
|
const yearlyPlanTitle = within(popupIframeDocument).queryByText('Yearly');
|
||||||
|
const fullAccessTitle = within(popupIframeDocument).queryByText('Full access');
|
||||||
|
return {
|
||||||
|
ghostApi,
|
||||||
|
popupIframeDocument,
|
||||||
|
popupFrame,
|
||||||
|
triggerButtonFrame,
|
||||||
|
siteTitle,
|
||||||
|
emailInput,
|
||||||
|
nameInput,
|
||||||
|
signinButton,
|
||||||
|
submitButton,
|
||||||
|
freePlanTitle,
|
||||||
|
monthlyPlanTitle,
|
||||||
|
yearlyPlanTitle,
|
||||||
|
fullAccessTitle,
|
||||||
|
...utils
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const multiTierSetup = async ({site, member = null}) => {
|
||||||
|
const ghostApi = setupGhostApi({siteUrl: 'https://example.com'});
|
||||||
|
ghostApi.init = jest.fn(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
site,
|
||||||
|
member
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ghostApi.member.sendMagicLink = jest.fn(() => {
|
||||||
|
return Promise.resolve('success');
|
||||||
|
});
|
||||||
|
|
||||||
|
ghostApi.member.checkoutPlan = jest.fn(() => {
|
||||||
|
return Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
const utils = appRender(
|
||||||
|
<App api={ghostApi} />
|
||||||
|
);
|
||||||
|
const freeTierDescription = site.products?.find(p => p.type === 'free')?.description;
|
||||||
|
const triggerButtonFrame = await utils.findByTitle(/portal-trigger/i);
|
||||||
|
const popupFrame = utils.queryByTitle(/portal-popup/i);
|
||||||
|
const popupIframeDocument = popupFrame.contentDocument;
|
||||||
|
const emailInput = within(popupIframeDocument).queryByLabelText(/email/i);
|
||||||
|
const nameInput = within(popupIframeDocument).queryByLabelText(/name/i);
|
||||||
|
const submitButton = within(popupIframeDocument).queryByRole('button', {name: 'Continue'});
|
||||||
|
const signinButton = within(popupIframeDocument).queryByRole('button', {name: 'Sign in'});
|
||||||
|
const siteTitle = within(popupIframeDocument).queryByText(site.title);
|
||||||
|
const freePlanTitle = within(popupIframeDocument).queryAllByText(/free$/i);
|
||||||
|
const freePlanDescription = within(popupIframeDocument).queryAllByText(freeTierDescription);
|
||||||
|
const monthlyPlanTitle = within(popupIframeDocument).queryByText('Monthly');
|
||||||
|
const yearlyPlanTitle = within(popupIframeDocument).queryByText('Yearly');
|
||||||
|
const fullAccessTitle = within(popupIframeDocument).queryByText('Full access');
|
||||||
|
return {
|
||||||
|
ghostApi,
|
||||||
|
popupIframeDocument,
|
||||||
|
popupFrame,
|
||||||
|
triggerButtonFrame,
|
||||||
|
siteTitle,
|
||||||
|
emailInput,
|
||||||
|
nameInput,
|
||||||
|
signinButton,
|
||||||
|
submitButton,
|
||||||
|
freePlanTitle,
|
||||||
|
monthlyPlanTitle,
|
||||||
|
yearlyPlanTitle,
|
||||||
|
fullAccessTitle,
|
||||||
|
freePlanDescription,
|
||||||
|
...utils
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const realLocation = window.location;
|
||||||
|
|
||||||
|
describe('Signin', () => {
|
||||||
|
describe('on single tier site', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Mock window.location
|
||||||
|
Object.defineProperty(window, 'location', {
|
||||||
|
value: new URL('https://portal.localhost/#/portal/signin'),
|
||||||
|
writable: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
window.location = realLocation;
|
||||||
|
});
|
||||||
|
test.only('with default settings', async () => {
|
||||||
|
const {
|
||||||
|
ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, submitButton,popupIframeDocument
|
||||||
|
} = await setup({
|
||||||
|
site: FixtureSite.singleTier.basic
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(popupFrame).toBeInTheDocument();
|
||||||
|
expect(triggerButtonFrame).toBeInTheDocument();
|
||||||
|
expect(emailInput).toBeInTheDocument();
|
||||||
|
expect(nameInput).not.toBeInTheDocument();
|
||||||
|
expect(submitButton).toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.change(emailInput, {target: {value: 'jamie@example.com'}});
|
||||||
|
|
||||||
|
expect(emailInput).toHaveValue('jamie@example.com');
|
||||||
|
|
||||||
|
fireEvent.click(submitButton);
|
||||||
|
expect(ghostApi.member.sendMagicLink).toHaveBeenLastCalledWith({
|
||||||
|
email: 'jamie@example.com'
|
||||||
|
});
|
||||||
|
|
||||||
|
const magicLink = await within(popupIframeDocument).findByText(/sent you a login link/i);
|
||||||
|
expect(magicLink).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.only('without name field', async () => {
|
||||||
|
const {ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, submitButton,
|
||||||
|
popupIframeDocument} = await setup({
|
||||||
|
site: FixtureSite.singleTier.withoutName
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(popupFrame).toBeInTheDocument();
|
||||||
|
expect(triggerButtonFrame).toBeInTheDocument();
|
||||||
|
expect(emailInput).toBeInTheDocument();
|
||||||
|
expect(nameInput).not.toBeInTheDocument();
|
||||||
|
expect(submitButton).toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.change(emailInput, {target: {value: 'jamie@example.com'}});
|
||||||
|
|
||||||
|
expect(emailInput).toHaveValue('jamie@example.com');
|
||||||
|
|
||||||
|
fireEvent.click(submitButton);
|
||||||
|
expect(ghostApi.member.sendMagicLink).toHaveBeenLastCalledWith({
|
||||||
|
email: 'jamie@example.com'
|
||||||
|
});
|
||||||
|
|
||||||
|
const magicLink = await within(popupIframeDocument).findByText(/sent you a login link/i);
|
||||||
|
expect(magicLink).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.only('with only free plan', async () => {
|
||||||
|
let {ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, submitButton,
|
||||||
|
popupIframeDocument} = await setup({
|
||||||
|
site: FixtureSite.singleTier.onlyFreePlan
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(popupFrame).toBeInTheDocument();
|
||||||
|
expect(triggerButtonFrame).toBeInTheDocument();
|
||||||
|
expect(emailInput).toBeInTheDocument();
|
||||||
|
expect(nameInput).not.toBeInTheDocument();
|
||||||
|
expect(submitButton).toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.change(emailInput, {target: {value: 'jamie@example.com'}});
|
||||||
|
|
||||||
|
expect(emailInput).toHaveValue('jamie@example.com');
|
||||||
|
|
||||||
|
fireEvent.click(submitButton);
|
||||||
|
expect(ghostApi.member.sendMagicLink).toHaveBeenLastCalledWith({
|
||||||
|
email: 'jamie@example.com'
|
||||||
|
});
|
||||||
|
|
||||||
|
const magicLink = await within(popupIframeDocument).findByText(/sent you a login link/i);
|
||||||
|
expect(magicLink).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Signin', () => {
|
||||||
|
describe('on multi tier site', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Mock window.location
|
||||||
|
Object.defineProperty(window, 'location', {
|
||||||
|
value: new URL('https://portal.localhost/#/portal/signin'),
|
||||||
|
writable: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
window.location = realLocation;
|
||||||
|
});
|
||||||
|
test.only('with default settings', async () => {
|
||||||
|
const {ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, submitButton,
|
||||||
|
popupIframeDocument} = await multiTierSetup({
|
||||||
|
site: FixtureSite.multipleTiers.basic
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(popupFrame).toBeInTheDocument();
|
||||||
|
expect(triggerButtonFrame).toBeInTheDocument();
|
||||||
|
expect(emailInput).toBeInTheDocument();
|
||||||
|
expect(nameInput).not.toBeInTheDocument();
|
||||||
|
expect(submitButton).toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.change(emailInput, {target: {value: 'jamie@example.com'}});
|
||||||
|
|
||||||
|
expect(emailInput).toHaveValue('jamie@example.com');
|
||||||
|
|
||||||
|
fireEvent.click(submitButton);
|
||||||
|
expect(ghostApi.member.sendMagicLink).toHaveBeenLastCalledWith({
|
||||||
|
email: 'jamie@example.com'
|
||||||
|
});
|
||||||
|
|
||||||
|
const magicLink = await within(popupIframeDocument).findByText(/sent you a login link/i);
|
||||||
|
expect(magicLink).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.only('without name field', async () => {
|
||||||
|
const {ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, submitButton,
|
||||||
|
popupIframeDocument} = await multiTierSetup({
|
||||||
|
site: FixtureSite.multipleTiers.withoutName
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(popupFrame).toBeInTheDocument();
|
||||||
|
expect(triggerButtonFrame).toBeInTheDocument();
|
||||||
|
expect(emailInput).toBeInTheDocument();
|
||||||
|
expect(nameInput).not.toBeInTheDocument();
|
||||||
|
expect(submitButton).toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.change(emailInput, {target: {value: 'jamie@example.com'}});
|
||||||
|
|
||||||
|
expect(emailInput).toHaveValue('jamie@example.com');
|
||||||
|
|
||||||
|
fireEvent.click(submitButton);
|
||||||
|
expect(ghostApi.member.sendMagicLink).toHaveBeenLastCalledWith({
|
||||||
|
email: 'jamie@example.com'
|
||||||
|
});
|
||||||
|
|
||||||
|
const magicLink = await within(popupIframeDocument).findByText(/sent you a login link/i);
|
||||||
|
expect(magicLink).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.only('with only free plan available', async () => {
|
||||||
|
let {ghostApi, popupFrame, triggerButtonFrame, emailInput, nameInput, submitButton,
|
||||||
|
popupIframeDocument} = await multiTierSetup({
|
||||||
|
site: FixtureSite.multipleTiers.onlyFreePlan
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(popupFrame).toBeInTheDocument();
|
||||||
|
expect(triggerButtonFrame).toBeInTheDocument();
|
||||||
|
expect(emailInput).toBeInTheDocument();
|
||||||
|
expect(nameInput).not.toBeInTheDocument();
|
||||||
|
expect(submitButton).toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.change(emailInput, {target: {value: 'jamie@example.com'}});
|
||||||
|
|
||||||
|
expect(emailInput).toHaveValue('jamie@example.com');
|
||||||
|
|
||||||
|
fireEvent.click(submitButton);
|
||||||
|
expect(ghostApi.member.sendMagicLink).toHaveBeenLastCalledWith({
|
||||||
|
email: 'jamie@example.com'
|
||||||
|
});
|
||||||
|
|
||||||
|
const magicLink = await within(popupIframeDocument).findByText(/sent you a login link/i);
|
||||||
|
expect(magicLink).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Add table
Reference in a new issue