Skip to content

Commit 743b744

Browse files
committed
Added integration tests for settings
1 parent 1f24edd commit 743b744

File tree

10 files changed

+220
-19
lines changed

10 files changed

+220
-19
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@sveltejs/kit": "next",
2424
"@testing-library/jest-dom": "^5.14.0",
2525
"@testing-library/svelte": "^3.0.0",
26+
"@testing-library/user-event": "^14.0.0-beta",
2627
"@types/jest": "^27.0.0",
2728
"@types/testing-library__jest-dom": "^5.14.0",
2829
"babel-jest": "^27.0.0",
+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
2+
import { Framework } from "$lib/controller/framework";
3+
import { BlacklistEntry } from "$lib/model/tables/blacklist/Blacklist";
4+
import { jest } from "@jest/globals";
5+
import { ServerMock } from "./__setup__/serverMock";
6+
import { AliasSuggestionsEntry } from "$lib/model/tables/suggestions/AliasSuggestions";
7+
import type { Alias } from "$lib/model/tables/official/OfficialAliases";
8+
import { matchers } from "./__setup__/matcher";
9+
import render from "./__setup__/pageRenderer";
10+
import { clickOnButtonForRows, clickOnButtonForSomeRows, getAllInputs, getAllRows, setValueOfInput } from "./__setup__/helpers";
11+
import { BUTTON, INPUT } from "./__setup__/constants";
12+
import { fireEvent } from "@testing-library/svelte";
13+
14+
class OpenFramework extends Framework {
15+
public constructor() {
16+
super();
17+
}
18+
}
19+
20+
expect.extend(matchers);
21+
22+
describe("Testing interactions of settings as user", () => {
23+
24+
const entries = [
25+
new AliasSuggestionsEntry("Infobau", "50.34", "-", 503400000, 10, 0, "tester"),
26+
new AliasSuggestionsEntry("Mathebau", "20.30", "-", 203000000, 8, 1, "tester2"),
27+
new AliasSuggestionsEntry("Seminarraum", "50.34", "-108", 503499108, 11, 3, "tester3"),
28+
new AliasSuggestionsEntry("HSaF", "50.36", "-", 503600000, 1, 2, "tester4"),
29+
new AliasSuggestionsEntry("Hörsaal am Fasanen", "50.36", "-", 503600000, 0, 7, "tester3")
30+
];
31+
32+
const originalWarn = console.warn.bind(console.warn)
33+
let page: HTMLElement;
34+
35+
let framework: OpenFramework;
36+
let serverMock: ServerMock;
37+
let fetchBackend: (body: string) => Promise<any>;
38+
39+
beforeAll(() => {
40+
serverMock = new ServerMock([], [], []);
41+
fetchBackend = serverMock.getFetchBackendMock();
42+
framework = new OpenFramework();
43+
Framework['instance'] = framework;
44+
framework['backend']['fetchBackend'] = fetchBackend;
45+
46+
console.warn = (msg) => !msg.toString().includes('prop') && originalWarn(msg);
47+
});
48+
49+
afterAll(() => {
50+
console.warn = originalWarn
51+
});
52+
53+
describe("setting value", () => {
54+
55+
beforeEach(async () => {
56+
serverMock.setBlacklist([]);
57+
serverMock.setOfficial([]);
58+
serverMock.setSuggestions([...entries]);
59+
page = await render.settings();
60+
await setValueOfInput(page, INPUT.SETTINGS.MIN_POSITIVE_SUGGESTION, 0);
61+
await setValueOfInput(page, INPUT.SETTINGS.MIN_NEGATIVE_SUGGESTION, 0);
62+
});
63+
64+
test.each([
65+
[0, [0,1,2,3,4], []],
66+
[-1, [0,1,2,3,4], []],
67+
[1, [0,1,2,3], [4]],
68+
[10, [0,2], [1,3,4]],
69+
[42, [], [0,1,2,3,4]]
70+
])(`upvotes`, async (value: number, shown: number[], notShown: number[]) => {
71+
page = await render.suggestion();
72+
expect(page).toHaveAllRows(entries);
73+
74+
page = await render.settings();
75+
await setValueOfInput(page, INPUT.SETTINGS.MIN_POSITIVE_SUGGESTION, value);
76+
77+
page = await render.suggestion();
78+
if (shown.length > 0) {
79+
expect(page).toHaveSomeRows(shown, entries);
80+
}
81+
if (notShown.length > 0) {
82+
expect(page).not.toHaveSomeRows(notShown, entries);
83+
}
84+
expect(serverMock.getSuggestions()).toEqual(entries);
85+
});
86+
87+
test.each([
88+
[0, [0,1,2,3,4], []],
89+
[-1, [0,1,2,3,4], []],
90+
[1, [1,2,3,4], [0]],
91+
[5, [4], [0,1,2,3]],
92+
[42, [], [0,1,2,3,4]]
93+
])(`downvotes`, async (value: number, shown: number[], notShown: number[]) => {
94+
page = await render.suggestion();
95+
expect(page).toHaveAllRows(entries);
96+
97+
page = await render.settings();
98+
await setValueOfInput(page, INPUT.SETTINGS.MIN_NEGATIVE_SUGGESTION, value);
99+
100+
page = await render.suggestion();
101+
if (shown.length > 0) {
102+
expect(page).toHaveSomeRows(shown, entries);
103+
}
104+
if (notShown.length > 0) {
105+
expect(page).not.toHaveSomeRows(notShown, entries);
106+
}
107+
expect(serverMock.getSuggestions()).toEqual(entries);
108+
});
109+
110+
test.each([
111+
[1, -1, [0,1,2,3], [4]],
112+
[4, 3, [2], [0,1,3,4]],
113+
[1, 1, [1,2,3], [0,4]],
114+
[-5, -8, [0,1,2,3,4], []],
115+
[42, 69, [], [0,1,2,3,4]]
116+
])(`both`, async (upvotes: number, downvotes: number, shown: number[], notShown: number[]) => {
117+
page = await render.suggestion();
118+
expect(page).toHaveAllRows(entries);
119+
120+
page = await render.settings();
121+
await setValueOfInput(page, INPUT.SETTINGS.MIN_POSITIVE_SUGGESTION, upvotes);
122+
await setValueOfInput(page, INPUT.SETTINGS.MIN_NEGATIVE_SUGGESTION, downvotes);
123+
124+
page = await render.suggestion();
125+
if (shown.length > 0) {
126+
expect(page).toHaveSomeRows(shown, entries);
127+
}
128+
if (notShown.length > 0) {
129+
expect(page).not.toHaveSomeRows(notShown, entries);
130+
}
131+
expect(serverMock.getSuggestions()).toEqual(entries);
132+
});
133+
});
134+
});

