@@ -3,6 +3,26 @@ import { jest } from "@jest/globals";
33
44jest . mock ( "../utils/logger.js" ) ;
55
6+ const VALID_STELLAR_SECRET =
7+ "SBJ6ZXIH5JXKHXJUDF7DUX2HY5Q3SOOAUCQ3OUO5TIIJMOYIGPPP6Q6W" ;
8+
9+ function setValidEnv ( ) : void {
10+ process . env . DATABASE_URL = "postgres://localhost" ;
11+ process . env . REDIS_URL = "redis://localhost" ;
12+ process . env . JWT_SECRET = "a" . repeat ( 32 ) ;
13+ process . env . STELLAR_RPC_URL = "http://localhost" ;
14+ process . env . STELLAR_NETWORK_PASSPHRASE = "test" ;
15+ process . env . LOAN_MANAGER_CONTRACT_ID = "C1" ;
16+ process . env . LENDING_POOL_CONTRACT_ID = "C2" ;
17+ process . env . POOL_TOKEN_ADDRESS = "T1" ;
18+ process . env . LOAN_MANAGER_ADMIN_SECRET = VALID_STELLAR_SECRET ;
19+ process . env . INTERNAL_API_KEY = "b" . repeat ( 32 ) ;
20+ process . env . FRONTEND_URL = "http://localhost:3000" ;
21+ process . env . SCORE_DELTA_REPAY = "15" ;
22+ process . env . SCORE_DELTA_DEFAULT = "50" ;
23+ process . env . SCORE_DELTA_LATE = "5" ;
24+ }
25+
626describe ( "Environment Variable Validation" , ( ) => {
727 const originalEnv = process . env ;
828 let mockExit : any ;
@@ -26,39 +46,77 @@ describe("Environment Variable Validation", () => {
2646 mockExit . mockRestore ( ) ;
2747 } ) ;
2848
29- it ( "should not exit if all required variables are present" , ( ) => {
30- // All required variables are expected to be in originalEnv/process.env
31- // or we set them here for the test
32- process . env . DATABASE_URL = "postgres://localhost" ;
33- process . env . REDIS_URL = "redis://localhost" ;
34- process . env . JWT_SECRET = "secret" ;
35- process . env . STELLAR_RPC_URL = "http://localhost" ;
36- process . env . STELLAR_NETWORK_PASSPHRASE = "test" ;
37- process . env . LOAN_MANAGER_CONTRACT_ID = "C1" ;
38- process . env . LENDING_POOL_CONTRACT_ID = "C2" ;
39- process . env . POOL_TOKEN_ADDRESS = "T1" ;
40- process . env . LOAN_MANAGER_ADMIN_SECRET = "S1" ;
41- process . env . INTERNAL_API_KEY = "K1" ;
42- process . env . FRONTEND_URL = "http://localhost:3000" ;
43- process . env . SCORE_DELTA_REPAY = "15" ;
44- process . env . SCORE_DELTA_DEFAULT = "50" ;
45- process . env . SCORE_DELTA_LATE = "5" ;
49+ it ( "should not exit if all required variables are present and valid" , ( ) => {
50+ setValidEnv ( ) ;
4651
4752 expect ( ( ) => validateEnvVars ( ) ) . not . toThrow ( ) ;
4853 expect ( mockExit ) . not . toHaveBeenCalled ( ) ;
4954 } ) ;
5055
5156 it ( "should exit with code 1 if a required variable is missing" , ( ) => {
57+ setValidEnv ( ) ;
5258 delete process . env . DATABASE_URL ;
5359
5460 expect ( ( ) => validateEnvVars ( ) ) . toThrow ( "Process.exit called with 1" ) ;
5561 expect ( mockExit ) . toHaveBeenCalledWith ( 1 ) ;
5662 } ) ;
5763
5864 it ( "should exit with code 1 if a required variable is empty string" , ( ) => {
65+ setValidEnv ( ) ;
5966 process . env . DATABASE_URL = " " ;
6067
6168 expect ( ( ) => validateEnvVars ( ) ) . toThrow ( "Process.exit called with 1" ) ;
6269 expect ( mockExit ) . toHaveBeenCalledWith ( 1 ) ;
6370 } ) ;
71+
72+ describe ( "JWT_SECRET format validation" , ( ) => {
73+ it ( "should exit if JWT_SECRET is shorter than 32 characters" , ( ) => {
74+ setValidEnv ( ) ;
75+ process . env . JWT_SECRET = "short" ;
76+
77+ expect ( ( ) => validateEnvVars ( ) ) . toThrow ( "Process.exit called with 1" ) ;
78+ expect ( mockExit ) . toHaveBeenCalledWith ( 1 ) ;
79+ } ) ;
80+
81+ it ( "should pass if JWT_SECRET is exactly 32 characters" , ( ) => {
82+ setValidEnv ( ) ;
83+ process . env . JWT_SECRET = "a" . repeat ( 32 ) ;
84+
85+ expect ( ( ) => validateEnvVars ( ) ) . not . toThrow ( ) ;
86+ } ) ;
87+ } ) ;
88+
89+ describe ( "INTERNAL_API_KEY format validation" , ( ) => {
90+ it ( "should exit if INTERNAL_API_KEY is shorter than 32 characters" , ( ) => {
91+ setValidEnv ( ) ;
92+ process . env . INTERNAL_API_KEY = "short" ;
93+
94+ expect ( ( ) => validateEnvVars ( ) ) . toThrow ( "Process.exit called with 1" ) ;
95+ expect ( mockExit ) . toHaveBeenCalledWith ( 1 ) ;
96+ } ) ;
97+
98+ it ( "should pass if INTERNAL_API_KEY is exactly 32 characters" , ( ) => {
99+ setValidEnv ( ) ;
100+ process . env . INTERNAL_API_KEY = "x" . repeat ( 32 ) ;
101+
102+ expect ( ( ) => validateEnvVars ( ) ) . not . toThrow ( ) ;
103+ } ) ;
104+ } ) ;
105+
106+ describe ( "LOAN_MANAGER_ADMIN_SECRET format validation" , ( ) => {
107+ it ( "should exit if LOAN_MANAGER_ADMIN_SECRET is not a valid Stellar secret key" , ( ) => {
108+ setValidEnv ( ) ;
109+ process . env . LOAN_MANAGER_ADMIN_SECRET = "not-a-stellar-key" ;
110+
111+ expect ( ( ) => validateEnvVars ( ) ) . toThrow ( "Process.exit called with 1" ) ;
112+ expect ( mockExit ) . toHaveBeenCalledWith ( 1 ) ;
113+ } ) ;
114+
115+ it ( "should pass if LOAN_MANAGER_ADMIN_SECRET is a valid Stellar secret key" , ( ) => {
116+ setValidEnv ( ) ;
117+ process . env . LOAN_MANAGER_ADMIN_SECRET = VALID_STELLAR_SECRET ;
118+
119+ expect ( ( ) => validateEnvVars ( ) ) . not . toThrow ( ) ;
120+ } ) ;
121+ } ) ;
64122} ) ;
0 commit comments