feat: release authentication laboratories 0.3.0
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { scanQrFromCamera } from "../../src/qr/camera";
|
||||
|
||||
describe("opt-in camera QR scanning", () => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("requests only video and stops every track after a match", async () => {
|
||||
const stop = vi.fn();
|
||||
const getUserMedia = vi.fn().mockResolvedValue({
|
||||
getTracks: () => [{ stop }],
|
||||
});
|
||||
Object.defineProperty(navigator, "mediaDevices", {
|
||||
configurable: true,
|
||||
value: { getUserMedia },
|
||||
});
|
||||
vi.stubGlobal("isSecureContext", true);
|
||||
vi.stubGlobal(
|
||||
"BarcodeDetector",
|
||||
class {
|
||||
detect = vi
|
||||
.fn()
|
||||
.mockResolvedValue([{ rawValue: "otpauth://totp/Test" }]);
|
||||
},
|
||||
);
|
||||
const video = document.createElement("video");
|
||||
vi.spyOn(video, "play").mockResolvedValue();
|
||||
vi.spyOn(video, "pause").mockImplementation(() => undefined);
|
||||
Object.defineProperty(video, "readyState", {
|
||||
configurable: true,
|
||||
value: HTMLMediaElement.HAVE_CURRENT_DATA,
|
||||
});
|
||||
await expect(
|
||||
scanQrFromCamera(video, new AbortController().signal),
|
||||
).resolves.toBe("otpauth://totp/Test");
|
||||
expect(getUserMedia).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ audio: false, video: expect.any(Object) }),
|
||||
);
|
||||
expect(stop).toHaveBeenCalledOnce();
|
||||
expect(video.srcObject).toBeNull();
|
||||
});
|
||||
|
||||
it("does not request permission after prior cancellation", async () => {
|
||||
const getUserMedia = vi.fn();
|
||||
Object.defineProperty(navigator, "mediaDevices", {
|
||||
configurable: true,
|
||||
value: { getUserMedia },
|
||||
});
|
||||
vi.stubGlobal("isSecureContext", true);
|
||||
const controller = new AbortController();
|
||||
controller.abort();
|
||||
await expect(
|
||||
scanQrFromCamera(document.createElement("video"), controller.signal),
|
||||
).rejects.toMatchObject({ name: "AbortError" });
|
||||
expect(getUserMedia).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user