import assert from "node:assert/strict"; import { existsSync, readFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { describe, it } from "node:test"; import { fileURLToPath } from "node:url"; const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", ".."); const TERRAFORM = join(ROOT, "terraform"); const lambdaTf = readFileSync(join(TERRAFORM, "lambda.tf"), "utf8"); const hcpIam = readFileSync(join(TERRAFORM, "hcp_iam.tf"), "utf8"); const deploy = readFileSync(join(ROOT, ".github", "workflows", "deploy.yaml"), "utf8"); const ci = readFileSync(join(ROOT, ".github", "workflows", "ci.yaml"), "utf8"); const locals = readFileSync(join(TERRAFORM, "locals.tf"), "utf8"); const variables = readFileSync(join(TERRAFORM, "variables.tf"), "utf8"); const versions = readFileSync(join(TERRAFORM, "versions.tf"), "utf8"); const githubDeploy = readFileSync(join(TERRAFORM, "iam_github_deploy.tf"), "utf8"); describe("HCP Terraform seam (PLAT-79)", () => { it("removes the SAM template", () => { assert.equal(existsSync(join(ROOT, "template.yaml")), false); assert.equal(existsSync(join(ROOT, "samconfig.toml.example")), false); }); it("ignores Lambda code attributes so zip CD is not drift", () => { for (const attr of ["filename", "s3_bucket", "s3_key", "s3_object_version", "source_code_hash"]) { assert.match(lambdaTf, new RegExp(attr)); } assert.match(lambdaTf, /lifecycle/); assert.match(lambdaTf, /ignore_changes/); }); it("keeps schedules disabled by default", () => { const chunk = variables.split('variable "schedules_enabled"')[1].split("variable ")[0]; assert.match(chunk, /default\s+= false/); }); it("is prod-only", () => { assert.match(versions, /payments-dashboard-prod/); assert.doesNotMatch(versions, /payments-dashboard-dev/); assert.match(locals, /environment = "prod"/); assert.doesNotMatch(locals, /seahaven-dev/); }); it("declares in-repo hcptf roles", () => { assert.match(locals, /apply_role\s+= "hcptf-payments-dashboard"/); assert.match(locals, /plan_role\s+= "hcptf-payments-dashboard-plan"/); assert.match(hcpIam, /hcptf_apply/); assert.match(hcpIam, /DenyCreatePolicy/); }); it("uses prod zip CD without SAM or GitHub Releases", () => { assert.doesNotMatch(deploy, /release: published/); assert.doesNotMatch(deploy, /cd-sam/); assert.match(deploy, /environment: prod/); assert.match(deploy, /deploy-payments-dashboard-prod/); assert.doesNotMatch(deploy, /gh release create/); assert.match(deploy, /package_lambdas\.mjs/); assert.match(deploy, /update-function-code/); }); it("runs npm test and terraform validate behind ci / ci", () => { assert.doesNotMatch(ci, /ci-typescript-cdk/); assert.doesNotMatch(ci, /run-sam-validate/); assert.match(ci, /npm test/); assert.match(ci, /terraform fmt -check/); assert.match(ci, /terraform init -backend=false/); assert.match(ci, /terraform validate/); assert.match(ci, /name: ci \/ ci/); }); it("names the five live functions", () => { for (const name of [ "payments-processPaymentCsv", "payments-slackAppHome", "payments-fetchBoaTransactions", "payments-expenseReceiver", "payments-expenseProcessor", ]) { assert.match(locals, new RegExp(name)); } assert.doesNotMatch(locals, /payments-processPayrollEmail/); }); it("pins GitHub deploy trust to Environment prod", () => { assert.match(githubDeploy, /environment:prod/); assert.match(githubDeploy, /deploy.yaml@refs\/heads\/\$\{var.github_deploy_branch\}/); assert.doesNotMatch(githubDeploy, /deploy.yaml@\*/); assert.doesNotMatch(githubDeploy, /refs\/tags\/v\*/); }); it("includes provider-6 S3 Get* needed for refresh", () => { assert.match(hcpIam, /s3:GetLifecycleConfiguration/); assert.match(hcpIam, /s3:GetReplicationConfiguration/); assert.match(hcpIam, /s3:GetBucketReplication/); }); });