Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor-To-Improve-Testability #32

Merged
merged 5 commits into from
Feb 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion jest.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,5 @@
}
},
"testEnvironment": "jsdom",
"collectCoverage": true,
"collectCoverageFrom": ["./src/**"]
}
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"build": " npm run test && svelte-kit build",
"package": "npm run test && svelte-kit package",
"preview": "svelte-kit preview",
"test": "NODE_OPTIONS=--experimental-vm-modules jest src --config jest.config.json --coverage",
"test": "NODE_OPTIONS=--experimental-vm-modules jest src --config jest.config.json",
"test:coverage": "NODE_OPTIONS=--experimental-vm-modules jest src --config jest.config.json --coverage",
"check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"test:watch": "npm run test -- --watch"
Expand All @@ -22,7 +23,8 @@
"@types/jest": "^27.0.0",
"@types/testing-library__jest-dom": "^5.14.0",
"babel-jest": "^27.0.0",
"jest": "^27.0.0",
"jest": "27",
"jsdom": "^19.0.0",
"sass": "^1.47.0",
"svelte": "^3.44.0",
"svelte-check": "^2.2.6",
Expand All @@ -35,8 +37,8 @@
},
"type": "module",
"dependencies": {
"@dopry/svelte-oidc": "^1.0.1",
"lodash": "^4.17.21",
"oidc-client": "^1.11.5",
"svelte-css-vars": "^0.0.3"
}
}
195 changes: 195 additions & 0 deletions src/__tests__/lib/controller/backend.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import AuthManager from "$lib/controller/AuthManager";
import { Backend } from "$lib/controller/backend";
import type { Table } from "$lib/model/recursive_table/TableComponents";
import type { DataObject, Predicate } from "$lib/model/recursive_table/Types";
import { Blacklist, BlacklistEntry } from "$lib/model/tables/blacklist/Blacklist";
import type { TableManager } from "$lib/model/tables/manager/TableManager";
import { Alias, OfficialAliases } from "$lib/model/tables/official/OfficialAliases";
import { AliasSuggestions } from "$lib/model/tables/suggestions/AliasSuggestions";
import { Tables } from "$lib/model/tables/Tables";
import { jest } from "@jest/globals";

jest.mock('$lib/controller/AuthManager');

class DummyOfficial extends OfficialAliases {

public constructor() {
super(jest.fn(), jest.fn(), () => true, jest.fn());
}

public addEntry = jest.fn();
public setActionComponentFactory = jest.fn();
}

class DummyBlacklist extends Blacklist {
public constructor() {
super(jest.fn(), jest.fn(), jest.fn());
}

public addEntry = jest.fn();
public setActionComponentFactory = jest.fn();
}

class DummySuggestions extends AliasSuggestions {
public constructor() {
super(jest.fn(), jest.fn(), jest.fn(), jest.fn(), jest.fn());
}

public setActionComponentFactory = jest.fn();
}

