d5279b124f
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { UserLoginActivity } from "../../types/api";
|
|
import { activitySourceKey, groupLoginActivitiesBySource } from "./loginActivitySources";
|
|
|
|
const activity = (overrides: Partial<UserLoginActivity>): UserLoginActivity => ({
|
|
id: "session-1",
|
|
client_type: "web",
|
|
client_platform: "macos",
|
|
client_version: "0.1.0",
|
|
login_ip: "192.168.97.1",
|
|
login_at: "2026-07-16T02:23:04Z",
|
|
last_seen_at: "2026-07-16T03:08:32Z",
|
|
activity_status: "ENDED",
|
|
...overrides,
|
|
});
|
|
|
|
describe("login activity sources", () => {
|
|
it("uses only client type and a recorded IP as the source identity", () => {
|
|
expect(activitySourceKey(activity({ client_platform: "windows", client_source: "installer" }))).toBe(
|
|
"web|192.168.97.1",
|
|
);
|
|
expect(activitySourceKey(activity({ id: "legacy", login_ip: null }))).toBe("session:legacy");
|
|
});
|
|
|
|
it("merges online and historical sessions from the same client and IP", () => {
|
|
const rows = groupLoginActivitiesBySource(
|
|
[
|
|
activity({
|
|
id: "current",
|
|
login_at: "2026-07-16T07:22:42Z",
|
|
last_seen_at: "2026-07-16T07:53:00Z",
|
|
activity_status: "ONLINE",
|
|
ended_at: null,
|
|
}),
|
|
activity({ id: "history", ended_at: "2026-07-16T03:08:32Z" }),
|
|
activity({
|
|
id: "desktop",
|
|
client_type: "desktop",
|
|
login_at: "2026-07-15T08:42:02Z",
|
|
last_seen_at: "2026-07-16T07:53:42Z",
|
|
activity_status: "ONLINE",
|
|
ended_at: null,
|
|
}),
|
|
],
|
|
(item) => item.activity_status!,
|
|
);
|
|
|
|
expect(rows).toHaveLength(2);
|
|
expect(rows[0]).toMatchObject({ id: "desktop", grouped_count: 1, activity_status: "ONLINE" });
|
|
expect(rows[1]).toMatchObject({
|
|
id: "current",
|
|
grouped_count: 2,
|
|
login_at: "2026-07-16T02:23:04Z",
|
|
last_seen_at: "2026-07-16T07:53:00Z",
|
|
activity_status: "ONLINE",
|
|
ended_at: null,
|
|
});
|
|
});
|
|
|
|
it("does not merge sessions whose IP was not recorded", () => {
|
|
const rows = groupLoginActivitiesBySource(
|
|
[activity({ id: "legacy-1", login_ip: null }), activity({ id: "legacy-2", login_ip: null })],
|
|
(item) => item.activity_status!,
|
|
);
|
|
|
|
expect(rows).toHaveLength(2);
|
|
});
|
|
});
|