options_parsing_test.go 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package config // import "miniflux.app/v2/internal/config"
  4. import (
  5. "slices"
  6. "testing"
  7. )
  8. func TestBaseURLOptionParsing(t *testing.T) {
  9. configParser := NewConfigParser()
  10. if configParser.options.BaseURL() != "http://localhost" {
  11. t.Fatalf("Expected BASE_URL to be 'http://localhost' by default")
  12. }
  13. if configParser.options.RootURL() != "http://localhost" {
  14. t.Fatalf("Expected ROOT_URL to be 'http://localhost' by default")
  15. }
  16. if configParser.options.BasePath() != "" {
  17. t.Fatalf("Expected BASE_PATH to be empty by default")
  18. }
  19. if err := configParser.parseLines([]string{"BASE_URL=https://example.com/app"}); err != nil {
  20. t.Fatalf("Unexpected error: %v", err)
  21. }
  22. if configParser.options.BaseURL() != "https://example.com/app" {
  23. t.Fatalf("Expected BASE_URL to be 'https://example.com/app', got '%s'", configParser.options.BaseURL())
  24. }
  25. if configParser.options.RootURL() != "https://example.com" {
  26. t.Fatalf("Expected ROOT_URL to be 'https://example.com', got '%s'", configParser.options.RootURL())
  27. }
  28. if configParser.options.BasePath() != "/app" {
  29. t.Fatalf("Expected BASE_PATH to be '/app', got '%s'", configParser.options.BasePath())
  30. }
  31. if err := configParser.parseLines([]string{"BASE_URL=https://example.com/app/"}); err != nil {
  32. t.Fatalf("Unexpected error: %v", err)
  33. }
  34. if configParser.options.BaseURL() != "https://example.com/app" {
  35. t.Fatalf("Expected BASE_URL to be 'https://example.com/app', got '%s'", configParser.options.BaseURL())
  36. }
  37. if configParser.options.RootURL() != "https://example.com" {
  38. t.Fatalf("Expected ROOT_URL to be 'https://example.com', got '%s'", configParser.options.RootURL())
  39. }
  40. if configParser.options.BasePath() != "/app" {
  41. t.Fatalf("Expected BASE_PATH to be '/app', got '%s'", configParser.options.BasePath())
  42. }
  43. if err := configParser.parseLines([]string{"BASE_URL=example.com/app/"}); err == nil {
  44. t.Fatal("Expected an error due to missing scheme in BASE_URL")
  45. }
  46. }
  47. func TestWatchdogOptionParsing(t *testing.T) {
  48. configParser := NewConfigParser()
  49. if !configParser.options.Watchdog() {
  50. t.Fatal("Expected WATCHDOG to be enabled by default")
  51. }
  52. if !configParser.options.HasSchedulerService() {
  53. t.Fatal("Expected HAS_SCHEDULER_SERVICE to be enabled by default")
  54. }
  55. if err := configParser.parseLines([]string{"WATCHDOG=1"}); err != nil {
  56. t.Fatal("Unexpected error:", err)
  57. }
  58. if !configParser.options.Watchdog() {
  59. t.Fatal("Expected WATCHDOG to be enabled")
  60. }
  61. if !configParser.options.HasSchedulerService() {
  62. t.Fatal("Expected HAS_SCHEDULER_SERVICE to be enabled")
  63. }
  64. if err := configParser.parseLines([]string{"WATCHDOG=0"}); err != nil {
  65. t.Fatal("Unexpected error:", err)
  66. }
  67. if configParser.options.Watchdog() {
  68. t.Fatal("Expected WATCHDOG to be disabled")
  69. }
  70. if configParser.options.HasWatchdog() {
  71. t.Fatal("Expected HAS_WATCHDOG to be disabled")
  72. }
  73. }
  74. func TestWebAuthnOptionParsing(t *testing.T) {
  75. configParser := NewConfigParser()
  76. if configParser.options.WebAuthn() {
  77. t.Fatalf("Expected WEBAUTHN to be disabled by default")
  78. }
  79. if err := configParser.parseLines([]string{"WEBAUTHN=1"}); err != nil {
  80. t.Fatalf("Unexpected error: %v", err)
  81. }
  82. if !configParser.options.WebAuthn() {
  83. t.Fatalf("Expected WEBAUTHN to be enabled")
  84. }
  85. }
  86. func TestWorkerPoolSizeOptionParsing(t *testing.T) {
  87. configParser := NewConfigParser()
  88. if configParser.options.WorkerPoolSize() != 16 {
  89. t.Fatalf("Expected WORKER_POOL_SIZE to be 16 by default")
  90. }
  91. if err := configParser.parseLines([]string{"WORKER_POOL_SIZE=8"}); err != nil {
  92. t.Fatalf("Unexpected error: %v", err)
  93. }
  94. if configParser.options.WorkerPoolSize() != 8 {
  95. t.Fatalf("Expected WORKER_POOL_SIZE to be 8")
  96. }
  97. }
  98. func TestYouTubeAPIKeyOptionParsing(t *testing.T) {
  99. configParser := NewConfigParser()
  100. if configParser.options.YouTubeAPIKey() != "" {
  101. t.Fatalf("Expected YOUTUBE_API_KEY to be empty by default")
  102. }
  103. if err := configParser.parseLines([]string{"YOUTUBE_API_KEY=somekey"}); err != nil {
  104. t.Fatalf("Unexpected error: %v", err)
  105. }
  106. if configParser.options.YouTubeAPIKey() != "somekey" {
  107. t.Fatalf("Expected YOUTUBE_API_KEY to be 'somekey'")
  108. }
  109. }
  110. func TestAdminPasswordOptionParsing(t *testing.T) {
  111. configParser := NewConfigParser()
  112. if configParser.options.AdminPassword() != "" {
  113. t.Fatalf("Expected ADMIN_PASSWORD to be empty by default")
  114. }
  115. if err := configParser.parseLines([]string{"ADMIN_PASSWORD=secret123"}); err != nil {
  116. t.Fatalf("Unexpected error: %v", err)
  117. }
  118. if configParser.options.AdminPassword() != "secret123" {
  119. t.Fatalf("Expected ADMIN_PASSWORD to be 'secret123'")
  120. }
  121. }
  122. func TestAdminUsernameOptionParsing(t *testing.T) {
  123. configParser := NewConfigParser()
  124. if configParser.options.AdminUsername() != "" {
  125. t.Fatalf("Expected ADMIN_USERNAME to be empty by default")
  126. }
  127. if err := configParser.parseLines([]string{"ADMIN_USERNAME=admin"}); err != nil {
  128. t.Fatalf("Unexpected error: %v", err)
  129. }
  130. if configParser.options.AdminUsername() != "admin" {
  131. t.Fatalf("Expected ADMIN_USERNAME to be 'admin'")
  132. }
  133. }
  134. func TestAuthProxyHeaderOptionParsing(t *testing.T) {
  135. configParser := NewConfigParser()
  136. if configParser.options.AuthProxyHeader() != "" {
  137. t.Fatalf("Expected AUTH_PROXY_HEADER to be empty by default")
  138. }
  139. if err := configParser.parseLines([]string{"AUTH_PROXY_HEADER=X-Forwarded-User"}); err != nil {
  140. t.Fatalf("Unexpected error: %v", err)
  141. }
  142. if configParser.options.AuthProxyHeader() != "X-Forwarded-User" {
  143. t.Fatalf("Expected AUTH_PROXY_HEADER to be 'X-Forwarded-User'")
  144. }
  145. }
  146. func TestAuthProxyUserCreationOptionParsing(t *testing.T) {
  147. configParser := NewConfigParser()
  148. if configParser.options.AuthProxyUserCreation() {
  149. t.Fatal("Expected AUTH_PROXY_USER_CREATION to be disabled by default")
  150. }
  151. if configParser.options.IsAuthProxyUserCreationAllowed() {
  152. t.Fatal("Expected HAS_AUTH_PROXY_USER_CREATION to be disabled by default")
  153. }
  154. if err := configParser.parseLines([]string{"AUTH_PROXY_USER_CREATION=1"}); err != nil {
  155. t.Fatalf("Unexpected error: %v", err)
  156. }
  157. if !configParser.options.AuthProxyUserCreation() {
  158. t.Fatal("Expected AUTH_PROXY_USER_CREATION to be enabled")
  159. }
  160. if !configParser.options.IsAuthProxyUserCreationAllowed() {
  161. t.Fatal("Expected HAS_AUTH_PROXY_USER_CREATION to be enabled")
  162. }
  163. if err := configParser.parseLines([]string{"AUTH_PROXY_USER_CREATION=0"}); err != nil {
  164. t.Fatalf("Unexpected error: %v", err)
  165. }
  166. if configParser.options.AuthProxyUserCreation() {
  167. t.Fatal("Expected AUTH_PROXY_USER_CREATION to be disabled")
  168. }
  169. if configParser.options.IsAuthProxyUserCreationAllowed() {
  170. t.Fatal("Expected HAS_AUTH_PROXY_USER_CREATION to be disabled")
  171. }
  172. }
  173. func TestBatchSizeOptionParsing(t *testing.T) {
  174. configParser := NewConfigParser()
  175. if configParser.options.BatchSize() != 100 {
  176. t.Fatalf("Expected BATCH_SIZE to be 100 by default")
  177. }
  178. if err := configParser.parseLines([]string{"BATCH_SIZE=50"}); err != nil {
  179. t.Fatalf("Unexpected error: %v", err)
  180. }
  181. if configParser.options.BatchSize() != 50 {
  182. t.Fatalf("Expected BATCH_SIZE to be 50")
  183. }
  184. }
  185. func TestCertDomainOptionParsing(t *testing.T) {
  186. configParser := NewConfigParser()
  187. if configParser.options.CertDomain() != "" {
  188. t.Fatalf("Expected CERT_DOMAIN to be empty by default")
  189. }
  190. if err := configParser.parseLines([]string{"CERT_DOMAIN=example.com"}); err != nil {
  191. t.Fatalf("Unexpected error: %v", err)
  192. }
  193. if configParser.options.CertDomain() != "example.com" {
  194. t.Fatalf("Expected CERT_DOMAIN to be 'example.com'")
  195. }
  196. }
  197. func TestCertFileOptionParsing(t *testing.T) {
  198. configParser := NewConfigParser()
  199. if configParser.options.CertFile() != "" {
  200. t.Fatalf("Expected CERT_FILE to be empty by default")
  201. }
  202. if err := configParser.parseLines([]string{"CERT_FILE=/path/to/cert.pem"}); err != nil {
  203. t.Fatalf("Unexpected error: %v", err)
  204. }
  205. if configParser.options.CertFile() != "/path/to/cert.pem" {
  206. t.Fatalf("Expected CERT_FILE to be '/path/to/cert.pem'")
  207. }
  208. }
  209. func TestCleanupArchiveBatchSizeOptionParsing(t *testing.T) {
  210. configParser := NewConfigParser()
  211. if configParser.options.CleanupArchiveBatchSize() != 10000 {
  212. t.Fatalf("Expected CLEANUP_ARCHIVE_BATCH_SIZE to be 10000 by default")
  213. }
  214. if err := configParser.parseLines([]string{"CLEANUP_ARCHIVE_BATCH_SIZE=5000"}); err != nil {
  215. t.Fatalf("Unexpected error: %v", err)
  216. }
  217. if configParser.options.CleanupArchiveBatchSize() != 5000 {
  218. t.Fatalf("Expected CLEANUP_ARCHIVE_BATCH_SIZE to be 5000")
  219. }
  220. }
  221. func TestCreateAdminOptionParsing(t *testing.T) {
  222. configParser := NewConfigParser()
  223. if configParser.options.CreateAdmin() {
  224. t.Fatalf("Expected CREATE_ADMIN to be disabled by default")
  225. }
  226. if err := configParser.parseLines([]string{"CREATE_ADMIN=1"}); err != nil {
  227. t.Fatalf("Unexpected error: %v", err)
  228. }
  229. if !configParser.options.CreateAdmin() {
  230. t.Fatalf("Expected CREATE_ADMIN to be enabled")
  231. }
  232. if err := configParser.parseLines([]string{"CREATE_ADMIN=0"}); err != nil {
  233. t.Fatalf("Unexpected error: %v", err)
  234. }
  235. if configParser.options.CreateAdmin() {
  236. t.Fatalf("Expected CREATE_ADMIN to be disabled")
  237. }
  238. }
  239. func TestDatabaseMaxConnsOptionParsing(t *testing.T) {
  240. configParser := NewConfigParser()
  241. if configParser.options.DatabaseMaxConns() != 20 {
  242. t.Fatalf("Expected DATABASE_MAX_CONNS to be 20 by default")
  243. }
  244. if err := configParser.parseLines([]string{"DATABASE_MAX_CONNS=10"}); err != nil {
  245. t.Fatalf("Unexpected error: %v", err)
  246. }
  247. if configParser.options.DatabaseMaxConns() != 10 {
  248. t.Fatalf("Expected DATABASE_MAX_CONNS to be 10")
  249. }
  250. }
  251. func TestDatabaseMinConnsOptionParsing(t *testing.T) {
  252. configParser := NewConfigParser()
  253. if configParser.options.DatabaseMinConns() != 1 {
  254. t.Fatalf("Expected DATABASE_MIN_CONNS to be 1 by default")
  255. }
  256. if err := configParser.parseLines([]string{"DATABASE_MIN_CONNS=2"}); err != nil {
  257. t.Fatalf("Unexpected error: %v", err)
  258. }
  259. if configParser.options.DatabaseMinConns() != 2 {
  260. t.Fatalf("Expected DATABASE_MIN_CONNS to be 2")
  261. }
  262. }
  263. func TestDatabaseURLOptionParsing(t *testing.T) {
  264. configParser := NewConfigParser()
  265. if configParser.options.DatabaseURL() != "user=postgres password=postgres dbname=miniflux2 sslmode=disable" {
  266. t.Fatal("Expected DATABASE_URL to have default value")
  267. }
  268. if !configParser.options.IsDefaultDatabaseURL() {
  269. t.Fatal("Expected DATABASE_URL to be the default value")
  270. }
  271. if err := configParser.parseLines([]string{"DATABASE_URL=postgres://user:pass@localhost/db"}); err != nil {
  272. t.Fatalf("Unexpected error: %v", err)
  273. }
  274. if configParser.options.DatabaseURL() != "postgres://user:pass@localhost/db" {
  275. t.Fatal("Expected DATABASE_URL to be 'postgres://user:pass@localhost/db'")
  276. }
  277. if configParser.options.IsDefaultDatabaseURL() {
  278. t.Fatal("Expected DATABASE_URL to not be the default value")
  279. }
  280. }
  281. func TestDisableHSTSOptionParsing(t *testing.T) {
  282. configParser := NewConfigParser()
  283. if configParser.options.DisableHSTS() {
  284. t.Fatal("Expected DISABLE_HSTS to be disabled by default")
  285. }
  286. if !configParser.options.HasHSTS() {
  287. t.Fatal("Expected HAS_HSTS to be enabled by default")
  288. }
  289. if err := configParser.parseLines([]string{"DISABLE_HSTS=1"}); err != nil {
  290. t.Fatalf("Unexpected error: %v", err)
  291. }
  292. if !configParser.options.DisableHSTS() {
  293. t.Fatal("Expected DISABLE_HSTS to be enabled")
  294. }
  295. if configParser.options.HasHSTS() {
  296. t.Fatal("Expected HAS_HSTS to be disabled")
  297. }
  298. if err := configParser.parseLines([]string{"DISABLE_HSTS=0"}); err != nil {
  299. t.Fatalf("Unexpected error: %v", err)
  300. }
  301. if configParser.options.DisableHSTS() {
  302. t.Fatal("Expected DISABLE_HSTS to be disabled")
  303. }
  304. if !configParser.options.HasHSTS() {
  305. t.Fatal("Expected HAS_HSTS to be enabled")
  306. }
  307. }
  308. func TestDisableHTTPServiceOptionParsing(t *testing.T) {
  309. configParser := NewConfigParser()
  310. if configParser.options.DisableHTTPService() {
  311. t.Fatal("Expected DISABLE_HTTP_SERVICE to be disabled by default")
  312. }
  313. if !configParser.options.HasHTTPService() {
  314. t.Fatal("Expected HAS_HTTP_SERVICE to be enabled by default")
  315. }
  316. if err := configParser.parseLines([]string{"DISABLE_HTTP_SERVICE=1"}); err != nil {
  317. t.Fatalf("Unexpected error: %v", err)
  318. }
  319. if !configParser.options.DisableHTTPService() {
  320. t.Fatal("Expected DISABLE_HTTP_SERVICE to be enabled")
  321. }
  322. if configParser.options.HasHTTPService() {
  323. t.Fatal("Expected HAS_HTTP_SERVICE to be disabled")
  324. }
  325. if err := configParser.parseLines([]string{"DISABLE_HTTP_SERVICE=0"}); err != nil {
  326. t.Fatalf("Unexpected error: %v", err)
  327. }
  328. if configParser.options.DisableHTTPService() {
  329. t.Fatal("Expected DISABLE_HTTP_SERVICE to be disabled")
  330. }
  331. if !configParser.options.HasHTTPService() {
  332. t.Fatal("Expected HAS_HTTP_SERVICE to be disabled")
  333. }
  334. }
  335. func TestDisableLocalAuthOptionParsing(t *testing.T) {
  336. configParser := NewConfigParser()
  337. if configParser.options.DisableLocalAuth() {
  338. t.Fatalf("Expected DISABLE_LOCAL_AUTH to be disabled by default")
  339. }
  340. if err := configParser.parseLines([]string{"DISABLE_LOCAL_AUTH=1"}); err != nil {
  341. t.Fatalf("Unexpected error: %v", err)
  342. }
  343. if !configParser.options.DisableLocalAuth() {
  344. t.Fatalf("Expected DISABLE_LOCAL_AUTH to be enabled")
  345. }
  346. if err := configParser.parseLines([]string{"DISABLE_LOCAL_AUTH=0"}); err != nil {
  347. t.Fatalf("Unexpected error: %v", err)
  348. }
  349. if configParser.options.DisableLocalAuth() {
  350. t.Fatalf("Expected DISABLE_LOCAL_AUTH to be disabled")
  351. }
  352. }
  353. func TestDisableSchedulerServiceOptionParsing(t *testing.T) {
  354. configParser := NewConfigParser()
  355. if configParser.options.DisableSchedulerService() {
  356. t.Fatal("Expected DISABLE_SCHEDULER_SERVICE to be disabled by default")
  357. }
  358. if !configParser.options.HasSchedulerService() {
  359. t.Fatal("Expected HAS_SCHEDULER_SERVICE to be enabled by default")
  360. }
  361. if err := configParser.parseLines([]string{"DISABLE_SCHEDULER_SERVICE=1"}); err != nil {
  362. t.Fatalf("Unexpected error: %v", err)
  363. }
  364. if !configParser.options.DisableSchedulerService() {
  365. t.Fatal("Expected DISABLE_SCHEDULER_SERVICE to be enabled")
  366. }
  367. if configParser.options.HasSchedulerService() {
  368. t.Fatal("Expected HAS_SCHEDULER_SERVICE to be disabled")
  369. }
  370. if err := configParser.parseLines([]string{"DISABLE_SCHEDULER_SERVICE=0"}); err != nil {
  371. t.Fatalf("Unexpected error: %v", err)
  372. }
  373. if configParser.options.DisableSchedulerService() {
  374. t.Fatal("Expected DISABLE_SCHEDULER_SERVICE to be disabled")
  375. }
  376. if !configParser.options.HasSchedulerService() {
  377. t.Fatal("Expected HAS_SCHEDULER_SERVICE to be enabled")
  378. }
  379. }
  380. func TestFetchBilibiliWatchTimeOptionParsing(t *testing.T) {
  381. configParser := NewConfigParser()
  382. if configParser.options.FetchBilibiliWatchTime() {
  383. t.Fatalf("Expected FETCH_BILIBILI_WATCH_TIME to be disabled by default")
  384. }
  385. if err := configParser.parseLines([]string{"FETCH_BILIBILI_WATCH_TIME=1"}); err != nil {
  386. t.Fatalf("Unexpected error: %v", err)
  387. }
  388. if !configParser.options.FetchBilibiliWatchTime() {
  389. t.Fatalf("Expected FETCH_BILIBILI_WATCH_TIME to be enabled")
  390. }
  391. if err := configParser.parseLines([]string{"FETCH_BILIBILI_WATCH_TIME=0"}); err != nil {
  392. t.Fatalf("Unexpected error: %v", err)
  393. }
  394. if configParser.options.FetchBilibiliWatchTime() {
  395. t.Fatalf("Expected FETCH_BILIBILI_WATCH_TIME to be disabled")
  396. }
  397. }
  398. func TestFetchNebulaWatchTimeOptionParsing(t *testing.T) {
  399. configParser := NewConfigParser()
  400. if configParser.options.FetchNebulaWatchTime() {
  401. t.Fatalf("Expected FETCH_NEBULA_WATCH_TIME to be disabled by default")
  402. }
  403. if err := configParser.parseLines([]string{"FETCH_NEBULA_WATCH_TIME=1"}); err != nil {
  404. t.Fatalf("Unexpected error: %v", err)
  405. }
  406. if !configParser.options.FetchNebulaWatchTime() {
  407. t.Fatalf("Expected FETCH_NEBULA_WATCH_TIME to be enabled")
  408. }
  409. if err := configParser.parseLines([]string{"FETCH_NEBULA_WATCH_TIME=0"}); err != nil {
  410. t.Fatalf("Unexpected error: %v", err)
  411. }
  412. if configParser.options.FetchNebulaWatchTime() {
  413. t.Fatalf("Expected FETCH_NEBULA_WATCH_TIME to be disabled")
  414. }
  415. }
  416. func TestFetchOdyseeWatchTimeOptionParsing(t *testing.T) {
  417. configParser := NewConfigParser()
  418. if configParser.options.FetchOdyseeWatchTime() {
  419. t.Fatalf("Expected FETCH_ODYSEE_WATCH_TIME to be disabled by default")
  420. }
  421. if err := configParser.parseLines([]string{"FETCH_ODYSEE_WATCH_TIME=1"}); err != nil {
  422. t.Fatalf("Unexpected error: %v", err)
  423. }
  424. if !configParser.options.FetchOdyseeWatchTime() {
  425. t.Fatalf("Expected FETCH_ODYSEE_WATCH_TIME to be enabled")
  426. }
  427. if err := configParser.parseLines([]string{"FETCH_ODYSEE_WATCH_TIME=0"}); err != nil {
  428. t.Fatalf("Unexpected error: %v", err)
  429. }
  430. if configParser.options.FetchOdyseeWatchTime() {
  431. t.Fatalf("Expected FETCH_ODYSEE_WATCH_TIME to be disabled")
  432. }
  433. }
  434. func TestFetchYouTubeWatchTimeOptionParsing(t *testing.T) {
  435. configParser := NewConfigParser()
  436. if configParser.options.FetchYouTubeWatchTime() {
  437. t.Fatalf("Expected FETCH_YOUTUBE_WATCH_TIME to be disabled by default")
  438. }
  439. if err := configParser.parseLines([]string{"FETCH_YOUTUBE_WATCH_TIME=1"}); err != nil {
  440. t.Fatalf("Unexpected error: %v", err)
  441. }
  442. if !configParser.options.FetchYouTubeWatchTime() {
  443. t.Fatalf("Expected FETCH_YOUTUBE_WATCH_TIME to be enabled")
  444. }
  445. if err := configParser.parseLines([]string{"FETCH_YOUTUBE_WATCH_TIME=0"}); err != nil {
  446. t.Fatalf("Unexpected error: %v", err)
  447. }
  448. if configParser.options.FetchYouTubeWatchTime() {
  449. t.Fatalf("Expected FETCH_YOUTUBE_WATCH_TIME to be disabled")
  450. }
  451. }
  452. func TestHTTPClientMaxBodySizeOptionParsing(t *testing.T) {
  453. configParser := NewConfigParser()
  454. if configParser.options.HTTPClientMaxBodySize() != 15*1024*1024 {
  455. t.Fatalf("Expected HTTP_CLIENT_MAX_BODY_SIZE to be 15 by default, got %d", configParser.options.HTTPClientMaxBodySize())
  456. }
  457. if err := configParser.parseLines([]string{"HTTP_CLIENT_MAX_BODY_SIZE=25"}); err != nil {
  458. t.Fatalf("Unexpected error: %v", err)
  459. }
  460. expectedValue := 25 * 1024 * 1024
  461. currentValue := configParser.options.HTTPClientMaxBodySize()
  462. if currentValue != int64(expectedValue) {
  463. t.Fatalf("Expected HTTP_CLIENT_MAX_BODY_SIZE to be %d, got %d", expectedValue, currentValue)
  464. }
  465. }
  466. func TestHTTPClientUserAgentOptionParsing(t *testing.T) {
  467. configParser := NewConfigParser()
  468. if configParser.options.HTTPClientUserAgent() != defaultHTTPClientUserAgent {
  469. t.Fatalf("Expected HTTP_CLIENT_USER_AGENT to have default value")
  470. }
  471. if err := configParser.parseLines([]string{"HTTP_CLIENT_USER_AGENT=Custom User Agent"}); err != nil {
  472. t.Fatalf("Unexpected error: %v", err)
  473. }
  474. if configParser.options.HTTPClientUserAgent() != "Custom User Agent" {
  475. t.Fatalf("Expected HTTP_CLIENT_USER_AGENT to be 'Custom User Agent'")
  476. }
  477. }
  478. func TestHTTPSOptionParsing(t *testing.T) {
  479. configParser := NewConfigParser()
  480. if configParser.options.HTTPS() {
  481. t.Fatalf("Expected HTTPS to be disabled by default")
  482. }
  483. if err := configParser.parseLines([]string{"HTTPS=1"}); err != nil {
  484. t.Fatalf("Unexpected error: %v", err)
  485. }
  486. if !configParser.options.HTTPS() {
  487. t.Fatalf("Expected HTTPS to be enabled")
  488. }
  489. if err := configParser.parseLines([]string{"HTTPS=0"}); err != nil {
  490. t.Fatalf("Unexpected error: %v", err)
  491. }
  492. if configParser.options.HTTPS() {
  493. t.Fatalf("Expected HTTPS to be disabled")
  494. }
  495. }
  496. func TestInvidiousInstanceOptionParsing(t *testing.T) {
  497. configParser := NewConfigParser()
  498. if configParser.options.InvidiousInstance() != "yewtu.be" {
  499. t.Fatalf("Expected INVIDIOUS_INSTANCE to be 'yewtu.be' by default")
  500. }
  501. if err := configParser.parseLines([]string{"INVIDIOUS_INSTANCE=invidious.example.com"}); err != nil {
  502. t.Fatalf("Unexpected error: %v", err)
  503. }
  504. if configParser.options.InvidiousInstance() != "invidious.example.com" {
  505. t.Fatalf("Expected INVIDIOUS_INSTANCE to be 'invidious.example.com'")
  506. }
  507. }
  508. func TestCertKeyFileOptionParsing(t *testing.T) {
  509. configParser := NewConfigParser()
  510. if configParser.options.CertKeyFile() != "" {
  511. t.Fatalf("Expected KEY_FILE to be empty by default")
  512. }
  513. if err := configParser.parseLines([]string{"KEY_FILE=/path/to/key.pem"}); err != nil {
  514. t.Fatalf("Unexpected error: %v", err)
  515. }
  516. if configParser.options.CertKeyFile() != "/path/to/key.pem" {
  517. t.Fatalf("Expected KEY_FILE to be '/path/to/key.pem'")
  518. }
  519. }
  520. func TestLogDateTimeOptionParsing(t *testing.T) {
  521. configParser := NewConfigParser()
  522. if configParser.options.LogDateTime() {
  523. t.Fatalf("Expected LOG_DATE_TIME to be disabled by default")
  524. }
  525. if err := configParser.parseLines([]string{"LOG_DATE_TIME=1"}); err != nil {
  526. t.Fatalf("Unexpected error: %v", err)
  527. }
  528. if !configParser.options.LogDateTime() {
  529. t.Fatalf("Expected LOG_DATE_TIME to be enabled")
  530. }
  531. if err := configParser.parseLines([]string{"LOG_DATE_TIME=0"}); err != nil {
  532. t.Fatalf("Unexpected error: %v", err)
  533. }
  534. if configParser.options.LogDateTime() {
  535. t.Fatalf("Expected LOG_DATE_TIME to be disabled")
  536. }
  537. }
  538. func TestLogFileOptionParsing(t *testing.T) {
  539. configParser := NewConfigParser()
  540. if configParser.options.LogFile() != "stderr" {
  541. t.Fatalf("Expected LOG_FILE to be 'stderr' by default")
  542. }
  543. if err := configParser.parseLines([]string{"LOG_FILE=/var/log/miniflux.log"}); err != nil {
  544. t.Fatalf("Unexpected error: %v", err)
  545. }
  546. if configParser.options.LogFile() != "/var/log/miniflux.log" {
  547. t.Fatalf("Expected LOG_FILE to be '/var/log/miniflux.log'")
  548. }
  549. }
  550. func TestLogFormatOptionParsing(t *testing.T) {
  551. configParser := NewConfigParser()
  552. if configParser.options.LogFormat() != "text" {
  553. t.Fatalf("Expected LOG_FORMAT to be 'text' by default")
  554. }
  555. if err := configParser.parseLines([]string{"LOG_FORMAT=json"}); err != nil {
  556. t.Fatalf("Unexpected error: %v", err)
  557. }
  558. if configParser.options.LogFormat() != "json" {
  559. t.Fatalf("Expected LOG_FORMAT to be 'json'")
  560. }
  561. }
  562. func TestLogLevelOptionParsing(t *testing.T) {
  563. configParser := NewConfigParser()
  564. if configParser.options.LogLevel() != "info" {
  565. t.Fatalf("Expected LOG_LEVEL to be 'info' by default")
  566. }
  567. if err := configParser.parseLines([]string{"LOG_LEVEL=debug"}); err != nil {
  568. t.Fatalf("Unexpected error: %v", err)
  569. }
  570. if configParser.options.LogLevel() != "debug" {
  571. t.Fatalf("Expected LOG_LEVEL to be 'debug'")
  572. }
  573. }
  574. func TestMaintenanceMessageOptionParsing(t *testing.T) {
  575. configParser := NewConfigParser()
  576. if configParser.options.MaintenanceMessage() != "Miniflux is currently under maintenance" {
  577. t.Fatalf("Expected MAINTENANCE_MESSAGE to have default value")
  578. }
  579. if err := configParser.parseLines([]string{"MAINTENANCE_MESSAGE=System upgrade in progress"}); err != nil {
  580. t.Fatalf("Unexpected error: %v", err)
  581. }
  582. if configParser.options.MaintenanceMessage() != "System upgrade in progress" {
  583. t.Fatalf("Expected MAINTENANCE_MESSAGE to be 'System upgrade in progress'")
  584. }
  585. }
  586. func TestMaintenanceModeOptionParsing(t *testing.T) {
  587. configParser := NewConfigParser()
  588. if configParser.options.MaintenanceMode() {
  589. t.Fatal("Expected MAINTENANCE_MODE to be disabled by default")
  590. }
  591. if configParser.options.HasMaintenanceMode() {
  592. t.Fatal("Expected HAS_MAINTENANCE_MODE to be disabled by default")
  593. }
  594. if err := configParser.parseLines([]string{"MAINTENANCE_MODE=1"}); err != nil {
  595. t.Fatalf("Unexpected error: %v", err)
  596. }
  597. if !configParser.options.MaintenanceMode() {
  598. t.Fatal("Expected MAINTENANCE_MODE to be enabled")
  599. }
  600. if !configParser.options.HasMaintenanceMode() {
  601. t.Fatal("Expected HAS_MAINTENANCE_MODE to be enabled")
  602. }
  603. if err := configParser.parseLines([]string{"MAINTENANCE_MODE=0"}); err != nil {
  604. t.Fatalf("Unexpected error: %v", err)
  605. }
  606. if configParser.options.MaintenanceMode() {
  607. t.Fatal("Expected MAINTENANCE_MODE to be disabled")
  608. }
  609. if configParser.options.HasMaintenanceMode() {
  610. t.Fatal("Expected HAS_MAINTENANCE_MODE to be disabled")
  611. }
  612. }
  613. func TestMediaProxyModeOptionParsing(t *testing.T) {
  614. configParser := NewConfigParser()
  615. if configParser.options.MediaProxyMode() != "http-only" {
  616. t.Fatalf("Expected MEDIA_PROXY_MODE to be 'http-only' by default")
  617. }
  618. if err := configParser.parseLines([]string{"MEDIA_PROXY_MODE=all"}); err != nil {
  619. t.Fatalf("Unexpected error: %v", err)
  620. }
  621. if configParser.options.MediaProxyMode() != "all" {
  622. t.Fatalf("Expected MEDIA_PROXY_MODE to be 'all'")
  623. }
  624. }
  625. func TestMetricsCollectorOptionParsing(t *testing.T) {
  626. configParser := NewConfigParser()
  627. if configParser.options.MetricsCollector() {
  628. t.Fatal("Expected METRICS_COLLECTOR to be disabled by default")
  629. }
  630. if configParser.options.HasMetricsCollector() {
  631. t.Fatal("Expected HAS_METRICS_COLLECTOR to be disabled by default")
  632. }
  633. if err := configParser.parseLines([]string{"METRICS_COLLECTOR=1"}); err != nil {
  634. t.Fatalf("Unexpected error: %v", err)
  635. }
  636. if !configParser.options.MetricsCollector() {
  637. t.Fatal("Expected METRICS_COLLECTOR to be enabled")
  638. }
  639. if !configParser.options.HasMetricsCollector() {
  640. t.Fatal("Expected HAS_METRICS_COLLECTOR to be enabled")
  641. }
  642. if err := configParser.parseLines([]string{"METRICS_COLLECTOR=0"}); err != nil {
  643. t.Fatalf("Unexpected error: %v", err)
  644. }
  645. if configParser.options.MetricsCollector() {
  646. t.Fatal("Expected METRICS_COLLECTOR to be disabled")
  647. }
  648. if configParser.options.HasMetricsCollector() {
  649. t.Fatal("Expected HAS_METRICS_COLLECTOR to be disabled")
  650. }
  651. }
  652. func TestMetricsPasswordOptionParsing(t *testing.T) {
  653. configParser := NewConfigParser()
  654. if configParser.options.MetricsPassword() != "" {
  655. t.Fatalf("Expected METRICS_PASSWORD to be empty by default")
  656. }
  657. if err := configParser.parseLines([]string{"METRICS_PASSWORD=secret123"}); err != nil {
  658. t.Fatalf("Unexpected error: %v", err)
  659. }
  660. if configParser.options.MetricsPassword() != "secret123" {
  661. t.Fatalf("Expected METRICS_PASSWORD to be 'secret123'")
  662. }
  663. }
  664. func TestMetricsUsernameOptionParsing(t *testing.T) {
  665. configParser := NewConfigParser()
  666. if configParser.options.MetricsUsername() != "" {
  667. t.Fatalf("Expected METRICS_USERNAME to be empty by default")
  668. }
  669. if err := configParser.parseLines([]string{"METRICS_USERNAME=metrics_user"}); err != nil {
  670. t.Fatalf("Unexpected error: %v", err)
  671. }
  672. if configParser.options.MetricsUsername() != "metrics_user" {
  673. t.Fatalf("Expected METRICS_USERNAME to be 'metrics_user'")
  674. }
  675. }
  676. func TestOAuth2ClientIDOptionParsing(t *testing.T) {
  677. configParser := NewConfigParser()
  678. if configParser.options.OAuth2ClientID() != "" {
  679. t.Fatalf("Expected OAUTH2_CLIENT_ID to be empty by default")
  680. }
  681. if err := configParser.parseLines([]string{"OAUTH2_CLIENT_ID=client123"}); err != nil {
  682. t.Fatalf("Unexpected error: %v", err)
  683. }
  684. if configParser.options.OAuth2ClientID() != "client123" {
  685. t.Fatalf("Expected OAUTH2_CLIENT_ID to be 'client123'")
  686. }
  687. }
  688. func TestOAuth2ClientSecretOptionParsing(t *testing.T) {
  689. configParser := NewConfigParser()
  690. if configParser.options.OAuth2ClientSecret() != "" {
  691. t.Fatalf("Expected OAUTH2_CLIENT_SECRET to be empty by default")
  692. }
  693. if err := configParser.parseLines([]string{"OAUTH2_CLIENT_SECRET=secret456"}); err != nil {
  694. t.Fatalf("Unexpected error: %v", err)
  695. }
  696. if configParser.options.OAuth2ClientSecret() != "secret456" {
  697. t.Fatalf("Expected OAUTH2_CLIENT_SECRET to be 'secret456'")
  698. }
  699. }
  700. func TestOAuth2OIDCDiscoveryEndpointOptionParsing(t *testing.T) {
  701. configParser := NewConfigParser()
  702. if configParser.options.OAuth2OIDCDiscoveryEndpoint() != "" {
  703. t.Fatalf("Expected OAUTH2_OIDC_DISCOVERY_ENDPOINT to be empty by default")
  704. }
  705. if err := configParser.parseLines([]string{"OAUTH2_OIDC_DISCOVERY_ENDPOINT=https://example.com/.well-known/openid_configuration"}); err != nil {
  706. t.Fatalf("Unexpected error: %v", err)
  707. }
  708. if configParser.options.OAuth2OIDCDiscoveryEndpoint() != "https://example.com/.well-known/openid_configuration" {
  709. t.Fatalf("Expected OAUTH2_OIDC_DISCOVERY_ENDPOINT to be 'https://example.com/.well-known/openid_configuration'")
  710. }
  711. }
  712. func TestOAuth2OIDCProviderNameOptionParsing(t *testing.T) {
  713. configParser := NewConfigParser()
  714. if configParser.options.OAuth2OIDCProviderName() != "OpenID Connect" {
  715. t.Fatalf("Expected OAUTH2_OIDC_PROVIDER_NAME to be 'OpenID Connect' by default")
  716. }
  717. if err := configParser.parseLines([]string{"OAUTH2_OIDC_PROVIDER_NAME=My Provider"}); err != nil {
  718. t.Fatalf("Unexpected error: %v", err)
  719. }
  720. if configParser.options.OAuth2OIDCProviderName() != "My Provider" {
  721. t.Fatalf("Expected OAUTH2_OIDC_PROVIDER_NAME to be 'My Provider'")
  722. }
  723. }
  724. func TestOAuth2ProviderOptionParsing(t *testing.T) {
  725. configParser := NewConfigParser()
  726. if configParser.options.OAuth2Provider() != "" {
  727. t.Fatal("Expected OAUTH2_PROVIDER to be empty by default")
  728. }
  729. if err := configParser.parseLines([]string{"OAUTH2_PROVIDER=google"}); err != nil {
  730. t.Fatalf("Unexpected error: %v", err)
  731. }
  732. if configParser.options.OAuth2Provider() != "google" {
  733. t.Fatal("Expected OAUTH2_PROVIDER to be 'google'")
  734. }
  735. if err := configParser.parseLines([]string{"OAUTH2_PROVIDER=oidc"}); err != nil {
  736. t.Fatalf("Unexpected error: %v", err)
  737. }
  738. if configParser.options.OAuth2Provider() != "oidc" {
  739. t.Fatal("Expected OAUTH2_PROVIDER to be 'oidc'")
  740. }
  741. if err := configParser.parseLines([]string{"OAUTH2_PROVIDER=invalid"}); err == nil {
  742. t.Fatal("Expected error for invalid OAUTH2_PROVIDER value")
  743. }
  744. }
  745. func TestOAuth2RedirectURLOptionParsing(t *testing.T) {
  746. configParser := NewConfigParser()
  747. if configParser.options.OAuth2RedirectURL() != "" {
  748. t.Fatalf("Expected OAUTH2_REDIRECT_URL to be empty by default")
  749. }
  750. if err := configParser.parseLines([]string{"OAUTH2_REDIRECT_URL=https://example.com/callback"}); err != nil {
  751. t.Fatalf("Unexpected error: %v", err)
  752. }
  753. if configParser.options.OAuth2RedirectURL() != "https://example.com/callback" {
  754. t.Fatalf("Expected OAUTH2_REDIRECT_URL to be 'https://example.com/callback'")
  755. }
  756. }
  757. func TestOAuth2UserCreationOptionParsing(t *testing.T) {
  758. configParser := NewConfigParser()
  759. if configParser.options.OAuth2UserCreation() {
  760. t.Fatal("Expected OAUTH2_USER_CREATION to be disabled by default")
  761. }
  762. if configParser.options.IsOAuth2UserCreationAllowed() {
  763. t.Fatal("Expected OAUTH2_USER_CREATION to be disabled by default")
  764. }
  765. if err := configParser.parseLines([]string{"OAUTH2_USER_CREATION=1"}); err != nil {
  766. t.Fatalf("Unexpected error: %v", err)
  767. }
  768. if !configParser.options.OAuth2UserCreation() {
  769. t.Fatal("Expected OAUTH2_USER_CREATION to be enabled")
  770. }
  771. if !configParser.options.IsOAuth2UserCreationAllowed() {
  772. t.Fatal("Expected OAUTH2_USER_CREATION to be enabled")
  773. }
  774. if err := configParser.parseLines([]string{"OAUTH2_USER_CREATION=0"}); err != nil {
  775. t.Fatalf("Unexpected error: %v", err)
  776. }
  777. if configParser.options.OAuth2UserCreation() {
  778. t.Fatal("Expected OAUTH2_USER_CREATION to be disabled")
  779. }
  780. if configParser.options.IsOAuth2UserCreationAllowed() {
  781. t.Fatal("Expected OAUTH2_USER_CREATION to be disabled")
  782. }
  783. }
  784. func TestPollingLimitPerHostOptionParsing(t *testing.T) {
  785. configParser := NewConfigParser()
  786. if configParser.options.PollingLimitPerHost() != 0 {
  787. t.Fatalf("Expected POLLING_LIMIT_PER_HOST to be 0 by default")
  788. }
  789. if err := configParser.parseLines([]string{"POLLING_LIMIT_PER_HOST=5"}); err != nil {
  790. t.Fatalf("Unexpected error: %v", err)
  791. }
  792. if configParser.options.PollingLimitPerHost() != 5 {
  793. t.Fatalf("Expected POLLING_LIMIT_PER_HOST to be 5")
  794. }
  795. }
  796. func TestPollingParsingErrorLimitOptionParsing(t *testing.T) {
  797. configParser := NewConfigParser()
  798. if configParser.options.PollingParsingErrorLimit() != 3 {
  799. t.Fatalf("Expected POLLING_PARSING_ERROR_LIMIT to be 3 by default")
  800. }
  801. if err := configParser.parseLines([]string{"POLLING_PARSING_ERROR_LIMIT=5"}); err != nil {
  802. t.Fatalf("Unexpected error: %v", err)
  803. }
  804. if configParser.options.PollingParsingErrorLimit() != 5 {
  805. t.Fatalf("Expected POLLING_PARSING_ERROR_LIMIT to be 5")
  806. }
  807. }
  808. func TestPollingSchedulerOptionParsing(t *testing.T) {
  809. configParser := NewConfigParser()
  810. if configParser.options.PollingScheduler() != "round_robin" {
  811. t.Fatalf("Expected POLLING_SCHEDULER to be 'round_robin' by default")
  812. }
  813. if err := configParser.parseLines([]string{"POLLING_SCHEDULER=entry_frequency"}); err != nil {
  814. t.Fatalf("Unexpected error: %v", err)
  815. }
  816. if configParser.options.PollingScheduler() != "entry_frequency" {
  817. t.Fatalf("Expected POLLING_SCHEDULER to be 'entry_frequency'")
  818. }
  819. }
  820. func TestPortOptionParsing(t *testing.T) {
  821. configParser := NewConfigParser()
  822. if configParser.options.Port() != "" {
  823. t.Fatalf("Expected PORT to be empty by default")
  824. }
  825. if err := configParser.parseLines([]string{"PORT=1234"}); err != nil {
  826. t.Fatalf("Unexpected error: %v", err)
  827. }
  828. if configParser.options.Port() != "1234" {
  829. t.Fatalf("Expected PORT to be '1234'")
  830. }
  831. addresses := configParser.options.ListenAddr()
  832. if len(addresses) != 1 || addresses[0] != ":1234" {
  833. t.Fatalf("Expected LISTEN_ADDR to be ':1234'")
  834. }
  835. }
  836. func TestRunMigrationsOptionParsing(t *testing.T) {
  837. configParser := NewConfigParser()
  838. if configParser.options.RunMigrations() {
  839. t.Fatalf("Expected RUN_MIGRATIONS to be disabled by default")
  840. }
  841. if err := configParser.parseLines([]string{"RUN_MIGRATIONS=1"}); err != nil {
  842. t.Fatalf("Unexpected error: %v", err)
  843. }
  844. if !configParser.options.RunMigrations() {
  845. t.Fatalf("Expected RUN_MIGRATIONS to be enabled")
  846. }
  847. if err := configParser.parseLines([]string{"RUN_MIGRATIONS=0"}); err != nil {
  848. t.Fatalf("Unexpected error: %v", err)
  849. }
  850. if configParser.options.RunMigrations() {
  851. t.Fatalf("Expected RUN_MIGRATIONS to be disabled")
  852. }
  853. }
  854. func TestSchedulerEntryFrequencyFactorOptionParsing(t *testing.T) {
  855. configParser := NewConfigParser()
  856. if configParser.options.SchedulerEntryFrequencyFactor() != 1 {
  857. t.Fatalf("Expected SCHEDULER_ENTRY_FREQUENCY_FACTOR to be 1 by default")
  858. }
  859. if err := configParser.parseLines([]string{"SCHEDULER_ENTRY_FREQUENCY_FACTOR=2"}); err != nil {
  860. t.Fatalf("Unexpected error: %v", err)
  861. }
  862. if configParser.options.SchedulerEntryFrequencyFactor() != 2 {
  863. t.Fatalf("Expected SCHEDULER_ENTRY_FREQUENCY_FACTOR to be 2")
  864. }
  865. }
  866. func TestYouTubeEmbedUrlOverrideOptionParsing(t *testing.T) {
  867. configParser := NewConfigParser()
  868. // Test default value
  869. if configParser.options.YouTubeEmbedUrlOverride() != "https://www.youtube-nocookie.com/embed/" {
  870. t.Fatal("Expected YOUTUBE_EMBED_URL_OVERRIDE to have default value")
  871. }
  872. if configParser.options.YouTubeEmbedDomain() != "www.youtube-nocookie.com" {
  873. t.Fatal("Expected YOUTUBE_EMBED_DOMAIN to be 'www.youtube-nocookie.com' by default")
  874. }
  875. // Test custom value
  876. if err := configParser.parseLines([]string{"YOUTUBE_EMBED_URL_OVERRIDE=https://custom.youtube.com/embed/"}); err != nil {
  877. t.Fatalf("Unexpected error: %v", err)
  878. }
  879. if configParser.options.YouTubeEmbedUrlOverride() != "https://custom.youtube.com/embed/" {
  880. t.Fatal("Expected YOUTUBE_EMBED_URL_OVERRIDE to be 'https://custom.youtube.com/embed/'")
  881. }
  882. if configParser.options.YouTubeEmbedDomain() != "custom.youtube.com" {
  883. t.Fatal("Expected YOUTUBE_EMBED_DOMAIN to be 'custom.youtube.com'")
  884. }
  885. // Test empty value resets to default
  886. configParser = NewConfigParser()
  887. if err := configParser.parseLines([]string{"YOUTUBE_EMBED_URL_OVERRIDE="}); err != nil {
  888. t.Fatalf("Unexpected error: %v", err)
  889. }
  890. if configParser.options.YouTubeEmbedUrlOverride() != "https://www.youtube-nocookie.com/embed/" {
  891. t.Fatal("Expected YOUTUBE_EMBED_URL_OVERRIDE to have default value")
  892. }
  893. // Test invalid value
  894. configParser = NewConfigParser()
  895. if err := configParser.parseLines([]string{"YOUTUBE_EMBED_URL_OVERRIDE=http://example.com/%"}); err == nil {
  896. t.Fatal("Expected error for invalid YOUTUBE_EMBED_URL_OVERRIDE")
  897. }
  898. }
  899. func TestCleanupArchiveReadIntervalOptionParsing(t *testing.T) {
  900. configParser := NewConfigParser()
  901. if configParser.options.CleanupArchiveReadInterval().Hours() != 24*60 {
  902. t.Fatalf("Expected CLEANUP_ARCHIVE_READ_DAYS to be 60 days by default")
  903. }
  904. if err := configParser.parseLines([]string{"CLEANUP_ARCHIVE_READ_DAYS=30"}); err != nil {
  905. t.Fatalf("Unexpected error: %v", err)
  906. }
  907. if configParser.options.CleanupArchiveReadInterval().Hours() != 24*30 {
  908. t.Fatalf("Expected CLEANUP_ARCHIVE_READ_DAYS to be 30 days")
  909. }
  910. }
  911. func TestCleanupArchiveUnreadIntervalOptionParsing(t *testing.T) {
  912. configParser := NewConfigParser()
  913. if configParser.options.CleanupArchiveUnreadInterval().Hours() != 24*180 {
  914. t.Fatalf("Expected CLEANUP_ARCHIVE_UNREAD_DAYS to be 180 days by default")
  915. }
  916. if err := configParser.parseLines([]string{"CLEANUP_ARCHIVE_UNREAD_DAYS=90"}); err != nil {
  917. t.Fatalf("Unexpected error: %v", err)
  918. }
  919. if configParser.options.CleanupArchiveUnreadInterval().Hours() != 24*90 {
  920. t.Fatalf("Expected CLEANUP_ARCHIVE_UNREAD_DAYS to be 90 days")
  921. }
  922. }
  923. func TestCleanupFrequencyOptionParsing(t *testing.T) {
  924. configParser := NewConfigParser()
  925. if configParser.options.CleanupFrequency().Hours() != 24 {
  926. t.Fatalf("Expected CLEANUP_FREQUENCY_HOURS to be 24 hours by default")
  927. }
  928. if err := configParser.parseLines([]string{"CLEANUP_FREQUENCY_HOURS=12"}); err != nil {
  929. t.Fatalf("Unexpected error: %v", err)
  930. }
  931. if configParser.options.CleanupFrequency().Hours() != 12 {
  932. t.Fatalf("Expected CLEANUP_FREQUENCY_HOURS to be 12 hours")
  933. }
  934. }
  935. func TestCleanupRemoveSessionsIntervalOptionParsing(t *testing.T) {
  936. configParser := NewConfigParser()
  937. if configParser.options.CleanupRemoveSessionsInterval().Hours() != 24*30 {
  938. t.Fatalf("Expected CLEANUP_REMOVE_SESSIONS_DAYS to be 30 days by default")
  939. }
  940. if err := configParser.parseLines([]string{"CLEANUP_REMOVE_SESSIONS_DAYS=14"}); err != nil {
  941. t.Fatalf("Unexpected error: %v", err)
  942. }
  943. if configParser.options.CleanupRemoveSessionsInterval().Hours() != 24*14 {
  944. t.Fatalf("Expected CLEANUP_REMOVE_SESSIONS_DAYS to be 14 days")
  945. }
  946. }
  947. func TestDatabaseConnectionLifetimeOptionParsing(t *testing.T) {
  948. configParser := NewConfigParser()
  949. if configParser.options.DatabaseConnectionLifetime().Minutes() != 5 {
  950. t.Fatalf("Expected DATABASE_CONNECTION_LIFETIME to be 5 minutes by default")
  951. }
  952. if err := configParser.parseLines([]string{"DATABASE_CONNECTION_LIFETIME=10"}); err != nil {
  953. t.Fatalf("Unexpected error: %v", err)
  954. }
  955. if configParser.options.DatabaseConnectionLifetime().Minutes() != 10 {
  956. t.Fatalf("Expected DATABASE_CONNECTION_LIFETIME to be 10 minutes")
  957. }
  958. }
  959. func TestFilterEntryMaxAgeDaysOptionParsing(t *testing.T) {
  960. configParser := NewConfigParser()
  961. if configParser.options.FilterEntryMaxAgeDays() != 0 {
  962. t.Fatalf("Expected FILTER_ENTRY_MAX_AGE_DAYS to be 0 by default")
  963. }
  964. if err := configParser.parseLines([]string{"FILTER_ENTRY_MAX_AGE_DAYS=7"}); err != nil {
  965. t.Fatalf("Unexpected error: %v", err)
  966. }
  967. if configParser.options.FilterEntryMaxAgeDays() != 7 {
  968. t.Fatalf("Expected FILTER_ENTRY_MAX_AGE_DAYS to be 7 days")
  969. }
  970. }
  971. func TestForceRefreshIntervalOptionParsing(t *testing.T) {
  972. configParser := NewConfigParser()
  973. if configParser.options.ForceRefreshInterval().Minutes() != 30 {
  974. t.Fatalf("Expected FORCE_REFRESH_INTERVAL to be 30 minutes by default")
  975. }
  976. if err := configParser.parseLines([]string{"FORCE_REFRESH_INTERVAL=15"}); err != nil {
  977. t.Fatalf("Unexpected error: %v", err)
  978. }
  979. if configParser.options.ForceRefreshInterval().Minutes() != 15 {
  980. t.Fatalf("Expected FORCE_REFRESH_INTERVAL to be 15 minutes")
  981. }
  982. }
  983. func TestHTTPClientProxiesOptionParsing(t *testing.T) {
  984. configParser := NewConfigParser()
  985. if configParser.options.HasHTTPClientProxiesConfigured() {
  986. t.Fatalf("Expected HTTP_CLIENT_PROXIES to be empty by default")
  987. }
  988. if err := configParser.parseLines([]string{"HTTP_CLIENT_PROXIES=proxy1.example.com:8080,proxy2.example.com:8080"}); err != nil {
  989. t.Fatalf("Unexpected error: %v", err)
  990. }
  991. if !configParser.options.HasHTTPClientProxiesConfigured() {
  992. t.Fatalf("Expected HTTP_CLIENT_PROXIES to be configured")
  993. }
  994. proxies := configParser.options.HTTPClientProxies()
  995. if len(proxies) != 2 || proxies[0] != "proxy1.example.com:8080" || proxies[1] != "proxy2.example.com:8080" {
  996. t.Fatalf("Expected HTTP_CLIENT_PROXIES to contain two proxies")
  997. }
  998. }
  999. func TestHTTPClientProxyOptionParsing(t *testing.T) {
  1000. configParser := NewConfigParser()
  1001. if configParser.options.HTTPClientProxyURL() != nil {
  1002. t.Fatal("Expected HTTP_CLIENT_PROXY to be nil by default")
  1003. }
  1004. if configParser.options.HasHTTPClientProxyURLConfigured() {
  1005. t.Fatal("Expected HAS_HTTP_CLIENT_PROXY to be disabled by default")
  1006. }
  1007. if err := configParser.parseLines([]string{"HTTP_CLIENT_PROXY=http://proxy.example.com:8080"}); err != nil {
  1008. t.Fatalf("Unexpected error: %v", err)
  1009. }
  1010. proxyURL := configParser.options.HTTPClientProxyURL()
  1011. if proxyURL == nil || proxyURL.String() != "http://proxy.example.com:8080" {
  1012. t.Fatal("Expected HTTP_CLIENT_PROXY to be 'http://proxy.example.com:8080'")
  1013. }
  1014. if !configParser.options.HasHTTPClientProxyURLConfigured() {
  1015. t.Fatal("Expected HAS_HTTP_CLIENT_PROXY to be enabled")
  1016. }
  1017. }
  1018. func TestHTTPClientTimeoutOptionParsing(t *testing.T) {
  1019. configParser := NewConfigParser()
  1020. if configParser.options.HTTPClientTimeout().Seconds() != 20 {
  1021. t.Fatalf("Expected HTTP_CLIENT_TIMEOUT to be 20 seconds by default")
  1022. }
  1023. if err := configParser.parseLines([]string{"HTTP_CLIENT_TIMEOUT=30"}); err != nil {
  1024. t.Fatalf("Unexpected error: %v", err)
  1025. }
  1026. if configParser.options.HTTPClientTimeout().Seconds() != 30 {
  1027. t.Fatalf("Expected HTTP_CLIENT_TIMEOUT to be 30 seconds")
  1028. }
  1029. }
  1030. func TestIconFetchAllowPrivateNetworksOptionParsing(t *testing.T) {
  1031. configParser := NewConfigParser()
  1032. if configParser.options.IconFetchAllowPrivateNetworks() {
  1033. t.Fatalf("Expected ICON_FETCH_ALLOW_PRIVATE_NETWORKS to be disabled by default")
  1034. }
  1035. if err := configParser.parseLines([]string{"ICON_FETCH_ALLOW_PRIVATE_NETWORKS=1"}); err != nil {
  1036. t.Fatalf("Unexpected error: %v", err)
  1037. }
  1038. if !configParser.options.IconFetchAllowPrivateNetworks() {
  1039. t.Fatalf("Expected ICON_FETCH_ALLOW_PRIVATE_NETWORKS to be enabled")
  1040. }
  1041. if err := configParser.parseLines([]string{"ICON_FETCH_ALLOW_PRIVATE_NETWORKS=0"}); err != nil {
  1042. t.Fatalf("Unexpected error: %v", err)
  1043. }
  1044. if configParser.options.IconFetchAllowPrivateNetworks() {
  1045. t.Fatalf("Expected ICON_FETCH_ALLOW_PRIVATE_NETWORKS to be disabled")
  1046. }
  1047. }
  1048. func TestHTTPServerTimeoutOptionParsing(t *testing.T) {
  1049. configParser := NewConfigParser()
  1050. if configParser.options.HTTPServerTimeout().Seconds() != 300 {
  1051. t.Fatal("Expected HTTP_SERVER_TIMEOUT to be 300 seconds by default")
  1052. }
  1053. if err := configParser.parseLines([]string{"HTTP_SERVER_TIMEOUT=60"}); err != nil {
  1054. t.Fatalf("Unexpected error: %v", err)
  1055. }
  1056. if configParser.options.HTTPServerTimeout().Seconds() != 60 {
  1057. t.Fatal("Expected HTTP_SERVER_TIMEOUT to be 60 seconds")
  1058. }
  1059. }
  1060. func TestListenAddrOptionParsing(t *testing.T) {
  1061. configParser := NewConfigParser()
  1062. addrs := configParser.options.ListenAddr()
  1063. if len(addrs) != 1 || addrs[0] != "127.0.0.1:8080" {
  1064. t.Fatalf("Expected LISTEN_ADDR to be '127.0.0.1:8080' by default")
  1065. }
  1066. if err := configParser.parseLines([]string{"LISTEN_ADDR=0.0.0.0:8080,127.0.0.1:8081,/unix.socket"}); err != nil {
  1067. t.Fatalf("Unexpected error: %v", err)
  1068. }
  1069. addrs = configParser.options.ListenAddr()
  1070. if len(addrs) != 3 || addrs[0] != "0.0.0.0:8080" || addrs[1] != "127.0.0.1:8081" || addrs[2] != "/unix.socket" {
  1071. t.Fatalf("Expected LISTEN_ADDR to contain two addresses")
  1072. }
  1073. }
  1074. func TestMediaCustomProxyURLOptionParsing(t *testing.T) {
  1075. configParser := NewConfigParser()
  1076. if configParser.options.MediaCustomProxyURL() != nil {
  1077. t.Fatalf("Expected MEDIA_PROXY_CUSTOM_URL to be nil by default")
  1078. }
  1079. if err := configParser.parseLines([]string{"MEDIA_PROXY_CUSTOM_URL=https://proxy.example.com"}); err != nil {
  1080. t.Fatalf("Unexpected error: %v", err)
  1081. }
  1082. proxyURL := configParser.options.MediaCustomProxyURL()
  1083. if proxyURL == nil || proxyURL.String() != "https://proxy.example.com" {
  1084. t.Fatalf("Expected MEDIA_PROXY_CUSTOM_URL to be 'https://proxy.example.com'")
  1085. }
  1086. }
  1087. func TestMediaProxyHTTPClientTimeoutOptionParsing(t *testing.T) {
  1088. configParser := NewConfigParser()
  1089. if configParser.options.MediaProxyHTTPClientTimeout().Seconds() != 120 {
  1090. t.Fatalf("Expected MEDIA_PROXY_HTTP_CLIENT_TIMEOUT to be 120 seconds by default")
  1091. }
  1092. if err := configParser.parseLines([]string{"MEDIA_PROXY_HTTP_CLIENT_TIMEOUT=60"}); err != nil {
  1093. t.Fatalf("Unexpected error: %v", err)
  1094. }
  1095. if configParser.options.MediaProxyHTTPClientTimeout().Seconds() != 60 {
  1096. t.Fatalf("Expected MEDIA_PROXY_HTTP_CLIENT_TIMEOUT to be 60 seconds")
  1097. }
  1098. }
  1099. func TestMediaProxyAllowPrivateNetworksOptionParsing(t *testing.T) {
  1100. configParser := NewConfigParser()
  1101. if configParser.options.MediaProxyAllowPrivateNetworks() {
  1102. t.Fatalf("Expected MEDIA_PROXY_ALLOW_PRIVATE_NETWORKS to be disabled by default")
  1103. }
  1104. if err := configParser.parseLines([]string{"MEDIA_PROXY_ALLOW_PRIVATE_NETWORKS=1"}); err != nil {
  1105. t.Fatalf("Unexpected error: %v", err)
  1106. }
  1107. if !configParser.options.MediaProxyAllowPrivateNetworks() {
  1108. t.Fatalf("Expected MEDIA_PROXY_ALLOW_PRIVATE_NETWORKS to be enabled")
  1109. }
  1110. if err := configParser.parseLines([]string{"MEDIA_PROXY_ALLOW_PRIVATE_NETWORKS=0"}); err != nil {
  1111. t.Fatalf("Unexpected error: %v", err)
  1112. }
  1113. if configParser.options.MediaProxyAllowPrivateNetworks() {
  1114. t.Fatalf("Expected MEDIA_PROXY_ALLOW_PRIVATE_NETWORKS to be disabled")
  1115. }
  1116. }
  1117. func TestMediaProxyPrivateKeyOptionParsing(t *testing.T) {
  1118. configParser := NewConfigParser()
  1119. if len(configParser.options.MediaProxyPrivateKey()) != 0 {
  1120. t.Fatalf("Expected MEDIA_PROXY_PRIVATE_KEY to be empty by default")
  1121. }
  1122. if err := configParser.parseLines([]string{"MEDIA_PROXY_PRIVATE_KEY=secret123"}); err != nil {
  1123. t.Fatalf("Unexpected error: %v", err)
  1124. }
  1125. privateKey := configParser.options.MediaProxyPrivateKey()
  1126. if string(privateKey) != "secret123" {
  1127. t.Fatalf("Expected MEDIA_PROXY_PRIVATE_KEY to be 'secret123'")
  1128. }
  1129. }
  1130. func TestMediaProxyResourceTypesOptionParsing(t *testing.T) {
  1131. configParser := NewConfigParser()
  1132. resourceTypes := configParser.options.MediaProxyResourceTypes()
  1133. if len(resourceTypes) != 1 || resourceTypes[0] != "image" {
  1134. t.Fatalf("Expected MEDIA_PROXY_RESOURCE_TYPES to have default values")
  1135. }
  1136. if err := configParser.parseLines([]string{"MEDIA_PROXY_RESOURCE_TYPES=image,video"}); err != nil {
  1137. t.Fatalf("Unexpected error: %v", err)
  1138. }
  1139. resourceTypes = configParser.options.MediaProxyResourceTypes()
  1140. if len(resourceTypes) != 2 || resourceTypes[0] != "image" || resourceTypes[1] != "video" {
  1141. t.Fatalf("Expected MEDIA_PROXY_RESOURCE_TYPES to contain image and video")
  1142. }
  1143. if err := configParser.parseLines([]string{"MEDIA_PROXY_RESOURCE_TYPES=image,invalid,video"}); err == nil {
  1144. t.Fatal("Expected error due to invalid resource type")
  1145. }
  1146. }
  1147. func TestMetricsAllowedNetworksOptionParsing(t *testing.T) {
  1148. configParser := NewConfigParser()
  1149. networks := configParser.options.MetricsAllowedNetworks()
  1150. if len(networks) != 1 || networks[0] != "127.0.0.1/8" {
  1151. t.Fatalf("Expected METRICS_ALLOWED_NETWORKS to have default values")
  1152. }
  1153. if err := configParser.parseLines([]string{"METRICS_ALLOWED_NETWORKS=10.0.0.0/8,192.168.0.0/16"}); err != nil {
  1154. t.Fatalf("Unexpected error: %v", err)
  1155. }
  1156. networks = configParser.options.MetricsAllowedNetworks()
  1157. if len(networks) != 2 || networks[0] != "10.0.0.0/8" || networks[1] != "192.168.0.0/16" {
  1158. t.Fatalf("Expected METRICS_ALLOWED_NETWORKS to contain specified networks")
  1159. }
  1160. }
  1161. func TestMetricsRefreshIntervalOptionParsing(t *testing.T) {
  1162. configParser := NewConfigParser()
  1163. if configParser.options.MetricsRefreshInterval().Seconds() != 60 {
  1164. t.Fatalf("Expected METRICS_REFRESH_INTERVAL to be 60 seconds by default")
  1165. }
  1166. if err := configParser.parseLines([]string{"METRICS_REFRESH_INTERVAL=120"}); err != nil {
  1167. t.Fatalf("Unexpected error: %v", err)
  1168. }
  1169. if configParser.options.MetricsRefreshInterval().Seconds() != 120 {
  1170. t.Fatalf("Expected METRICS_REFRESH_INTERVAL to be 120 seconds")
  1171. }
  1172. }
  1173. func TestPollingFrequencyOptionParsing(t *testing.T) {
  1174. configParser := NewConfigParser()
  1175. if configParser.options.PollingFrequency().Minutes() != 60 {
  1176. t.Fatalf("Expected POLLING_FREQUENCY to be 60 minutes by default")
  1177. }
  1178. if err := configParser.parseLines([]string{"POLLING_FREQUENCY=30"}); err != nil {
  1179. t.Fatalf("Unexpected error: %v", err)
  1180. }
  1181. if configParser.options.PollingFrequency().Minutes() != 30 {
  1182. t.Fatalf("Expected POLLING_FREQUENCY to be 30 minutes")
  1183. }
  1184. }
  1185. func TestSchedulerEntryFrequencyMaxIntervalOptionParsing(t *testing.T) {
  1186. configParser := NewConfigParser()
  1187. if configParser.options.SchedulerEntryFrequencyMaxInterval().Hours() != 24 {
  1188. t.Fatalf("Expected SCHEDULER_ENTRY_FREQUENCY_MAX_INTERVAL to be 24 hours by default")
  1189. }
  1190. if err := configParser.parseLines([]string{"SCHEDULER_ENTRY_FREQUENCY_MAX_INTERVAL=720"}); err != nil {
  1191. t.Fatalf("Unexpected error: %v", err)
  1192. }
  1193. if configParser.options.SchedulerEntryFrequencyMaxInterval().Hours() != 12 {
  1194. t.Fatalf("Expected SCHEDULER_ENTRY_FREQUENCY_MAX_INTERVAL to be 12 hours")
  1195. }
  1196. }
  1197. func TestSchedulerEntryFrequencyMinIntervalOptionParsing(t *testing.T) {
  1198. configParser := NewConfigParser()
  1199. if configParser.options.SchedulerEntryFrequencyMinInterval().Minutes() != 5 {
  1200. t.Fatalf("Expected SCHEDULER_ENTRY_FREQUENCY_MIN_INTERVAL to be 5 minutes by default")
  1201. }
  1202. if err := configParser.parseLines([]string{"SCHEDULER_ENTRY_FREQUENCY_MIN_INTERVAL=10"}); err != nil {
  1203. t.Fatalf("Unexpected error: %v", err)
  1204. }
  1205. if configParser.options.SchedulerEntryFrequencyMinInterval().Minutes() != 10 {
  1206. t.Fatalf("Expected SCHEDULER_ENTRY_FREQUENCY_MIN_INTERVAL to be 10 minutes")
  1207. }
  1208. }
  1209. func TestSchedulerRoundRobinMaxIntervalOptionParsing(t *testing.T) {
  1210. configParser := NewConfigParser()
  1211. if configParser.options.SchedulerRoundRobinMaxInterval().Hours() != 24 {
  1212. t.Fatalf("Expected SCHEDULER_ROUND_ROBIN_MAX_INTERVAL to be 24 hours by default")
  1213. }
  1214. if err := configParser.parseLines([]string{"SCHEDULER_ROUND_ROBIN_MAX_INTERVAL=60"}); err != nil {
  1215. t.Fatalf("Unexpected error: %v", err)
  1216. }
  1217. if configParser.options.SchedulerRoundRobinMaxInterval().Hours() != 1 {
  1218. t.Fatalf("Expected SCHEDULER_ROUND_ROBIN_MAX_INTERVAL to be 1 hour")
  1219. }
  1220. }
  1221. func TestSchedulerRoundRobinMinIntervalOptionParsing(t *testing.T) {
  1222. configParser := NewConfigParser()
  1223. if configParser.options.SchedulerRoundRobinMinInterval().Minutes() != 60 {
  1224. t.Fatalf("Expected SCHEDULER_ROUND_ROBIN_MIN_INTERVAL to be 60 minutes by default")
  1225. }
  1226. if err := configParser.parseLines([]string{"SCHEDULER_ROUND_ROBIN_MIN_INTERVAL=30"}); err != nil {
  1227. t.Fatalf("Unexpected error: %v", err)
  1228. }
  1229. if configParser.options.SchedulerRoundRobinMinInterval().Minutes() != 30 {
  1230. t.Fatalf("Expected SCHEDULER_ROUND_ROBIN_MIN_INTERVAL to be 30 minutes")
  1231. }
  1232. }
  1233. func TestTrustedReverseProxyNetworksOptionParsing(t *testing.T) {
  1234. configParser := NewConfigParser()
  1235. // Test default value
  1236. defaultNetworks := configParser.options.TrustedReverseProxyNetworks()
  1237. if len(defaultNetworks) != 0 {
  1238. t.Fatalf("Expected 0 allowed networks by default, got %d", len(defaultNetworks))
  1239. }
  1240. // Test valid value
  1241. if err := configParser.parseLines([]string{"TRUSTED_REVERSE_PROXY_NETWORKS=10.0.0.0/8,192.168.1.0/24"}); err != nil {
  1242. t.Fatalf("Unexpected error: %v", err)
  1243. }
  1244. allowedNetworks := configParser.options.TrustedReverseProxyNetworks()
  1245. if len(allowedNetworks) != 2 {
  1246. t.Fatalf("Expected 2 allowed networks, got %d", len(allowedNetworks))
  1247. }
  1248. if !slices.Contains(allowedNetworks, "10.0.0.0/8") {
  1249. t.Errorf("Expected 10.0.0.0/8 in allowed networks")
  1250. }
  1251. if !slices.Contains(allowedNetworks, "192.168.1.0/24") {
  1252. t.Errorf("Expected 192.168.1.0/24 in allowed networks")
  1253. }
  1254. }
  1255. func TestYouTubeEmbedDomainOptionParsing(t *testing.T) {
  1256. configParser := NewConfigParser()
  1257. if configParser.options.YouTubeEmbedDomain() != "www.youtube-nocookie.com" {
  1258. t.Fatalf("Expected YouTubeEmbedDomain to be 'www.youtube-nocookie.com' by default")
  1259. }
  1260. // YouTube embed domain is derived from YOUTUBE_EMBED_URL_OVERRIDE
  1261. if err := configParser.parseLines([]string{"YOUTUBE_EMBED_URL_OVERRIDE=https://custom.youtube.com/embed/"}); err != nil {
  1262. t.Fatalf("Unexpected error: %v", err)
  1263. }
  1264. if configParser.options.YouTubeEmbedDomain() != "custom.youtube.com" {
  1265. t.Fatalf("Expected YouTubeEmbedDomain to be 'custom.youtube.com'")
  1266. }
  1267. }
  1268. func TestSetLogLevelFunction(t *testing.T) {
  1269. configParser := NewConfigParser()
  1270. // Test default log level
  1271. if configParser.options.LogLevel() != "info" {
  1272. t.Fatalf("Expected LOG_LEVEL to be 'info' by default, got '%s'", configParser.options.LogLevel())
  1273. }
  1274. // Test setting log level to debug
  1275. configParser.options.SetLogLevel("debug")
  1276. if configParser.options.LogLevel() != "debug" {
  1277. t.Fatalf("Expected LOG_LEVEL to be 'debug' after SetLogLevel('debug'), got '%s'", configParser.options.LogLevel())
  1278. }
  1279. if configParser.options.options["LOG_LEVEL"].rawValue != "debug" {
  1280. t.Fatalf("Expected LOG_LEVEL RawValue to be 'debug', got '%s'", configParser.options.options["LOG_LEVEL"].rawValue)
  1281. }
  1282. // Test setting log level to warning
  1283. configParser.options.SetLogLevel("warning")
  1284. if configParser.options.LogLevel() != "warning" {
  1285. t.Fatalf("Expected LOG_LEVEL to be 'warning' after SetLogLevel('warning'), got '%s'", configParser.options.LogLevel())
  1286. }
  1287. if configParser.options.options["LOG_LEVEL"].rawValue != "warning" {
  1288. t.Fatalf("Expected LOG_LEVEL RawValue to be 'warning', got '%s'", configParser.options.options["LOG_LEVEL"].rawValue)
  1289. }
  1290. }
  1291. func TestSetHTTPSValueFunction(t *testing.T) {
  1292. configParser := NewConfigParser()
  1293. // Test setting HTTPS to true
  1294. configParser.options.SetHTTPSValue(true)
  1295. if !configParser.options.HTTPS() {
  1296. t.Fatalf("Expected HTTPS to be true after SetHTTPSValue(true)")
  1297. }
  1298. // Test setting HTTPS to false
  1299. configParser.options.SetHTTPSValue(false)
  1300. if configParser.options.HTTPS() {
  1301. t.Fatalf("Expected HTTPS to be false after SetHTTPSValue(false)")
  1302. }
  1303. // Test setting HTTPS to true again
  1304. configParser.options.SetHTTPSValue(true)
  1305. if !configParser.options.HTTPS() {
  1306. t.Fatalf("Expected HTTPS to be true after second SetHTTPSValue(true)")
  1307. }
  1308. }
  1309. func TestConfigMap(t *testing.T) {
  1310. configMap := NewConfigOptions().ConfigMap(false)
  1311. if len(configMap) == 0 {
  1312. t.Fatal("Expected ConfigMap to contain configuration options")
  1313. }
  1314. // The first option should be "ADMIN_PASSWORD"
  1315. if configMap[0].Key != "ADMIN_PASSWORD" {
  1316. t.Fatalf("Expected first config option to be 'ADMIN_PASSWORD', got '%s'", configMap[0].Key)
  1317. }
  1318. }
  1319. func TestConfigMapWithRedactedSecrets(t *testing.T) {
  1320. configParser := NewConfigParser()
  1321. if err := configParser.parseLines([]string{"ADMIN_PASSWORD=secret123"}); err != nil {
  1322. t.Fatalf("Unexpected error: %v", err)
  1323. }
  1324. configMap := configParser.options.ConfigMap(true)
  1325. if len(configMap) == 0 {
  1326. t.Fatal("Expected ConfigMap to contain configuration options")
  1327. }
  1328. // The first option should be "ADMIN_PASSWORD"
  1329. if configMap[0].Key != "ADMIN_PASSWORD" {
  1330. t.Fatalf("Expected first config option to be 'ADMIN_PASSWORD', got '%s'", configMap[0].Key)
  1331. }
  1332. // The value should be redacted
  1333. if configMap[0].Value != "<redacted>" {
  1334. t.Fatalf("Expected ADMIN_PASSWORD value to be redacted, got '%s'", configMap[0].Value)
  1335. }
  1336. }