Remove any from codebase
This commit is contained in:
@@ -21,12 +21,14 @@ module.exports = {
|
||||
'no-undef': 'off',
|
||||
'no-redeclare': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['*.d.ts'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ global.Headers = class HeadersMock extends Headers implements Headers {
|
||||
delete(key: string) {
|
||||
this.headers.delete(key);
|
||||
}
|
||||
forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: any) {
|
||||
forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: unknown) {
|
||||
this.headers.forEach((value, key) => {
|
||||
callbackfn.call(thisArg || this, value, key, this);
|
||||
});
|
||||
|
||||
@@ -28,9 +28,9 @@ describe('fetcher', () => {
|
||||
});
|
||||
it('should throw special error object on 401 status', async () => {
|
||||
const response = '<html>unauthorized nginx response</html>';
|
||||
(window.fetch as any) = jest.fn().mockImplementation(async () => ({
|
||||
window.fetch = jest.fn().mockImplementation(async () => ({
|
||||
status: 401,
|
||||
headers: new (window as any).Headers(),
|
||||
headers: new Headers(),
|
||||
json: async () => {
|
||||
throw new Error('json parse error');
|
||||
},
|
||||
@@ -48,9 +48,9 @@ describe('fetcher', () => {
|
||||
});
|
||||
});
|
||||
it('should throw "Something went wrong." object on unknown status', async () => {
|
||||
(jest.spyOn(window, 'fetch') as any).mockImplementation(async () => ({
|
||||
window.fetch = jest.fn().mockImplementation(async () => ({
|
||||
status: 400,
|
||||
headers: new (window as any).Headers(),
|
||||
headers: new Headers(),
|
||||
async json() {
|
||||
throw new Error('json parse error');
|
||||
},
|
||||
|
||||
@@ -12,7 +12,7 @@ describe('getJsonItem', () => {
|
||||
});
|
||||
|
||||
it('should update json in localStoeage', () => {
|
||||
setJsonItem<any[]>(LS_KEY, []);
|
||||
setJsonItem(LS_KEY, []);
|
||||
expect(localStorage.getItem(LS_KEY)).toBe('[]');
|
||||
});
|
||||
});
|
||||
@@ -88,7 +88,7 @@ describe('updateJsonItem', () => {
|
||||
|
||||
it('should update data in localStorage with merge', () => {
|
||||
localStorage.setItem(LS_KEY, JSON.stringify([3, 4, 5]));
|
||||
updateJsonItem<any[]>(LS_KEY, data => [1, 2, ...data]);
|
||||
updateJsonItem(LS_KEY, (data: unknown[]) => [1, 2, ...data]);
|
||||
|
||||
expect(localStorage.getItem(LS_KEY)).toBe(JSON.stringify([1, 2, 3, 4, 5]));
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@ export const removeItem = IS_STORAGE_AVAILABLE
|
||||
console.error(failMessage); // eslint-disable-line no-console
|
||||
};
|
||||
|
||||
export function getJsonItem<T = any>(key: string): T | null {
|
||||
export function getJsonItem<T = unknown>(key: string): T | null {
|
||||
try {
|
||||
const json = getItem(key);
|
||||
|
||||
@@ -38,7 +38,7 @@ export function getJsonItem<T = any>(key: string): T | null {
|
||||
}
|
||||
}
|
||||
|
||||
export function setJsonItem<T = any>(key: string, data: T) {
|
||||
export function setJsonItem<T = unknown>(key: string, data: T) {
|
||||
try {
|
||||
setItem(key, JSON.stringify(data));
|
||||
} catch (e) {
|
||||
@@ -48,10 +48,11 @@ export function setJsonItem<T = any>(key: string, data: T) {
|
||||
|
||||
export function updateJsonItem<T extends {}>(key: string, value: (data: T) => T): void;
|
||||
export function updateJsonItem<T extends {}>(key: string, value: T): void;
|
||||
export function updateJsonItem<T = Record<string, unknown>>(key: string, value: T) {
|
||||
const savedData = getJsonItem<any>(key);
|
||||
export function updateJsonItem<T extends unknown[]>(key: string, value: T): void;
|
||||
export function updateJsonItem<T>(key: string, value: T) {
|
||||
const savedData = getJsonItem<T>(key);
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
if (Array.isArray(value) && Array.isArray(savedData)) {
|
||||
setJsonItem(key, [...savedData, ...value]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Middleware } from 'redux';
|
||||
import { Provider } from 'react-redux';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
|
||||
import type { User } from 'common/types';
|
||||
import enMessages from 'locales/en.json';
|
||||
|
||||
import AuthPanel, { Props } from './auth-panel';
|
||||
@@ -61,7 +62,7 @@ describe('<AuthPanel />', () => {
|
||||
...DefaultProps,
|
||||
user: null,
|
||||
postInfo: { ...DefaultProps.postInfo, read_only: true },
|
||||
hiddenUsers: { hidden_joe: {} as any },
|
||||
hiddenUsers: { hidden_joe: {} as User },
|
||||
} as Props);
|
||||
|
||||
const adminAction = element.find('.auth-panel__admin-action');
|
||||
@@ -76,7 +77,7 @@ describe('<AuthPanel />', () => {
|
||||
...DefaultProps,
|
||||
user: null,
|
||||
postInfo: { ...DefaultProps.postInfo, read_only: true },
|
||||
hiddenUsers: { hidden_joe: {} as any },
|
||||
hiddenUsers: { hidden_joe: {} as User },
|
||||
} as Props);
|
||||
|
||||
const firstCol = element.find('.auth-panel__column').first();
|
||||
|
||||
@@ -20,22 +20,26 @@ jest.mock('utils/jwt', () => ({
|
||||
|
||||
jest.mock('common/api');
|
||||
|
||||
const sendEmailVerificationRequestMock = sendEmailVerificationRequest as jest.Mock<
|
||||
ReturnType<typeof sendEmailVerificationRequest>
|
||||
>;
|
||||
|
||||
function simulateInput(input: ReactWrapper, value: string) {
|
||||
input.getDOMNode<HTMLTextAreaElement>().value = value;
|
||||
input.simulate('input');
|
||||
}
|
||||
|
||||
describe('EmailLoginForm', () => {
|
||||
const testUser = ({} as any) as User;
|
||||
const testUser = {} as User;
|
||||
const onSuccess = jest.fn(async () => undefined);
|
||||
const onSignIn = jest.fn(async () => testUser);
|
||||
|
||||
beforeEach(() => {
|
||||
(sendEmailVerificationRequest as any).mockReset();
|
||||
sendEmailVerificationRequestMock.mockReset();
|
||||
});
|
||||
|
||||
it('works', async () => {
|
||||
(sendEmailVerificationRequest as any).mockResolvedValueOnce({});
|
||||
sendEmailVerificationRequestMock.mockResolvedValueOnce();
|
||||
const el = mount<Props, State>(
|
||||
<IntlProvider locale="en" messages={enMessages}>
|
||||
<EmailLoginForm onSignIn={onSignIn} onSuccess={onSuccess} theme="light" />
|
||||
@@ -45,7 +49,7 @@ describe('EmailLoginForm', () => {
|
||||
simulateInput(el.find(`input[name="username"]`), 'someone');
|
||||
el.find('form').simulate('submit');
|
||||
await sleep(100);
|
||||
expect(sendEmailVerificationRequest).toBeCalledWith('someone', 'someone@example.com');
|
||||
expect(sendEmailVerificationRequestMock).toBeCalledWith('someone', 'someone@example.com');
|
||||
el.update();
|
||||
simulateInput(el.find(`textarea[name="token"]`), 'abcd');
|
||||
|
||||
@@ -58,7 +62,7 @@ describe('EmailLoginForm', () => {
|
||||
});
|
||||
|
||||
it('should send form by pasting token', async () => {
|
||||
(sendEmailVerificationRequest as any).mockResolvedValueOnce({});
|
||||
sendEmailVerificationRequestMock.mockResolvedValueOnce();
|
||||
const onSignIn = jest.fn(async () => testUser);
|
||||
|
||||
const wrapper = mount<Props, State>(
|
||||
@@ -78,7 +82,7 @@ describe('EmailLoginForm', () => {
|
||||
});
|
||||
|
||||
it('should show error "Token is expired" on paste', async () => {
|
||||
(sendEmailVerificationRequest as any).mockResolvedValueOnce({});
|
||||
sendEmailVerificationRequestMock.mockResolvedValueOnce();
|
||||
const onSignIn = jest.fn(async () => testUser);
|
||||
|
||||
const wrapper = mount<Props, State>(
|
||||
|
||||
+3
-4
@@ -15,7 +15,6 @@ import { sleep } from 'utils/sleep';
|
||||
import { Input } from 'components/input';
|
||||
import { Button } from 'components/button';
|
||||
import { Dropdown } from 'components/dropdown';
|
||||
import TextareaAutosize from 'components/comment-form/textarea-autosize';
|
||||
import enMessages from 'locales/en.json';
|
||||
import { LS_EMAIL_KEY } from 'common/constants';
|
||||
|
||||
@@ -161,10 +160,10 @@ describe('<SubscribeByEmailForm/>', () => {
|
||||
await sleep(0);
|
||||
wrapper.update();
|
||||
|
||||
const textarea = wrapper.find(TextareaAutosize);
|
||||
const onInputToken = textarea.prop('onInput') as (e: any) => void;
|
||||
const textarea = wrapper.find('textarea');
|
||||
|
||||
act(() => onInputToken(makeInputEvent(validToken)));
|
||||
textarea.getDOMNode<HTMLTextAreaElement>().value = validToken;
|
||||
textarea.simulate('input');
|
||||
|
||||
await sleep(0);
|
||||
wrapper.update();
|
||||
|
||||
@@ -9,8 +9,9 @@ import * as localStorageModule from 'common/local-storage';
|
||||
import { CommentForm, CommentFormProps, messages } from './comment-form';
|
||||
import { SubscribeByEmail } from './__subscribe-by-email';
|
||||
import TextareaAutosize from './textarea-autosize';
|
||||
import { IntlShape } from 'react-intl';
|
||||
|
||||
function createEvent<E extends Event, T = any>(type: string, value: T): E {
|
||||
function createEvent<E extends Event, T = unknown>(type: string, value: T): E {
|
||||
const event = new Event(type);
|
||||
|
||||
Object.defineProperty(event, 'target', { value });
|
||||
@@ -31,7 +32,7 @@ const intl = {
|
||||
formatMessage(message: { defaultMessage: string }) {
|
||||
return message.defaultMessage || '';
|
||||
},
|
||||
} as any;
|
||||
} as IntlShape;
|
||||
|
||||
describe('<CommentForm />', () => {
|
||||
it('should shallow without control panel, preview button, and rss links in "simple view" mode', () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { h } from 'preact';
|
||||
import { mount as enzymeMount } from 'enzyme';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { IntlProvider, IntlShape } from 'react-intl';
|
||||
|
||||
import enMessages from 'locales/en.json';
|
||||
import type { User, Comment as CommentType, PostInfo } from 'common/types';
|
||||
@@ -9,7 +9,7 @@ import { sleep } from 'utils/sleep';
|
||||
|
||||
import Comment, { CommentProps } from './comment';
|
||||
|
||||
const mount = (component: any) =>
|
||||
const mount = <T extends JSX.Element>(component: T) =>
|
||||
enzymeMount(
|
||||
<IntlProvider locale="en" messages={enMessages}>
|
||||
{component}
|
||||
@@ -20,7 +20,7 @@ const intl = {
|
||||
formatMessage(message: { defaultMessage: string }) {
|
||||
return message.defaultMessage || '';
|
||||
},
|
||||
} as any;
|
||||
} as IntlShape;
|
||||
|
||||
const DefaultProps: Partial<CommentProps> = {
|
||||
CommentForm: null,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { useCallback, useMemo } from 'preact/compat';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { BoundActionCreator, BoundActionCreators } from 'utils/actionBinder';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Comment } from 'common/types';
|
||||
import { StoreState } from 'store';
|
||||
|
||||
import { setCollapse } from './actions';
|
||||
import { THREAD_SET_COLLAPSE } from './types';
|
||||
@@ -6,11 +7,11 @@ import { THREAD_SET_COLLAPSE } from './types';
|
||||
describe('collapsedThreads', () => {
|
||||
it('should set collapsed to true', () => {
|
||||
const comment = { id: 'some-id' } as Comment;
|
||||
const node = { comment, replies: [] };
|
||||
const state = { collapsedThreads: {}, comments: [node] };
|
||||
const state = { collapsedThreads: {} } as StoreState;
|
||||
|
||||
const dispatch = jest.fn();
|
||||
const getState = jest.fn(() => state) as any;
|
||||
const getState = jest.fn(() => state);
|
||||
|
||||
setCollapse(comment.id, true)(dispatch, getState, undefined);
|
||||
expect(dispatch).toBeCalledWith({
|
||||
type: THREAD_SET_COLLAPSE,
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import * as api from 'common/api';
|
||||
import { getUser, logIn as logInApi, logOut } from 'common/api';
|
||||
import { User } from 'common/types';
|
||||
|
||||
import { fetchUser, logIn, logout } from './actions';
|
||||
import { user } from './reducers';
|
||||
import { USER_SET } from './types';
|
||||
import { USER_ACTIONS, USER_SET } from './types';
|
||||
|
||||
jest.mock('common/api');
|
||||
|
||||
const getUserMock = (getUser as unknown) as jest.Mock<ReturnType<typeof getUser>>;
|
||||
const logInMock = (logInApi as unknown) as jest.Mock<ReturnType<typeof logInApi>>;
|
||||
const logOutMock = (logOut as unknown) as jest.Mock<ReturnType<typeof logOut>>;
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetModules();
|
||||
});
|
||||
@@ -14,12 +18,13 @@ afterEach(() => {
|
||||
describe('user', () => {
|
||||
it('should return null by default', () => {
|
||||
const action = { type: 'OTHER' };
|
||||
const newState = user(null, action as any);
|
||||
const newState = user(null, action as USER_ACTIONS);
|
||||
|
||||
expect(newState).toEqual(null);
|
||||
});
|
||||
|
||||
it('should set state of user on fetchUser', async () => {
|
||||
(api.getUser as any).mockImplementation(
|
||||
getUserMock.mockImplementation(
|
||||
async (): Promise<User> =>
|
||||
({
|
||||
id: 'john',
|
||||
@@ -41,7 +46,7 @@ describe('user', () => {
|
||||
});
|
||||
|
||||
it('should set state of user on logIn', async () => {
|
||||
(api.logIn as any).mockImplementation(
|
||||
logInMock.mockImplementation(
|
||||
async (): Promise<User> =>
|
||||
({
|
||||
id: 'john',
|
||||
@@ -63,7 +68,7 @@ describe('user', () => {
|
||||
});
|
||||
|
||||
it('should NOT set state of user on failed logIn', async () => {
|
||||
(api.logIn as any).mockImplementation(
|
||||
logInMock.mockImplementation(
|
||||
async (): Promise<User> => {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
@@ -75,7 +80,7 @@ describe('user', () => {
|
||||
});
|
||||
|
||||
it('should unset user on logOut', async () => {
|
||||
(api.logOut as any).mockImplementation(async (): Promise<void> => undefined);
|
||||
logOutMock.mockImplementation(async (): Promise<void> => undefined);
|
||||
const dispatch = jest.fn();
|
||||
const getState = jest.fn();
|
||||
await logout()(dispatch, getState, undefined);
|
||||
|
||||
@@ -6,7 +6,7 @@ export default function debounce<T extends unknown[]>(
|
||||
): (...args: Parameters<FnType<T>>) => void {
|
||||
let timeout: number | undefined;
|
||||
|
||||
return function (this: any, ...args): void {
|
||||
return function (this: unknown, ...args): void {
|
||||
const laterCall = (): unknown => fn.apply(this, args);
|
||||
window.clearTimeout(timeout);
|
||||
timeout = window.setTimeout(laterCall, wait);
|
||||
|
||||
Reference in New Issue
Block a user