chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { tenantContext, type TenantContext } from "../app/services/tenantContext.server";
|
||||
|
||||
const sample: TenantContext = {
|
||||
orgSlug: "acme",
|
||||
projectSlug: "web",
|
||||
envSlug: "prod",
|
||||
};
|
||||
|
||||
describe("tenantContext", () => {
|
||||
it("returns undefined outside run()", () => {
|
||||
expect(tenantContext.get()).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns the active context inside run()", () => {
|
||||
tenantContext.run(sample, () => {
|
||||
expect(tenantContext.get()).toEqual(sample);
|
||||
});
|
||||
});
|
||||
|
||||
it("isolates concurrent async trees", async () => {
|
||||
const a: TenantContext = { ...sample, orgSlug: "a" };
|
||||
const b: TenantContext = { ...sample, orgSlug: "b" };
|
||||
|
||||
const [got1, got2] = await Promise.all([
|
||||
tenantContext.run(a, async () => {
|
||||
await new Promise((r) => setTimeout(r, 10));
|
||||
return tenantContext.get()?.orgSlug;
|
||||
}),
|
||||
tenantContext.run(b, async () => {
|
||||
await new Promise((r) => setTimeout(r, 5));
|
||||
return tenantContext.get()?.orgSlug;
|
||||
}),
|
||||
]);
|
||||
expect(got1).toBe("a");
|
||||
expect(got2).toBe("b");
|
||||
});
|
||||
|
||||
it("supports nested run() overriding", () => {
|
||||
const inner: TenantContext = { ...sample, orgSlug: "inner" };
|
||||
tenantContext.run(sample, () => {
|
||||
tenantContext.run(inner, () => {
|
||||
expect(tenantContext.get()?.orgSlug).toBe("inner");
|
||||
});
|
||||
expect(tenantContext.get()?.orgSlug).toBe("acme");
|
||||
});
|
||||
});
|
||||
|
||||
it("enrich() patches the active context in-place", () => {
|
||||
tenantContext.run({ ...sample }, () => {
|
||||
tenantContext.enrich({
|
||||
userId: "usr_1",
|
||||
orgId: "org_1",
|
||||
projectId: "proj_1",
|
||||
envType: "PRODUCTION",
|
||||
});
|
||||
expect(tenantContext.get()).toMatchObject({
|
||||
orgSlug: "acme",
|
||||
projectSlug: "web",
|
||||
envSlug: "prod",
|
||||
userId: "usr_1",
|
||||
orgId: "org_1",
|
||||
projectId: "proj_1",
|
||||
envType: "PRODUCTION",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("enrich() outside run() is a no-op", () => {
|
||||
expect(() => tenantContext.enrich({ orgId: "x" })).not.toThrow();
|
||||
expect(tenantContext.get()).toBeUndefined();
|
||||
});
|
||||
|
||||
it("supports starting from an empty scope and enriching userId only (non-tenant page)", () => {
|
||||
tenantContext.run({}, () => {
|
||||
tenantContext.enrich({ userId: "usr_1" });
|
||||
expect(tenantContext.get()).toEqual({ userId: "usr_1" });
|
||||
});
|
||||
});
|
||||
|
||||
it("enrich() patches do not bleed across concurrent run() scopes", async () => {
|
||||
const a: TenantContext = { ...sample, orgSlug: "a" };
|
||||
const b: TenantContext = { ...sample, orgSlug: "b" };
|
||||
const [got1, got2] = await Promise.all([
|
||||
tenantContext.run(a, async () => {
|
||||
await new Promise((r) => setTimeout(r, 5));
|
||||
tenantContext.enrich({ orgId: "org_a" });
|
||||
await new Promise((r) => setTimeout(r, 5));
|
||||
return tenantContext.get();
|
||||
}),
|
||||
tenantContext.run(b, async () => {
|
||||
await new Promise((r) => setTimeout(r, 10));
|
||||
tenantContext.enrich({ orgId: "org_b" });
|
||||
return tenantContext.get();
|
||||
}),
|
||||
]);
|
||||
expect(got1?.orgId).toBe("org_a");
|
||||
expect(got2?.orgId).toBe("org_b");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user