mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-11-09 01:22:27 +05:30
Add more auth/oauth/multi-acc related test cases
This commit is contained in:
parent
0325f0aac4
commit
951f538ee5
@ -66,9 +66,10 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
styles.accountSwitcher,
|
||||
styles[`${skin}AccountSwitcher`],
|
||||
)}
|
||||
data-testid="account-switcher"
|
||||
>
|
||||
{highlightActiveAccount ? (
|
||||
<div className={styles.item}>
|
||||
{highlightActiveAccount && (
|
||||
<div className={styles.item} data-testid="active-account">
|
||||
<div
|
||||
className={clsx(
|
||||
styles.accountIcon,
|
||||
@ -97,6 +98,7 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
<div className={styles.link}>
|
||||
<a
|
||||
className={styles.link}
|
||||
data-testid="logout-account"
|
||||
onClick={this.onRemove(activeAccount)}
|
||||
href="#"
|
||||
>
|
||||
@ -106,11 +108,13 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
)}
|
||||
|
||||
{available.map((account, index) => (
|
||||
<div
|
||||
className={clsx(styles.item, styles.accountSwitchItem)}
|
||||
key={account.id}
|
||||
data-e2e-account-id={account.id}
|
||||
onClick={this.onSwitch(account)}
|
||||
>
|
||||
<div
|
||||
@ -125,6 +129,7 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
{allowLogout ? (
|
||||
<div
|
||||
className={styles.logoutIcon}
|
||||
data-testid="logout-account"
|
||||
onClick={this.onRemove(account)}
|
||||
/>
|
||||
) : (
|
||||
@ -141,6 +146,7 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
<Link to="/login" onClick={this.props.onAfterAction}>
|
||||
<Button
|
||||
color={COLOR_WHITE}
|
||||
data-testid="add-account"
|
||||
block
|
||||
small
|
||||
className={styles.addAccount}
|
||||
|
@ -89,10 +89,12 @@ class RootPage extends React.PureComponent<{
|
||||
<Route path="/rules" component={RulesPage} />
|
||||
<Route path="/dev" component={DevPage} />
|
||||
|
||||
{!user.isGuest && (
|
||||
<PrivateRoute exact path="/" component={ProfilePage} />
|
||||
)}
|
||||
|
||||
<AuthFlowRoute
|
||||
exact
|
||||
path="/"
|
||||
key="indexPage"
|
||||
component={user.isGuest ? AuthPage : ProfilePage}
|
||||
/>
|
||||
<AuthFlowRoute path="/" component={AuthPage} />
|
||||
|
||||
<Route component={PageNotFound} />
|
||||
|
@ -77,6 +77,7 @@ export default class AuthFlow implements AuthContext {
|
||||
onReady: () => void;
|
||||
navigate: (route: string, options: { replace?: boolean }) => void;
|
||||
currentRequest: Request;
|
||||
oAuthStateRestored = false;
|
||||
dispatch: (action: { [key: string]: any }) => void;
|
||||
getState: () => RootState;
|
||||
|
||||
@ -184,9 +185,6 @@ export default class AuthFlow implements AuthContext {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {object} - current request object
|
||||
*/
|
||||
getRequest() {
|
||||
return {
|
||||
path: '',
|
||||
@ -296,6 +294,12 @@ export default class AuthFlow implements AuthContext {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.oAuthStateRestored) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.oAuthStateRestored = true;
|
||||
|
||||
try {
|
||||
const data = JSON.parse(localStorage.getItem('oauthData'));
|
||||
const expirationTime = 2 * 60 * 60 * 1000; // 2h
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"account1": {
|
||||
"id": "7",
|
||||
"id": 7,
|
||||
"username": "SleepWalker",
|
||||
"email": "danilenkos@auroraglobal.com",
|
||||
"login": "SleepWalker",
|
||||
|
@ -1,4 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
import { account1 } from '../../fixtures/accounts.json';
|
||||
|
||||
const defaults = {
|
||||
client_id: 'ely',
|
||||
redirect_uri: 'http://ely.by/authorization/oauth',
|
||||
@ -14,6 +16,29 @@ it('should complete oauth', () => {
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
|
||||
it('should restore previous oauthData if any', () => {
|
||||
localStorage.setItem(
|
||||
'oauthData',
|
||||
JSON.stringify({
|
||||
timestamp: Date.now() - 3600,
|
||||
payload: {
|
||||
clientId: 'ely',
|
||||
redirectUrl: 'http://ely.by/authorization/oauth',
|
||||
responseType: 'code',
|
||||
description: null,
|
||||
scope: 'account_info account_email',
|
||||
loginHint: null,
|
||||
state: null,
|
||||
},
|
||||
}),
|
||||
);
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
|
||||
it('should ask to choose an account if user has multiple', () => {
|
||||
cy.login({ accounts: ['default', 'default2'] }).then(
|
||||
({ accounts: [account] }) => {
|
||||
@ -72,6 +97,20 @@ it('should prompt for permissions', () => {
|
||||
cy.url().should('match', /^http:\/\/localhost:8080\/?\?code=[^&]+&state=$/);
|
||||
});
|
||||
|
||||
it('should allow sign in during oauth (guest oauth)', () => {
|
||||
cy.visit(`/oauth2/v1/ely?${new URLSearchParams(defaults)}`);
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
|
||||
// TODO: enable, when backend api will return correct response on auth decline
|
||||
xit('should redirect to error page, when permission request declined', () => {
|
||||
cy.server();
|
||||
@ -170,7 +209,28 @@ describe('login_hint', () => {
|
||||
|
||||
describe('prompts', () => {
|
||||
it('should prompt for account', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
cy.login({ accounts: ['default'] }).then(({ accounts: [account] }) => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
prompt: 'select_account',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow sign in with another account', () => {
|
||||
cy.login({ accounts: ['default2'] });
|
||||
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
@ -181,7 +241,19 @@ describe('prompts', () => {
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('another account')
|
||||
.click();
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
cy.url().should('equal', 'https://ely.by/');
|
||||
});
|
||||
|
||||
it('should prompt for permissions', () => {
|
||||
@ -258,6 +330,33 @@ describe('prompts', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow sign in during oauth (guest oauth)', () => {
|
||||
cy.visit(
|
||||
`/oauth2/v1/ely?${new URLSearchParams({
|
||||
...defaults,
|
||||
client_id: 'tlauncher',
|
||||
redirect_uri: 'http://localhost:8080',
|
||||
prompt: 'select_account,consent',
|
||||
})}`,
|
||||
);
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
|
||||
cy.url().should('match', /^http:\/\/localhost:8080\/?\?code=[^&]+&state=$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('static pages', () => {
|
@ -1,8 +1,10 @@
|
||||
import { account1 } from '../../fixtures/accounts.json';
|
||||
import { account1, account2 } from '../../fixtures/accounts.json';
|
||||
|
||||
it('should sign in', () => {
|
||||
cy.visit('/');
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
@ -122,3 +124,129 @@ it('should sign in with totp', () => {
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
|
||||
it('should allow logout', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account')
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
cy.getByTestId('toolbar').should('contain', 'Join');
|
||||
});
|
||||
|
||||
describe('multi account', () => {
|
||||
it('should allow sign in with another account', () => {
|
||||
cy.login({ accounts: ['default2'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account').should('have.length', 1);
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
|
||||
cy.getByTestId('add-account').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
|
||||
cy.get('[data-e2e-go-back]').should('exist');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account').should('have.length', 1);
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 1);
|
||||
|
||||
cy.get('[data-e2e-account-id]')
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
});
|
||||
|
||||
it('should go back to profile from login screen', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('add-account').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
|
||||
cy.get('[data-e2e-go-back]').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
|
||||
it('should allow logout active account', () => {
|
||||
cy.login({ accounts: ['default', 'default2'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account')
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
});
|
||||
|
||||
it('should not allow log in the same account twice', () => {
|
||||
cy.login({ accounts: ['default'] });
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
|
||||
cy.getByTestId('active-account').should('have.length', 1);
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
|
||||
cy.getByTestId('add-account').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
|
||||
cy.get('[data-e2e-go-back]').should('exist');
|
||||
|
||||
cy.get('[name=login]').type(`${account1.login}{enter}`);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(`${account1.password}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
});
|
||||
});
|
||||
|
@ -27,8 +27,8 @@ import { account1, account2 } from '../fixtures/accounts';
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
|
||||
const accountsMap = {
|
||||
default: account2,
|
||||
default2: account1,
|
||||
default: account1,
|
||||
default2: account2,
|
||||
};
|
||||
|
||||
Cypress.Commands.add(
|
||||
@ -82,8 +82,18 @@ Cypress.Commands.add(
|
||||
},
|
||||
);
|
||||
|
||||
Cypress.Commands.add('getByTestId', (id, options) =>
|
||||
cy.get(`[data-testid=${id}]`, options),
|
||||
Cypress.Commands.add(
|
||||
'getByTestId',
|
||||
{ prevSubject: 'optional' },
|
||||
(subject, id, options) => {
|
||||
const selector = `[data-testid=${id}]`;
|
||||
|
||||
if (subject) {
|
||||
return cy.wrap(subject.find(selector));
|
||||
}
|
||||
|
||||
return cy.get(selector, options);
|
||||
},
|
||||
);
|
||||
|
||||
function createState(accounts) {
|
||||
|
Loading…
Reference in New Issue
Block a user