validateEnv.test.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // lib/config/validateEnv.test.js
  2. import { describe, it, expect } from "vitest";
  3. import { validateEnv, MIN_SESSION_SECRET_LENGTH } from "./validateEnv.js";
  4. function validSecret() {
  5. return "x".repeat(MIN_SESSION_SECRET_LENGTH);
  6. }
  7. describe("validateEnv", () => {
  8. it("returns normalized config for a valid env", () => {
  9. const cfg = validateEnv({
  10. MONGODB_URI: "mongodb://localhost:27017/rhl",
  11. SESSION_SECRET: validSecret(),
  12. NAS_ROOT_PATH: "/mnt/niederlassungen/",
  13. PORT: "3000",
  14. });
  15. expect(cfg.mongodbUri).toBe("mongodb://localhost:27017/rhl");
  16. expect(cfg.sessionSecret).toBe(validSecret());
  17. expect(cfg.nasRootPath).toBe("/mnt/niederlassungen");
  18. expect(cfg.nodeEnv).toBe("development");
  19. expect(cfg.port).toBe(3000);
  20. });
  21. it("accepts optional SESSION_COOKIE_SECURE=false", () => {
  22. expect(() =>
  23. validateEnv({
  24. MONGODB_URI: "mongodb://localhost:27017/rhl",
  25. SESSION_SECRET: validSecret(),
  26. NAS_ROOT_PATH: "/mnt/niederlassungen",
  27. NODE_ENV: "production",
  28. SESSION_COOKIE_SECURE: "false",
  29. })
  30. ).not.toThrow();
  31. });
  32. it("rejects invalid SESSION_COOKIE_SECURE values", () => {
  33. expect(() =>
  34. validateEnv({
  35. MONGODB_URI: "mongodb://localhost:27017/rhl",
  36. SESSION_SECRET: validSecret(),
  37. NAS_ROOT_PATH: "/mnt/niederlassungen",
  38. SESSION_COOKIE_SECURE: "maybe",
  39. })
  40. ).toThrow(/SESSION_COOKIE_SECURE/i);
  41. });
  42. it("throws with a clear error if required vars are missing", () => {
  43. try {
  44. validateEnv({});
  45. throw new Error("Expected validateEnv to throw");
  46. } catch (err) {
  47. expect(err.code).toBe("ENV_INVALID");
  48. expect(err.missing).toEqual([
  49. "MONGODB_URI",
  50. "SESSION_SECRET",
  51. "NAS_ROOT_PATH",
  52. ]);
  53. expect(String(err.message)).toContain(
  54. "Missing required environment variables:"
  55. );
  56. }
  57. });
  58. it("rejects invalid MONGODB_URI schemes", () => {
  59. expect(() =>
  60. validateEnv({
  61. MONGODB_URI: "http://localhost:27017/rhl",
  62. SESSION_SECRET: validSecret(),
  63. NAS_ROOT_PATH: "/mnt/niederlassungen",
  64. NODE_ENV: "production",
  65. })
  66. ).toThrow(/MONGODB_URI/i);
  67. });
  68. it("rejects too-short SESSION_SECRET", () => {
  69. expect(() =>
  70. validateEnv({
  71. MONGODB_URI: "mongodb://localhost:27017/rhl",
  72. SESSION_SECRET: "short-secret",
  73. NAS_ROOT_PATH: "/mnt/niederlassungen",
  74. })
  75. ).toThrow(/SESSION_SECRET/i);
  76. });
  77. it("rejects placeholder-like SESSION_SECRET even if long enough", () => {
  78. const secret = `change-me-${"x".repeat(64)}`;
  79. expect(() =>
  80. validateEnv({
  81. MONGODB_URI: "mongodb://localhost:27017/rhl",
  82. SESSION_SECRET: secret,
  83. NAS_ROOT_PATH: "/mnt/niederlassungen",
  84. })
  85. ).toThrow(/placeholder/i);
  86. });
  87. it("rejects NAS_ROOT_PATH that is not absolute", () => {
  88. expect(() =>
  89. validateEnv({
  90. MONGODB_URI: "mongodb://localhost:27017/rhl",
  91. SESSION_SECRET: validSecret(),
  92. NAS_ROOT_PATH: "mnt/niederlassungen",
  93. })
  94. ).toThrow(/NAS_ROOT_PATH/i);
  95. });
  96. it('rejects NAS_ROOT_PATH containing ".." segments', () => {
  97. expect(() =>
  98. validateEnv({
  99. MONGODB_URI: "mongodb://localhost:27017/rhl",
  100. SESSION_SECRET: validSecret(),
  101. NAS_ROOT_PATH: "/mnt/../etc",
  102. })
  103. ).toThrow(/NAS_ROOT_PATH/i);
  104. });
  105. it("rejects invalid NODE_ENV values", () => {
  106. expect(() =>
  107. validateEnv({
  108. MONGODB_URI: "mongodb://localhost:27017/rhl",
  109. SESSION_SECRET: validSecret(),
  110. NAS_ROOT_PATH: "/mnt/niederlassungen",
  111. NODE_ENV: "staging",
  112. })
  113. ).toThrow(/NODE_ENV/i);
  114. });
  115. it("rejects invalid PORT values", () => {
  116. expect(() =>
  117. validateEnv({
  118. MONGODB_URI: "mongodb://localhost:27017/rhl",
  119. SESSION_SECRET: validSecret(),
  120. NAS_ROOT_PATH: "/mnt/niederlassungen",
  121. PORT: "70000",
  122. })
  123. ).toThrow(/PORT/i);
  124. expect(() =>
  125. validateEnv({
  126. MONGODB_URI: "mongodb://localhost:27017/rhl",
  127. SESSION_SECRET: validSecret(),
  128. NAS_ROOT_PATH: "/mnt/niederlassungen",
  129. PORT: "abc",
  130. })
  131. ).toThrow(/PORT/i);
  132. });
  133. });