@@ -265,6 +265,99 @@ void setProfile() throws Exception {
265265 assertThat (v1Profile .phoneNumberSharing ()).isEqualTo (validPhoneNumberSharing );
266266 }
267267
268+ @ Test
269+ void setProfileExpectedDataWriteConflict () throws Exception {
270+ final byte [] commitment = new ProfileKey (new byte [32 ]).getCommitment (new ServiceId .Aci (AUTHENTICATED_ACI )).serialize ();
271+ final byte [] validAboutEmoji = new byte [60 ];
272+ final byte [] validAbout = new byte [540 ];
273+ final byte [] validPaymentAddress = new byte [582 ];
274+ final byte [] validPhoneNumberSharing = new byte [29 ];
275+
276+ doThrow (WriteConflictException .class )
277+ .when (profilesManager ).set (any (), any (), any (), any ());
278+
279+ final SetProfileRequest request = SetProfileRequest .newBuilder ()
280+ .setVersion (ByteString .copyFrom (VERSION ))
281+ .setData (ByteString .copyFrom (VALID_DATA ))
282+ .setCommitment (ByteString .copyFrom (commitment )) // after v1 -> v2 migration, commitment can be null if expectedDataHash is present
283+ .setPaymentAddress (ByteString .copyFrom (validPaymentAddress ))
284+ .setV1Request (V1_REQUEST .toBuilder ()
285+ .setAvatarChange (AvatarChange .AVATAR_CHANGE_UNCHANGED )
286+ .setAboutEmoji (ByteString .copyFrom (validAboutEmoji ))
287+ .setAbout (ByteString .copyFrom (validAbout ))
288+ .setPhoneNumberSharing (ByteString .copyFrom (validPhoneNumberSharing ))
289+ )
290+ .build ();
291+
292+ final SetProfileResponse response = authenticatedServiceStub ().setProfile (request );
293+
294+ assertTrue (response .hasExpectedDataWriteConflict ());
295+ verify (accountsManager , never ()).updateCurrentProfileVersion (any (), any (), any (), any ());
296+ }
297+
298+ @ Test
299+ void setProfileExpectedVersionWriteConflictBeforeUpdates () throws Exception {
300+ final byte [] commitment = new ProfileKey (new byte [32 ]).getCommitment (new ServiceId .Aci (AUTHENTICATED_ACI )).serialize ();
301+ final byte [] validAboutEmoji = new byte [60 ];
302+ final byte [] validAbout = new byte [540 ];
303+ final byte [] validPaymentAddress = new byte [582 ];
304+ final byte [] validPhoneNumberSharing = new byte [29 ];
305+
306+ when (account .getCurrentProfileVersion ()).thenReturn (
307+ Optional .of (HexFormat .of ().formatHex (TestRandomUtil .nextBytes (32 ))));
308+
309+ final SetProfileRequest request = SetProfileRequest .newBuilder ()
310+ .setVersion (ByteString .copyFrom (VERSION ))
311+ .setData (ByteString .copyFrom (VALID_DATA ))
312+ .setCommitment (ByteString .copyFrom (commitment )) // after v1 -> v2 migration, commitment can be null if expectedDataHash is present
313+ .setPaymentAddress (ByteString .copyFrom (validPaymentAddress ))
314+ .setExpectedCurrentVersion (ByteString .copyFrom (VERSION ))
315+ .setV1Request (V1_REQUEST .toBuilder ()
316+ .setAvatarChange (AvatarChange .AVATAR_CHANGE_UNCHANGED )
317+ .setAboutEmoji (ByteString .copyFrom (validAboutEmoji ))
318+ .setAbout (ByteString .copyFrom (validAbout ))
319+ .setPhoneNumberSharing (ByteString .copyFrom (validPhoneNumberSharing ))
320+ )
321+ .build ();
322+
323+ final SetProfileResponse response = authenticatedServiceStub ().setProfile (request );
324+
325+ assertTrue (response .hasExpectedVersionWriteConflict ());
326+ verify (profilesManager , never ()).set (any (), any (), any (), any ());
327+ verify (accountsManager , never ()).updateCurrentProfileVersion (any (), any (), any (), any ());
328+ }
329+
330+ @ Test
331+ void setProfileExpectedVersionWriteConflict () throws Exception {
332+ final byte [] commitment = new ProfileKey (new byte [32 ]).getCommitment (new ServiceId .Aci (AUTHENTICATED_ACI )).serialize ();
333+ final byte [] validAboutEmoji = new byte [60 ];
334+ final byte [] validAbout = new byte [540 ];
335+ final byte [] validPaymentAddress = new byte [582 ];
336+ final byte [] validPhoneNumberSharing = new byte [29 ];
337+
338+ doThrow (WriteConflictException .class )
339+ .when (accountsManager ).updateCurrentProfileVersion (any (), any (), any (), any ());
340+
341+ final SetProfileRequest request = SetProfileRequest .newBuilder ()
342+ .setVersion (ByteString .copyFrom (VERSION ))
343+ .setData (ByteString .copyFrom (VALID_DATA ))
344+ .setCommitment (ByteString .copyFrom (commitment )) // after v1 -> v2 migration, commitment can be null if expectedDataHash is present
345+ .setPaymentAddress (ByteString .copyFrom (validPaymentAddress ))
346+ .setV1Request (V1_REQUEST .toBuilder ()
347+ .setAvatarChange (AvatarChange .AVATAR_CHANGE_UNCHANGED )
348+ .setAboutEmoji (ByteString .copyFrom (validAboutEmoji ))
349+ .setAbout (ByteString .copyFrom (validAbout ))
350+ .setPhoneNumberSharing (ByteString .copyFrom (validPhoneNumberSharing ))
351+ )
352+ .build ();
353+
354+ final SetProfileResponse response = authenticatedServiceStub ().setProfile (request );
355+
356+ assertTrue (response .hasExpectedVersionWriteConflict ());
357+ verify (profilesManager ).set (any (), any (), any (), any ());
358+ verify (accountsManager ).updateCurrentProfileVersion (any (), any (), any (), any ());
359+ }
360+
268361 @ Test
269362 void setProfileWithoutCapability () {
270363 when (account .hasCapability (DeviceCapability .PROFILES_V2 )).thenReturn (false );
@@ -640,7 +733,7 @@ void getVersionedProfile(final byte[] requestVersion, @Nullable final byte[] acc
640733 if (expectResponseHasPaymentAddress ) {
641734 expectedResultBuilder .setPaymentAddressDataEtag (
642735 DataEtag .newBuilder ().setData (ByteString .copyFrom (paymentAddress ))
643- .setEtag (ByteString .copyFrom (ProfileGrpcHelper .hash (paymentAddress )))
736+ .setEtagSha256 (ByteString .copyFrom (ProfileGrpcHelper .hash (paymentAddress )))
644737 .build ());
645738
646739 }
@@ -693,10 +786,10 @@ void getVersionedProfileV2() {
693786
694787 assertTrue (result .hasDataEtag ());
695788 assertEquals (ByteString .copyFrom (data ), result .getDataEtag ().getData ());
696- assertEquals (ByteString .copyFrom (v2Profile .dataHash ()), result .getDataEtag ().getEtag ());
789+ assertEquals (ByteString .copyFrom (v2Profile .dataHash ()), result .getDataEtag ().getEtagSha256 ());
697790 assertTrue (result .hasPaymentAddressDataEtag ());
698791 assertEquals (ByteString .copyFrom (paymentAddress ), result .getPaymentAddressDataEtag ().getData ());
699- assertEquals (ByteString .copyFrom (v2Profile .paymentAddressHash ()), result .getPaymentAddressDataEtag ().getEtag ());
792+ assertEquals (ByteString .copyFrom (v2Profile .paymentAddressHash ()), result .getPaymentAddressDataEtag ().getEtagSha256 ());
700793 assertFalse (result .getDataEtagMatched ());
701794 assertFalse (result .getPaymentAddressEtagMatched ());
702795 assertFalse (result .hasV1Response ());
0 commit comments