import { describe, expect, it } from "@effect/vitest";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import { PgDialect } from "drizzle-orm/pg-core"; import * as RelayDb from "../db.ts";import { relayEnvironmentLinks } from "../persistence/schema.ts";import * as EnvironmentLinks from "./EnvironmentLinks.ts"; describe("EnvironmentLinks", () => { it.effect("retains link lookup failures with user and environment identity", () => { const cause = new Error("database unavailable"); const fakeDb = { select: () => ({ from: (table: unknown) => { expect(table).toBe(relayEnvironmentLinks); return { where: () => ({ limit: () => Effect.fail(cause), }), }; }, }), } as unknown as RelayDb.RelayDb["Service"]; return Effect.gen(function* () { const links = yield* EnvironmentLinks.EnvironmentLinks; const error = yield* Effect.flip( links.getForUser({ userId: "user-1", environmentId: "env-1" }), ); expect(error).toMatchObject({ _tag: "EnvironmentLinkLookupPersistenceError", userId: "user-1", environmentId: "env-1", }); expect(error.cause).toBe(cause); }).pipe( Effect.provide( EnvironmentLinks.layer.pipe(Layer.provide(Layer.succeed(RelayDb.RelayDb, fakeDb))), ), ); }); it.effect("identifies delivery-user list failures without retaining key material", () => { const cause = new Error("database unavailable"); const fakeDb = { select: () => ({ from: (table: unknown) => { expect(table).toBe(relayEnvironmentLinks); return { where: () => Effect.fail(cause), }; }, }), } as unknown as RelayDb.RelayDb["Service"]; return Effect.gen(function* () { const links = yield* EnvironmentLinks.EnvironmentLinks; const error = yield* Effect.flip( links.listDeliveryUsersForEnvironment({ environmentId: "env-1", environmentPublicKey: "sensitive-public-key-material", }), ); expect(error).toMatchObject({ _tag: "EnvironmentLinkUserListPersistenceError", operation: "list-delivery-users", environmentId: "env-1", }); expect(error.cause).toBe(cause); expect(error).not.toHaveProperty("environmentPublicKey"); }).pipe( Effect.provide( EnvironmentLinks.layer.pipe(Layer.provide(Layer.succeed(RelayDb.RelayDb, fakeDb))), ), ); }); it.effect("selects users when either notifications or Live Activities are enabled", () => { const whereConditions: Array<unknown> = []; const fakeDb = { select: (selection: unknown) => { expect(selection).toBeDefined(); return { from: (table: unknown) => { expect(table).toBe(relayEnvironmentLinks); return { where: (condition: unknown) => { whereConditions.push(condition); return Effect.succeed([]); }, }; }, }; }, } as unknown as RelayDb.RelayDb["Service"]; return Effect.gen(function* () { const links = yield* EnvironmentLinks.EnvironmentLinks; expect(yield* links.listUsersForEnvironment({ environmentId: "env-1" })).toEqual([]); expect(whereConditions).toHaveLength(1); const query = new PgDialect().sqlToQuery(whereConditions[0] as never); expect(query.sql).toContain('"relay_environment_links"."environment_id" = $1'); expect(query.sql).toContain('"relay_environment_links"."revoked_at" is null'); expect(query.sql).toContain('"relay_environment_links"."notifications_enabled" = $2'); expect(query.sql).toContain('"relay_environment_links"."live_activities_enabled" = $3'); expect(query.sql).toContain(" or "); expect(query.params).toEqual(["env-1", true, true]); }).pipe( Effect.provide( EnvironmentLinks.layer.pipe(Layer.provide(Layer.succeed(RelayDb.RelayDb, fakeDb))), ), ); }); it.effect("revokes only the active link owned by the requesting user", () => { const updateValues: Array<Record<string, unknown>> = []; const whereConditions: Array<unknown> = []; const fakeDb = { update: (table: unknown) => { expect(table).toBe(relayEnvironmentLinks); return { set: (values: Record<string, unknown>) => { updateValues.push(values); return { where: (condition: unknown) => { whereConditions.push(condition); return { returning: (selection: unknown) => { expect(selection).toBeDefined(); return Effect.succeed([{ environmentId: "env-1" }]); }, }; }, }; }, }; }, } as unknown as RelayDb.RelayDb["Service"]; return Effect.gen(function* () { const links = yield* EnvironmentLinks.EnvironmentLinks; const revoked = yield* links.revokeForUser({ userId: "user-1", environmentId: "env-1", }); expect(revoked).toBe(true); expect(updateValues).toHaveLength(1); expect(updateValues[0]?.revokedAt).toEqual(updateValues[0]?.updatedAt); expect(typeof updateValues[0]?.revokedAt).toBe("string"); expect(whereConditions).toHaveLength(1); const dialect = new PgDialect(); const query = dialect.sqlToQuery(whereConditions[0] as never); expect(query.sql).toContain('"relay_environment_links"."user_id" = $1'); expect(query.sql).toContain('"relay_environment_links"."environment_id" = $2'); expect(query.sql).toContain('"relay_environment_links"."revoked_at" is null'); expect(query.params).toEqual(["user-1", "env-1"]); }).pipe( Effect.provide( EnvironmentLinks.layer.pipe(Layer.provide(Layer.succeed(RelayDb.RelayDb, fakeDb))), ), ); });});
import { describe, expect, it } from "@effect/vitest";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import { PgDialect } from "drizzle-orm/pg-core";
import * as RelayDb from "../db.ts";
import { relayEnvironmentLinks } from "../persistence/schema.ts";
import * as EnvironmentLinks from "./EnvironmentLinks.ts";
describe("EnvironmentLinks", () => {
it.effect("retains link lookup failures with user and environment identity", () => {
const cause = new Error("database unavailable");
const fakeDb = {
select: () => ({
from: (table: unknown) => {
expect(table).toBe(relayEnvironmentLinks);
return {
where: () => ({
limit: () => Effect.fail(cause),
}),
};
},
}),
} as unknown as RelayDb.RelayDb["Service"];
return Effect.gen(function* () {
const links = yield* EnvironmentLinks.EnvironmentLinks;
const error = yield* Effect.flip(
links.getForUser({ userId: "user-1", environmentId: "env-1" }),
);
expect(error).toMatchObject({
_tag: "EnvironmentLinkLookupPersistenceError",
userId: "user-1",
environmentId: "env-1",
});
expect(error.cause).toBe(cause);
}).pipe(
Effect.provide(
EnvironmentLinks.layer.pipe(Layer.provide(Layer.succeed(RelayDb.RelayDb, fakeDb))),
),
);
});
it.effect("identifies delivery-user list failures without retaining key material", () => {
const cause = new Error("database unavailable");
const fakeDb = {
select: () => ({
from: (table: unknown) => {
expect(table).toBe(relayEnvironmentLinks);
return {
where: () => Effect.fail(cause),
};
},
}),
} as unknown as RelayDb.RelayDb["Service"];
return Effect.gen(function* () {
const links = yield* EnvironmentLinks.EnvironmentLinks;
const error = yield* Effect.flip(
links.listDeliveryUsersForEnvironment({
environmentId: "env-1",
environmentPublicKey: "sensitive-public-key-material",
}),
);
expect(error).toMatchObject({
_tag: "EnvironmentLinkUserListPersistenceError",
operation: "list-delivery-users",
environmentId: "env-1",
});
expect(error.cause).toBe(cause);
expect(error).not.toHaveProperty("environmentPublicKey");
}).pipe(
Effect.provide(
EnvironmentLinks.layer.pipe(Layer.provide(Layer.succeed(RelayDb.RelayDb, fakeDb))),
),
);
});
it.effect("selects users when either notifications or Live Activities are enabled", () => {
const whereConditions: Array<unknown> = [];
const fakeDb = {
select: (selection: unknown) => {
expect(selection).toBeDefined();
return {
from: (table: unknown) => {
expect(table).toBe(relayEnvironmentLinks);
return {
where: (condition: unknown) => {
whereConditions.push(condition);
return Effect.succeed([]);
},
};
},
};
},
} as unknown as RelayDb.RelayDb["Service"];
return Effect.gen(function* () {
const links = yield* EnvironmentLinks.EnvironmentLinks;
expect(yield* links.listUsersForEnvironment({ environmentId: "env-1" })).toEqual([]);
expect(whereConditions).toHaveLength(1);
const query = new PgDialect().sqlToQuery(whereConditions[0] as never);
expect(query.sql).toContain('"relay_environment_links"."environment_id" = $1');
expect(query.sql).toContain('"relay_environment_links"."revoked_at" is null');
expect(query.sql).toContain('"relay_environment_links"."notifications_enabled" = $2');
expect(query.sql).toContain('"relay_environment_links"."live_activities_enabled" = $3');
expect(query.sql).toContain(" or ");
expect(query.params).toEqual(["env-1", true, true]);
}).pipe(
Effect.provide(
EnvironmentLinks.layer.pipe(Layer.provide(Layer.succeed(RelayDb.RelayDb, fakeDb))),
),
);
});
it.effect("revokes only the active link owned by the requesting user", () => {
const updateValues: Array<Record<string, unknown>> = [];
const whereConditions: Array<unknown> = [];
const fakeDb = {
update: (table: unknown) => {
expect(table).toBe(relayEnvironmentLinks);
return {
set: (values: Record<string, unknown>) => {
updateValues.push(values);
return {
where: (condition: unknown) => {
whereConditions.push(condition);
return {
returning: (selection: unknown) => {
expect(selection).toBeDefined();
return Effect.succeed([{ environmentId: "env-1" }]);
},
};
},
};
},
};
},
} as unknown as RelayDb.RelayDb["Service"];
return Effect.gen(function* () {
const links = yield* EnvironmentLinks.EnvironmentLinks;
const revoked = yield* links.revokeForUser({
userId: "user-1",
environmentId: "env-1",
});
expect(revoked).toBe(true);
expect(updateValues).toHaveLength(1);
expect(updateValues[0]?.revokedAt).toEqual(updateValues[0]?.updatedAt);
expect(typeof updateValues[0]?.revokedAt).toBe("string");
expect(whereConditions).toHaveLength(1);
const dialect = new PgDialect();
const query = dialect.sqlToQuery(whereConditions[0] as never);
expect(query.sql).toContain('"relay_environment_links"."user_id" = $1');
expect(query.sql).toContain('"relay_environment_links"."environment_id" = $2');
expect(query.sql).toContain('"relay_environment_links"."revoked_at" is null');
expect(query.params).toEqual(["user-1", "env-1"]);
}).pipe(
Effect.provide(
EnvironmentLinks.layer.pipe(Layer.provide(Layer.succeed(RelayDb.RelayDb, fakeDb))),
),
);
});
});