|
| 1 | +import { setupAuthenticatedEnvironment } from "@internal/run-engine/tests"; |
| 2 | +import { containerTest } from "@internal/testcontainers"; |
| 3 | +import { describe, expect, vi } from "vitest"; |
| 4 | +import type { PrismaClient, PrismaReplicaClient } from "~/db.server"; |
| 5 | +import { EnvironmentVariablesRepository } from "~/v3/environmentVariables/environmentVariablesRepository.server"; |
| 6 | + |
| 7 | +type OpLog = Array<{ label: string; model?: string; operation: string }>; |
| 8 | + |
| 9 | +function instrument<T>(client: T, label: string, log: OpLog): T { |
| 10 | + return (client as any).$extends({ |
| 11 | + name: `spy-${label}`, |
| 12 | + query: { |
| 13 | + $allOperations({ model, operation, args, query }: any) { |
| 14 | + log.push({ label, model, operation }); |
| 15 | + return query(args); |
| 16 | + }, |
| 17 | + }, |
| 18 | + }) as T; |
| 19 | +} |
| 20 | + |
| 21 | +vi.setConfig({ testTimeout: 60_000 }); |
| 22 | + |
| 23 | +describe("EnvironmentVariablesRepository control-plane read routing", () => { |
| 24 | + containerTest( |
| 25 | + "getEnvironmentVariables reads SecretStore from the replica only when readFromReplica is set, returning the same values", |
| 26 | + async ({ prisma }) => { |
| 27 | + const environment = await setupAuthenticatedEnvironment(prisma, "PRODUCTION"); |
| 28 | + const projectId = environment.projectId; |
| 29 | + const environmentId = environment.id; |
| 30 | + |
| 31 | + await prisma.secretStore.create({ |
| 32 | + data: { |
| 33 | + key: `environmentvariable:${projectId}:${environmentId}:MY_VAR`, |
| 34 | + value: { secret: "hello-from-db" }, |
| 35 | + }, |
| 36 | + }); |
| 37 | + |
| 38 | + const log: OpLog = []; |
| 39 | + const writer = instrument(prisma, "writer", log) as unknown as PrismaClient; |
| 40 | + const replica = instrument(prisma, "replica", log) as unknown as PrismaReplicaClient; |
| 41 | + const repository = new EnvironmentVariablesRepository(writer, replica); |
| 42 | + |
| 43 | + log.length = 0; |
| 44 | + const viaReplica = await repository.getEnvironmentVariables( |
| 45 | + projectId, |
| 46 | + environmentId, |
| 47 | + undefined, |
| 48 | + { |
| 49 | + readFromReplica: true, |
| 50 | + } |
| 51 | + ); |
| 52 | + expect(viaReplica).toContainEqual({ key: "MY_VAR", value: "hello-from-db" }); |
| 53 | + |
| 54 | + const replicaSecretOps = log.filter((l) => l.model === "SecretStore"); |
| 55 | + expect(replicaSecretOps.length).toBeGreaterThan(0); |
| 56 | + expect(replicaSecretOps.every((l) => l.label === "replica")).toBe(true); |
| 57 | + expect(log.some((l) => l.model === "SecretStore" && l.label === "writer")).toBe(false); |
| 58 | + |
| 59 | + log.length = 0; |
| 60 | + const viaWriter = await repository.getEnvironmentVariables(projectId, environmentId); |
| 61 | + expect(viaWriter).toContainEqual({ key: "MY_VAR", value: "hello-from-db" }); |
| 62 | + |
| 63 | + const writerSecretOps = log.filter((l) => l.model === "SecretStore"); |
| 64 | + expect(writerSecretOps.length).toBeGreaterThan(0); |
| 65 | + expect(writerSecretOps.every((l) => l.label === "writer")).toBe(true); |
| 66 | + } |
| 67 | + ); |
| 68 | +}); |
0 commit comments