Skip to content

Commit

Permalink
Merge pull request #870 from neet/multiple-accounts
Browse files Browse the repository at this point in the history
E2E test using multiple accounts
  • Loading branch information
neet committed Apr 8, 2023
2 parents 6b40407 + 767675f commit 72b40fc
Show file tree
Hide file tree
Showing 106 changed files with 2,251 additions and 405 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
DB_USER: mastodon
DB_NAME: mastodon
DB_PASS: password
MASTODON_CONTAINER: mastodon

services:
db:
Expand Down Expand Up @@ -69,6 +70,9 @@ jobs:
-d
-p 3000:3000
-p 4000:4000
--name ${{ env.MASTODON_CONTAINER }}
-e DEEPL_PLAN=${{ secrets.DEEPL_PLAN }}
-e DEEPL_API_KEY=${{ secrets.DEEPL_API_KEY }}
--env-file ./.github/.env.test
docker.io/neetshin/mastodon-dev:latest
bash -c "foreman start"
Expand Down
4 changes: 4 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
comment: false

flag_management:
default_rules:
carryforward: true
5 changes: 4 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"asynckit",
"blurhash",
"builtins",
"carryforward",
"codecov",
"conventionalcommits",
"Datetime",
Expand Down Expand Up @@ -37,6 +38,7 @@
"shortcode",
"subprotocol",
"subresource",
"tootctl",
"trendable",
"typedoc",
"unassign",
Expand All @@ -47,6 +49,7 @@
"unprocessable",
"unreblog",
"unreviewed",
"unsilence"
"unsilence",
"unstorage"
]
}
2 changes: 1 addition & 1 deletion jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ module.exports = {
setupFilesAfterEnv: ['<rootDir>/test-utils/jest-setup-after-env.ts'],
},
],
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.spec.ts'],
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.spec.ts', '!**/__mocks__/**'],
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-simple-import-sort": "^10.0.0",
"eslint-plugin-unicorn": "^45.0.2",
"generic-pool": "^3.9.0",
"iterator-helpers-polyfill": "^2.2.8",
"jest": "^29.4.2",
"npm-run-all": "^4.1.5",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Http } from './http';
import type { Http } from '../http/http';

export const httpRequest = jest.fn();
export const httpGet = jest.fn();
Expand Down
3 changes: 3 additions & 0 deletions src/__mocks__/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './http-mock-impl';
export * from './ws-mock-impl';
export * from './logger-mock-impl';
7 changes: 7 additions & 0 deletions src/__mocks__/logger-mock-impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { BaseLogger } from '../logger';

export const log = jest.fn();

export class LoggerMockImpl extends BaseLogger {
log = log;
}
2 changes: 1 addition & 1 deletion src/ws/ws-mock-impl.ts → src/__mocks__/ws-mock-impl.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import EventEmitter from 'eventemitter3';

import type { EventTypeMap, Ws, WsEvents } from './ws';
import type { EventTypeMap, Ws, WsEvents } from '../ws';

export const wsDisconnect = jest.fn();
export const wsOn = jest.fn();
Expand Down
118 changes: 118 additions & 0 deletions src/errors/factory.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { createHttpError } from './factory';
import { MastoHttpConflictError } from './masto-http-conflict-error';
import { MastoHttpForbiddenError } from './masto-http-forbidden-error';
import { MastoHttpGoneError } from './masto-http-gone-error';
import { MastoHttpNotFoundError } from './masto-http-not-found-error';
import { MastoHttpRateLimitError } from './masto-http-rate-limit-error';
import { MastoHttpUnauthorizedError } from './masto-http-unauthorized-error';
import { MastoHttpUnexpectedError } from './masto-http-unexpected-error';
import { MastoHttpUnprocessableEntityError } from './masto-http-unprocessable-entity-error';

describe('HTTP error factory', () => {
it('creates unauthorized error', () => {
const cause = {};
const error = createHttpError({
statusCode: 401,
message: 'Unauthorized',
cause,
});

expect(error).toBeInstanceOf(MastoHttpUnauthorizedError);
expect(error.cause).toBe(cause);
expect(error.message).toBe('Unauthorized');
});

it('creates forbidden error', () => {
const cause = {};
const error = createHttpError({
statusCode: 403,
message: 'Forbidden',
cause,
});

expect(error).toBeInstanceOf(MastoHttpForbiddenError);
expect(error.cause).toBe(cause);
expect(error.message).toBe('Forbidden');
});

it('creates not found error', () => {
const cause = {};
const error = createHttpError({
statusCode: 404,
message: 'Not Found',
cause,
});

expect(error).toBeInstanceOf(MastoHttpNotFoundError);
expect(error.cause).toBe(cause);
expect(error.message).toBe('Not Found');
});

it('creates conflict error', () => {
const cause = {};
const error = createHttpError({
statusCode: 409,
message: 'Conflict',
cause,
});

expect(error).toBeInstanceOf(MastoHttpConflictError);
expect(error.cause).toBe(cause);
expect(error.message).toBe('Conflict');
});

it('creates gone error', () => {
const cause = {};
const error = createHttpError({
statusCode: 410,
message: 'Gone',
cause,
});

expect(error).toBeInstanceOf(MastoHttpGoneError);
expect(error.cause).toBe(cause);
expect(error.message).toBe('Gone');
});

it('creates unprocessable entity error', () => {
const cause = {};
const error = createHttpError({
statusCode: 422,
message: 'Unprocessable Entity',
cause,
});

expect(error).toBeInstanceOf(MastoHttpUnprocessableEntityError);
expect(error.cause).toBe(cause);
expect(error.message).toBe('Unprocessable Entity');
});

it('creates rate limit error', () => {
const cause = {};
const error = createHttpError({
statusCode: 429,
message: 'Rate Limit Exceeded',
cause,
limit: 100,
remaining: 0,
reset: '2021-01-01T00:00:00.000Z',
});

expect(error).toBeInstanceOf(MastoHttpRateLimitError);
expect(error.cause).toBe(cause);
expect(error.message).toBe('Rate Limit Exceeded');
});

it('creates unexpected error', () => {
const cause = {};
const error = createHttpError({
statusCode: 500,
message: 'Internal Server Error',
cause,
});

expect(error).toBeInstanceOf(MastoHttpUnexpectedError);
expect(error.cause).toBe(cause);
expect(error.message).toBe('Internal Server Error');
});
});
6 changes: 3 additions & 3 deletions src/errors/masto-http-rate-limit-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export class MastoHttpRateLimitError extends MastoHttpError {
super(message, 429, props);
Object.setPrototypeOf(this, MastoHttpRateLimitError.prototype);

this.limit = props?.limit;
this.remaining = props?.remaining;
this.reset = props?.reset;
this.limit = props.limit;
this.remaining = props.remaining;
this.reset = props.reset;
}
}
8 changes: 8 additions & 0 deletions src/errors/masto-unexpected-error.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { MastoUnexpectedError } from './masto-unexpected-error';

it('constructs', () => {
const error = new MastoUnexpectedError('foo');
expect(error.message).toBe('foo');
expect(error.name).toBe('MastoUnexpectedError');
expect(error.stack).toBeDefined();
});
8 changes: 8 additions & 0 deletions src/errors/masto-version-error.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { MastoVersionError } from './masto-version-error';

it('constructs', () => {
const error = new MastoVersionError('foo');
expect(error.message).toBe('foo');
expect(error.name).toBe('MastoVersionError');
expect(error.stack).toBeDefined();
});
1 change: 1 addition & 0 deletions src/http/get-content-type.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ test.each([
[{ 'Content-Type': 'text/plain; charset=utf-8' }, 'text/plain'],
[{ 'content-type': 'text/plain; charset=utf-8' }, 'text/plain'],
[{ 'Content-Type': 'text/plain' }, 'text/plain'],
[{}, undefined],
])('removes charset from content-type', (headers, expected) => {
expect(getContentType(new Headers(headers))).toBe(expected);
});
131 changes: 131 additions & 0 deletions src/logger/base-logger.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/* eslint-disable unicorn/no-useless-undefined */
import { log, LoggerMockImpl } from '../__mocks__';
import { LogLevel } from './log-level';

