Skip to content

Commit

Permalink
chore(tests): Add tests for WebSocket and Proxy API
Browse files Browse the repository at this point in the history
  • Loading branch information
neet committed Jul 27, 2023
1 parent 0aa23ca commit 507fe44
Show file tree
Hide file tree
Showing 270 changed files with 3,337 additions and 2,213 deletions.
15 changes: 10 additions & 5 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
"plugins": ["import", "simple-import-sort"],
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module"
"sourceType": "module",
"project": "./tsconfig.json"
},
"env": {
"browser": true,
"node": true
},
"rules": {
"no-console": "error",
"no-unused-vars": "off",
"import/no-cycle": "error",
"simple-import-sort/imports": "error",
"unicorn/prevent-abbreviations": "off",
Expand All @@ -26,8 +28,7 @@
{
"files": "**/*.ts",
"extends": [
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/strict",
"plugin:import/typescript",
"plugin:prettier/recommended"
],
Expand All @@ -41,7 +42,8 @@
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_"
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
],
"@typescript-eslint/consistent-type-imports": [
Expand All @@ -60,9 +62,12 @@
}
},
{
"files": ["tests/**/*.ts", "**/*.spec.ts"],
"files": ["tests/**/*.ts", "test-utils/**/*.ts", "**/*.spec.ts"],
"env": {
"jest": true
},
"rules": {
"no-constant-condition": "off"
}
}
]
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-e2e.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: 'CI: E2E'
name: "CI: E2E"

on:
push:
branches:
- main
pull_request:
branches:
- '*'
- "*"
workflow_call:
workflow_dispatch:

Expand Down
1 change: 0 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "all"
}
20 changes: 10 additions & 10 deletions examples/create-new-status-with-image.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import fs from 'node:fs';
import fs from "node:fs";

import { createRestClient } from 'masto';
import { createRestClient } from "masto";

const masto = createRestClient({
url: 'https://example.com',
accessToken: 'YOUR TOKEN',
url: "https://example.com",
accessToken: "YOUR TOKEN",
});

// What you need to specify as `file` argument depends on your runtime.
// If you're on Node.js >= 18 or other platforms that supports `fetch` natively...
const attachment = await masto.v2.media.create({
file: new Blob([fs.readFileSync('../some_image.png')]),
description: 'Some image',
file: new Blob([fs.readFileSync("../some_image.png")]),
description: "Some image",
});

// If you're on Node.js < 18, Use `fs.readFileSync` directly.
await masto.v2.media.create({
file: fs.readFileSync('../some_image.png'),
description: 'Some image',
file: fs.readFileSync("../some_image.png"),
description: "Some image",
});

// Publish!
const status = await masto.v1.statuses.create({
status: 'Hello from #mastojs!',
visibility: 'public',
status: "Hello from #mastojs!",
visibility: "public",
mediaIds: [attachment.id],
});

Expand Down
10 changes: 5 additions & 5 deletions examples/create-new-status.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { createRestClient, type mastodon } from 'masto';
import { createRestClient, type mastodon } from "masto";

const masto = createRestClient({
url: 'https://example.com',
accessToken: 'YOUR TOKEN',
url: "https://example.com",
accessToken: "YOUR TOKEN",
});

const s: mastodon.v1.Status = await masto.v1.statuses.create({
status: 'Hello from #mastojs!',
visibility: 'public',
status: "Hello from #mastojs!",
visibility: "public",
});

console.log(s);
10 changes: 5 additions & 5 deletions examples/moderate-reports.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { createRestClient } from 'masto';
import { createRestClient } from "masto";

const masto = createRestClient({
url: 'https://example.com',
accessToken: 'TOKEN',
url: "https://example.com",
accessToken: "TOKEN",
});

// Fetching reports
const reports = await masto.v1.admin.reports.list();

// Disable an account of the 1st report
await masto.v1.admin.accounts.$select(reports[0].account.id).action.create({
type: 'disable',
type: "disable",
reportId: reports[0].id,
text: 'Your account has been disabled',
text: "Your account has been disabled",
});
12 changes: 6 additions & 6 deletions examples/register-new-app.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { createRestClient } from 'masto';
import { createRestClient } from "masto";

const masto = createRestClient({
url: 'https://example.com',
url: "https://example.com",
});

const app = await masto.v1.apps.create({
clientName: 'My app',
redirectUris: 'urn:ietf:wg:oauth:2.0:oob',
scopes: 'read write',
website: 'example.com',
clientName: "My app",
redirectUris: "urn:ietf:wg:oauth:2.0:oob",
scopes: "read write",
website: "example.com",
});

console.log(app);
6 changes: 3 additions & 3 deletions examples/timeline-with-iterable.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { AsyncIterator } from 'iterator-helpers-polyfill';
import { createRestClient } from 'masto';
import { AsyncIterator } from "iterator-helpers-polyfill";
import { createRestClient } from "masto";

const masto = createRestClient({
url: 'https://example.com',
url: "https://example.com",
});

// You can fetch single page by `await`
Expand Down
18 changes: 9 additions & 9 deletions examples/timeline-with-streaming.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { createStreamingClient } from 'masto';
import { createStreamingClient } from "masto";

