@@ -4,42 +4,254 @@ import (
44 "testing"
55
66 "github.com/stretchr/testify/require"
7+
8+ "gitlab.com/postgres-ai/database-lab/v3/pkg/models"
79)
810
911func TestCustomOptions (t * testing.T ) {
1012 testCases := []struct {
1113 customOptions []interface {}
1214 expectedResult error
15+ }{
16+ {customOptions : []interface {}{"--verbose" }, expectedResult : nil },
17+ {customOptions : []interface {}{"--exclude-scheme=test_scheme" }, expectedResult : nil },
18+ {customOptions : []interface {}{`--exclude-scheme="test_scheme"` }, expectedResult : nil },
19+ {customOptions : []interface {}{"--table=$(echo 'test')" }, expectedResult : errInvalidOption },
20+ {customOptions : []interface {}{"--table=test&table" }, expectedResult : errInvalidOption },
21+ {customOptions : []interface {}{5 }, expectedResult : errInvalidOptionType },
22+ }
23+
24+ for _ , tc := range testCases {
25+ validationResult := validateCustomOptions (tc .customOptions )
26+
27+ require .ErrorIs (t , validationResult , tc .expectedResult )
28+ }
29+ }
30+
31+ func TestDetectConfigChanges (t * testing.T ) {
32+ boolTrue := true
33+ boolFalse := false
34+ port1 := uint (6000 )
35+ port2 := uint (6100 )
36+
37+ testCases := []struct {
38+ name string
39+ oldProj * models.ConfigProjection
40+ newProj * models.ConfigProjection
41+ expectedChangedSettings int
42+ expectedRestartSettings int
1343 }{
1444 {
15- customOptions : []interface {}{"--verbose" },
16- expectedResult : nil ,
45+ name : "no changes" ,
46+ oldProj : & models.ConfigProjection {Debug : & boolTrue },
47+ newProj : & models.ConfigProjection {Debug : & boolTrue },
48+ expectedChangedSettings : 0 ,
49+ expectedRestartSettings : 0 ,
1750 },
1851 {
19- customOptions : []interface {}{"--exclude-scheme=test_scheme" },
20- expectedResult : nil ,
52+ name : "debug changed" ,
53+ oldProj : & models.ConfigProjection {Debug : & boolTrue },
54+ newProj : & models.ConfigProjection {Debug : & boolFalse },
55+ expectedChangedSettings : 1 ,
56+ expectedRestartSettings : 0 ,
2157 },
2258 {
23- customOptions : []interface {}{`--exclude-scheme="test_scheme"` },
24- expectedResult : nil ,
59+ name : "port pool changed - requires restart" ,
60+ oldProj : & models.ConfigProjection {PortPoolFrom : & port1 },
61+ newProj : & models.ConfigProjection {PortPoolFrom : & port2 },
62+ expectedChangedSettings : 1 ,
63+ expectedRestartSettings : 1 ,
2564 },
2665 {
27- customOptions : []interface {}{"--table=$(echo 'test')" },
28- expectedResult : errInvalidOption ,
66+ name : "multiple changes with restart" ,
67+ oldProj : & models.ConfigProjection {Debug : & boolTrue , PortPoolFrom : & port1 },
68+ newProj : & models.ConfigProjection {Debug : & boolFalse , PortPoolFrom : & port2 },
69+ expectedChangedSettings : 2 ,
70+ expectedRestartSettings : 1 ,
2971 },
72+ }
73+
74+ for _ , tc := range testCases {
75+ t .Run (tc .name , func (t * testing.T ) {
76+ changedSettings , restartSettings := detectConfigChanges (tc .oldProj , tc .newProj )
77+ require .Equal (t , tc .expectedChangedSettings , len (changedSettings ))
78+ require .Equal (t , tc .expectedRestartSettings , len (restartSettings ))
79+ })
80+ }
81+ }
82+
83+ func TestGenerateRestartWarnings (t * testing.T ) {
84+ testCases := []struct {
85+ name string
86+ restartSettings []string
87+ expectedWarnings int
88+ }{
89+ {name : "no restart settings" , restartSettings : []string {}, expectedWarnings : 0 },
90+ {name : "one restart setting" , restartSettings : []string {"server.port" }, expectedWarnings : 1 },
91+ {name : "multiple restart settings" , restartSettings : []string {"server.port" , "provision.portPool.from" }, expectedWarnings : 2 },
92+ }
93+
94+ for _ , tc := range testCases {
95+ t .Run (tc .name , func (t * testing.T ) {
96+ warnings := generateRestartWarnings (tc .restartSettings )
97+ require .Equal (t , tc .expectedWarnings , len (warnings ))
98+ for _ , warning := range warnings {
99+ require .Equal (t , "restart" , warning .Type )
100+ require .NotEmpty (t , warning .Message )
101+ }
102+ })
103+ }
104+ }
105+
106+ func TestValidatePortPoolSettings (t * testing.T ) {
107+ validFrom := uint (6000 )
108+ validTo := uint (6100 )
109+ invalidFrom := uint (0 )
110+ invalidTo := uint (5000 )
111+
112+ testCases := []struct {
113+ name string
114+ proj * models.ConfigProjection
115+ expectErr bool
116+ }{
117+ {name : "valid port pool" , proj : & models.ConfigProjection {PortPoolFrom : & validFrom , PortPoolTo : & validTo }, expectErr : false },
118+ {name : "nil port pool" , proj : & models.ConfigProjection {}, expectErr : false },
119+ {name : "invalid from port" , proj : & models.ConfigProjection {PortPoolFrom : & invalidFrom , PortPoolTo : & validTo }, expectErr : true },
120+ {name : "from greater than to" , proj : & models.ConfigProjection {PortPoolFrom : & validTo , PortPoolTo : & invalidTo }, expectErr : true },
121+ }
122+
123+ for _ , tc := range testCases {
124+ t .Run (tc .name , func (t * testing.T ) {
125+ err := validatePortPoolSettings (tc .proj )
126+ if tc .expectErr {
127+ require .Error (t , err )
128+ } else {
129+ require .NoError (t , err )
130+ }
131+ })
132+ }
133+ }
134+
135+ func TestValidateDiagnosticSettings (t * testing.T ) {
136+ validDays := 30
137+ negativeDays := - 1
138+
139+ testCases := []struct {
140+ name string
141+ proj * models.ConfigProjection
142+ expectErr bool
143+ }{
144+ {name : "valid retention days" , proj : & models.ConfigProjection {LogsRetentionDays : & validDays }, expectErr : false },
145+ {name : "nil retention days" , proj : & models.ConfigProjection {}, expectErr : false },
146+ {name : "negative retention days" , proj : & models.ConfigProjection {LogsRetentionDays : & negativeDays }, expectErr : true },
147+ }
148+
149+ for _ , tc := range testCases {
150+ t .Run (tc .name , func (t * testing.T ) {
151+ err := validateDiagnosticSettings (tc .proj )
152+ if tc .expectErr {
153+ require .Error (t , err )
154+ } else {
155+ require .NoError (t , err )
156+ }
157+ })
158+ }
159+ }
160+
161+ func TestValidateEmbeddedUISettings (t * testing.T ) {
162+ validPort := 2345
163+ invalidPortLow := 0
164+ invalidPortHigh := 70000
165+
166+ testCases := []struct {
167+ name string
168+ proj * models.ConfigProjection
169+ expectErr bool
170+ }{
171+ {name : "valid port" , proj : & models.ConfigProjection {EmbeddedUIPort : & validPort }, expectErr : false },
172+ {name : "nil port" , proj : & models.ConfigProjection {}, expectErr : false },
173+ {name : "port too low" , proj : & models.ConfigProjection {EmbeddedUIPort : & invalidPortLow }, expectErr : true },
174+ {name : "port too high" , proj : & models.ConfigProjection {EmbeddedUIPort : & invalidPortHigh }, expectErr : true },
175+ }
176+
177+ for _ , tc := range testCases {
178+ t .Run (tc .name , func (t * testing.T ) {
179+ err := validateEmbeddedUISettings (tc .proj )
180+ if tc .expectErr {
181+ require .Error (t , err )
182+ } else {
183+ require .NoError (t , err )
184+ }
185+ })
186+ }
187+ }
188+
189+ func TestValidateWebhookSettings (t * testing.T ) {
190+ testCases := []struct {
191+ name string
192+ proj * models.ConfigProjection
193+ expectErr bool
194+ }{
195+ {name : "no webhooks" , proj : & models.ConfigProjection {}, expectErr : false },
30196 {
31- customOptions : []interface {}{"--table=test&table" },
32- expectedResult : errInvalidOption ,
197+ name : "valid webhook" ,
198+ proj : & models.ConfigProjection {
199+ WebhooksHooks : []models.WebhookHookProjection {{URL : "http://example.com" , Trigger : []string {"clone.created" }}},
200+ },
201+ expectErr : false ,
33202 },
34203 {
35- customOptions : []interface {}{5 },
36- expectedResult : errInvalidOptionType ,
204+ name : "empty url" ,
205+ proj : & models.ConfigProjection {
206+ WebhooksHooks : []models.WebhookHookProjection {{URL : "" , Trigger : []string {"clone.created" }}},
207+ },
208+ expectErr : true ,
209+ },
210+ {
211+ name : "empty trigger" ,
212+ proj : & models.ConfigProjection {
213+ WebhooksHooks : []models.WebhookHookProjection {{URL : "http://example.com" , Trigger : []string {}}},
214+ },
215+ expectErr : true ,
216+ },
217+ {
218+ name : "invalid trigger" ,
219+ proj : & models.ConfigProjection {
220+ WebhooksHooks : []models.WebhookHookProjection {{URL : "http://example.com" , Trigger : []string {"invalid.trigger" }}},
221+ },
222+ expectErr : true ,
37223 },
38224 }
39225
40226 for _ , tc := range testCases {
41- validationResult := validateCustomOptions (tc .customOptions )
227+ t .Run (tc .name , func (t * testing.T ) {
228+ err := validateWebhookSettings (tc .proj )
229+ if tc .expectErr {
230+ require .Error (t , err )
231+ } else {
232+ require .NoError (t , err )
233+ }
234+ })
235+ }
236+ }
42237
43- require .ErrorIs (t , validationResult , tc .expectedResult )
238+ func TestHasRetrievalSettings (t * testing.T ) {
239+ testCases := []struct {
240+ name string
241+ objMap map [string ]interface {}
242+ expected bool
243+ }{
244+ {name : "empty map" , objMap : map [string ]interface {}{}, expected : false },
245+ {name : "has debug only" , objMap : map [string ]interface {}{"debug" : true }, expected : false },
246+ {name : "has host" , objMap : map [string ]interface {}{"host" : "localhost" }, expected : true },
247+ {name : "has timetable" , objMap : map [string ]interface {}{"timetable" : "0 0 * * *" }, expected : true },
248+ {name : "has databases" , objMap : map [string ]interface {}{"databases" : []string {"db1" }}, expected : true },
249+ }
250+
251+ for _ , tc := range testCases {
252+ t .Run (tc .name , func (t * testing.T ) {
253+ result := hasRetrievalSettings (tc .objMap )
254+ require .Equal (t , tc .expected , result )
255+ })
44256 }
45257}
0 commit comments