Skip to content
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
2 changes: 1 addition & 1 deletion backend/__tests__/middlewares/auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ describe("middlewares/auth", () => {
await expect(() =>
authenticate({ headers: { authorization: "Uid 123" } }),
).rejects.toMatchMonkeyError(
new MonkeyError(401, "Baerer type uid is not supported"),
new MonkeyError(401, "Bearer type uid is not supported"),
);
});
it("should fail without authentication", async () => {
Expand Down
2 changes: 1 addition & 1 deletion backend/src/middlewares/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ async function authenticateWithApeKey(

async function authenticateWithUid(token: string): Promise<DecodedToken> {
if (!isDevEnvironment()) {
throw new MonkeyError(401, "Baerer type uid is not supported");
throw new MonkeyError(401, "Bearer type uid is not supported");
}
const [uid, email] = token.split("|");

Expand Down
34 changes: 33 additions & 1 deletion frontend/.oxlintrc-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,37 @@
"jsPlugins": ["eslint-plugin-compat"],
"rules": {
"compat/compat": "error"
}
},
"overrides": [
{
"jsPlugins": ["eslint-plugin-solid"],
"files": ["src/**/*.tsx"],
"rules": {
"solid/components-return-once": "error",
"solid/event-handlers": "error",
"solid/imports": "error",
"solid/jsx-no-duplicate-props": "error",
"solid/jsx-no-script-url": "error",
"solid/jsx-no-undef": "error",
"solid/no-array-handlers": "error",
"solid/no-destructure": "error",
"solid/no-innerhtml": "error",
"solid/no-proxy-apis": "error",
"solid/no-react-deps": "error",
"solid/no-react-specific-props": "error",
"solid/no-unknown-namespaces": "error",
"solid/prefer-classlist": "error",
"solid/prefer-for": "error",
"solid/prefer-show": "error",
"solid/reactivity": "error",
"solid/self-closing-comp": [
"error",
{
"html": "void"
}
],
"solid/style-prop": "error"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
import { vi } from "vitest";
import $ from "jquery";
import { ElementsWithUtils, ElementWithUtils } from "../src/ts/utils/dom";
import { ElementsWithUtils, ElementWithUtils } from "../../src/ts/utils/dom";

//@ts-expect-error add to global
global["$"] = $;
//@ts-expect-error add to global
global["jQuery"] = $;

vi.mock("../src/ts/constants/env-config", () => ({
envConfig: {
backendUrl: "invalid",
isDevelopment: true,
},
}));

vi.mock("../src/ts/firebase", () => ({
app: undefined,
Auth: undefined,
isAuthenticated: () => false,
}));

vi.mock("../src/ts/utils/dom", async (importOriginal) => {
// Mock dom-utils to always return a mock element
vi.mock("../../src/ts/utils/dom", async (importOriginal) => {
const createMockElement = (): ElementWithUtils => {
return {
disable: vi.fn().mockReturnThis(),
Expand Down
7 changes: 7 additions & 0 deletions frontend/__tests__/__harness__/mock-env-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { vi } from "vitest";
vi.mock("../src/ts/constants/env-config", () => ({
envConfig: {
backendUrl: "invalid",
isDevelopment: true,
},
}));
6 changes: 6 additions & 0 deletions frontend/__tests__/__harness__/mock-firebase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { vi } from "vitest";
vi.mock("../../src/ts/firebase", () => ({
app: undefined,
Auth: undefined,
isAuthenticated: () => false,
}));
2 changes: 2 additions & 0 deletions frontend/__tests__/__harness__/setup-jsx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//extend expect with dom matchers
import "@testing-library/jest-dom";
102 changes: 102 additions & 0 deletions frontend/__tests__/components/ScrollToTop.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import { render } from "@solidjs/testing-library";
import { userEvent } from "@testing-library/user-event";
import {
ScrollToTop,
__testing,
hideScrollToTop,
} from "../../src/ts/components/ScrollToTop";
import * as ActivePage from "../../src/ts/states/active-page";

describe("ScrollToTop", () => {
const getActivePageMock = vi.spyOn(ActivePage, "get");
beforeEach(() => {
getActivePageMock.mockClear().mockReturnValue("account");
Object.defineProperty(window, "scrollY", { value: 0, writable: true });
__testing.resetState();
});

function renderElement(): {
container: HTMLElement;
button: HTMLButtonElement;
} {
const { container } = render(() => <ScrollToTop />);

return {
// oxlint-disable-next-line no-non-null-assertion
container: container.children[0]! as HTMLElement,
// oxlint-disable-next-line no-non-null-assertion
button: container.querySelector("div.button")!,
};
}

it("renders with correct classes and structure", () => {
const { container, button } = renderElement();

expect(container).toHaveClass("content-grid", "ScrollToTop");
expect(button).toHaveClass("breakout", "button");
expect(button).toContainHTML(`<i class="fas fa-angle-double-up"></i>`);
});

it("renders invisible when scrollY is 0", () => {
const { button } = renderElement();

expect(button).toHaveClass("invisible");
});

it("becomes visible when scrollY > 100", () => {
const { button } = renderElement();
scrollTo(150);

expect(button).not.toHaveClass("invisible");
});

it("stays invisible on test page regardless of scroll", () => {
getActivePageMock.mockReturnValue("test");
const { button } = renderElement();
scrollTo(150);

expect(button).toHaveClass("invisible");
});

it("scrolls to top and hides button on click", async () => {
const scrollToSpy = vi.fn();
window.scrollTo = scrollToSpy;
const { button } = renderElement();
scrollTo(150);

await userEvent.click(button);

expect(scrollToSpy).toHaveBeenCalledWith({
top: 0,
behavior: "smooth",
});
expect(button).toHaveClass("invisible");
});

it("hides button when hideScrollToTop is called", () => {
const { button } = renderElement();
scrollTo(150);

hideScrollToTop();

expect(button).toHaveClass("invisible");
});

it("cleans up scroll listener on unmount", () => {
const removeEventListenerSpy = vi.spyOn(window, "removeEventListener");
const { unmount } = render(() => <ScrollToTop />);

unmount();

expect(removeEventListenerSpy).toHaveBeenCalledWith(
"scroll",
expect.any(Function),
);
});

function scrollTo(value: number): void {
Object.defineProperty(window, "scrollY", { value, writable: true });
window.dispatchEvent(new Event("scroll"));
}
});
11 changes: 9 additions & 2 deletions frontend/__tests__/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
"compilerOptions": {
"moduleResolution": "Bundler",
"module": "ESNext",
"noEmit": true
"noEmit": true,
"jsx": "preserve",
"jsxImportSource": "solid-js"
},
"files": ["vitest.d.ts"],
"include": ["./**/*.spec.ts", "./**/*.jsdom-spec.ts", "./setup-tests.ts"]
"include": [
"./**/*.spec.ts",
"./**/*.spec.tsx",
"./**/*.jsdom-spec.ts",
"./setup-tests.ts"
]
}
4 changes: 2 additions & 2 deletions frontend/__tests__/utils/dom.jsdom-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe("dom", () => {
}

beforeEach(() => {
handler.mockReset();
handler.mockClear();

document.body.innerHTML = "";
const root = document.createElement("div");
Expand Down Expand Up @@ -151,7 +151,7 @@ describe("dom", () => {
);

//WHEN click on mid1 handler is only called one time
handler.mockReset();
handler.mockClear();
clickTarget = screen.getByTestId("mid1");
await userEvent.click(clickTarget);

Expand Down
3 changes: 3 additions & 0 deletions frontend/__tests__/vitest.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ interface ActivityDayMatchers<R = TestActivityDay> {
toBeFiller: () => ActivityDayMatchers<R>;
}

/// <reference types="vitest" />
import "@testing-library/jest-dom";

declare module "vitest" {
interface Assertion<T = any> extends ActivityDayMatchers<T> {}
interface AsymmetricMatchersContaining extends ActivityDayMatchers {}
Expand Down
8 changes: 7 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@
"@fortawesome/fontawesome-free": "5.15.4",
"@monkeytype/oxlint-config": "workspace:*",
"@monkeytype/typescript-config": "workspace:*",
"@solidjs/testing-library": "0.8.10",
"@testing-library/dom": "10.4.1",
"@testing-library/jest-dom": "6.9.1",
"@testing-library/user-event": "14.6.1",
"@types/canvas-confetti": "1.4.3",
"@types/chartjs-plugin-trendline": "1.0.1",
Expand All @@ -77,16 +79,19 @@
"concurrently": "8.2.2",
"eslint": "9.39.1",
"eslint-plugin-compat": "6.0.2",
"eslint-plugin-solid": "0.14.5",
"firebase-tools": "13.15.1",
"fontawesome-subset": "4.4.0",
"happy-dom": "20.0.10",
"jsdom": "27.4.0",
"madge": "8.0.0",
"magic-string": "0.30.17",
"normalize.css": "8.0.1",
"oxlint": "1.38.0",
"oxlint-tsgolint": "0.10.1",
"postcss": "8.4.31",
"sass": "1.70.0",
"solid-js": "1.9.10",
"subset-font": "2.3.0",
"tsx": "4.16.2",
"typescript": "5.9.3",
Expand All @@ -98,13 +103,14 @@
"vite-plugin-inspect": "11.3.3",
"vite-plugin-minify": "2.1.0",
"vite-plugin-pwa": "1.1.0",
"vite-plugin-solid": "2.11.10",
"vitest": "4.0.15"
},
"lint-staged": {
"*": [
"oxfmt --no-error-on-unmatched-pattern"
],
"*.{ts,js}": [
"*.{ts,js,tsx}": [
"oxlint --type-aware --type-check"
]
},
Expand Down
5 changes: 0 additions & 5 deletions frontend/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@
<div class="bar"></div>
</div>
</div>
<div class="content-grid scrollToTopContainer">
<div class="scrollToTopButton invisible breakout">
<i class="fas fa-angle-double-up"></i>
</div>
</div>
<div id="popups">
<load src="html/popups.html" />
</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/privacy-policy.html
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ <h1 id="Cookies">What are cookies?</h1>
>
HTTP cookie
</a>
&nbsp; on Wikipedia.
on Wikipedia.
</p>

<h1 id="Usage_of_Cookies">How do we use cookies?</h1>
Expand Down
31 changes: 0 additions & 31 deletions frontend/src/styles/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -256,37 +256,6 @@ key {
visibility: hidden !important;
}

.scrollToTopContainer {
position: fixed;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 99999999;

.scrollToTopButton {
pointer-events: all;
place-self: end end;
margin-bottom: 2rem;
font-size: 2rem;
width: 4rem;
height: 4rem;
text-align: center;

line-height: 4rem;
background: var(--sub-alt-color);
border-radius: 99rem;
outline: 0.5rem solid var(--bg-color);

cursor: pointer;
color: var(--sub-color);
transition: 0.25s;
&:hover {
background: var(--text-color);
color: var(--bg-color);
}
}
}

.inputAndIndicator {
input {
width: 100%;
Expand Down
36 changes: 36 additions & 0 deletions frontend/src/ts/components/ScrollToTop.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.ScrollToTop {
position: fixed;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 99999999;
top: 0;
left: 0;

.button {
pointer-events: all;
place-self: end end;
margin-bottom: 2rem;
font-size: 2rem;
width: 4rem;
height: 4rem;
text-align: center;

line-height: 4rem;
background: var(--sub-alt-color);
border-radius: 99rem;
outline: 0.5rem solid var(--bg-color);

.fas {
line-height: 1;
}

cursor: pointer;
color: var(--sub-color);
transition: 0.25s;
&:hover {
background: var(--text-color);
color: var(--bg-color);
}
}
}
Loading
Loading