44 "encoding/json"
55 "fmt"
66 "strings"
7+ "time"
78
89 "github.com/google/uuid"
910 ginkgo "github.com/onsi/ginkgo/v2"
@@ -470,9 +471,30 @@ var _ = ginkgo.Describe("SearchResourceSelectors", func() {
470471 }
471472
472473 ginkgo .It ("populates timestamps when requested" , func () {
474+ // Seed an analysis with explicit first/last observed so the mapping
475+ // (first_observed -> created_at, last_observed -> updated_at) is
476+ // unambiguous and not reliant on column defaults.
477+ firstObserved := time .Date (2024 , 1 , 2 , 3 , 4 , 5 , 0 , time .UTC )
478+ lastObserved := time .Date (2025 , 6 , 7 , 8 , 9 , 10 , 0 , time .UTC )
479+ analysis := models.ConfigAnalysis {
480+ ID : uuid .New (),
481+ ConfigID : dummy .EKSCluster .ID ,
482+ Analyzer : "timestamp-mapping" ,
483+ AnalysisType : models .AnalysisTypeSecurity ,
484+ Severity : models .SeverityLow ,
485+ Status : models .AnalysisStatusOpen ,
486+ FirstObserved : & firstObserved ,
487+ LastObserved : & lastObserved ,
488+ }
489+ Expect (DefaultContext .DB ().Create (& analysis ).Error ).To (Succeed ())
490+ ginkgo .DeferCleanup (func () {
491+ Expect (DefaultContext .DB ().Where ("id = ?" , analysis .ID ).Delete (& models.ConfigAnalysis {}).Error ).To (Succeed ())
492+ })
493+
473494 items , err := query .SearchResources (DefaultContext , query.SearchResourcesRequest {
474- Timestamps : true ,
475- Configs : []types.ResourceSelector {{ID : dummy .KubernetesNodeA .ID .String ()}},
495+ Timestamps : true ,
496+ Configs : []types.ResourceSelector {{ID : dummy .KubernetesNodeA .ID .String ()}},
497+ ConfigAnalysis : []types.ResourceSelector {{ID : analysis .ID .String ()}},
476498 })
477499 Expect (err ).To (BeNil ())
478500 Expect (items .Configs ).To (HaveLen (1 ))
@@ -486,15 +508,31 @@ var _ = ginkgo.Describe("SearchResourceSelectors", func() {
486508 Expect (err ).To (BeNil ())
487509 Expect (string (payload )).To (ContainSubstring ("created_at" ))
488510 Expect (string (payload )).ToNot (ContainSubstring ("deleted_at" ))
511+
512+ // config analysis maps first_observed -> created_at and last_observed -> updated_at.
513+ Expect (items .ConfigAnalysis ).To (HaveLen (1 ))
514+ Expect (items .ConfigAnalysis [0 ].ID ).To (Equal (analysis .ID .String ()))
515+ Expect (items .ConfigAnalysis [0 ].CreatedAt ).ToNot (BeNil ())
516+ Expect (items .ConfigAnalysis [0 ].CreatedAt .UTC ()).To (Equal (firstObserved ))
517+ Expect (items .ConfigAnalysis [0 ].UpdatedAt ).ToNot (BeNil ())
518+ Expect (items .ConfigAnalysis [0 ].UpdatedAt .UTC ()).To (Equal (lastObserved ))
519+
520+ analysisPayload , err := json .Marshal (items .ConfigAnalysis [0 ])
521+ Expect (err ).To (BeNil ())
522+ Expect (string (analysisPayload )).To (ContainSubstring ("created_at" ))
523+ Expect (string (analysisPayload )).To (ContainSubstring ("updated_at" ))
489524 })
490525
491526 ginkgo .It ("omits timestamps by default" , func () {
492527 items , err := query .SearchResources (DefaultContext , query.SearchResourcesRequest {
493- Configs : []types.ResourceSelector {{ID : dummy .KubernetesNodeA .ID .String ()}},
528+ Configs : []types.ResourceSelector {{ID : dummy .KubernetesNodeA .ID .String ()}},
529+ ConfigAnalysis : []types.ResourceSelector {{ID : dummy .LogisticsDBRDSAnalysis .ID .String ()}},
494530 })
495531 Expect (err ).To (BeNil ())
496532 Expect (items .Configs ).To (HaveLen (1 ))
497533 Expect (items .Configs [0 ].CreatedAt ).To (BeNil ())
534+ Expect (items .ConfigAnalysis ).To (HaveLen (1 ))
535+ Expect (items .ConfigAnalysis [0 ].CreatedAt ).To (BeNil ())
498536
499537 payload , err := json .Marshal (items .Configs [0 ])
500538 Expect (err ).To (BeNil ())
0 commit comments