@@ -107,14 +107,9 @@ func TestStoreIdentity(t *testing.T, store walletStoreConstructor) {
107107 walletID := driver .WalletID ("my wallet" )
108108 roleID := 5
109109
110- mockDB .
111- ExpectQuery ("SELECT wallet_id FROM WALLETS WHERE \\ (identity_hash = \\ $1\\ ) AND \\ (wallet_id = \\ $2\\ ) AND \\ (role_id = \\ $3\\ )" ).
112- WithArgs (tokenID .UniqueID (), walletID , roleID ).
113- WillReturnRows (mockDB .NewRows ([]string {"wallet_id" }))
114-
115110 mockDB .ExpectExec ("INSERT INTO WALLETS " +
116111 "\\ (identity_hash, meta, wallet_id, role_id, created_at, enrollment_id\\ ) " +
117- "VALUES \\ (\\ $1, \\ $2, \\ $3, \\ $4, \\ $5, \\ $6\\ )" ).
112+ "VALUES \\ (\\ $1, \\ $2, \\ $3, \\ $4, \\ $5, \\ $6\\ ) ON CONFLICT DO NOTHING " ).
118113 WithArgs (tokenID .UniqueID (), []uint8 (nil ), walletID , roleID , sqlmock .AnyArg (), eID ).
119114 WillReturnResult (sqlmock .NewResult (1 , 1 ))
120115
@@ -123,3 +118,37 @@ func TestStoreIdentity(t *testing.T, store walletStoreConstructor) {
123118 gomega .Expect (mockDB .ExpectationsWereMet ()).To (gomega .Succeed ())
124119 gomega .Expect (err ).ToNot (gomega .HaveOccurred ())
125120}
121+
122+ func TestStoreIdentityIdempotent (t * testing.T , store walletStoreConstructor ) {
123+ gomega .RegisterTestingT (t )
124+ db , mockDB , err := sqlmock .New ()
125+ gomega .Expect (err ).ToNot (gomega .HaveOccurred ())
126+
127+ tokenID := token .Identity ([]byte ("1234" ))
128+ eID := "5678"
129+ walletID := driver .WalletID ("my wallet" )
130+ roleID := 5
131+
132+ insertQuery := "INSERT INTO WALLETS " +
133+ "\\ (identity_hash, meta, wallet_id, role_id, created_at, enrollment_id\\ ) " +
134+ "VALUES \\ (\\ $1, \\ $2, \\ $3, \\ $4, \\ $5, \\ $6\\ ) ON CONFLICT DO NOTHING"
135+
136+ // First call: row inserted (1 row affected)
137+ mockDB .ExpectExec (insertQuery ).
138+ WithArgs (tokenID .UniqueID (), []uint8 (nil ), walletID , roleID , sqlmock .AnyArg (), eID ).
139+ WillReturnResult (sqlmock .NewResult (1 , 1 ))
140+
141+ // Second call: conflict, 0 rows affected — must still return nil
142+ mockDB .ExpectExec (insertQuery ).
143+ WithArgs (tokenID .UniqueID (), []uint8 (nil ), walletID , roleID , sqlmock .AnyArg (), eID ).
144+ WillReturnResult (sqlmock .NewResult (0 , 0 ))
145+
146+ s := store (db )
147+ err = s .StoreIdentity (t .Context (), tokenID , eID , walletID , roleID , nil )
148+ gomega .Expect (err ).ToNot (gomega .HaveOccurred ())
149+
150+ err = s .StoreIdentity (t .Context (), tokenID , eID , walletID , roleID , nil )
151+ gomega .Expect (err ).ToNot (gomega .HaveOccurred ())
152+
153+ gomega .Expect (mockDB .ExpectationsWereMet ()).To (gomega .Succeed ())
154+ }
0 commit comments