describe("Testing Backend.ts", () => {

let backend: Backend;
let onError: (error: string | Error) => void;
let showEntry: Predicate<DataObject<string>>;
let official: DummyOfficial;
let blacklist: DummyBlacklist;
let suggestions: DummySuggestions;

function mockImplementation(impl: (body: string) => Promise<Object>) {
(backend as any).fetchBackend = jest.fn().mockImplementation(impl);
}

function init() {
onError = jest.fn();
showEntry = jest.fn<boolean, any>().mockImplementation(() => true);
official = new DummyOfficial();
blacklist = new DummyBlacklist();
suggestions = new DummySuggestions();
backend = new Backend(onError, showEntry, jest.fn());
(backend as any).official = official;
(backend as any).blacklist = blacklist;
(backend as any).suggestions = suggestions;
mockImplementation(jest.fn());
}

beforeEach(init)

describe("by mocking fetch:", () => {

describe("isAdmin", () => {
beforeEach(init)

test.each([[true, true], [false, false]])("resolving", (real: boolean, expected: boolean) => {
mockImplementation(body => {
if (body.includes("isAdmin")) {
return Promise.resolve({data: {isAdmin: expected}})
}
});
expect(backend.isAdmin()).toEqual(Promise.resolve(real));
});

test("rejected", (done) => {
mockImplementation(body => {
if (body.includes("isAdmin")) {
return Promise.reject()
}
});
backend.isAdmin().then(isAdmin => {
expect(onError).toBeCalled();
expect(isAdmin).toBe(false);
done()
});
});
});

describe("addToOfficial", () => {
beforeEach(init);

describe.each([[true, true],[false, false]])("resolves", (real: boolean, expected: boolean) => {
test(`${expected}`, (done) => {
const alias: Alias = new Alias("test", "test", "test", 1)
mockImplementation(body => {
if (body.includes("approveAliasSuggestion")) {
return Promise.resolve({data: {approveAliasSuggestion: real}})
}
});
(backend as any).addToOfficial(alias).then(result => {
expect(result).toBe(expected);
if (expected) {
expect(official.addEntry).toBeCalled();
}
done()
})
// (async () => {
// await (async () => (backend as any).addToOfficial(alias).then(result => {
// expect(result).toBe(expected);
// if (expected) {
// expect(official.addEntry).toBeCalled();
// }
// done()
// }))();
// })()
});
});

test("rejects", (done) => {
const alias: Alias = new Alias("test", "test", "test", 1)
mockImplementation(body => {
if (body.includes("approveAliasSuggestion")) {
return Promise.reject();
}
});
(backend as any).addToOfficial(alias).then(result => {
expect(result).toBe(false);
expect(onError).toBeCalled();
done();
});
});
});

describe("addToBlacklist", () => {
beforeEach(init);

describe.each([[true, true],[false, false]])("resolves", (real: boolean, expected: boolean) => {
test(`${expected}`, (done) => {
mockImplementation(body => {
if (body.includes("blacklistAlias")) {
return Promise.resolve({data: {blacklistAlias: real}})
}
});
backend.addToBlacklist(new BlacklistEntry("test")).then(result => {
expect(result).toBe(expected);
if (expected) {
expect(blacklist.addEntry).toBeCalled();
}
done();
});
});
});

test("rejects", (done) => {
mockImplementation(body => {
if (body.includes("blacklistAlias")) {
return Promise.reject();
}
});
backend.addToBlacklist(new BlacklistEntry("test")).then(result => {
expect(result).toBe(false);
expect(onError).toBeCalled();
done();
});
});
});

describe("setActionComponentFactory", () => {
beforeEach(init);
test("blacklist", () => {
backend.setActionComponentFactory(Tables.BLACKLIST, undefined);
expect(blacklist.setActionComponentFactory).toBeCalled();
});
test("suggestions", () => {
backend.setActionComponentFactory(Tables.ALIAS_SUGGESTIONS, undefined);
expect(suggestions.setActionComponentFactory).toBeCalled();
});
test("official", () => {
backend.setActionComponentFactory(Tables.ALIAS, undefined);
expect(official.setActionComponentFactory).toBeCalled();
});
test("changes", () => {
expect(() => backend.setActionComponentFactory(Tables.CHANGES, undefined)).toThrowError("matching")
});
})
})
})
82 changes: 82 additions & 0 deletions src/__tests__/lib/model/tables/Blacklist.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { Blacklist, BlacklistEntry } from "$lib/model/tables/blacklist/Blacklist"
import type { ChangeAction } from "$lib/model/tables/changes/ChangeAction";
import { jest } from "@jest/globals"

describe("Testing Blacklist.ts", () => {

const entry: string = "test";
let blacklist: Blacklist;

function init(fetch?: <T>(body: string) => Promise<T>, addChange?: (change: ChangeAction) => void) {
blacklist = new Blacklist(
fetch? fetch : jest.fn(),
jest.fn(),
addChange? addChange : jest.fn(),
[new BlacklistEntry(entry)]
)
}

beforeEach(() => init());

test("removeEntry", (done) => {
let addChange = jest.fn<void, any>().mockImplementation((action: ChangeAction) => {
action.perform().then(_ => {
expect((blacklist as any).getTableWithoutFetch().getChildren().length).toBe(0);
done();
})
});
init(jest.fn(), addChange);
(blacklist as any).removeFromBackend = jest.fn().mockImplementation((_) => true);
(blacklist as any).removeEntry(new BlacklistEntry(entry));
});

describe("by mocking fetch:", () => {

describe("removeFromBackend", () => {
beforeEach(() => init())

test.each([[true, true], [false, false]])("resolving", (real: boolean, expected: boolean) => {
(blacklist as any).fetch = jest.fn<Object, [string]>().mockImplementation(body => {
if (body.includes("removeFromBlacklist")) {
return Promise.resolve({data: {removeFromBlacklist: expected}})
}
});
expect((blacklist as any).removeFromBackend(new BlacklistEntry(entry))).toEqual(Promise.resolve(real));
});
});

describe("size", () => {
beforeEach(() => init())

test.each([
[1, "1"],
[42, "42"],
[0, "0"]
])("resolving", (real: number, expected: string) => {
(blacklist as any).fetch = jest.fn<Object, [string]>().mockImplementation(body => {
if (body.includes("getAmountEntriesBlacklist")) {
return Promise.resolve({data: {getAmountEntriesBlacklist: expected}})
}
});
expect((blacklist as any).size()).toEqual(Promise.resolve(real));
});
});

describe("fetchData", () => {
beforeEach(() => init())

test.each([
[[], []],
[["test"], [new BlacklistEntry("test")]],
[["test1", "test2"], [new BlacklistEntry("test1"), new BlacklistEntry("test2")]]
])("resolving", (real: string[], expected: BlacklistEntry[]) => {
(blacklist as any).fetch = jest.fn<Object, [string]>().mockImplementation(body => {
if (body.includes("getBlacklist")) {
return Promise.resolve({data: {getBlacklist: real}})
}
});
expect((blacklist as any).fetchData()).toEqual(Promise.resolve(expected));
});
});
});
})
Loading