@@ -723,16 +723,8 @@ var _ = Describe("External users e2e test", Ordered, func() {
723723 })
724724
725725 AfterAll (func () {
726- // Clean up external_user_groups first (foreign key constraint)
727- err := DefaultContext .DB ().Where ("external_user_id IN (?)" ,
728- []string {
729- "018e4c6a-1111-7000-8000-000000000001" ,
730- "018e4c6a-1111-7000-8000-000000000002" ,
731- }).Delete (& dutymodels.ExternalUserGroup {}).Error
732- Expect (err ).NotTo (HaveOccurred (), "failed to delete external user groups" )
733-
734726 // Clean up external users
735- err = DefaultContext .DB ().Where ("scraper_id = ?" , scraperModel .ID ).Delete (& dutymodels.ExternalUser {}).Error
727+ err : = DefaultContext .DB ().Where ("scraper_id = ?" , scraperModel .ID ).Delete (& dutymodels.ExternalUser {}).Error
736728 Expect (err ).NotTo (HaveOccurred (), "failed to delete external users" )
737729
738730 // Clean up external groups
@@ -748,19 +740,29 @@ var _ = Describe("External users e2e test", Ordered, func() {
748740 Expect (err ).NotTo (HaveOccurred (), "failed to delete scrape config" )
749741 })
750742
751- It ("should scrape and save external users, groups, roles, and user-group mappings " , func () {
743+ It ("should scrape and save external users, groups, and roles " , func () {
752744 _ , err := RunScraper (scraperCtx )
753745 Expect (err ).To (BeNil ())
754746 })
755747
756- It ("should have saved external users to the database" , func () {
748+ It ("should have saved external users to the database with aliases " , func () {
757749 var users []dutymodels.ExternalUser
758750 err := DefaultContext .DB ().Where ("scraper_id = ?" , scraperModel .ID ).Find (& users ).Error
759751 Expect (err ).NotTo (HaveOccurred ())
760752 Expect (users ).To (HaveLen (2 ))
761753
762754 userNames := lo .Map (users , func (u dutymodels.ExternalUser , _ int ) string { return u .Name })
763755 Expect (userNames ).To (ContainElements ("John Doe" , "Service Bot" ))
756+
757+ // Verify aliases are saved
758+ for _ , user := range users {
759+ switch user .Name {
760+ case "John Doe" :
761+ Expect (
user .
Aliases ).
To (
ContainElements (
"john-doe" ,
"[email protected] " ))
762+ case "Service Bot" :
763+ Expect (user .Aliases ).To (ContainElements ("service-bot" , "bot-001" ))
764+ }
765+ }
764766 })
765767
766768 It ("should have saved external groups to the database" , func () {
@@ -783,14 +785,56 @@ var _ = Describe("External users e2e test", Ordered, func() {
783785 Expect (roleNames ).To (ContainElements ("Admin" , "Reader" ))
784786 })
785787
786- It ("should have saved external user groups to the database" , func () {
787- var userGroups []dutymodels.ExternalUserGroup
788- err := DefaultContext .DB ().Where ("external_user_id IN (?)" ,
789- []string {
790- "018e4c6a-1111-7000-8000-000000000001" ,
791- "018e4c6a-1111-7000-8000-000000000002" ,
792- }).Find (& userGroups ).Error
788+ It ("should upsert external users by alias on second scrape (not create duplicates)" , func () {
789+ // Get existing user IDs before second scrape
790+ var usersBefore []dutymodels.ExternalUser
791+ err := DefaultContext .DB ().Where ("scraper_id = ?" , scraperModel .ID ).Find (& usersBefore ).Error
792+ Expect (err ).NotTo (HaveOccurred ())
793+ Expect (usersBefore ).To (HaveLen (2 ))
794+
795+ userIDsBefore := lo .Map (usersBefore , func (u dutymodels.ExternalUser , _ int ) uuid.UUID { return u .ID })
796+
797+ // Clear cache to ensure we test DB lookup path
798+ db .ExternalUserCache .Flush ()
799+
800+ // Run scraper again
801+ _ , err = RunScraper (scraperCtx )
802+ Expect (err ).To (BeNil ())
803+
804+ // Verify same number of users (no duplicates)
805+ var usersAfter []dutymodels.ExternalUser
806+ err = DefaultContext .DB ().Where ("scraper_id = ?" , scraperModel .ID ).Find (& usersAfter ).Error
793807 Expect (err ).NotTo (HaveOccurred ())
794- Expect (userGroups ).To (HaveLen (2 ))
808+ Expect (usersAfter ).To (HaveLen (2 ))
809+
810+ // Verify same IDs were used (upsert, not insert)
811+ userIDsAfter := lo .Map (usersAfter , func (u dutymodels.ExternalUser , _ int ) uuid.UUID { return u .ID })
812+ Expect (userIDsAfter ).To (ConsistOf (userIDsBefore ))
813+ })
814+
815+ It ("should use cache for external user lookup on subsequent scrapes" , func () {
816+ // Clear cache first
817+ db .ExternalUserCache .Flush ()
818+
819+ // Run scraper to populate cache
820+ _ , err := RunScraper (scraperCtx )
821+ Expect (err ).To (BeNil ())
822+
823+ // Verify cache is populated for all aliases (key is just the alias)
824+ johnDoeID , found := db .ExternalUserCache .Get ("john-doe" )
825+ Expect (found ).To (BeTrue ())
826+ Expect (johnDoeID ).NotTo (Equal (uuid .Nil ))
827+
828+ jdoeID ,
found := db .
ExternalUserCache .
Get (
"[email protected] " )
829+ Expect (found ).To (BeTrue ())
830+ Expect (jdoeID ).To (Equal (johnDoeID )) // Same user, same ID
831+
832+ serviceBotID , found := db .ExternalUserCache .Get ("service-bot" )
833+ Expect (found ).To (BeTrue ())
834+ Expect (serviceBotID ).NotTo (Equal (uuid .Nil ))
835+
836+ bot001ID , found := db .ExternalUserCache .Get ("bot-001" )
837+ Expect (found ).To (BeTrue ())
838+ Expect (bot001ID ).To (Equal (serviceBotID )) // Same user, same ID
795839 })
796840})
0 commit comments