const subscribe = async (): Promise<void> => {
const masto = createStreamingClient({
url: '<STREAMING API URL>',
accessToken: '<TOKEN>',
url: "<STREAMING API URL>",
accessToken: "<TOKEN>",
});

console.log('subscribed to #mastojs');
console.log("subscribed to #mastojs");

for await (const event of masto.subscribe('hashtag', { tag: 'mastojs' })) {
for await (const event of masto.subscribe("hashtag", { tag: "mastojs" })) {
switch (event.event) {
case 'update': {
console.log('new post', event.payload.content);
case "update": {
console.log("new post", event.payload.content);
break;
}
case 'delete': {
console.log('deleted post', event.payload);
case "delete": {
console.log("deleted post", event.payload);
break;
}
default: {
Expand Down
16 changes: 8 additions & 8 deletions examples/update-profile.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import fs from 'node:fs/promises';
import fs from "node:fs/promises";

import { createRestClient } from '../src';
import { createRestClient } from "../src";

const masto = createRestClient({
url: 'https://example.com',
accessToken: 'YOUR TOKEN',
url: "https://example.com",
accessToken: "YOUR TOKEN",
});

const newProfile = await masto.v1.accounts.updateCredentials.update({
displayName: 'Fluffy elephant friend',
note: 'Hi fediverse!',
const newProfile = await masto.v1.accounts.updateCredentials({
displayName: "Fluffy elephant friend",
note: "Hi fediverse!",
// See `create-new-status-with-image.ts` example for this field.
avatar: new Blob([await fs.readFile('../some_image.png')]),
avatar: new Blob([await fs.readFile("../some_image.png")]),
});

console.log(newProfile);
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
"test:unit": "jest --coverage --config=jest.config.cjs --selectProjects unit",
"test:e2e": "jest --coverage --config=jest.config.cjs --selectProjects e2e",
"lint": "npm-run-all lint:*",
"lint:eslint": "eslint --ext ts --report-unused-disable-directives --cache '{src,examples,tests,test-utils}/**/*'",
"lint:spellcheck": "cspell '{src,examples}/**/*.{ts,tsx,js,json,md}'",
"lint:eslint": "eslint --ext ts --report-unused-disable-directives --cache '{src,tests,test-utils}/**/*'",
"lint:spellcheck": "cspell '{src,test,test-utils}/**/*.{ts,tsx,js,json,md}'",
"build": "rollup -c rollup.config.cjs",
"prepublishOnly": "yarn run build",
"docs:build": "typedoc ./src/index.ts && touch ./docs/.nojekyll",
Expand Down Expand Up @@ -57,6 +57,7 @@
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-simple-import-sort": "^10.0.0",
"eslint-plugin-unicorn": "^47.0.0",
"get-port": "^5.1.1",
"iterator-helpers-polyfill": "^2.3.1",
"jest": "^29.5.0",
"npm-run-all": "^4.1.5",
Expand Down
66 changes: 66 additions & 0 deletions src/adapters/action/dispatcher-http.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { httpGet, HttpMockImpl, httpPost } from "../../__mocks__";
import { MastoHttpError, MastoTimeoutError } from "../errors";
import { HttpActionDispatcher } from "./dispatcher-http";

describe("DispatcherHttp", () => {
afterEach(() => {
httpGet.mockClear();
httpPost.mockClear();
});

it("waits for media attachment to be created", async () => {
const dispatcher = new HttpActionDispatcher(new HttpMockImpl());

httpPost.mockResolvedValueOnce({ id: "1" });

httpGet
.mockRejectedValueOnce(new MastoHttpError(404, "Not Found"))
.mockRejectedValueOnce(new MastoHttpError(404, "Not Found"))
.mockResolvedValueOnce({ id: "1", url: "https://example.com" });

const media = await dispatcher.dispatch({
type: "create",
path: "/api/v2/media",
data: undefined,
meta: {},
});

expect(media).toHaveProperty("id", "1");
expect(media).toHaveProperty("url", "https://example.com");
expect(httpGet).toHaveBeenCalledTimes(3);
});

it("throws an error if media processing did not finish", async () => {
const dispatcher = new HttpActionDispatcher(new HttpMockImpl(), {
mediaTimeout: 1,
});

httpPost.mockResolvedValueOnce({ id: "1" });
httpGet.mockRejectedValue(new MastoHttpError(404, "Not Found"));

const promise = dispatcher.dispatch({
type: "create",
path: "/api/v2/media",
data: undefined,
meta: {},
});

await expect(promise).rejects.toBeInstanceOf(MastoTimeoutError);
});

it("rethrows errors for media processing", async () => {
const dispatcher = new HttpActionDispatcher(new HttpMockImpl());

httpPost.mockResolvedValueOnce({ id: "1" });
httpGet.mockRejectedValueOnce(new Error("Unknown error"));

const promise = dispatcher.dispatch({
type: "create",
path: "/api/v2/media",
data: undefined,
meta: {},
});

await expect(promise).rejects.toBeInstanceOf(Error);
});
});
Loading

0 comments on commit 507fe44

Please sign in to comment.