1+ package main
2+
3+ import (
4+ "identity-service/layer/utils"
5+ "testing"
6+
7+ "github.com/aws/aws-lambda-go/events"
8+ "github.com/stretchr/testify/assert"
9+ )
10+
11+ func TestHandler (t * testing.T ) {
12+ for _ , test := range TestRequests {
13+ t .Run (test .Name , func (t * testing.T ) {
14+ t .Parallel ()
15+ response , err := handler (test .Request )
16+
17+ if test .ExpectedErr {
18+ assert .Error (t , err )
19+ assert .Contains (t , err .Error (), "project id is required" )
20+ assert .Equal (t , "" , response .Body )
21+ } else {
22+ assert .NoError (t , err )
23+ }
24+
25+ assert .IsType (t , events.APIGatewayProxyResponse {}, response )
26+ })
27+ }
28+ }
29+
30+ func TestHandler_NoFirestore (t * testing.T ) {
31+ request := events.APIGatewayProxyRequest {
32+ Body : `{"userId": "mock-user-id"}` ,
33+ }
34+
35+ _ , err := handler (request )
36+ assert .Error (t , err )
37+ }
38+
39+ func TestGetDataFromBody (t * testing.T ) {
40+ for _ , test := range GetDataFromBodyTests {
41+ t .Run (test .Name , func (t * testing.T ) {
42+ t .Parallel ()
43+ userId , sessionId := utils .GetDataFromBody ([]byte (test .Body ))
44+ assert .Equal (t , test .ExpectedUserId , userId , test .Description )
45+ assert .Equal (t , test .ExpectedSessionId , sessionId , test .Description )
46+ })
47+ }
48+ }
49+
50+ func TestHandler_EmptyUserIdLogic (t * testing.T ) {
51+ for _ , test := range EmptyUserIdTests {
52+ t .Run (test .Name , func (t * testing.T ) {
53+ t .Parallel ()
54+
55+ userId , sessionId := utils .GetDataFromBody ([]byte (test .Body ))
56+
57+ if userId == "" {
58+ response := events.APIGatewayProxyResponse {
59+ Body : test .ExpectedBody ,
60+ StatusCode : test .ExpectedStatus ,
61+ }
62+
63+ assert .Equal (t , test .ExpectedBody , response .Body , test .Description )
64+ assert .Equal (t , test .ExpectedStatus , response .StatusCode , test .Description )
65+ }
66+
67+ if test .Body == `{"userId": "", "sessionId": "session123"}` {
68+ assert .Equal (t , "session123" , sessionId )
69+ }
70+ })
71+ }
72+ }
73+
74+ func TestURLFormatting (t * testing.T ) {
75+ for _ , test := range URLFormattingTests {
76+ t .Run (test .Name , func (t * testing.T ) {
77+ t .Parallel ()
78+
79+ userUrl := test .Input
80+ if userUrl [len (userUrl )- 1 ] != '/' {
81+ userUrl = userUrl + "/"
82+ }
83+ result := userUrl + "health"
84+
85+ assert .Equal (t , test .Expected , result , test .Description )
86+ })
87+ }
88+ }
89+
90+ func TestResValidation (t * testing.T ) {
91+ for _ , test := range ResValidationTests {
92+ t .Run (test .Name , func (t * testing.T ) {
93+ t .Parallel ()
94+
95+ err := test .Res .Validate ()
96+
97+ if test .IsValid {
98+ assert .NoError (t , err , test .Description )
99+ } else {
100+ assert .Error (t , err , test .Description )
101+ }
102+ })
103+ }
104+ }
105+
106+ func TestHandlerLogicPaths (t * testing.T ) {
107+ tests := []struct {
108+ name string
109+ body string
110+ expectedResult string
111+ testLogic func (string , string ) (string , bool )
112+ }{
113+ {
114+ name : "Empty userId should trigger skip logic" ,
115+ body : `{"userId": "", "sessionId": "test"}` ,
116+ expectedResult : MockResponses .ProfileSkippedNoUserID ,
117+ testLogic : func (userId , sessionId string ) (string , bool ) {
118+ if userId == "" {
119+ return MockResponses .ProfileSkippedNoUserID , true
120+ }
121+ return "" , false
122+ },
123+ },
124+ {
125+ name : "Missing userId should trigger skip logic" ,
126+ body : `{"sessionId": "test"}` ,
127+ expectedResult : MockResponses .ProfileSkippedNoUserID ,
128+ testLogic : func (userId , sessionId string ) (string , bool ) {
129+ if userId == "" {
130+ return MockResponses .ProfileSkippedNoUserID , true
131+ }
132+ return "" , false
133+ },
134+ },
135+ {
136+ name : "Valid userId should pass first check" ,
137+ body : `{"userId": "valid-user", "sessionId": "test"}` ,
138+ expectedResult : "" ,
139+ testLogic : func (userId , sessionId string ) (string , bool ) {
140+ if userId == "" {
141+ return MockResponses .ProfileSkippedNoUserID , true
142+ }
143+ return "" , false
144+ },
145+ },
146+ }
147+
148+ for _ , test := range tests {
149+ t .Run (test .name , func (t * testing.T ) {
150+ t .Parallel ()
151+
152+ userId , sessionId := utils .GetDataFromBody ([]byte (test .body ))
153+ result , shouldReturn := test .testLogic (userId , sessionId )
154+
155+ if shouldReturn {
156+ assert .Equal (t , test .expectedResult , result )
157+ }
158+ })
159+ }
160+ }
161+
162+ func TestURLFormattingEdgeCases (t * testing.T ) {
163+ edgeCases := []struct {
164+ name string
165+ url string
166+ expected string
167+ }{
168+ {"Single char" , "a" , "a/health" },
169+ {"Two chars" , "ab" , "ab/health" },
170+ {"With slash" , "abc/" , "abc/health" },
171+ {"Complex URL" , "https://api.service.com/v1/endpoint" , "https://api.service.com/v1/endpoint/health" },
172+ }
173+
174+ for _ , test := range edgeCases {
175+ t .Run (test .name , func (t * testing.T ) {
176+ t .Parallel ()
177+
178+ assert .NotPanics (t , func () {
179+ userUrl := test .url
180+ if len (userUrl ) > 0 && userUrl [len (userUrl )- 1 ] != '/' {
181+ userUrl = userUrl + "/"
182+ }
183+ result := userUrl + "health"
184+ assert .Equal (t , test .expected , result )
185+ })
186+ })
187+ }
188+ }
189+
190+ func TestHTTPClientTimeout (t * testing.T ) {
191+ tests := []struct {
192+ name string
193+ timeout int
194+ }{
195+ {"Standard timeout" , 5 },
196+ {"Short timeout" , 2 },
197+ {"Long timeout" , 10 },
198+ }
199+
200+ for _ , test := range tests {
201+ t .Run (test .name , func (t * testing.T ) {
202+ t .Parallel ()
203+
204+ timeoutDuration := test .timeout
205+ assert .Greater (t , timeoutDuration , 0 )
206+ assert .LessOrEqual (t , timeoutDuration , 30 )
207+ })
208+ }
209+ }
210+
211+ func TestServiceRunningLogic (t * testing.T ) {
212+ tests := []struct {
213+ name string
214+ serviceError bool
215+ expectedState bool
216+ }{
217+ {"Service running" , false , true },
218+ {"Service down" , true , false },
219+ }
220+
221+ for _ , test := range tests {
222+ t .Run (test .name , func (t * testing.T ) {
223+ t .Parallel ()
224+
225+ var isServiceRunning bool
226+ if test .serviceError {
227+ isServiceRunning = false
228+ } else {
229+ isServiceRunning = true
230+ }
231+
232+ assert .Equal (t , test .expectedState , isServiceRunning )
233+ })
234+ }
235+ }
236+
237+ func TestDataExtractionPipeline (t * testing.T ) {
238+ tests := []struct {
239+ name string
240+ body string
241+ validate func (userId , sessionId string ) error
242+ }{
243+ {
244+ name : "Valid data extraction" ,
245+ body : `{"userId": "user123", "sessionId": "session456"}` ,
246+ validate : func (userId , sessionId string ) error {
247+ assert .Equal (t , "user123" , userId )
248+ assert .Equal (t , "session456" , sessionId )
249+ return nil
250+ },
251+ },
252+ {
253+ name : "Partial data extraction" ,
254+ body : `{"userId": "user123"}` ,
255+ validate : func (userId , sessionId string ) error {
256+ assert .Equal (t , "user123" , userId )
257+ assert .Equal (t , "" , sessionId )
258+ return nil
259+ },
260+ },
261+ }
262+
263+ for _ , test := range tests {
264+ t .Run (test .name , func (t * testing.T ) {
265+ t .Parallel ()
266+
267+ userId , sessionId := utils .GetDataFromBody ([]byte (test .body ))
268+ err := test .validate (userId , sessionId )
269+ assert .NoError (t , err )
270+ })
271+ }
272+ }
273+
274+ func TestResponseStructure (t * testing.T ) {
275+ responses := []struct {
276+ name string
277+ body string
278+ statusCode int
279+ }{
280+ {"Skip no user ID" , MockResponses .ProfileSkippedNoUserID , 200 },
281+ {"Skip no URL" , MockResponses .ProfileSkippedNoURL , 200 },
282+ {"Skip blocked" , MockResponses .ProfileSkippedBlocked , 200 },
283+ {"Skip service down" , MockResponses .ProfileSkippedServiceDown , 200 },
284+ {"Profile saved" , MockResponses .ProfileSaved , 200 },
285+ }
286+
287+ for _ , test := range responses {
288+ t .Run (test .name , func (t * testing.T ) {
289+ t .Parallel ()
290+
291+ response := events.APIGatewayProxyResponse {
292+ Body : test .body ,
293+ StatusCode : test .statusCode ,
294+ }
295+
296+ assert .Equal (t , test .body , response .Body )
297+ assert .Equal (t , test .statusCode , response .StatusCode )
298+ assert .IsType (t , events.APIGatewayProxyResponse {}, response )
299+ })
300+ }
301+ }
0 commit comments