src/__tests__/integration/Suggestions.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ describe("Testing interactions of suggestions as user", () => {
3434
Framework['instance'] = framework;
3535
framework['backend']['fetchBackend'] = fetchBackend;
3636

37-
console.warn = (msg) => !msg.toString().includes('prop') && originalWarn(msg)
37+
console.warn = (msg) => !msg.toString().includes('prop') && originalWarn(msg);
3838
});
3939

4040
afterAll(() => {

src/__tests__/integration/__setup__/constants.ts

+10
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,14 @@ export const BUTTON = {
1515
DELETE: 0,
1616
BLACKLIST: 1
1717
}
18+
}
19+
20+
export const INPUT = {
21+
BLACKLIST: {
22+
ADD: 0
23+
},
24+
SETTINGS: {
25+
MIN_NEGATIVE_SUGGESTION: 0,
26+
MIN_POSITIVE_SUGGESTION: 1,
27+
}
1828
}

src/__tests__/integration/__setup__/helpers.ts

+9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { fireEvent } from "@testing-library/dom";
2+
import userEvent from "@testing-library/user-event";
23

34
export function getAllRows(page: HTMLElement): HTMLCollection {
45
return page.getElementsByClassName("row");
@@ -8,6 +9,10 @@ export function getAllButtons(page: HTMLElement): HTMLCollection {
89
return page.getElementsByTagName("button");
910
}
1011

12+
export function getAllInputs(page: HTMLElement): HTMLCollection {
13+
return page.getElementsByTagName("input");
14+
}
15+
1116
export function clickOnButtonForRows(page: HTMLElement, buttonIndex: number) {
1217
let elements = getAllRows(page);
1318
for (let i = 0; i < elements.length; ++i) {
@@ -18,4 +23,8 @@ export function clickOnButtonForRows(page: HTMLElement, buttonIndex: number) {
1823
export function clickOnButtonForSomeRows(page: HTMLElement, indices: number[], buttonIndex: number) {
1924
let elements = getAllRows(page);
2025
indices.forEach(index => fireEvent.click(getAllButtons(elements[index] as HTMLElement)[buttonIndex]))
26+
}
27+
28+
export async function setValueOfInput(page: HTMLElement, index: number, value: string | number) {
29+
await fireEvent.input(getAllInputs(page)[index], {target: {value: String(value)}})
2130
}

src/__tests__/integration/__setup__/pageRenderer.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Svelte__Blacklist from "$lib/../routes/admin/panel/blacklist/index.svelte
44
import Svelte__Official from "$lib/../routes/admin/panel/alias/index.svelte";
55
import Svelte__Suggestions from "$lib/../routes/admin/panel/suggestions/index.svelte";
66
import Svelte__Changes from "$lib/../routes/admin/panel/changes/index.svelte";
7+
import Svelte__Settings from "$lib/../routes/admin/panel/settings/index.svelte";
78
import Svelte__Dashboard from "$lib/../routes/admin/panel/index.svelte";
89

910
async function renderBlacklist(): Promise<HTMLElement> {
@@ -51,12 +52,22 @@ async function renderDashboard(): Promise<HTMLElement> {
5152
return page;
5253
}
5354

55+
async function renderSettings(): Promise<HTMLElement> {
56+
cleanup();
57+
let page = r(Svelte__Settings).container;
58+
// Cannot intercept on component awaiting its promise, which is resolved immediately
59+
// Therefore let the browser finish the rendering of the component by awaiting a pseudo-timeout
60+
await new Promise((r) => setTimeout(r, 0));
61+
return page;
62+
}
63+
5464
const render = {
5565
blacklist: renderBlacklist,
5666
official: renderOfficial,
5767
suggestion: renderSuggestions,
5868
changes: renderChanges,
59-
dashboard: renderDashboard
69+
dashboard: renderDashboard,
70+
settings: renderSettings
6071
}
6172

62-
export default render
73+
export default render;

src/__tests__/integration/__setup__/serverMock.ts

+17-9
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,24 @@ export class ServerMock {
5757
return Promise.resolve({data: {getAmountEntriesAlias: this.official.length}})
5858
}
5959
if (body.includes("getAliasSuggestions")) {
60-
return Promise.resolve({data: {getAliasSuggestions: this.suggestions.map(e => {
61-
return {
62-
suggester: e.getSuggester(),
63-
name: e.getName(),
64-
posVotes: e.getUpvotes(),
65-
negVotes: e.getDownvotes(),
66-
mapID: e.getId(),
67-
mapObject: e.getBuilding() + "," + e.getRoom()
60+
61+
let { minValToShowPos, minValToShowNeg } = variables;
62+
return Promise.resolve({
63+
data: {
64+
getAliasSuggestions: this.suggestions
65+
.filter(e => e.getUpvotes() >= minValToShowPos && e.getDownvotes() >= minValToShowNeg)
66+
.map(e => {
67+
return {
68+
suggester: e.getSuggester(),
69+
name: e.getName(),
70+
posVotes: e.getUpvotes(),
71+
negVotes: e.getDownvotes(),
72+
mapID: e.getId(),
73+
mapObject: e.getBuilding() + "," + e.getRoom()
74+
}
75+
})
6876
}
69-
})}});
77+
});
7078
}
7179
if (body.includes("getAllAliases")) {
7280
return Promise.resolve({data: {getAllAliases: this.official.map(e => {

src/lib/model/tables/suggestions/AliasSuggestions.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,8 @@ export class AliasSuggestions extends TableManager<AliasSuggestionsEntry, AliasS
292292
}[],
293293
}}>(JSON.stringify({
294294
query: `
295-
query getAliasSuggestions($minPositive: Int!, $minNegative: Int!) {
296-
getAliasSuggestions(minValToShowPos: $minPositive, minValToShowNeg: $minNegative) {
295+
query getAliasSuggestions($minValToShowPos: Int!, $minValToShowNeg: Int!) {
296+
getAliasSuggestions(minValToShowPos: $minValToShowPos, minValToShowNeg: $minValToShowNeg) {
297297
suggester
298298
name
299299
posVotes
@@ -304,8 +304,8 @@ export class AliasSuggestions extends TableManager<AliasSuggestionsEntry, AliasS
304304
}
305305
`,
306306
variables: {
307-
minPositive: this.minUpvotes,
308-
minNegative: this.minDownvotes
307+
minValToShowPos: Math.trunc(this.minUpvotes),
308+
minValToShowNeg: Math.trunc(this.minDownvotes)
309309
}
310310
})).then(response => {
311311
if (response.data) {

src/lib/view/components/settings/Setting.svelte

+24-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
<script lang=ts>
22
3-
type T = $$Generic;
3+
type T = $$Generic<string | number>;
44
export let start: T;
55
let value = start;
6+
let oldValue = start;
67
export let text: string;
78
export let update: (value: T) => void;
89
9-
$: update(value);
10+
function passNumbers(n: string): string {
11+
let acc: string = "";
12+
for (let c of n) {
13+
if ("0" <= c && c <= "9") {
14+
acc += c;
15+
}
16+
}
17+
return acc;
18+
}
19+
20+
$: if (typeof start === 'number') {
21+
if (value != undefined && value != null && value == passNumbers(String(value))) {
22+
update(value);
23+
oldValue = value;
24+
} else {
25+
value = oldValue as T;
26+
}
27+
} else {
28+
update(value);
29+
oldValue = value;
30+
}
1031
</script>
1132

1233
<style lang=scss>
@@ -27,7 +48,7 @@
2748
<div class=setting>
2849
<span>{text? text : ""}</span>
2950
{#if typeof start === 'number'}
30-
<input bind:value={value} type="number">
51+
<input bind:value={value} type="number" pattern="\d+" step="1">
3152
{:else}
3253
<input bind:value={value}>
3354
{/if}

yarn.lock

+7
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,13 @@
13621362
dependencies:
13631363
"@testing-library/dom" "^7.0.3"
13641364

1365+
"@testing-library/user-event@^14.0.0-beta":
1366+
version "14.0.0-beta.13"
1367+
resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.0.0-beta.13.tgz#dd7d819588ac28e96b7e7af6d6d61b6f0a99f1a5"
1368+
integrity sha512-KjgkzbV3TmVOU6rUvNs7coezsPEVZKAcejG+GjxpmzB4JszyX9S6hyN729bIPFE7hl/5/LbfSn9KChUaTxd22Q==
1369+
dependencies:
1370+
"@babel/runtime" "^7.12.5"
1371+
13651372
"@tootallnate/once@1":
13661373
version "1.1.2"
13671374
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"

0 commit comments

Comments
 (0)