| 1 | import * as Neon from "@/Neon"; |
| 2 | import * as Test from "@/Test/Alchemy"; |
| 3 | import * as SDK from "@distilled.cloud/neon"; |
| 4 | import { expect } from "alchemy-test"; |
| 5 | import * as Effect from "effect/Effect"; |
| 6 | import * as HttpClient from "effect/http/HttpClient"; |
| 7 | import BackendEffect from "./fixtures/backend-effect.ts"; |
| 8 | import { backendBranch, backendDataApi } from "./fixtures/backend-resources.ts"; |
| 9 | |
| 10 | const { test } = Test.make({ providers: Neon.providers() }); |
| 11 | |
| 12 | test.provider( |
| 13 | "native and Effect backend configuration use injected credentials without account keys", |
| 14 | (stack) => |
| 15 | Effect.gen(function* () { |
| 16 | yield* stack.destroy(); |
| 17 | const deployed = yield* stack.deploy( |
| 18 | Effect.gen(function* () { |
| 19 | const branch = yield* backendBranch; |
| 20 | const data = yield* backendDataApi; |
| 21 | const native = yield* Neon.Function("BackendNative", { |
| 22 | branch: { projectId: data.projectId, branchId: data.branchId }, |
| 23 | main: "./test/Neon/fixtures/backend-native.ts", |
| 24 | }); |
| 25 | const effect = yield* BackendEffect; |
| 26 | return { branch, native, effect }; |
| 27 | }), |
| 28 | ); |
| 29 | const http = yield* HttpClient.HttpClient; |
| 30 | const native = yield* http |
| 31 | .get(deployed.native.url) |
| 32 | .pipe(Effect.flatMap((response) => response.json)); |
| 33 | const effect = yield* http |
| 34 | .get(deployed.effect.url) |
| 35 | .pipe(Effect.flatMap((response) => response.json)); |
| 36 | expect(native).toMatchObject({ hasToken: true, hasDeploymentKey: false }); |
| 37 | expect(effect).toMatchObject({ hasToken: true }); |
| 38 | const credentials = yield* SDK.listCredentials({ |
| 39 | project_id: deployed.branch.projectId, |
| 40 | branch_id: deployed.branch.branchId, |
| 41 | }); |
| 42 | expect( |
| 43 | credentials.credentials.filter( |
| 44 | (item) => |
| 45 | item.principal_type === "user" && |
| 46 | item.branch_id === deployed.branch.branchId && |
| 47 | !item.revoked_at, |
| 48 | ), |
| 49 | ).toHaveLength(0); |
| 50 | const rejected = yield* http |
| 51 | .get(`${deployed.effect.url}/data-foreign-origin`) |
| 52 | .pipe(Effect.flatMap((response) => response.json)); |
| 53 | expect(rejected).toEqual({ rejected: true }); |
| 54 | const unauthorized = yield* http |
| 55 | .get(`${deployed.effect.url}/data-invalid-token`) |
| 56 | .pipe(Effect.flatMap((response) => response.text)); |
| 57 | expect(unauthorized).toBe("400"); |
| 58 | yield* stack.destroy(); |
| 59 | expect( |
| 60 | yield* SDK.getProjectBranch({ |
| 61 | project_id: deployed.branch.projectId, |
| 62 | branch_id: deployed.branch.branchId, |
| 63 | }).pipe( |
| 64 | Effect.as(false), |
| 65 | Effect.catchTag("NotFound", () => Effect.succeed(true)), |
| 66 | ), |
| 67 | ).toBe(true); |
| 68 | yield* stack.destroy(); |
| 69 | }), |
| 70 | { |
| 71 | tags: [ |
| 72 | "provider:neon", |
| 73 | "provider:neon:aigateway", |
| 74 | "provider:neon:auth", |
| 75 | "provider:neon:branch", |
| 76 | "provider:neon:dataapi", |
| 77 | "provider:neon:function", |
| 78 | "provider:neon:project", |
| 79 | "live", |
| 80 | ], |
| 81 | timeout: 120_000, |
| 82 | }, |
| 83 | ); |