mirror of
https://github.com/elyby/accounts-frontend.git
synced 2025-05-31 14:11:58 +05:30
Upgrade prettier before it will be removed forever
This commit is contained in:
@@ -69,7 +69,6 @@ module.exports = {
|
||||
'error',
|
||||
{ min: 2, exceptions: ['x', 'y', 'i', 'k', 'l', 'm', 'n', '$', '_'] },
|
||||
],
|
||||
'require-atomic-updates': 'warn',
|
||||
'guard-for-in': ['error'],
|
||||
'no-var': ['error'],
|
||||
'prefer-const': ['error'],
|
||||
|
@@ -7,3 +7,5 @@ cache
|
||||
*.png
|
||||
*.gif
|
||||
*.svg
|
||||
*.hbs
|
||||
.gitlab-ci.yml
|
||||
|
@@ -5,7 +5,7 @@ import storyDecorator from './storyDecorator';
|
||||
const req = require.context('../packages/app', true, /\.story\.[tj]sx?$/);
|
||||
|
||||
function loadStories() {
|
||||
req.keys().forEach(filename => req(filename));
|
||||
req.keys().forEach((filename) => req(filename));
|
||||
}
|
||||
|
||||
addDecorator(storyDecorator);
|
||||
|
@@ -9,7 +9,7 @@ import { IntlDecorator } from './decorators';
|
||||
|
||||
const store = storeFactory();
|
||||
|
||||
export default (story => {
|
||||
export default ((story) => {
|
||||
const channel = addons.getChannel();
|
||||
|
||||
return (
|
||||
|
@@ -31,8 +31,8 @@
|
||||
"test:watch": "yarn test --watch",
|
||||
"lint": "eslint --ext js,ts,tsx --fix .",
|
||||
"lint:check": "eslint --ext js,ts,tsx --quiet .",
|
||||
"prettier": "prettier --write \"{packages/**/*,tests-e2e/**/*,jest/**/*,config/**/*,*}.{js,ts,tsx,json,md,scss,css}\"",
|
||||
"prettier:check": "prettier --check \"{packages/**/*,tests-e2e/**/*,jest/**/*,config/**/*,*}.{js,ts,tsx,json,md,scss,css}\"",
|
||||
"prettier": "prettier --write .",
|
||||
"prettier:check": "prettier --check .",
|
||||
"ts:check": "tsc",
|
||||
"ci:check": "yarn lint:check && yarn ts:check && yarn test",
|
||||
"analyze": "yarn run clean && yarn run build:webpack --analyze",
|
||||
@@ -154,7 +154,7 @@
|
||||
"postcss-import": "^12.0.1",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-scss": "^2.1.1",
|
||||
"prettier": "^1.19.1",
|
||||
"prettier": "^2.0.5",
|
||||
"raw-loader": "^4.0.1",
|
||||
"react-test-renderer": "^16.13.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
|
@@ -57,7 +57,9 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
let { available } = accounts;
|
||||
|
||||
if (highlightActiveAccount) {
|
||||
available = available.filter(account => account.id !== activeAccount.id);
|
||||
available = available.filter(
|
||||
(account) => account.id !== activeAccount.id,
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -152,7 +154,7 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
className={styles.addAccount}
|
||||
label={
|
||||
<Message {...messages.addAccount}>
|
||||
{message => (
|
||||
{(message) => (
|
||||
<span>
|
||||
<div className={styles.addIcon} />
|
||||
{message}
|
||||
@@ -178,7 +180,7 @@ export class AccountSwitcher extends React.Component<Props> {
|
||||
.then(() => this.props.onSwitch(account))
|
||||
// we won't sent any logs to sentry, because an error should be already
|
||||
// handled by external logic
|
||||
.catch(error => console.warn('Error switching account', { error }))
|
||||
.catch((error) => console.warn('Error switching account', { error }))
|
||||
.finally(() => loader.hide());
|
||||
};
|
||||
|
||||
|
@@ -48,7 +48,7 @@ describe('components/accounts/actions', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
dispatch = sinon
|
||||
.spy(arg => (typeof arg === 'function' ? arg(dispatch, getState) : arg))
|
||||
.spy((arg) => (typeof arg === 'function' ? arg(dispatch, getState) : arg))
|
||||
.named('store.dispatch');
|
||||
getState = sinon.stub().named('store.getState');
|
||||
|
||||
@@ -146,7 +146,7 @@ describe('components/accounts/actions', () => {
|
||||
));
|
||||
|
||||
it('resolves with account', () =>
|
||||
authenticate(account)(dispatch, getState, undefined).then(resp =>
|
||||
authenticate(account)(dispatch, getState, undefined).then((resp) =>
|
||||
expect(resp, 'to equal', account),
|
||||
));
|
||||
|
||||
|
@@ -53,7 +53,7 @@ export function authenticate(
|
||||
}
|
||||
|
||||
const knownAccount = getState().accounts.available.find(
|
||||
item => item.id === accountId,
|
||||
(item) => item.id === accountId,
|
||||
);
|
||||
|
||||
if (knownAccount) {
|
||||
@@ -246,10 +246,10 @@ export function requestNewToken(): ThunkAction<Promise<void>> {
|
||||
}
|
||||
|
||||
return requestToken(refreshToken)
|
||||
.then(token => {
|
||||
.then((token) => {
|
||||
dispatch(updateToken(token));
|
||||
})
|
||||
.catch(resp => {
|
||||
.catch((resp) => {
|
||||
// all the logic to get the valid token was failed,
|
||||
// looks like we have some problems with token
|
||||
// lets redirect to login page
|
||||
@@ -313,7 +313,7 @@ export function logoutAll(): ThunkAction<Promise<void>> {
|
||||
accounts: { available },
|
||||
} = getState();
|
||||
|
||||
available.forEach(account =>
|
||||
available.forEach((account) =>
|
||||
logout(account.token).catch(() => {
|
||||
// we don't care
|
||||
}),
|
||||
@@ -345,10 +345,12 @@ export function logoutStrangers(): ThunkAction<Promise<void>> {
|
||||
!refreshToken && !sessionStorage.getItem(`stranger${id}`);
|
||||
|
||||
if (available.some(isStranger)) {
|
||||
const accountToReplace = available.find(account => !isStranger(account));
|
||||
const accountToReplace = available.find(
|
||||
(account) => !isStranger(account),
|
||||
);
|
||||
|
||||
if (accountToReplace) {
|
||||
available.filter(isStranger).forEach(account => {
|
||||
available.filter(isStranger).forEach((account) => {
|
||||
dispatch(remove(account));
|
||||
logout(account.token);
|
||||
});
|
||||
|
@@ -17,7 +17,7 @@ export function getActiveAccount(state: { accounts: State }): Account | null {
|
||||
const accountId = state.accounts.active;
|
||||
|
||||
return (
|
||||
state.accounts.available.find(account => account.id === accountId) || null
|
||||
state.accounts.available.find((account) => account.id === accountId) || null
|
||||
);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export default function accounts(
|
||||
const { payload } = action;
|
||||
|
||||
state.available = state.available
|
||||
.filter(account => account.id !== payload.id)
|
||||
.filter((account) => account.id !== payload.id)
|
||||
.concat(payload);
|
||||
|
||||
state.available.sort((account1, account2) => {
|
||||
@@ -65,7 +65,7 @@ export default function accounts(
|
||||
const { payload } = action;
|
||||
|
||||
return {
|
||||
available: state.available.map(account => {
|
||||
available: state.available.map((account) => {
|
||||
if (account.id === payload.id) {
|
||||
return { ...payload };
|
||||
}
|
||||
@@ -91,7 +91,9 @@ export default function accounts(
|
||||
|
||||
return {
|
||||
...state,
|
||||
available: state.available.filter(account => account.id !== payload.id),
|
||||
available: state.available.filter(
|
||||
(account) => account.id !== payload.id,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -104,7 +106,7 @@ export default function accounts(
|
||||
|
||||
return {
|
||||
...state,
|
||||
available: state.available.map(account => {
|
||||
available: state.available.map((account) => {
|
||||
if (account.id === state.active) {
|
||||
return {
|
||||
...account,
|
||||
|
@@ -5,7 +5,7 @@ import { FormattedMessage as Message, MessageDescriptor } from 'react-intl';
|
||||
export default function AuthTitle({ title }: { title: MessageDescriptor }) {
|
||||
return (
|
||||
<Message {...title}>
|
||||
{msg => (
|
||||
{(msg) => (
|
||||
<span>
|
||||
{msg}
|
||||
<Helmet title={msg as string} />
|
||||
|
@@ -1,4 +1,9 @@
|
||||
import React, { CSSProperties, MouseEventHandler, ReactElement, ReactNode } from 'react';
|
||||
import React, {
|
||||
CSSProperties,
|
||||
MouseEventHandler,
|
||||
ReactElement,
|
||||
ReactNode,
|
||||
} from 'react';
|
||||
import { AccountsState } from 'app/components/accounts';
|
||||
import { User } from 'app/components/user';
|
||||
import { connect } from 'react-redux';
|
||||
@@ -64,7 +69,7 @@ if (process.env.NODE_ENV !== 'production') {
|
||||
// TODO: it may be moved to tests in future
|
||||
|
||||
contexts.reduce((acc, context) => {
|
||||
context.forEach(panel => {
|
||||
context.forEach((panel) => {
|
||||
if (acc[panel]) {
|
||||
throw new Error(
|
||||
`Panel ${panel} is already exists in context ${JSON.stringify(
|
||||
@@ -186,7 +191,7 @@ class PanelTransition extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.timerIds.forEach(id => clearTimeout(id));
|
||||
this.timerIds.forEach((id) => clearTimeout(id));
|
||||
this.timerIds = [];
|
||||
}
|
||||
|
||||
@@ -262,7 +267,7 @@ class PanelTransition extends React.PureComponent<Props, State> {
|
||||
willEnter={this.willEnter}
|
||||
willLeave={this.willLeave}
|
||||
>
|
||||
{items => {
|
||||
{(items) => {
|
||||
const panels = items.filter(({ key }) => key !== 'common');
|
||||
const [common] = items.filter(({ key }) => key === 'common');
|
||||
|
||||
@@ -289,7 +294,7 @@ class PanelTransition extends React.PureComponent<Props, State> {
|
||||
>
|
||||
<Panel>
|
||||
<PanelHeader>
|
||||
{panels.map(config => this.getHeader(config))}
|
||||
{panels.map((config) => this.getHeader(config))}
|
||||
</PanelHeader>
|
||||
<div style={contentHeight}>
|
||||
<MeasureHeight
|
||||
@@ -298,11 +303,11 @@ class PanelTransition extends React.PureComponent<Props, State> {
|
||||
>
|
||||
<PanelBody>
|
||||
<div style={bodyHeight}>
|
||||
{panels.map(config => this.getBody(config))}
|
||||
{panels.map((config) => this.getBody(config))}
|
||||
</div>
|
||||
</PanelBody>
|
||||
<PanelFooter>
|
||||
{panels.map(config => this.getFooter(config))}
|
||||
{panels.map((config) => this.getFooter(config))}
|
||||
</PanelFooter>
|
||||
</MeasureHeight>
|
||||
</div>
|
||||
@@ -311,7 +316,7 @@ class PanelTransition extends React.PureComponent<Props, State> {
|
||||
className={helpLinksStyles}
|
||||
data-testid="auth-controls-secondary"
|
||||
>
|
||||
{panels.map(config => this.getLinks(config))}
|
||||
{panels.map((config) => this.getLinks(config))}
|
||||
</div>
|
||||
</Form>
|
||||
);
|
||||
@@ -356,7 +361,7 @@ class PanelTransition extends React.PureComponent<Props, State> {
|
||||
const fromLeft = -1;
|
||||
const fromRight = 1;
|
||||
|
||||
const currentContext = contexts.find(context => context.includes(key));
|
||||
const currentContext = contexts.find((context) => context.includes(key));
|
||||
|
||||
if (!currentContext) {
|
||||
throw new Error(`Can not find settings for ${key} panel`);
|
||||
@@ -377,7 +382,7 @@ class PanelTransition extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
getDirection(next: PanelId, prev: PanelId): 'X' | 'Y' {
|
||||
const context = contexts.find(item => item.includes(prev));
|
||||
const context = contexts.find((item) => item.includes(prev));
|
||||
|
||||
if (!context) {
|
||||
throw new Error(`Can not find context for transition ${prev} -> ${next}`);
|
||||
@@ -521,11 +526,11 @@ class PanelTransition extends React.PureComponent<Props, State> {
|
||||
key={`body/${key}`}
|
||||
style={transitionStyle}
|
||||
state={this.shouldMeasureHeight()}
|
||||
onMeasure={height => this.onUpdateHeight(height, key)}
|
||||
onMeasure={(height) => this.onUpdateHeight(height, key)}
|
||||
>
|
||||
{React.cloneElement(Body, {
|
||||
// @ts-ignore
|
||||
ref: body => {
|
||||
ref: (body) => {
|
||||
this.body = body;
|
||||
},
|
||||
})}
|
||||
@@ -596,7 +601,7 @@ class PanelTransition extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
requestRedraw = (): Promise<void> =>
|
||||
new Promise(resolve =>
|
||||
new Promise((resolve) =>
|
||||
this.setState({ isHeightDirty: true }, () => {
|
||||
this.setState({ isHeightDirty: false });
|
||||
|
||||
|
@@ -25,7 +25,7 @@ const RejectionLink: ComponentType<Props> = ({
|
||||
return (
|
||||
<a
|
||||
href="#"
|
||||
onClick={event => {
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
||||
context.reject(payload);
|
||||
|
@@ -176,7 +176,7 @@ describe('components/auth/actions', () => {
|
||||
|
||||
(request.post as any).returns(Promise.reject(resp));
|
||||
|
||||
return callThunk(oAuthComplete).catch(error => {
|
||||
return callThunk(oAuthComplete).catch((error) => {
|
||||
expect(error.acceptRequired, 'to be true');
|
||||
expectDispatchCalls([[requirePermissionsAccept()]]);
|
||||
});
|
||||
|
@@ -87,10 +87,10 @@ export function login({
|
||||
totp?: string;
|
||||
rememberMe?: boolean;
|
||||
}) {
|
||||
return wrapInLoader(dispatch =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
loginEndpoint({ login, password, totp, rememberMe })
|
||||
.then(authHandler(dispatch))
|
||||
.catch(resp => {
|
||||
.catch((resp) => {
|
||||
if (resp.errors) {
|
||||
if (resp.errors.password === PASSWORD_REQUIRED) {
|
||||
return dispatch(setLogin(login));
|
||||
@@ -118,7 +118,7 @@ export function login({
|
||||
}
|
||||
|
||||
export function acceptRules() {
|
||||
return wrapInLoader(dispatch =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
dispatch(userAcceptRules()).catch(validationErrorsHandler(dispatch)),
|
||||
);
|
||||
}
|
||||
@@ -152,7 +152,7 @@ export function recoverPassword({
|
||||
newPassword: string;
|
||||
newRePassword: string;
|
||||
}) {
|
||||
return wrapInLoader(dispatch =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
recoverPasswordEndpoint(key, newPassword, newRePassword)
|
||||
.then(authHandler(dispatch))
|
||||
.catch(validationErrorsHandler(dispatch, '/forgot-password')),
|
||||
@@ -205,7 +205,7 @@ export function activate({
|
||||
}: {
|
||||
key: string;
|
||||
}): ThunkAction<Promise<Account>> {
|
||||
return wrapInLoader(dispatch =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
activateEndpoint(key)
|
||||
.then(authHandler(dispatch))
|
||||
.catch(validationErrorsHandler(dispatch, '/resend-activation')),
|
||||
@@ -219,9 +219,9 @@ export function resendActivation({
|
||||
email: string;
|
||||
captcha: string;
|
||||
}) {
|
||||
return wrapInLoader(dispatch =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
resendActivationEndpoint(email, captcha)
|
||||
.then(resp => {
|
||||
.then((resp) => {
|
||||
dispatch(
|
||||
updateUser({
|
||||
email,
|
||||
@@ -368,17 +368,17 @@ const KNOWN_SCOPES: ReadonlyArray<string> = [
|
||||
export function oAuthValidate(oauthData: OauthData) {
|
||||
// TODO: move to oAuth actions?
|
||||
// test request: /oauth?client_id=ely&redirect_uri=http%3A%2F%2Fely.by&response_type=code&scope=minecraft_server_session&description=foo
|
||||
return wrapInLoader(dispatch =>
|
||||
return wrapInLoader((dispatch) =>
|
||||
oauth
|
||||
.validate(oauthData)
|
||||
.then(resp => {
|
||||
.then((resp) => {
|
||||
const { scopes } = resp.session;
|
||||
const invalidScopes = scopes.filter(
|
||||
scope => !KNOWN_SCOPES.includes(scope),
|
||||
(scope) => !KNOWN_SCOPES.includes(scope),
|
||||
);
|
||||
let prompt = (oauthData.prompt || 'none')
|
||||
.split(',')
|
||||
.map(item => item.trim());
|
||||
.map((item) => item.trim());
|
||||
|
||||
if (prompt.includes('none')) {
|
||||
prompt = ['none'];
|
||||
@@ -415,7 +415,7 @@ export function oAuthValidate(oauthData: OauthData) {
|
||||
/**
|
||||
* @param {object} params
|
||||
* @param {bool} params.accept=false
|
||||
*
|
||||
* @param params.accept
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function oAuthComplete(params: { accept?: boolean } = {}) {
|
||||
@@ -638,12 +638,12 @@ function wrapInLoader<T>(fn: ThunkAction<Promise<T>>): ThunkAction<Promise<T>> {
|
||||
const endLoading = () => dispatch(setLoadingState(false));
|
||||
|
||||
return fn(dispatch, getState, undefined).then(
|
||||
resp => {
|
||||
(resp) => {
|
||||
endLoading();
|
||||
|
||||
return resp;
|
||||
},
|
||||
resp => {
|
||||
(resp) => {
|
||||
endLoading();
|
||||
|
||||
return Promise.reject(resp);
|
||||
@@ -668,7 +668,7 @@ function authHandler(dispatch: Dispatch) {
|
||||
token: oAuthResp.access_token,
|
||||
refreshToken: oAuthResp.refresh_token || null,
|
||||
}),
|
||||
).then(resp => {
|
||||
).then((resp) => {
|
||||
dispatch(setLogin(null));
|
||||
|
||||
return resp;
|
||||
@@ -684,7 +684,7 @@ function validationErrorsHandler(
|
||||
data?: Record<string, any>;
|
||||
}>,
|
||||
) => Promise<never> {
|
||||
return resp => {
|
||||
return (resp) => {
|
||||
if (resp.errors) {
|
||||
const [firstError] = Object.keys(resp.errors);
|
||||
const firstErrorObj: ValidationError = {
|
||||
@@ -711,7 +711,7 @@ function validationErrorsHandler(
|
||||
}
|
||||
|
||||
// TODO: can I clone the object or its necessary to catch modified errors list on corresponding catches?
|
||||
const errors: Record<string, ValidationError> = resp.errors;
|
||||
const { errors } = resp;
|
||||
errors[firstError] = firstErrorObj;
|
||||
|
||||
dispatch(setErrors(errors));
|
||||
|
@@ -25,7 +25,7 @@ interface FactoryParams {
|
||||
links?: RejectionLinkProps | Array<RejectionLinkProps>;
|
||||
}
|
||||
|
||||
export default function({
|
||||
export default function ({
|
||||
title,
|
||||
body,
|
||||
footer,
|
||||
|
@@ -84,7 +84,7 @@ class Finish extends React.Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
onCopyClick: MouseEventHandler = event => {
|
||||
onCopyClick: MouseEventHandler = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const { code } = this.props;
|
||||
|
@@ -10,7 +10,7 @@ export default factory({
|
||||
label: messages.next,
|
||||
},
|
||||
links: {
|
||||
isAvailable: context => !context.user.isGuest,
|
||||
isAvailable: (context) => !context.user.isGuest,
|
||||
label: messages.createNewAccount,
|
||||
},
|
||||
});
|
||||
|
@@ -41,7 +41,7 @@ export default class PermissionsBody extends BaseAuthBody {
|
||||
<Message {...messages.theAppNeedsAccess2} />
|
||||
</div>
|
||||
<ul className={styles.permissionsList}>
|
||||
{scopes.map(scope => {
|
||||
{scopes.map((scope) => {
|
||||
const key = `scope_${scope}`;
|
||||
const message = messages[key];
|
||||
|
||||
@@ -50,7 +50,7 @@ export default class PermissionsBody extends BaseAuthBody {
|
||||
{message ? (
|
||||
<Message {...message} />
|
||||
) : (
|
||||
scope.replace(/^\w|_/g, match =>
|
||||
scope.replace(/^\w|_/g, (match) =>
|
||||
match.replace('_', ' ').toUpperCase(),
|
||||
)
|
||||
)}
|
||||
|
@@ -40,7 +40,7 @@ describe('ContactForm', () => {
|
||||
type: 'TextArea',
|
||||
name: 'message',
|
||||
},
|
||||
].forEach(el => {
|
||||
].forEach((el) => {
|
||||
it(`should have ${el.name} field`, () => {
|
||||
expect(component.find(`${el.type}[name="${el.name}"]`), 'to satisfy', {
|
||||
length: 1,
|
||||
@@ -107,7 +107,7 @@ describe('ContactForm', () => {
|
||||
|
||||
wrapper = mount(
|
||||
<IntlProvider locale="en" defaultLocale="en">
|
||||
<ContactForm user={user} ref={el => (component = el!)} />
|
||||
<ContactForm user={user} ref={(el) => (component = el!)} />
|
||||
</IntlProvider>,
|
||||
);
|
||||
});
|
||||
@@ -143,7 +143,7 @@ describe('ContactForm', () => {
|
||||
// TODO: try to rewrite with unexpected-react
|
||||
wrapper = mount(
|
||||
<IntlProvider locale="en" defaultLocale="en">
|
||||
<ContactForm user={user} ref={el => (component = el!)} />
|
||||
<ContactForm user={user} ref={(el) => (component = el!)} />
|
||||
</IntlProvider>,
|
||||
);
|
||||
|
||||
|
@@ -187,7 +187,7 @@ export class ContactForm extends React.Component<
|
||||
lastEmail: this.form.value('email'),
|
||||
}),
|
||||
)
|
||||
.catch(resp => {
|
||||
.catch((resp) => {
|
||||
if (resp.errors) {
|
||||
this.form.setErrors(resp.errors);
|
||||
|
||||
|
@@ -12,7 +12,7 @@ function ContactLink({ createContactPopup, ...props }: Props) {
|
||||
<a
|
||||
href="#"
|
||||
data-e2e-button="feedbackPopup"
|
||||
onClick={event => {
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
|
||||
createContactPopup();
|
||||
|
@@ -22,11 +22,11 @@ export function getApp(
|
||||
state: { apps: Apps },
|
||||
clientId: string,
|
||||
): OauthAppResponse | null {
|
||||
return state.apps.available.find(app => app.clientId === clientId) || null;
|
||||
return state.apps.available.find((app) => app.clientId === clientId) || null;
|
||||
}
|
||||
|
||||
export function fetchApp(clientId: string): ThunkAction<Promise<void>> {
|
||||
return async dispatch => {
|
||||
return async (dispatch) => {
|
||||
const app = await oauth.getApp(clientId);
|
||||
|
||||
dispatch(addApp(app));
|
||||
@@ -88,7 +88,7 @@ export function resetApp(
|
||||
clientId: string,
|
||||
resetSecret: boolean,
|
||||
): ThunkAction<Promise<void>> {
|
||||
return async dispatch => {
|
||||
return async (dispatch) => {
|
||||
const { data: app } = await oauth.reset(clientId, resetSecret);
|
||||
|
||||
if (resetSecret) {
|
||||
|
@@ -19,7 +19,7 @@ const ApplicationTypeSwitcher: ComponentType<Props> = ({
|
||||
}) => (
|
||||
<div>
|
||||
{((Object.keys(appTypes) as unknown) as Array<ApplicationType>).map(
|
||||
type => (
|
||||
(type) => (
|
||||
<div className={styles.radioContainer} key={type}>
|
||||
<Radio
|
||||
onChange={() => setType(type)}
|
||||
|
@@ -151,7 +151,7 @@ export default class ApplicationItem extends React.Component<
|
||||
|
||||
<div
|
||||
className={styles.appActionContainer}
|
||||
ref={el => {
|
||||
ref={(el) => {
|
||||
this.actionContainer = el;
|
||||
}}
|
||||
>
|
||||
|
@@ -55,10 +55,10 @@ export default class ApplicationsList extends React.Component<Props, State> {
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.appsListContainer}>
|
||||
{applications.map(app => (
|
||||
{applications.map((app) => (
|
||||
<div
|
||||
key={app.clientId}
|
||||
ref={elem => {
|
||||
ref={(elem) => {
|
||||
this.appsRefs[app.clientId] = elem;
|
||||
}}
|
||||
>
|
||||
@@ -83,7 +83,7 @@ export default class ApplicationsList extends React.Component<Props, State> {
|
||||
if (
|
||||
clientId &&
|
||||
expandedApp !== clientId &&
|
||||
applications.some(app => app.clientId === clientId)
|
||||
applications.some((app) => app.clientId === clientId)
|
||||
) {
|
||||
requestAnimationFrame(() =>
|
||||
this.onTileClick(clientId, { noReset: true }),
|
||||
|
@@ -21,7 +21,9 @@ export default function apps(state: Apps = defaults, action: Action): Apps {
|
||||
case 'apps:addApp': {
|
||||
const { payload } = action;
|
||||
const available = [...state.available];
|
||||
let index = available.findIndex(app => app.clientId === payload.clientId);
|
||||
let index = available.findIndex(
|
||||
(app) => app.clientId === payload.clientId,
|
||||
);
|
||||
|
||||
if (index === -1) {
|
||||
index = available.length;
|
||||
@@ -39,7 +41,7 @@ export default function apps(state: Apps = defaults, action: Action): Apps {
|
||||
return {
|
||||
...state,
|
||||
available: state.available.filter(
|
||||
app => app.clientId !== action.payload,
|
||||
(app) => app.clientId !== action.payload,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ import messages from './footerMenu.intl.json';
|
||||
const FooterMenu: ComponentType = () => {
|
||||
const dispatch = useDispatch();
|
||||
const onLanguageSwitcherClick = useCallback<MouseEventHandler>(
|
||||
event => {
|
||||
(event) => {
|
||||
event.preventDefault();
|
||||
dispatch(createPopup({ Popup: LanguageSwitcher }));
|
||||
},
|
||||
|
@@ -3,7 +3,7 @@ import i18n from 'app/services/i18n';
|
||||
import { ThunkAction } from 'app/reducers';
|
||||
|
||||
export function setLocale(desiredLocale: string): ThunkAction<Promise<string>> {
|
||||
return async dispatch => {
|
||||
return async (dispatch) => {
|
||||
const locale = i18n.detectLanguage(desiredLocale);
|
||||
|
||||
dispatch(_setLocale(locale));
|
||||
|
@@ -15,7 +15,7 @@ const SUPPORTED_LANGUAGES: string[] = Object.keys(supportedLocales);
|
||||
export default {
|
||||
getCountryList(): string[] {
|
||||
return SUPPORTED_LANGUAGES.map(
|
||||
locale => localeToCountryCode[locale] || locale,
|
||||
(locale) => localeToCountryCode[locale] || locale,
|
||||
);
|
||||
},
|
||||
|
||||
@@ -29,9 +29,9 @@ export default {
|
||||
*/
|
||||
getIconUrl(locale: string): string {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const mod = require(`flag-icon-css/flags/4x3/${localeToCountryCode[
|
||||
locale
|
||||
] || locale}.svg`);
|
||||
const mod = require(`flag-icon-css/flags/4x3/${
|
||||
localeToCountryCode[locale] || locale
|
||||
}.svg`);
|
||||
|
||||
return mod.default || mod;
|
||||
},
|
||||
|
@@ -10,7 +10,7 @@ const defaultState: State = {
|
||||
locale: i18n.detectLanguage(),
|
||||
};
|
||||
|
||||
export default function(
|
||||
export default function (
|
||||
state: State = defaultState,
|
||||
{ type, payload }: Action,
|
||||
): State {
|
||||
|
@@ -71,7 +71,7 @@ export default class LanguageList extends React.Component<{
|
||||
willLeave={this.willLeave}
|
||||
willEnter={this.willEnter}
|
||||
>
|
||||
{items => (
|
||||
{(items) => (
|
||||
<div className={styles.languagesList} data-testid="language-list">
|
||||
<div
|
||||
className={clsx(styles.emptyLanguagesListWrapper, {
|
||||
@@ -125,7 +125,7 @@ export default class LanguageList extends React.Component<{
|
||||
}
|
||||
|
||||
onChangeLang(lang: string): MouseEventHandler {
|
||||
return event => {
|
||||
return (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
this.props.onChangeLang(lang);
|
||||
|
@@ -19,11 +19,11 @@ function ProfileField({
|
||||
let Action: React.ElementType | null = null;
|
||||
|
||||
if (link) {
|
||||
Action = props => <Link to={link} {...props} />;
|
||||
Action = (props) => <Link to={link} {...props} />;
|
||||
}
|
||||
|
||||
if (onChange) {
|
||||
Action = props => <a {...props} onClick={onChange} href="#" />;
|
||||
Action = (props) => <a {...props} onClick={onChange} href="#" />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@@ -88,7 +88,7 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
<div className={styles.form}>
|
||||
<div className={styles.formBody}>
|
||||
<Message {...messages.changeEmailTitle}>
|
||||
{pageTitle => (
|
||||
{(pageTitle) => (
|
||||
<h3 className={styles.violetTitle}>
|
||||
<Helmet title={pageTitle as string} />
|
||||
{pageTitle}
|
||||
@@ -347,7 +347,7 @@ export default class ChangeEmail extends React.Component<Props, State> {
|
||||
code: '',
|
||||
});
|
||||
},
|
||||
resp => {
|
||||
(resp) => {
|
||||
if (resp.errors) {
|
||||
form.setErrors(resp.errors);
|
||||
this.forceUpdate();
|
||||
|
@@ -36,7 +36,7 @@ export default class ChangePassword extends React.Component<Props> {
|
||||
<div className={styles.form}>
|
||||
<div className={styles.formBody}>
|
||||
<Message {...messages.changePasswordTitle}>
|
||||
{pageTitle => (
|
||||
{(pageTitle) => (
|
||||
<h3 className={styles.title}>
|
||||
<Helmet title={pageTitle as string} />
|
||||
{pageTitle}
|
||||
@@ -105,7 +105,7 @@ export default class ChangePassword extends React.Component<Props> {
|
||||
onFormSubmit = () => {
|
||||
const { form } = this.props;
|
||||
|
||||
this.props.onSubmit(form).catch(resp => {
|
||||
this.props.onSubmit(form).catch((resp) => {
|
||||
if (resp.errors) {
|
||||
form.setErrors(resp.errors);
|
||||
} else {
|
||||
|
@@ -32,7 +32,7 @@ export default class ChangeUsername extends React.Component<Props> {
|
||||
<div className={styles.form}>
|
||||
<div className={styles.formBody}>
|
||||
<Message {...messages.changeUsernameTitle}>
|
||||
{pageTitle => (
|
||||
{(pageTitle) => (
|
||||
<h3 className={styles.title}>
|
||||
<Helmet title={pageTitle as string} />
|
||||
{pageTitle}
|
||||
@@ -82,7 +82,7 @@ export default class ChangeUsername extends React.Component<Props> {
|
||||
onFormSubmit = () => {
|
||||
const { form } = this.props;
|
||||
|
||||
this.props.onSubmit(form).catch(resp => {
|
||||
this.props.onSubmit(form).catch((resp) => {
|
||||
if (resp.errors) {
|
||||
form.setErrors(resp.errors);
|
||||
} else {
|
||||
|
@@ -46,7 +46,7 @@ export default class MfaDisable extends React.Component<
|
||||
return disableMFA(this.context.userId, totp, password);
|
||||
})
|
||||
.then(() => this.props.onComplete())
|
||||
.catch(resp => {
|
||||
.catch((resp) => {
|
||||
const { errors } = resp || {};
|
||||
|
||||
if (errors) {
|
||||
|
@@ -122,7 +122,7 @@ export default class MfaEnable extends React.PureComponent<Props, State> {
|
||||
<Confirmation
|
||||
key="step3"
|
||||
form={this.props.confirmationForm}
|
||||
formRef={el => (this.confirmationFormEl = el)}
|
||||
formRef={(el) => (this.confirmationFormEl = el)}
|
||||
onSubmit={this.onTotpSubmit}
|
||||
onInvalid={() => this.forceUpdate()}
|
||||
/>
|
||||
@@ -136,7 +136,7 @@ export default class MfaEnable extends React.PureComponent<Props, State> {
|
||||
if (props.step === 1 && !isLoading && !qrCodeSrc) {
|
||||
this.setState({ isLoading: true });
|
||||
|
||||
getSecret(this.context.userId).then(resp => {
|
||||
getSecret(this.context.userId).then((resp) => {
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
secret: resp.secret,
|
||||
@@ -164,7 +164,7 @@ export default class MfaEnable extends React.PureComponent<Props, State> {
|
||||
return enableMFA(this.context.userId, data.totp, data.password);
|
||||
})
|
||||
.then(() => this.props.onComplete())
|
||||
.catch(resp => {
|
||||
.catch((resp) => {
|
||||
const { errors } = resp || {};
|
||||
|
||||
if (errors) {
|
||||
|
@@ -32,7 +32,7 @@ class MultiFactorAuth extends React.Component<{
|
||||
<div className={styles.form}>
|
||||
<div className={styles.formBody}>
|
||||
<Message {...messages.mfaTitle}>
|
||||
{pageTitle => (
|
||||
{(pageTitle) => (
|
||||
<h3 className={styles.title}>
|
||||
<Helmet title={pageTitle as string} />
|
||||
{pageTitle}
|
||||
|
@@ -48,19 +48,19 @@ export default class Instructions extends React.Component<{}, State> {
|
||||
className={styles.androidTile}
|
||||
logo={androidLogo}
|
||||
label="Google Play"
|
||||
onClick={event => this.onChangeOs(event, 'android')}
|
||||
onClick={(event) => this.onChangeOs(event, 'android')}
|
||||
/>
|
||||
<OsTile
|
||||
className={styles.appleTile}
|
||||
logo={appleLogo}
|
||||
label="App Store"
|
||||
onClick={event => this.onChangeOs(event, 'ios')}
|
||||
onClick={(event) => this.onChangeOs(event, 'ios')}
|
||||
/>
|
||||
<OsTile
|
||||
className={styles.windowsTile}
|
||||
logo={windowsLogo}
|
||||
label="Windows Store"
|
||||
onClick={event => this.onChangeOs(event, 'windows')}
|
||||
onClick={(event) => this.onChangeOs(event, 'windows')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@@ -87,7 +87,7 @@ export default function OsInstruction({ os }: { os: OS }) {
|
||||
</h3>
|
||||
|
||||
<ul className={styles.appList}>
|
||||
{linksByOs[os].featured.map(item => (
|
||||
{linksByOs[os].featured.map((item) => (
|
||||
<li key={item.label}>
|
||||
<a href={item.link} target="_blank">
|
||||
{item.label}
|
||||
|
@@ -31,7 +31,7 @@ export default function MfaStatus({ onProceed }: { onProceed: () => void }) {
|
||||
<p className={styles.description}>
|
||||
<a
|
||||
href="#"
|
||||
onClick={event => {
|
||||
onClick={(event) => {
|
||||
event.preventDefault();
|
||||
onProceed();
|
||||
}}
|
||||
|
@@ -91,7 +91,7 @@ export default class Box {
|
||||
endY: number;
|
||||
}> = [];
|
||||
|
||||
Object.values(boxPoints).forEach(point => {
|
||||
Object.values(boxPoints).forEach((point) => {
|
||||
const angle = Math.atan2(light.y - point.y, light.x - point.x);
|
||||
const endX = point.x + shadowLength * Math.sin(-angle - Math.PI / 2);
|
||||
const endY = point.y + shadowLength * Math.cos(-angle - Math.PI / 2);
|
||||
|
@@ -160,7 +160,7 @@ export default class BoxesField {
|
||||
|
||||
bindWindowListeners() {
|
||||
window.addEventListener('resize', this.resize.bind(this));
|
||||
window.addEventListener('mousemove', event => {
|
||||
window.addEventListener('mousemove', (event) => {
|
||||
this.light.x = event.clientX;
|
||||
this.light.y = event.clientY;
|
||||
});
|
||||
|
@@ -4,7 +4,7 @@ import sinon from 'sinon';
|
||||
import BsodMiddleware from 'app/components/ui/bsod/BsodMiddleware';
|
||||
|
||||
describe('BsodMiddleware', () => {
|
||||
[500, 503, 555].forEach(code =>
|
||||
[500, 503, 555].forEach((code) =>
|
||||
it(`should dispatch for ${code}`, () => {
|
||||
const resp = {
|
||||
originalResponse: { status: code },
|
||||
@@ -27,7 +27,7 @@ describe('BsodMiddleware', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
[200, 404].forEach(code =>
|
||||
[200, 404].forEach((code) =>
|
||||
it(`should not dispatch for ${code}`, () => {
|
||||
const resp = {
|
||||
originalResponse: { status: code },
|
||||
|
@@ -2,7 +2,7 @@ import { Action } from './actions';
|
||||
|
||||
export type State = boolean;
|
||||
|
||||
export default function(state: State = false, { type }: Action): State {
|
||||
export default function (state: State = false, { type }: Action): State {
|
||||
if (type === 'BSOD') {
|
||||
return true;
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
@import '~app/components/ui/colors.scss';
|
||||
|
||||
$font-family-monospaced: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Roboto Mono', monospace;
|
||||
$font-family-monospaced: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Roboto Mono',
|
||||
monospace;
|
||||
|
||||
.body {
|
||||
height: 100%;
|
||||
|
@@ -36,10 +36,10 @@ export default class Captcha extends FormInputComponent<
|
||||
skin: this.props.skin,
|
||||
onSetCode: this.setCode,
|
||||
})
|
||||
.then(captchaId => {
|
||||
.then((captchaId) => {
|
||||
this.captchaId = captchaId;
|
||||
})
|
||||
.catch(error => {
|
||||
.catch((error) => {
|
||||
logger.error('Failed rendering captcha', {
|
||||
error,
|
||||
});
|
||||
|
@@ -101,7 +101,7 @@ export default class Dropdown extends FormInputComponent<Props, State> {
|
||||
}
|
||||
|
||||
onSelectItem(item: OptionItem): MouseEventHandler {
|
||||
return event => {
|
||||
return (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
this.setState({
|
||||
@@ -143,7 +143,7 @@ export default class Dropdown extends FormInputComponent<Props, State> {
|
||||
this.toggle();
|
||||
};
|
||||
|
||||
onBodyClick: MouseEventHandler = event => {
|
||||
onBodyClick: MouseEventHandler = (event) => {
|
||||
if (this.state.isActive) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const el = ReactDOM.findDOMNode(this)!;
|
||||
|
@@ -130,7 +130,7 @@ export default class FormModel {
|
||||
const oldErrors = this.errors;
|
||||
this.errors = errors;
|
||||
|
||||
Object.keys(this.fields).forEach(fieldId => {
|
||||
Object.keys(this.fields).forEach((fieldId) => {
|
||||
if (this.renderErrors) {
|
||||
if (oldErrors[fieldId] || errors[fieldId]) {
|
||||
this.fields[fieldId].setError(errors[fieldId] || null);
|
||||
@@ -192,7 +192,7 @@ export default class FormModel {
|
||||
* @param {Function} fn
|
||||
*/
|
||||
removeLoadingListener(fn: LoadingListener): void {
|
||||
this.handlers = this.handlers.filter(handler => handler !== fn);
|
||||
this.handlers = this.handlers.filter((handler) => handler !== fn);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,6 +212,6 @@ export default class FormModel {
|
||||
}
|
||||
|
||||
private notifyHandlers(): void {
|
||||
this.handlers.forEach(fn => fn(this._isLoading));
|
||||
this.handlers.forEach((fn) => fn(this._isLoading));
|
||||
}
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ describe('Input', () => {
|
||||
<Input
|
||||
defaultValue="foo"
|
||||
name="test"
|
||||
ref={el => {
|
||||
ref={(el) => {
|
||||
component = el;
|
||||
}}
|
||||
/>
|
||||
|
@@ -11,7 +11,7 @@ export default function LinkButton(
|
||||
|
||||
return (
|
||||
<Button
|
||||
component={linkProps => <Link {...linkProps} to={to} />}
|
||||
component={(linkProps) => <Link {...linkProps} to={to} />}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
|
@@ -1,12 +1,12 @@
|
||||
<div id="loader" class="loader-overlay is-first-launch">
|
||||
<div class="loader">
|
||||
<div class="loader__cube loader__cube--1"></div>
|
||||
<div class="loader__cube loader__cube--2"></div>
|
||||
<div class="loader__cube loader__cube--3"></div>
|
||||
<div class="loader__cube loader__cube--4"></div>
|
||||
<div class="loader__cube loader__cube--5"></div>
|
||||
<div class="loader__cube loader__cube--6"></div>
|
||||
<div class="loader__cube loader__cube--7"></div>
|
||||
<div class="loader__cube loader__cube--8"></div>
|
||||
</div>
|
||||
<div class="loader">
|
||||
<div class="loader__cube loader__cube--1"></div>
|
||||
<div class="loader__cube loader__cube--2"></div>
|
||||
<div class="loader__cube loader__cube--3"></div>
|
||||
<div class="loader__cube loader__cube--4"></div>
|
||||
<div class="loader__cube loader__cube--5"></div>
|
||||
<div class="loader__cube loader__cube--6"></div>
|
||||
<div class="loader__cube loader__cube--7"></div>
|
||||
<div class="loader__cube loader__cube--8"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -67,7 +67,7 @@ class SlideMotion extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<Motion style={motionStyle}>
|
||||
{interpolatingStyle => (
|
||||
{(interpolatingStyle) => (
|
||||
<div
|
||||
style={{
|
||||
overflow: 'hidden',
|
||||
|
@@ -69,10 +69,7 @@ describe('<PopupStack />', () => {
|
||||
};
|
||||
const component = shallow(<PopupStack {...props} />);
|
||||
|
||||
component
|
||||
.find(DummyPopup)
|
||||
.last()
|
||||
.prop('onClose')();
|
||||
component.find(DummyPopup).last().prop('onClose')();
|
||||
|
||||
expect(props.destroy, 'was called once');
|
||||
expect(props.destroy, 'to have a call satisfying', [
|
||||
|
@@ -27,7 +27,7 @@ function popups(state: Array<PopupConfig> = [], { type, payload }: Action) {
|
||||
|
||||
return state.concat(payload);
|
||||
case 'POPUP_DESTROY':
|
||||
return state.filter(popup => popup !== payload);
|
||||
return state.filter((popup) => popup !== payload);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ class ScrollIntoView extends React.PureComponent<Props> {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <span ref={el => el && restoreScroll(el)} />;
|
||||
return <span ref={(el) => el && restoreScroll(el)} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -80,7 +80,7 @@ export function acceptRules(): ThunkAction<Promise<{ success: boolean }>> {
|
||||
);
|
||||
}
|
||||
|
||||
return acceptRulesEndpoint(id).then(resp => {
|
||||
return acceptRulesEndpoint(id).then((resp) => {
|
||||
dispatch(
|
||||
updateUser({
|
||||
shouldAcceptRules: false,
|
||||
|
@@ -32,7 +32,7 @@ describe('refreshTokenMiddleware', () => {
|
||||
|
||||
getState = sinon.stub().named('store.getState');
|
||||
dispatch = sinon
|
||||
.spy(arg => (typeof arg === 'function' ? arg(dispatch, getState) : arg))
|
||||
.spy((arg) => (typeof arg === 'function' ? arg(dispatch, getState) : arg))
|
||||
.named('store.dispatch');
|
||||
|
||||
middleware = refreshTokenMiddleware({ getState, dispatch } as any);
|
||||
@@ -94,7 +94,7 @@ describe('refreshTokenMiddleware', () => {
|
||||
Promise.resolve(validToken),
|
||||
);
|
||||
|
||||
return middleware.before!(data).then(resp => {
|
||||
return middleware.before!(data).then((resp) => {
|
||||
expect(resp, 'to satisfy', data);
|
||||
|
||||
expect(authentication.requestToken, 'to have a call satisfying', [
|
||||
|
@@ -42,7 +42,7 @@ export default class LoggedInPanel extends React.Component<
|
||||
const { isAccountSwitcherActive } = this.state;
|
||||
|
||||
return (
|
||||
<div ref={el => (this.el = el)} className={clsx(styles.loggedInPanel)}>
|
||||
<div ref={(el) => (this.el = el)} className={clsx(styles.loggedInPanel)}>
|
||||
<div
|
||||
className={clsx(styles.activeAccount, {
|
||||
[styles.activeAccountExpanded]: isAccountSwitcherActive,
|
||||
@@ -111,7 +111,7 @@ function createOnOutsideComponentClickHandler(
|
||||
// TODO: we have the same logic in LangMenu
|
||||
// Probably we should decouple this into some helper function
|
||||
// TODO: the name of function may be better...
|
||||
return event => {
|
||||
return (event) => {
|
||||
const el = getEl();
|
||||
|
||||
if (isActive() && el) {
|
||||
|
@@ -13,7 +13,7 @@ export default function AuthFlowRoute(props: RouteProps) {
|
||||
return (
|
||||
<Route
|
||||
{...routeProps}
|
||||
render={routerProps => (
|
||||
render={(routerProps) => (
|
||||
<AuthFlowRouteContents
|
||||
routerProps={routerProps}
|
||||
component={Component}
|
||||
|
@@ -15,7 +15,7 @@ export function omit(
|
||||
): { [key: string]: any } {
|
||||
const newObj = { ...obj };
|
||||
|
||||
keys.forEach(key => {
|
||||
keys.forEach((key) => {
|
||||
Reflect.deleteProperty(newObj, key);
|
||||
});
|
||||
|
||||
|
@@ -53,7 +53,7 @@ function initAnalytics() {
|
||||
const ga: {
|
||||
[key: string]: any;
|
||||
(...args: any[]): void;
|
||||
} = function(...args) {
|
||||
} = function (...args) {
|
||||
// eslint-disable-next-line id-length
|
||||
(ga.q = ga.q || []).push(args);
|
||||
};
|
||||
|
@@ -11,7 +11,7 @@ import profileStyles from '../profile/profile.scss';
|
||||
const PageNotFound: ComponentType = () => (
|
||||
<div className={styles.page}>
|
||||
<Message {...messages.title}>
|
||||
{pageTitle => <Helmet title={pageTitle as string} />}
|
||||
{(pageTitle) => <Helmet title={pageTitle as string} />}
|
||||
</Message>
|
||||
|
||||
<div className={styles.loading}>
|
||||
|
@@ -96,7 +96,7 @@ function renderPanelTransition(
|
||||
): (props: RouteComponentProps<any>) => ReactNode {
|
||||
const { Title, Body, Footer, Links } = factory();
|
||||
|
||||
return props => (
|
||||
return (props) => (
|
||||
<PanelTransition
|
||||
key="panel-transition"
|
||||
Title={<Title />}
|
||||
|
@@ -42,7 +42,7 @@ export default class SuccessOauthPage extends React.Component<{
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
<Message {...messages.title}>
|
||||
{pageTitle => <Helmet title={pageTitle as string} />}
|
||||
{(pageTitle) => <Helmet title={pageTitle as string} />}
|
||||
</Message>
|
||||
|
||||
<div className={styles.wrapper}>
|
||||
|
@@ -86,7 +86,7 @@ class ChangeEmailPage extends React.Component<Props> {
|
||||
function handleErrors(
|
||||
repeatUrl?: string,
|
||||
): <T extends { errors: Record<string, any> }>(resp: T) => Promise<T> {
|
||||
return resp => {
|
||||
return (resp) => {
|
||||
if (resp.errors) {
|
||||
if (resp.errors.key) {
|
||||
resp.errors.key = {
|
||||
|
@@ -124,7 +124,7 @@ export default connect(
|
||||
form.beginLoading();
|
||||
|
||||
return sendData()
|
||||
.catch(resp => {
|
||||
.catch((resp) => {
|
||||
const requirePassword = resp.errors && !!resp.errors.password;
|
||||
|
||||
// prevalidate user input, because requestPassword popup will block the
|
||||
@@ -154,7 +154,7 @@ export default connect(
|
||||
|
||||
return Promise.reject(resp);
|
||||
})
|
||||
.catch(resp => {
|
||||
.catch((resp) => {
|
||||
if (!resp || !resp.errors) {
|
||||
logger.warn('Unexpected profile editing error', {
|
||||
resp,
|
||||
@@ -176,13 +176,13 @@ export default connect(
|
||||
sendData()
|
||||
.then(resolve)
|
||||
.then(props.onClose)
|
||||
.catch(resp => {
|
||||
.catch((resp) => {
|
||||
if (resp.errors) {
|
||||
form.setErrors(resp.errors);
|
||||
|
||||
const parentFormHasErrors =
|
||||
Object.keys(resp.errors).filter(
|
||||
name => name !== 'password',
|
||||
(name) => name !== 'password',
|
||||
).length > 0;
|
||||
|
||||
if (parentFormHasErrors) {
|
||||
|
@@ -98,7 +98,7 @@ export default class RulesPage extends Component<{
|
||||
return (
|
||||
<div>
|
||||
<Message {...messages.title}>
|
||||
{pageTitle => <Helmet title={pageTitle as string} />}
|
||||
{(pageTitle) => <Helmet title={pageTitle as string} />}
|
||||
</Message>
|
||||
|
||||
<div className={styles.rules}>
|
||||
|
@@ -3,13 +3,13 @@ import expect from 'app/test/unexpected';
|
||||
describe('promise.prototype.finally', () => {
|
||||
it('should be invoked after promise resolved', () =>
|
||||
expect(
|
||||
new Promise(resolve => Promise.resolve().finally(resolve)),
|
||||
new Promise((resolve) => Promise.resolve().finally(resolve)),
|
||||
'to be fulfilled',
|
||||
));
|
||||
|
||||
it('should be invoked after promise rejected', () =>
|
||||
expect(
|
||||
new Promise(resolve =>
|
||||
new Promise((resolve) =>
|
||||
expect(Promise.reject().finally(resolve), 'to be rejected'),
|
||||
),
|
||||
'to be fulfilled',
|
||||
|
@@ -23,7 +23,7 @@ describe('services/api/options', () => {
|
||||
});
|
||||
|
||||
it('should request options without token', () =>
|
||||
options.get().then(resp => {
|
||||
options.get().then((resp) => {
|
||||
expect(resp, 'to be', expectedResp);
|
||||
expect(request.get, 'to have a call satisfying', [
|
||||
'/api/options',
|
||||
@@ -35,7 +35,7 @@ describe('services/api/options', () => {
|
||||
it('should cache options', () =>
|
||||
// NOTE: this is bad practice, but we are relying on the state from
|
||||
// the previous test
|
||||
options.get().then(resp => {
|
||||
options.get().then((resp) => {
|
||||
expect(resp, 'to be', expectedResp);
|
||||
expect(request.get, 'was not called');
|
||||
}));
|
||||
|
@@ -114,7 +114,7 @@ describe('AuthFlow.functional', () => {
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
flow.run.onCall(0).returns({ then: fn => fn() });
|
||||
flow.run.onCall(0).returns({ then: (fn) => fn() });
|
||||
// @ts-ignore
|
||||
flow.run.onCall(1).returns({
|
||||
then: (fn: Function) =>
|
||||
|
@@ -154,7 +154,7 @@ export default class AuthFlow implements AuthContext {
|
||||
const callback = this.onReady;
|
||||
this.onReady = () => {};
|
||||
|
||||
return resp.then(callback, error => {
|
||||
return resp.then(callback, (error) => {
|
||||
logger.error('State transition error', { error });
|
||||
|
||||
return error;
|
||||
|
@@ -57,7 +57,7 @@ export default class CompleteState extends AbstractState {
|
||||
|
||||
if (loginHint) {
|
||||
const account = accounts.available.find(
|
||||
item =>
|
||||
(item) =>
|
||||
item.id === Number(loginHint) ||
|
||||
item.email === loginHint ||
|
||||
item.username === loginHint,
|
||||
@@ -111,7 +111,7 @@ export default class CompleteState extends AbstractState {
|
||||
return context.run('redirect', resp.redirectUri);
|
||||
}
|
||||
},
|
||||
resp => {
|
||||
(resp) => {
|
||||
if (resp.unauthorized) {
|
||||
context.setState(new LoginState());
|
||||
} else if (resp.acceptRequired) {
|
||||
|
@@ -56,10 +56,7 @@ describe('ForgotPasswordState', () => {
|
||||
const promise = Promise.resolve();
|
||||
const expectedLogin = 'foo@bar.com';
|
||||
|
||||
mock
|
||||
.expects('run')
|
||||
.twice()
|
||||
.returns(promise);
|
||||
mock.expects('run').twice().returns(promise);
|
||||
expectState(mock, RecoverPasswordState);
|
||||
|
||||
state.resolve(context, { login: expectedLogin });
|
||||
@@ -71,10 +68,7 @@ describe('ForgotPasswordState', () => {
|
||||
const promise = Promise.resolve();
|
||||
const expectedLogin = 'foo@bar.com';
|
||||
|
||||
mock
|
||||
.expects('run')
|
||||
.withArgs('forgotPassword')
|
||||
.returns(promise);
|
||||
mock.expects('run').withArgs('forgotPassword').returns(promise);
|
||||
expectState(mock, RecoverPasswordState);
|
||||
mock.expects('run').withArgs('setLogin', expectedLogin);
|
||||
|
||||
|
@@ -4,7 +4,13 @@ import LoginState from 'app/services/authFlow/LoginState';
|
||||
import PasswordState from 'app/services/authFlow/PasswordState';
|
||||
import RegisterState from 'app/services/authFlow/RegisterState';
|
||||
|
||||
import { bootstrap, expectState, expectNavigate, expectRun, MockedAuthContext } from './helpers';
|
||||
import {
|
||||
bootstrap,
|
||||
expectState,
|
||||
expectNavigate,
|
||||
expectRun,
|
||||
MockedAuthContext,
|
||||
} from './helpers';
|
||||
|
||||
describe('LoginState', () => {
|
||||
let state: LoginState;
|
||||
|
@@ -53,10 +53,7 @@ export function expectNavigate(
|
||||
.withExactArgs(route, sinon.match(options));
|
||||
}
|
||||
|
||||
return mock
|
||||
.expects('navigate')
|
||||
.once()
|
||||
.withExactArgs(route);
|
||||
return mock.expects('navigate').once().withExactArgs(route);
|
||||
}
|
||||
|
||||
export function expectRun(
|
||||
|
@@ -72,10 +72,10 @@ class Captcha {
|
||||
private loadApi(): Promise<void> {
|
||||
if (!readyPromise) {
|
||||
readyPromise = Promise.all([
|
||||
new Promise(resolve => {
|
||||
new Promise((resolve) => {
|
||||
(window as any).onReCaptchaReady = resolve;
|
||||
}),
|
||||
options.get().then(resp => this.setApiKey(resp.reCaptchaPublicKey)),
|
||||
options.get().then((resp) => this.setApiKey(resp.reCaptchaPublicKey)),
|
||||
]).then(() => {});
|
||||
|
||||
loadScript(
|
||||
|
@@ -31,12 +31,15 @@ const ResendKey: ComponentType<{ url: string }> = ({ url }) => (
|
||||
</>
|
||||
);
|
||||
|
||||
const errorsMap: Record<string, (props?: Record<string, any>) => ReactElement> = {
|
||||
const errorsMap: Record<
|
||||
string,
|
||||
(props?: Record<string, any>) => ReactElement
|
||||
> = {
|
||||
'error.login_required': () => <Message {...messages.loginRequired} />,
|
||||
'error.login_not_exist': () => <Message {...messages.loginNotExist} />,
|
||||
'error.password_required': () => <Message {...messages.passwordRequired} />,
|
||||
|
||||
'error.password_incorrect': (props ) => (
|
||||
'error.password_incorrect': (props) => (
|
||||
// props are handled in validationErrorsHandler in components/auth/actions
|
||||
<>
|
||||
<Message {...messages.invalidPassword} />
|
||||
@@ -81,13 +84,13 @@ const errorsMap: Record<string, (props?: Record<string, any>) => ReactElement> =
|
||||
<Message {...messages.rulesAgreementRequired} />
|
||||
),
|
||||
'error.key_required': () => <Message {...messages.keyRequired} />,
|
||||
'error.key_not_exists': props => (
|
||||
'error.key_not_exists': (props) => (
|
||||
<>
|
||||
<Message {...messages.keyNotExists} />
|
||||
{props && props.repeatUrl ? <ResendKey url={props.repeatUrl} /> : null}
|
||||
</>
|
||||
),
|
||||
'error.key_expire': props => errorsMap['error.key_not_exists'](props),
|
||||
'error.key_expire': (props) => errorsMap['error.key_not_exists'](props),
|
||||
|
||||
'error.newPassword_required': () => (
|
||||
<Message {...messages.newPasswordRequired} />
|
||||
@@ -101,7 +104,7 @@ const errorsMap: Record<string, (props?: Record<string, any>) => ReactElement> =
|
||||
),
|
||||
'error.account_banned': () => <Message {...messages.accountBanned} />,
|
||||
|
||||
'error.recently_sent_message': props => (
|
||||
'error.recently_sent_message': (props) => (
|
||||
<Message
|
||||
{...messages.emailFrequency}
|
||||
values={{
|
||||
@@ -117,7 +120,8 @@ const errorsMap: Record<string, (props?: Record<string, any>) => ReactElement> =
|
||||
),
|
||||
|
||||
'error.captcha_required': () => <Message {...messages.captchaRequired} />,
|
||||
'error.captcha_invalid': props => errorsMap['error.captcha_required'](props),
|
||||
'error.captcha_invalid': (props) =>
|
||||
errorsMap['error.captcha_required'](props),
|
||||
|
||||
'error.redirectUri_required': () => (
|
||||
<Message {...messages.redirectUriRequired} />
|
||||
|
@@ -25,7 +25,7 @@ export default {
|
||||
};
|
||||
}
|
||||
|
||||
return new Promise(resolve =>
|
||||
return new Promise((resolve) =>
|
||||
webFont.load({
|
||||
classes: false,
|
||||
active: resolve,
|
||||
|
@@ -23,8 +23,9 @@ function detectLanguage(
|
||||
): string {
|
||||
return (
|
||||
userLanguages
|
||||
.map(lang => (lang.split('-').shift() || '').toLowerCase())
|
||||
.find(lang => availableLanguages.indexOf(lang) !== -1) || defaultLanguage
|
||||
.map((lang) => (lang.split('-').shift() || '').toLowerCase())
|
||||
.find((lang) => availableLanguages.indexOf(lang) !== -1) ||
|
||||
defaultLanguage
|
||||
);
|
||||
}
|
||||
|
||||
@@ -35,7 +36,7 @@ let intl: IntlShape;
|
||||
class I18N {
|
||||
detectLanguage(lang: string = ''): string {
|
||||
return detectLanguage(
|
||||
[lang].concat(getBrowserPreferredLanguages()).filter(item => !!item),
|
||||
[lang].concat(getBrowserPreferredLanguages()).filter((item) => !!item),
|
||||
SUPPORTED_LANGUAGES,
|
||||
DEFAULT_LANGUAGE,
|
||||
);
|
||||
|
@@ -203,7 +203,7 @@ function browserFilter(key: any, val: any): any {
|
||||
|
||||
export { abbreviate, nodeFilter, browserFilter };
|
||||
|
||||
export default function(obj: any): string {
|
||||
export default function (obj: any): string {
|
||||
return abbreviate(obj, {
|
||||
filter: browserFilter,
|
||||
});
|
||||
|
@@ -17,7 +17,7 @@ class Logger {
|
||||
: 'Development',
|
||||
release: process.env.__VERSION__,
|
||||
shouldSendCallback: () => !isTest,
|
||||
dataCallback: data => {
|
||||
dataCallback: (data) => {
|
||||
if (!data.level) {
|
||||
// log unhandled errors as info
|
||||
data.level = 'info';
|
||||
@@ -28,7 +28,7 @@ class Logger {
|
||||
whitelistUrls: isProduction ? [/ely\.by/] : [],
|
||||
}).install();
|
||||
|
||||
window.addEventListener('unhandledrejection', event => {
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
const error = event.reason || {};
|
||||
|
||||
let message = error.message || error;
|
||||
@@ -102,7 +102,7 @@ function log(
|
||||
};
|
||||
}
|
||||
|
||||
prepareContext(context).then(context => {
|
||||
prepareContext(context).then((context) => {
|
||||
console[method](message, context); // eslint-disable-line
|
||||
|
||||
Raven.captureException(message, {
|
||||
@@ -126,7 +126,7 @@ function prepareContext(context: Record<string, any>): Promise<string> {
|
||||
return context
|
||||
.json()
|
||||
.catch(() => context.text())
|
||||
.then(body =>
|
||||
.then((body) =>
|
||||
abbreviate({
|
||||
type: context.type,
|
||||
url: context.url,
|
||||
@@ -136,7 +136,7 @@ function prepareContext(context: Record<string, any>): Promise<string> {
|
||||
}),
|
||||
);
|
||||
} else if (context.originalResponse instanceof Response) {
|
||||
return prepareContext(context.originalResponse).then(originalResponse =>
|
||||
return prepareContext(context.originalResponse).then((originalResponse) =>
|
||||
abbreviate({
|
||||
...context,
|
||||
originalResponse,
|
||||
|
@@ -41,7 +41,7 @@ class PromiseMiddlewareLayer {
|
||||
throw new Error('A middleware must be an object');
|
||||
}
|
||||
|
||||
if (!this.middlewares.some(mdware => mdware === middleware)) {
|
||||
if (!this.middlewares.some((mdware) => mdware === middleware)) {
|
||||
this.middlewares.push(middleware);
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class PromiseMiddlewareLayer {
|
||||
const promiseMethod = action === 'catch' ? 'catch' : 'then';
|
||||
|
||||
return this.middlewares
|
||||
.filter(middleware => middleware[action])
|
||||
.filter((middleware) => middleware[action])
|
||||
.reduce(
|
||||
(promise: Promise<any>, middleware) =>
|
||||
invoke(
|
||||
|
@@ -127,16 +127,16 @@ const toJSON = (resp: Response) => {
|
||||
}
|
||||
|
||||
return resp.json().then(
|
||||
json => {
|
||||
(json) => {
|
||||
json.originalResponse = resp;
|
||||
|
||||
return json;
|
||||
},
|
||||
error => Promise.reject(new InternalServerError(error, resp)),
|
||||
(error) => Promise.reject(new InternalServerError(error, resp)),
|
||||
);
|
||||
};
|
||||
const rejectWithJSON = (resp: Response) =>
|
||||
toJSON(resp).then(resp => {
|
||||
toJSON(resp).then((resp) => {
|
||||
if (resp.originalResponse.status >= 500) {
|
||||
throw new InternalServerError(resp, resp.originalResponse);
|
||||
}
|
||||
@@ -164,13 +164,13 @@ async function doFetch<T>(url: string, options: Options): Promise<Resp<T>> {
|
||||
.then(checkStatus)
|
||||
.then(toJSON, rejectWithJSON)
|
||||
.then(handleResponseSuccess)
|
||||
.then(resp =>
|
||||
.then((resp) =>
|
||||
middlewareLayer.run('then', resp, {
|
||||
url: nextUrl,
|
||||
options: nextOptions,
|
||||
}),
|
||||
)
|
||||
.catch(resp =>
|
||||
.catch((resp) =>
|
||||
middlewareLayer.run(
|
||||
'catch',
|
||||
resp,
|
||||
@@ -213,7 +213,7 @@ function convertQueryValue(value: any): string {
|
||||
*/
|
||||
function buildQuery(data: { [key: string]: any } = {}): string {
|
||||
return Object.keys(data)
|
||||
.map(keyName =>
|
||||
.map((keyName) =>
|
||||
[keyName, convertQueryValue(data[keyName])]
|
||||
.map(encodeURIComponent)
|
||||
.join('='),
|
||||
|
@@ -27,7 +27,7 @@ Promise.all([
|
||||
|
||||
logResult(chalk.green('Current dlls are up to date!'));
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
if (err.code !== 'ENOENT' && err.code !== 'OUTDATED') {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ Promise.all([
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
.catch((err) => {
|
||||
logResult(chalk.red('Unexpected error checking dll state'), err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
@@ -26,7 +26,7 @@ interface MessageDescriptor {
|
||||
let idToFileMap: Record<string, Array<string>> = {};
|
||||
let duplicateIds: Array<string | number> = [];
|
||||
const collectedMessages = globSync(MESSAGES_PATTERN)
|
||||
.map<[string, Array<MessageDescriptor>]>(filename => [
|
||||
.map<[string, Array<MessageDescriptor>]>((filename) => [
|
||||
filename,
|
||||
JSON.parse(fs.readFileSync(filename, 'utf8')),
|
||||
])
|
||||
@@ -45,7 +45,7 @@ const collectedMessages = globSync(MESSAGES_PATTERN)
|
||||
|
||||
if (duplicateIds.length) {
|
||||
console.log('\nFound duplicated ids:');
|
||||
duplicateIds.forEach(id =>
|
||||
duplicateIds.forEach((id) =>
|
||||
console.log(`${chalk.yellow(id)}:\n - ${idToFileMap[id].join('\n - ')}\n`),
|
||||
);
|
||||
console.log(chalk.red('Please correct the errors above to proceed further!'));
|
||||
@@ -77,10 +77,10 @@ const prevMessagesMap = Object.entries(prevMessages).reduce(
|
||||
);
|
||||
|
||||
const keysToAdd = Object.keys(collectedMessages).filter(
|
||||
key => !prevMessages[key],
|
||||
(key) => !prevMessages[key],
|
||||
);
|
||||
const keysToRemove: Array<string> = Object.keys(prevMessages)
|
||||
.filter(key => !collectedMessages[key])
|
||||
.filter((key) => !collectedMessages[key])
|
||||
.filter(isNotMarked);
|
||||
const keysToUpdate: Array<string> = Object.entries(prevMessages).reduce(
|
||||
(acc, [key, message]) =>
|
||||
@@ -92,9 +92,9 @@ const keysToUpdate: Array<string> = Object.entries(prevMessages).reduce(
|
||||
|
||||
const keysToRename: Array<[string, string]> = [];
|
||||
// detect keys to rename, mutating keysToAdd and keysToRemove
|
||||
[...keysToAdd].forEach(toKey => {
|
||||
[...keysToAdd].forEach((toKey) => {
|
||||
const keys = prevMessagesMap[collectedMessages[toKey]] || [];
|
||||
const fromKey = keys.find(key => keysToRemove.indexOf(key) > -1);
|
||||
const fromKey = keys.find((key) => keysToRemove.indexOf(key) > -1);
|
||||
|
||||
if (fromKey) {
|
||||
keysToRename.push([fromKey, toKey]);
|
||||
@@ -162,7 +162,7 @@ prompt.get(
|
||||
pattern: /^y|n$/i,
|
||||
message: 'Please enter "y" or "n"',
|
||||
default: 'y',
|
||||
before: value => value.toLowerCase() === 'y',
|
||||
before: (value) => value.toLowerCase() === 'y',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -182,7 +182,7 @@ prompt.get(
|
||||
function buildLocales() {
|
||||
mkdirpSync(LANG_DIR);
|
||||
|
||||
SUPPORTED_LANGS.map(lang => {
|
||||
SUPPORTED_LANGS.map((lang) => {
|
||||
const destPath = `${LANG_DIR}/${lang}.json`;
|
||||
const newMessages = readJSON<Record<string, string>>(destPath);
|
||||
|
||||
@@ -190,14 +190,14 @@ function buildLocales() {
|
||||
newMessages[toKey] = newMessages[fromKey];
|
||||
delete newMessages[fromKey];
|
||||
});
|
||||
keysToRemove.forEach(key => {
|
||||
keysToRemove.forEach((key) => {
|
||||
delete newMessages[key];
|
||||
});
|
||||
keysToUpdate.forEach(key => {
|
||||
keysToUpdate.forEach((key) => {
|
||||
newMessages[`--${key}`] = newMessages[key];
|
||||
newMessages[key] = collectedMessages[key];
|
||||
});
|
||||
keysToAdd.forEach(key => {
|
||||
keysToAdd.forEach((key) => {
|
||||
newMessages[key] = collectedMessages[key];
|
||||
});
|
||||
|
||||
|
@@ -3,7 +3,11 @@
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import CrowdinApi, { LanguageStatusNode, LanguageStatusResponse, ProjectInfoResponse } from 'crowdin-api';
|
||||
import CrowdinApi, {
|
||||
LanguageStatusNode,
|
||||
LanguageStatusResponse,
|
||||
ProjectInfoResponse,
|
||||
} from 'crowdin-api';
|
||||
import MultiProgress from 'multi-progress';
|
||||
import ch from 'chalk';
|
||||
import iso639 from 'iso-639-1';
|
||||
@@ -35,7 +39,16 @@ const progressBar = new MultiProgress();
|
||||
/**
|
||||
* Locales that has been verified by core team members
|
||||
*/
|
||||
const RELEASED_LOCALES: Array<string> = ['be', 'fr', 'id', 'pt', 'ru', 'uk', 'vi', 'zh'];
|
||||
const RELEASED_LOCALES: Array<string> = [
|
||||
'be',
|
||||
'fr',
|
||||
'id',
|
||||
'pt',
|
||||
'ru',
|
||||
'uk',
|
||||
'vi',
|
||||
'zh',
|
||||
];
|
||||
|
||||
/**
|
||||
* Array of Crowdin locales to our internal locales representation
|
||||
@@ -158,55 +171,57 @@ async function pull() {
|
||||
let downloadingReady = 0;
|
||||
|
||||
interface Result {
|
||||
locale: ValuesType<typeof locales>,
|
||||
progress: number,
|
||||
translatesFilePath: string,
|
||||
locale: ValuesType<typeof locales>;
|
||||
progress: number;
|
||||
translatesFilePath: string;
|
||||
}
|
||||
|
||||
const results = await Promise.all(
|
||||
// TODO: there is should be some way to reimplement this
|
||||
// with reduce to avoid null values
|
||||
locales.map(async (locale): Promise<Result | null> => {
|
||||
const { files } = await crowdin.languageStatus(locale.code);
|
||||
checkingProgressBar.tick();
|
||||
const fileInfo = findFile(files, CROWDIN_FILE_PATH);
|
||||
locales.map(
|
||||
async (locale): Promise<Result | null> => {
|
||||
const { files } = await crowdin.languageStatus(locale.code);
|
||||
checkingProgressBar.tick();
|
||||
const fileInfo = findFile(files, CROWDIN_FILE_PATH);
|
||||
|
||||
if (fileInfo === null) {
|
||||
throw new Error(
|
||||
'Unable to find translation file. Please check the CROWDIN_FILE_PATH param.',
|
||||
if (fileInfo === null) {
|
||||
throw new Error(
|
||||
'Unable to find translation file. Please check the CROWDIN_FILE_PATH param.',
|
||||
);
|
||||
}
|
||||
|
||||
const progress = (fileInfo.words_approved / fileInfo.words) * 100;
|
||||
|
||||
if (
|
||||
!RELEASED_LOCALES.includes(toInternalLocale(locale.code)) &&
|
||||
progress < MIN_RELEASE_PROGRESS
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
downloadingProgressBar.update(downloadingReady / ++downloadingTotal, {
|
||||
cCurrent: downloadingReady,
|
||||
cTotal: downloadingTotal,
|
||||
});
|
||||
|
||||
const translatesFilePath = await crowdin.exportFile(
|
||||
CROWDIN_FILE_PATH,
|
||||
locale.code,
|
||||
);
|
||||
}
|
||||
|
||||
const progress = (fileInfo.words_approved / fileInfo.words) * 100;
|
||||
downloadingProgressBar.update(++downloadingReady / downloadingTotal, {
|
||||
cCurrent: downloadingReady,
|
||||
cTotal: downloadingTotal,
|
||||
});
|
||||
|
||||
if (
|
||||
!RELEASED_LOCALES.includes(toInternalLocale(locale.code)) &&
|
||||
progress < MIN_RELEASE_PROGRESS
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
downloadingProgressBar.update(downloadingReady / ++downloadingTotal, {
|
||||
cCurrent: downloadingReady,
|
||||
cTotal: downloadingTotal,
|
||||
});
|
||||
|
||||
const translatesFilePath = await crowdin.exportFile(
|
||||
CROWDIN_FILE_PATH,
|
||||
locale.code,
|
||||
);
|
||||
|
||||
downloadingProgressBar.update(++downloadingReady / downloadingTotal, {
|
||||
cCurrent: downloadingReady,
|
||||
cTotal: downloadingTotal,
|
||||
});
|
||||
|
||||
return {
|
||||
locale,
|
||||
progress,
|
||||
translatesFilePath,
|
||||
};
|
||||
}),
|
||||
return {
|
||||
locale,
|
||||
progress,
|
||||
translatesFilePath,
|
||||
};
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
console.log('Locales are downloaded. Writing them to file system.');
|
||||
@@ -223,31 +238,34 @@ async function pull() {
|
||||
await Promise.all(
|
||||
results
|
||||
.filter((result): result is Result => result !== null)
|
||||
.map(result => new Promise((resolve, reject) => {
|
||||
const {
|
||||
locale: { code, name },
|
||||
progress,
|
||||
translatesFilePath,
|
||||
} = result;
|
||||
const ourCode = toInternalLocale(code);
|
||||
.map(
|
||||
(result) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const {
|
||||
locale: { code, name },
|
||||
progress,
|
||||
translatesFilePath,
|
||||
} = result;
|
||||
const ourCode = toInternalLocale(code);
|
||||
|
||||
indexFileEntries[ourCode] = {
|
||||
code: ourCode,
|
||||
name: NATIVE_NAMES_MAP[ourCode] || iso639.getNativeName(ourCode),
|
||||
englishName: ENGLISH_NAMES_MAP[ourCode] || name,
|
||||
progress: parseFloat(progress.toFixed(1)),
|
||||
isReleased: RELEASED_LOCALES.includes(ourCode),
|
||||
};
|
||||
indexFileEntries[ourCode] = {
|
||||
code: ourCode,
|
||||
name: NATIVE_NAMES_MAP[ourCode] || iso639.getNativeName(ourCode),
|
||||
englishName: ENGLISH_NAMES_MAP[ourCode] || name,
|
||||
progress: parseFloat(progress.toFixed(1)),
|
||||
isReleased: RELEASED_LOCALES.includes(ourCode),
|
||||
};
|
||||
|
||||
fs.copyFile(
|
||||
translatesFilePath,
|
||||
path.join(LANG_DIR, `${ourCode}.json`),
|
||||
0,
|
||||
err => {
|
||||
err ? reject(err) : resolve();
|
||||
},
|
||||
);
|
||||
})),
|
||||
fs.copyFile(
|
||||
translatesFilePath,
|
||||
path.join(LANG_DIR, `${ourCode}.json`),
|
||||
0,
|
||||
(err) => {
|
||||
err ? reject(err) : resolve();
|
||||
},
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
console.log('Writing an index file.');
|
||||
@@ -271,7 +289,7 @@ function push() {
|
||||
pattern: /^y|n$/i,
|
||||
message: 'Please enter "y" or "n"',
|
||||
default: 'y',
|
||||
before: value => value.toLowerCase() === 'y',
|
||||
before: (value) => value.toLowerCase() === 'y',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@@ -21,7 +21,7 @@ const mimeTypes = {
|
||||
|
||||
function absolute(from, to) {
|
||||
if (arguments.length < 2) {
|
||||
return function(to) {
|
||||
return function (to) {
|
||||
return path.resolve(from, to);
|
||||
};
|
||||
}
|
||||
@@ -50,7 +50,7 @@ function getFilesAndDeps(patterns, context) {
|
||||
}
|
||||
|
||||
// Re-work the files array.
|
||||
patterns.forEach(pattern => {
|
||||
patterns.forEach((pattern) => {
|
||||
if (glob.hasMagic(pattern)) {
|
||||
addByGlob(pattern);
|
||||
} else {
|
||||
@@ -67,7 +67,7 @@ function getFilesAndDeps(patterns, context) {
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function(content) {
|
||||
module.exports = function (content) {
|
||||
this.cacheable();
|
||||
const params = loaderUtils.getOptions(this) || {};
|
||||
let config;
|
||||
@@ -121,7 +121,7 @@ module.exports = function(content) {
|
||||
if (typeof config.rename === 'function') {
|
||||
fontconf.rename = config.rename;
|
||||
} else {
|
||||
fontconf.rename = function(filePath) {
|
||||
fontconf.rename = function (filePath) {
|
||||
return path.basename(filePath, '.svg');
|
||||
};
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ function transform(src, modulePath, rootContext) {
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = function(content) {
|
||||
module.exports = function (content) {
|
||||
this.cacheable && this.cacheable();
|
||||
|
||||
content = transform(content, this.context, this.rootContext);
|
||||
|
@@ -3,7 +3,7 @@
|
||||
const path = require('path');
|
||||
const loaderUtils = require('loader-utils');
|
||||
const fileCache = {};
|
||||
const isProduction = process.argv.some(arg => arg === '-p');
|
||||
const isProduction = process.argv.some((arg) => arg === '-p');
|
||||
const rootPath = path.resolve('./src');
|
||||
|
||||
module.exports = ({ webpack: loader }) => ({
|
||||
@@ -12,7 +12,7 @@ module.exports = ({ webpack: loader }) => ({
|
||||
'postcss-import': {
|
||||
addModulesDirectories: ['./src'],
|
||||
|
||||
resolve: (defaultResolve => (url, basedir, importOptions) =>
|
||||
resolve: ((defaultResolve) => (url, basedir, importOptions) =>
|
||||
defaultResolve(
|
||||
// mainly to remove '~' from request
|
||||
loaderUtils.urlToRequest(url),
|
||||
@@ -20,7 +20,7 @@ module.exports = ({ webpack: loader }) => ({
|
||||
importOptions,
|
||||
))(require('postcss-import/lib/resolve-id')),
|
||||
|
||||
load: (defaultLoad => (filename, importOptions) => {
|
||||
load: ((defaultLoad) => (filename, importOptions) => {
|
||||
if (/\.font.(js|json)$/.test(filename)) {
|
||||
// separately process calls to font loader
|
||||
// e.g. `@import '~app/icons.font.json';`
|
||||
|
@@ -35,14 +35,12 @@ describe('Forgot / reset password', () => {
|
||||
);
|
||||
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
cy.window().then((win) => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
cy.get('[type=submit]').should('have.length', 1).click();
|
||||
|
||||
cy.wait('@forgot')
|
||||
.its('requestBody')
|
||||
@@ -93,14 +91,12 @@ describe('Forgot / reset password', () => {
|
||||
|
||||
cy.get('[name=login]').type(`{selectall}${login}`);
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
cy.window().then((win) => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
cy.get('[type=submit]').should('have.length', 1).click();
|
||||
|
||||
cy.wait('@forgot')
|
||||
.its('requestBody')
|
||||
@@ -136,14 +132,12 @@ describe('Forgot / reset password', () => {
|
||||
|
||||
cy.get('[name=login]').type(login);
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
cy.window().then((win) => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
});
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
cy.get('[type=submit]').should('have.length', 1).click();
|
||||
|
||||
cy.wait('@forgot')
|
||||
.its('requestBody')
|
||||
@@ -187,9 +181,7 @@ describe('Forgot / reset password', () => {
|
||||
|
||||
cy.location('pathname').should('eq', '/forgot-password');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Already have')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls-secondary').contains('Already have').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/recover-password');
|
||||
|
||||
@@ -203,9 +195,7 @@ describe('Forgot / reset password', () => {
|
||||
cy.get('[name=key]').type(key);
|
||||
cy.get('[name=newPassword]').type(newPassword);
|
||||
cy.get('[name=newRePassword]').type(newPassword);
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
cy.get('[type=submit]').should('have.length', 1).click();
|
||||
|
||||
cy.wait('@recover')
|
||||
.its('requestBody')
|
||||
@@ -244,9 +234,7 @@ describe('Forgot / reset password', () => {
|
||||
cy.get('[name=key]').should('have.attr', 'readonly');
|
||||
cy.get('[name=newPassword]').type(newPassword);
|
||||
cy.get('[name=newRePassword]').type(newPassword);
|
||||
cy.get('[type=submit]')
|
||||
.should('have.length', 1)
|
||||
.click();
|
||||
cy.get('[type=submit]').should('have.length', 1).click();
|
||||
|
||||
cy.wait('@recover')
|
||||
.its('requestBody')
|
||||
|
@@ -6,7 +6,7 @@ const multiAccount = createState();
|
||||
const multiAccountWithBadTokens = createState();
|
||||
const singleAccount = createState();
|
||||
singleAccount.accounts.available = singleAccount.accounts.available.filter(
|
||||
account => account.id === singleAccount.accounts.active,
|
||||
(account) => account.id === singleAccount.accounts.active,
|
||||
);
|
||||
|
||||
describe('User with invalid token and refreshToken', () => {
|
||||
@@ -18,7 +18,7 @@ describe('User with invalid token and refreshToken', () => {
|
||||
rawApiResp: true,
|
||||
}).then(({ accounts: [resp] }) => {
|
||||
const account = multiAccount.accounts.available.find(
|
||||
item => item.username === account1.username,
|
||||
(item) => item.username === account1.username,
|
||||
);
|
||||
|
||||
if (!account) {
|
||||
@@ -49,10 +49,7 @@ describe('User with invalid token and refreshToken', () => {
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.get('a')
|
||||
.contains('Ely.by')
|
||||
.click();
|
||||
cy.getByTestId('toolbar').get('a').contains('Ely.by').click();
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
});
|
||||
@@ -64,13 +61,9 @@ describe('User with invalid token and refreshToken', () => {
|
||||
|
||||
cy.location('pathname').should('eq', '/choose-account');
|
||||
|
||||
cy.get('[data-e2e-content]')
|
||||
.contains(account2.email)
|
||||
.should('not.exist');
|
||||
cy.get('[data-e2e-content]').contains(account2.email).should('not.exist');
|
||||
|
||||
cy.get('[data-e2e-content]')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.get('[data-e2e-content]').contains(account1.username).click();
|
||||
cy.get('[name="password"]').type(`${account2.password}{enter}`);
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
@@ -104,24 +97,14 @@ describe('User with invalid token and refreshToken', () => {
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.wait('@account')
|
||||
.its('status')
|
||||
.should('eq', 401);
|
||||
cy.wait('@account').its('status').should('eq', 401);
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
cy.getByTestId('toolbar')
|
||||
.contains('Log out')
|
||||
.click();
|
||||
cy.getByTestId('toolbar').contains(account2.username).click();
|
||||
cy.getByTestId('toolbar').contains('Log out').click();
|
||||
|
||||
cy.wait('@logout');
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.email)
|
||||
.should('not.exist');
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.should('not.exist');
|
||||
cy.getByTestId('toolbar').contains(account2.email).should('not.exist');
|
||||
cy.getByTestId('toolbar').contains(account2.username).should('not.exist');
|
||||
});
|
||||
|
||||
it('should allow enter new login from choose account', () => {
|
||||
@@ -132,9 +115,7 @@ describe('User with invalid token and refreshToken', () => {
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.wait('@account')
|
||||
.its('status')
|
||||
.should('eq', 401);
|
||||
cy.wait('@account').its('status').should('eq', 401);
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
@@ -186,9 +167,7 @@ describe('User with invalid token and refreshToken', () => {
|
||||
|
||||
cy.url().should('include', '/choose-account');
|
||||
|
||||
cy.get('[data-e2e-content]')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.get('[data-e2e-content]').contains(account1.username).click();
|
||||
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
@@ -258,9 +237,7 @@ describe('User with invalid token and refreshToken', () => {
|
||||
|
||||
cy.url().should('contain', '/oauth/choose-account');
|
||||
|
||||
cy.get('[data-e2e-content]')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
cy.get('[data-e2e-content]').contains(account2.username).click();
|
||||
|
||||
cy.url().should('contain', '//dev.ely.by');
|
||||
});
|
||||
|
@@ -49,9 +49,7 @@ describe('OAuth', () => {
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
cy.getByTestId('auth-body').contains(account.email).click();
|
||||
|
||||
cy.url().should('equal', 'https://dev.ely.by/');
|
||||
},
|
||||
@@ -91,9 +89,7 @@ describe('OAuth', () => {
|
||||
|
||||
cy.server({ enable: false });
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls').contains('Approve').click();
|
||||
|
||||
cy.url().should('match', /^http:\/\/localhost:8080\/?\?code=[^&]+&state=$/);
|
||||
});
|
||||
@@ -145,9 +141,7 @@ describe('OAuth', () => {
|
||||
|
||||
cy.server({ enable: false });
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Decline')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls-secondary').contains('Decline').click();
|
||||
|
||||
cy.url().should('include', 'error=access_denied');
|
||||
});
|
||||
@@ -222,9 +216,7 @@ describe('OAuth', () => {
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
cy.getByTestId('auth-body').contains(account.email).click();
|
||||
|
||||
cy.url().should('equal', 'https://dev.ely.by/');
|
||||
});
|
||||
@@ -242,9 +234,7 @@ describe('OAuth', () => {
|
||||
|
||||
cy.url().should('include', '/oauth/choose-account');
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('another account')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls').contains('another account').click();
|
||||
|
||||
cy.url().should('include', '/login');
|
||||
|
||||
@@ -271,9 +261,7 @@ describe('OAuth', () => {
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls').contains('Approve').click();
|
||||
|
||||
cy.url().should(
|
||||
'match',
|
||||
@@ -296,9 +284,7 @@ describe('OAuth', () => {
|
||||
|
||||
cy.url().should('include', '/oauth/permissions');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Decline')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls-secondary').contains('Decline').click();
|
||||
|
||||
cy.url().should('include', 'error=access_denied');
|
||||
});
|
||||
@@ -318,15 +304,11 @@ describe('OAuth', () => {
|
||||
|
||||
cy.getByTestId('auth-header').should('contain', 'Choose an account');
|
||||
|
||||
cy.getByTestId('auth-body')
|
||||
.contains(account.email)
|
||||
.click();
|
||||
cy.getByTestId('auth-body').contains(account.email).click();
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls').contains('Approve').click();
|
||||
|
||||
cy.url().should(
|
||||
'match',
|
||||
@@ -355,9 +337,7 @@ describe('OAuth', () => {
|
||||
|
||||
assertPermissions();
|
||||
|
||||
cy.getByTestId('auth-controls')
|
||||
.contains('Approve')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls').contains('Approve').click();
|
||||
|
||||
cy.url().should(
|
||||
'match',
|
||||
@@ -418,9 +398,7 @@ describe('OAuth', () => {
|
||||
// just click on copy, but we won't assert if the string was copied
|
||||
// because it is a little bit complicated
|
||||
// https://github.com/cypress-io/cypress/issues/2752
|
||||
cy.getByTestId('oauth-code-container')
|
||||
.contains('Copy')
|
||||
.click();
|
||||
cy.getByTestId('oauth-code-container').contains('Copy').click();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -27,9 +27,7 @@ describe('Register', () => {
|
||||
});
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains('Join')
|
||||
.click();
|
||||
cy.getByTestId('toolbar').contains('Join').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/register');
|
||||
|
||||
@@ -38,12 +36,10 @@ describe('Register', () => {
|
||||
cy.get('[name=password]').type(password);
|
||||
cy.get('[name=rePassword]').type(password);
|
||||
cy.get('[name=rulesAgreement]').should('not.be.checked');
|
||||
cy.get('[name=rulesAgreement]')
|
||||
.parent()
|
||||
.click();
|
||||
cy.get('[name=rulesAgreement]').parent().click();
|
||||
cy.get('[name=rulesAgreement]').should('be.checked');
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
cy.window().then((win) => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
@@ -93,9 +89,7 @@ describe('Register', () => {
|
||||
});
|
||||
cy.visit('/register');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('Already have')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls-secondary').contains('Already have').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/activation');
|
||||
|
||||
@@ -148,15 +142,13 @@ describe('Register', () => {
|
||||
}).as('resend');
|
||||
cy.visit('/register');
|
||||
|
||||
cy.getByTestId('auth-controls-secondary')
|
||||
.contains('not received')
|
||||
.click();
|
||||
cy.getByTestId('auth-controls-secondary').contains('not received').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/resend-activation');
|
||||
|
||||
cy.get('[name=email]').type(email);
|
||||
cy.window().should('have.property', 'e2eCaptchaSetCode');
|
||||
cy.window().then(win => {
|
||||
cy.window().then((win) => {
|
||||
// fake captcha response
|
||||
// @ts-ignore
|
||||
win.e2eCaptchaSetCode(captchaCode);
|
||||
|
@@ -24,18 +24,10 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
const [account] = state.accounts.available;
|
||||
expect(account.username).to.be.equal(account1.username);
|
||||
expect(account.id)
|
||||
.to.be.a('number')
|
||||
.and.to.be.gt(0);
|
||||
expect(account.email)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.token)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.refreshToken)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.id).to.be.a('number').and.to.be.gt(0);
|
||||
expect(account.email).to.be.a('string').and.have.length.gt(0);
|
||||
expect(account.token).to.be.a('string').and.have.length.gt(0);
|
||||
expect(account.refreshToken).to.be.a('string').and.have.length.gt(0);
|
||||
|
||||
expect(state.accounts.active).to.be.equal(account.id);
|
||||
|
||||
@@ -64,9 +56,7 @@ describe('Sign in / Log out', () => {
|
||||
cy.url().should('include', '/password');
|
||||
|
||||
cy.get('[name=password]').type(account1.password);
|
||||
cy.get('[name=rememberMe]')
|
||||
.parent()
|
||||
.click();
|
||||
cy.get('[name=rememberMe]').parent().click();
|
||||
cy.get('[name=rememberMe]').should('not.be.checked');
|
||||
cy.get('[type=submit]').click();
|
||||
|
||||
@@ -80,15 +70,9 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
const [account] = state.accounts.available;
|
||||
expect(account.username).to.be.equal(account1.username);
|
||||
expect(account.id)
|
||||
.to.be.a('number')
|
||||
.and.to.be.gt(0);
|
||||
expect(account.email)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.token)
|
||||
.to.be.a('string')
|
||||
.and.have.length.gt(0);
|
||||
expect(account.id).to.be.a('number').and.to.be.gt(0);
|
||||
expect(account.email).to.be.a('string').and.have.length.gt(0);
|
||||
expect(account.token).to.be.a('string').and.have.length.gt(0);
|
||||
expect(account.refreshToken).eql(null);
|
||||
|
||||
expect(state.accounts.active).to.be.equal(account.id);
|
||||
@@ -129,9 +113,7 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
cy.get('[name=totp]').type('123{enter}');
|
||||
|
||||
cy.wait('@login')
|
||||
.its('requestBody')
|
||||
.should('include', 'totp=123');
|
||||
cy.wait('@login').its('requestBody').should('include', 'totp=123');
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
@@ -141,13 +123,9 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.getByTestId('toolbar').contains(account1.username).click();
|
||||
|
||||
cy.getByTestId('active-account')
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
cy.getByTestId('active-account').getByTestId('logout-account').click();
|
||||
|
||||
cy.location('pathname').should('eq', '/login');
|
||||
cy.getByTestId('toolbar').should('contain', 'Join');
|
||||
@@ -159,9 +137,7 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
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);
|
||||
@@ -180,16 +156,12 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
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();
|
||||
cy.get('[data-e2e-account-id]').getByTestId('logout-account').click();
|
||||
});
|
||||
|
||||
it('should go back to profile from login screen', () => {
|
||||
@@ -197,9 +169,7 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.getByTestId('toolbar').contains(account1.username).click();
|
||||
|
||||
cy.getByTestId('add-account').click();
|
||||
|
||||
@@ -215,17 +185,11 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.getByTestId('toolbar').contains(account1.username).click();
|
||||
|
||||
cy.getByTestId('active-account')
|
||||
.getByTestId('logout-account')
|
||||
.click();
|
||||
cy.getByTestId('active-account').getByTestId('logout-account').click();
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account2.username)
|
||||
.click();
|
||||
cy.getByTestId('toolbar').contains(account2.username).click();
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
cy.getByTestId('profile-index').should('not.contain', account1.username);
|
||||
cy.getByTestId('profile-index').should('contain', account2.username);
|
||||
@@ -236,9 +200,7 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
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);
|
||||
@@ -257,9 +219,7 @@ describe('Sign in / Log out', () => {
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account1.username)
|
||||
.click();
|
||||
cy.getByTestId('toolbar').contains(account1.username).click();
|
||||
cy.get('[data-e2e-account-id]').should('have.length', 0);
|
||||
});
|
||||
});
|
||||
|
@@ -5,13 +5,13 @@ describe('Applications', () => {
|
||||
cy.visit('/dev/applications');
|
||||
|
||||
// remove all previously added apps
|
||||
cy.window().then(async win => {
|
||||
cy.window().then(async (win) => {
|
||||
const { oauthApi } = (win as any) as {
|
||||
oauthApi: typeof import('app/services/api/oauth').default;
|
||||
};
|
||||
const apps = await oauthApi.getAppsByUser(user.id);
|
||||
|
||||
await Promise.all(apps.map(app => oauthApi.delete(app.clientId)));
|
||||
await Promise.all(apps.map((app) => oauthApi.delete(app.clientId)));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -59,9 +59,7 @@ describe('Profile — Change Email', () => {
|
||||
cy.location('pathname').should('eq', '/profile/change-email/step2');
|
||||
|
||||
cy.getByTestId('step2').should('be.visible');
|
||||
cy.getByTestId('step2')
|
||||
.find('[name=key]')
|
||||
.type(key);
|
||||
cy.getByTestId('step2').find('[name=key]').type(key);
|
||||
cy.getByTestId('step2')
|
||||
.find('[name=email]')
|
||||
.type(`${account.email}{enter}`);
|
||||
@@ -77,15 +75,9 @@ describe('Profile — Change Email', () => {
|
||||
);
|
||||
cy.location('pathname').should('eq', '/profile/change-email/step3');
|
||||
|
||||
cy.getByTestId('step3')
|
||||
.find('[name=key]')
|
||||
.should('be.visible');
|
||||
cy.getByTestId('step3')
|
||||
.find('[name=key]')
|
||||
.should('have.value', '');
|
||||
cy.getByTestId('step3')
|
||||
.find('[name=key]')
|
||||
.type(`${key2}{enter}`);
|
||||
cy.getByTestId('step3').find('[name=key]').should('be.visible');
|
||||
cy.getByTestId('step3').find('[name=key]').should('have.value', '');
|
||||
cy.getByTestId('step3').find('[name=key]').type(`${key2}{enter}`);
|
||||
|
||||
cy.wait('@saveEmail')
|
||||
.its('requestBody')
|
||||
@@ -126,12 +118,8 @@ describe('Profile — Change Email', () => {
|
||||
|
||||
cy.visit(`/profile/change-email/step2/${key}`);
|
||||
|
||||
cy.getByTestId('step2')
|
||||
.find('[name=key]')
|
||||
.should('have.value', key);
|
||||
cy.getByTestId('step2')
|
||||
.find('[name=key]')
|
||||
.should('be.disabled');
|
||||
cy.getByTestId('step2').find('[name=key]').should('have.value', key);
|
||||
cy.getByTestId('step2').find('[name=key]').should('be.disabled');
|
||||
cy.getByTestId('step2')
|
||||
.find('[name=email]')
|
||||
.type(`${account.email}{enter}`);
|
||||
@@ -146,9 +134,7 @@ describe('Profile — Change Email', () => {
|
||||
}).toString(),
|
||||
);
|
||||
cy.location('pathname').should('eq', '/profile/change-email/step3');
|
||||
cy.getByTestId('step3')
|
||||
.find('[name=key]')
|
||||
.should('have.value', '');
|
||||
cy.getByTestId('step3').find('[name=key]').should('have.value', '');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -165,25 +151,17 @@ describe('Profile — Change Email', () => {
|
||||
|
||||
cy.visit(`/profile/change-email/step3/${key}`);
|
||||
|
||||
cy.getByTestId('step3')
|
||||
.find('[name=key]')
|
||||
.should('have.value', key);
|
||||
cy.getByTestId('step3')
|
||||
.find('[name=key]')
|
||||
.should('be.disabled');
|
||||
cy.getByTestId('step3').find('[name=key]').should('have.value', key);
|
||||
cy.getByTestId('step3').find('[name=key]').should('be.disabled');
|
||||
|
||||
cy.getByTestId('change-email')
|
||||
.find('[type=submit]')
|
||||
.click();
|
||||
cy.getByTestId('change-email').find('[type=submit]').click();
|
||||
|
||||
cy.wait('@saveEmail')
|
||||
.its('requestBody')
|
||||
.should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
key,
|
||||
}).toString(),
|
||||
);
|
||||
cy.wait('@saveEmail').its('requestBody').should(
|
||||
'eq',
|
||||
new URLSearchParams({
|
||||
key,
|
||||
}).toString(),
|
||||
);
|
||||
cy.location('pathname').should('eq', '/');
|
||||
});
|
||||
});
|
||||
|
@@ -67,9 +67,7 @@ describe('Profile — Change Username', () => {
|
||||
|
||||
cy.location('pathname').should('eq', '/');
|
||||
cy.getByTestId('profile-item').should('contain', account.username);
|
||||
cy.getByTestId('toolbar')
|
||||
.contains(account.username)
|
||||
.click();
|
||||
cy.getByTestId('toolbar').contains(account.username).click();
|
||||
cy.getByTestId('active-account').should('contain', account.username);
|
||||
});
|
||||
});
|
||||
|
@@ -16,9 +16,7 @@ describe('feedback popup', () => {
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('footer')
|
||||
.contains('Contact Us')
|
||||
.click();
|
||||
cy.getByTestId('footer').contains('Contact Us').click();
|
||||
cy.getByTestId('feedbackPopup').should('be.visible');
|
||||
|
||||
cy.get('[name=subject]').type(subject);
|
||||
@@ -29,16 +27,12 @@ describe('feedback popup', () => {
|
||||
.getByTestId('select-label')
|
||||
.should('contain', 'What are you interested');
|
||||
cy.get('[data-e2e-select-name=category]').click();
|
||||
cy.get('[data-e2e-select-name=category]')
|
||||
.contains('bug')
|
||||
.click();
|
||||
cy.get('[data-e2e-select-name=category]').contains('bug').click();
|
||||
cy.get('[data-e2e-select-name=category]')
|
||||
.getByTestId('select-label')
|
||||
.should('contain', 'bug');
|
||||
|
||||
cy.getByTestId('feedbackPopup')
|
||||
.get('[type=submit]')
|
||||
.click();
|
||||
cy.getByTestId('feedbackPopup').get('[type=submit]').click();
|
||||
|
||||
cy.getByTestId('feedbackPopup').should(
|
||||
'contain',
|
||||
|
@@ -2,9 +2,7 @@ describe('Change locale', () => {
|
||||
it('should change locale from footer', () => {
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('footer')
|
||||
.contains('Site language')
|
||||
.click();
|
||||
cy.getByTestId('footer').contains('Site language').click();
|
||||
|
||||
cy.getByTestId('language-switcher').should('be.visible');
|
||||
cy.getByTestId('language-switcher').should(
|
||||
@@ -13,15 +11,11 @@ describe('Change locale', () => {
|
||||
'en',
|
||||
);
|
||||
|
||||
cy.getByTestId('language-list')
|
||||
.contains('Belarusian')
|
||||
.click();
|
||||
cy.getByTestId('language-list').contains('Belarusian').click();
|
||||
|
||||
cy.getByTestId('language-switcher').should('not.be.visible');
|
||||
|
||||
cy.getByTestId('footer')
|
||||
.contains('Мова сайта')
|
||||
.click();
|
||||
cy.getByTestId('footer').contains('Мова сайта').click();
|
||||
|
||||
cy.getByTestId('language-switcher').should('be.visible');
|
||||
cy.getByTestId('language-switcher').should(
|
||||
@@ -30,9 +24,7 @@ describe('Change locale', () => {
|
||||
'be',
|
||||
);
|
||||
|
||||
cy.getByTestId('language-list')
|
||||
.contains('English')
|
||||
.click();
|
||||
cy.getByTestId('language-list').contains('English').click();
|
||||
|
||||
cy.getByTestId('language-switcher').should('not.be.visible');
|
||||
cy.getByTestId('footer').should('contain', 'Site language');
|
||||
@@ -50,9 +42,7 @@ describe('Change locale', () => {
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.getByTestId('profile-index')
|
||||
.contains('English')
|
||||
.click();
|
||||
cy.getByTestId('profile-index').contains('English').click();
|
||||
|
||||
cy.getByTestId('language-switcher').should('be.visible');
|
||||
cy.getByTestId('language-switcher').should(
|
||||
@@ -61,13 +51,9 @@ describe('Change locale', () => {
|
||||
'en',
|
||||
);
|
||||
|
||||
cy.getByTestId('language-list')
|
||||
.contains('Belarusian')
|
||||
.click();
|
||||
cy.getByTestId('language-list').contains('Belarusian').click();
|
||||
|
||||
cy.wait('@language')
|
||||
.its('requestBody')
|
||||
.should('eq', 'lang=be');
|
||||
cy.wait('@language').its('requestBody').should('eq', 'lang=be');
|
||||
|
||||
cy.getByTestId('language-switcher').should('not.be.visible');
|
||||
cy.getByTestId('profile-index').should('contain', 'Беларуская');
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user