Add full shell, replaceable Omics adapter and bilingual interaction
Implement approved specification #32 and tickets #33-#37. Keep host authentication server-verified and pin session interaction language. Compile scoped base selectors for browser compatibility and retain full gutters during CSS pruning.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import { afterEach, expect, test, vi } from "vitest";
|
||||
import { OmicsPortalAdapter } from "./OmicsPortalAdapter";
|
||||
|
||||
afterEach(() => {
|
||||
document.body.replaceChildren();
|
||||
document.documentElement.removeAttribute("data-bs-theme");
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
function portal() {
|
||||
document.documentElement.lang = "en";
|
||||
document.documentElement.setAttribute("data-bs-theme", "dark");
|
||||
document.body.innerHTML = '<form action="/i18n/setlang/"><select class="omics-language-select" data-lang="it"><option value="it">Italiano</option></select></form>';
|
||||
}
|
||||
|
||||
test("publishes rendered language, observes theme and actual fullscreen, and cleans up repeated mounts", async () => {
|
||||
portal();
|
||||
let fullscreen: Element | null = null;
|
||||
Object.defineProperty(document, "fullscreenElement", { configurable: true, get: () => fullscreen });
|
||||
const adapter = new OmicsPortalAdapter();
|
||||
for (let mount = 0; mount < 2; mount++) {
|
||||
document.documentElement.setAttribute("data-bs-theme", "dark");
|
||||
const state = vi.fn();
|
||||
const error = vi.fn();
|
||||
const unsubscribe = adapter.subscribe(state, error);
|
||||
expect(state).toHaveBeenLastCalledWith({ locale: "it", theme: "dark", fullscreen: false });
|
||||
document.documentElement.setAttribute("data-bs-theme", "light");
|
||||
await Promise.resolve();
|
||||
expect(state).toHaveBeenLastCalledWith({ locale: "it", theme: "light", fullscreen: false });
|
||||
fullscreen = document.documentElement;
|
||||
document.dispatchEvent(new Event("fullscreenchange"));
|
||||
expect(state).toHaveBeenLastCalledWith({ locale: "it", theme: "light", fullscreen: true });
|
||||
fullscreen = null;
|
||||
document.dispatchEvent(new Event("fullscreenchange"));
|
||||
expect(state).toHaveBeenLastCalledWith({ locale: "it", theme: "light", fullscreen: false });
|
||||
unsubscribe();
|
||||
state.mockClear();
|
||||
document.documentElement.setAttribute("data-bs-theme", "dark");
|
||||
document.dispatchEvent(new Event("fullscreenchange"));
|
||||
await Promise.resolve();
|
||||
expect(state).not.toHaveBeenCalled();
|
||||
expect(error).not.toHaveBeenCalled();
|
||||
}
|
||||
});
|
||||
|
||||
test("missing Omics DOM reports an integration error instead of using fixed html language", () => {
|
||||
document.documentElement.lang = "it";
|
||||
const state = vi.fn();
|
||||
const error = vi.fn();
|
||||
const unsubscribe = new OmicsPortalAdapter().subscribe(state, error);
|
||||
expect(state).not.toHaveBeenCalled();
|
||||
expect(error).toHaveBeenCalledWith(expect.objectContaining({ message: expect.stringMatching(/portal preferences/i) }));
|
||||
unsubscribe();
|
||||
});
|
||||
|
||||
test.each(["not_a_locale", "en--US", " "])("rejects malformed portal language %j", locale => {
|
||||
portal();
|
||||
document.querySelector<HTMLSelectElement>(".omics-language-select")!.dataset.lang = locale;
|
||||
const state = vi.fn();
|
||||
const error = vi.fn();
|
||||
const unsubscribe = new OmicsPortalAdapter().subscribe(state, error);
|
||||
expect(state).not.toHaveBeenCalled();
|
||||
expect(error).toHaveBeenCalledWith(expect.objectContaining({ message: expect.stringMatching(/portal preferences/i) }));
|
||||
unsubscribe();
|
||||
});
|
||||
|
||||
test("accepts a well-formed unsupported language for the shell's catalogue fallback", () => {
|
||||
portal();
|
||||
document.querySelector<HTMLSelectElement>(".omics-language-select")!.dataset.lang = "fr-ca";
|
||||
const state = vi.fn();
|
||||
const error = vi.fn();
|
||||
const unsubscribe = new OmicsPortalAdapter().subscribe(state, error);
|
||||
expect(state).toHaveBeenCalledWith(expect.objectContaining({ locale: "fr-CA" }));
|
||||
expect(error).not.toHaveBeenCalled();
|
||||
unsubscribe();
|
||||
});
|
||||
Reference in New Issue
Block a user