describe('debug', () => {
const level = LogLevel.from('debug');

afterEach(() => {
log.mockClear();
});

test('debug', () => {
const logger = new LoggerMockImpl(level);
logger.debug('message');
expect(log).toBeCalledWith('debug', 'message', undefined);
});

test('info', () => {
const logger = new LoggerMockImpl(level);
logger.info('message');
expect(log).toBeCalledWith('info', 'message', undefined);
});

test('warn', () => {
const logger = new LoggerMockImpl(level);
logger.warn('message');
expect(log).toBeCalledWith('warn', 'message', undefined);
});

test('error', () => {
const logger = new LoggerMockImpl(level);
logger.error('message');
expect(log).toBeCalledWith('error', 'message', undefined);
});
});

describe('info', () => {
const level = LogLevel.from('info');

afterEach(() => {
log.mockClear();
});

test('debug', () => {
const logger = new LoggerMockImpl(level);
logger.debug('message');
expect(log).not.toBeCalledWith('debug', 'message', undefined);
});

test('info', () => {
const logger = new LoggerMockImpl(level);
logger.info('message');
expect(log).toBeCalledWith('info', 'message', undefined);
});

test('warn', () => {
const logger = new LoggerMockImpl(level);
logger.warn('message');
expect(log).toBeCalledWith('warn', 'message', undefined);
});

test('error', () => {
const logger = new LoggerMockImpl(level);
logger.error('message');
expect(log).toBeCalledWith('error', 'message', undefined);
});
});

describe('warn', () => {
const level = LogLevel.from('warn');

afterEach(() => {
log.mockClear();
});

test('debug', () => {
const logger = new LoggerMockImpl(level);
logger.debug('message');
expect(log).not.toBeCalledWith('debug', 'message', undefined);
});

test('info', () => {
const logger = new LoggerMockImpl(level);
logger.info('message');
expect(log).not.toBeCalledWith('info', 'message', undefined);
});

test('warn', () => {
const logger = new LoggerMockImpl(level);
logger.warn('message');
expect(log).toBeCalledWith('warn', 'message', undefined);
});

test('error', () => {
const logger = new LoggerMockImpl(level);
logger.error('message');
expect(log).toBeCalledWith('error', 'message', undefined);
});
});

describe('error', () => {
const level = LogLevel.from('error');

afterEach(() => {
log.mockClear();
});

test('debug', () => {
const logger = new LoggerMockImpl(level);
logger.debug('message');
expect(log).not.toBeCalledWith('debug', 'message', undefined);
});

test('info', () => {
const logger = new LoggerMockImpl(level);
logger.info('message');
expect(log).not.toBeCalledWith('info', 'message', undefined);
});

test('warn', () => {
const logger = new LoggerMockImpl(level);
logger.warn('message');
expect(log).not.toBeCalledWith('warn', 'message', undefined);
});

test('error', () => {
const logger = new LoggerMockImpl(level);
logger.error('message');
expect(log).toBeCalledWith('error', 'message', undefined);
});
});
Loading

0 comments on commit 72b40fc

Please sign in to comment.