3131import org .mockito .invocation .InvocationOnMock ;
3232import org .mockito .stubbing .Answer ;
3333
34+ import java .io .File ;
35+ import java .lang .reflect .Constructor ;
36+ import java .lang .reflect .InvocationTargetException ;
37+ import java .net .MalformedURLException ;
3438import java .net .URI ;
3539import java .net .URISyntaxException ;
3640import java .net .URL ;
41+ import java .util .Calendar ;
42+ import java .util .Iterator ;
3743import java .util .List ;
3844import java .util .Map ;
39- import java .util .Iterator ;
4045import java .util .UUID ;
4146
47+ import io .realm .entities .StringOnly ;
4248import io .realm .internal .network .AuthenticateResponse ;
4349import io .realm .internal .network .AuthenticationServer ;
50+ import io .realm .internal .objectserver .Token ;
4451import io .realm .log .RealmLog ;
52+ import io .realm .objectserver .utils .StringOnlyModule ;
4553import io .realm .rule .RunInLooperThread ;
4654import io .realm .rule .RunTestInLooperThread ;
4755import io .realm .util .SyncTestUtils ;
5058import static io .realm .util .SyncTestUtils .createTestUser ;
5159import static junit .framework .Assert .assertEquals ;
5260import static org .junit .Assert .assertFalse ;
61+ import static org .junit .Assert .assertNotEquals ;
5362import static org .junit .Assert .assertNotNull ;
5463import static org .junit .Assert .assertNull ;
5564import static org .junit .Assert .assertTrue ;
6069@ RunWith (AndroidJUnit4 .class )
6170public class SyncUserTests {
6271
72+ private static final URL authUrl ;
73+ private static final Constructor <SyncUser > SYNC_USER_CONSTRUCTOR ;
74+ static {
75+ try {
76+ authUrl = new URL ("http://localhost/auth" );
77+ SYNC_USER_CONSTRUCTOR = SyncUser .class .getDeclaredConstructor (Token .class , URL .class );
78+ SYNC_USER_CONSTRUCTOR .setAccessible (true );
79+ } catch (MalformedURLException e ) {
80+ throw new ExceptionInInitializerError (e );
81+ } catch (NoSuchMethodException e ) {
82+ throw new ExceptionInInitializerError (e );
83+ }
84+ }
85+
6386 @ Rule
6487 public final RunInLooperThread looperThread = new RunInLooperThread ();
6588
@@ -81,6 +104,45 @@ public void setUp() {
81104 SyncManager .reset ();
82105 }
83106
107+ private static SyncUser createFakeUser (String id ) {
108+ final Token token = new Token ("token_value" , id , "path_value" , Long .MAX_VALUE , null );
109+ try {
110+ return SYNC_USER_CONSTRUCTOR .newInstance (token , authUrl );
111+ } catch (InstantiationException | IllegalAccessException | InvocationTargetException e ) {
112+ fail (e .getMessage ());
113+ }
114+ return null ;
115+ }
116+
117+ @ Test
118+ public void equals_validUser () {
119+ final SyncUser user1 = createFakeUser ("id_value" );
120+ final SyncUser user2 = createFakeUser ("id_value" );
121+ assertTrue (user1 .equals (user2 ));
122+ }
123+
124+ @ Test
125+ public void equals_loggedOutUser () {
126+ final SyncUser user1 = createFakeUser ("id_value" );
127+ final SyncUser user2 = createFakeUser ("id_value" );
128+ user1 .logout ();
129+ user2 .logout ();
130+ assertTrue (user1 .equals (user2 ));
131+ }
132+
133+ @ Test
134+ public void hashCode_validUser () {
135+ final SyncUser user = createFakeUser ("id_value" );
136+ assertNotEquals (0 , user .hashCode ());
137+ }
138+
139+ @ Test
140+ public void hashCode_loggedOutUser () {
141+ final SyncUser user = createFakeUser ("id_value" );
142+ user .logout ();
143+ assertNotEquals (0 , user .hashCode ());
144+ }
145+
84146 @ Test
85147 public void toAndFromJson () {
86148 SyncUser user1 = createTestUser ();
@@ -407,4 +469,66 @@ public void allSessions() {
407469 realm2 .close ();
408470 assertEquals (0 , user .allSessions ().size ());
409471 }
472+
473+ // JSON format changed in 3.6.0 (removed unnecessary fields), this regression test
474+ // makes sure we can still deserialize a valid SyncUser from the old format.
475+ @ Test
476+ public void fromJson_WorkWithRemovedObjectServerUser () {
477+ String oldSyncUserJSON = "{\" authUrl\" :\" http:\\ /\\ /192.168.1.151:9080\\ /auth\" ,\" userToken\" :{\" token\" :\" eyJpZGVudGl0eSI6IjY4OWQ5MGMxNDIyYTIwMmZkNTljNDYwM2M0ZTRmNmNjIiwiZXhwaXJlcyI6MTgxNjM1ODE4NCwiYXBwX2lkIjoiaW8ucmVhbG0ucmVhbG10YXNrcyIsImFjY2VzcyI6WyJyZWZyZXNoIl0sImlzX2FkbWluIjpmYWxzZSwic2FsdCI6MC4yMTEwMjQyNDgwOTEyMzg1NH0=:lEDa83o1zu8rkwdZVpTyunLHh1wmjxPPSGmZQNxdEM7xDmpbiU7V+8dgDWGevJNHMFluNDAOmrcAOI9TLfhI4rMDl70NI1K9rv\\ /Aeq5uIOzq\\ /Gf7JTeTUKY5Z7yRoppd8NArlNBKesLFxzdLRlfm1hflF9wH23xQXA19yUZ67JIlkhDPL5e3bau8O3Pr\\ /St0unW3KzPOiZUk1l9KRrs2iMCCiXCfq4rf6rp7B2M7rBUMQm68GnB1Ot7l1CblxEWcREcbpyhBKTWIOFRGMwg2TW\\ /zRR3cRNglx+ZC4FOeO0mfkX+nf+slyFODAnQkOzPZcGO8xc3I1emafX58Wl\\ /Guw==\" ,\" token_data\" :{\" identity\" :\" 689d90c1422a202fd59c4603c4e4f6cc\" ,\" path\" :\" \" ,\" expires\" :1816358184,\" access\" :[\" unknown\" ],\" is_admin\" :false}},\" realms\" :[]}" ;
478+ SyncUser syncUser = SyncUser .fromJson (oldSyncUserJSON );
479+
480+ // Note: we can't call isValid() and expect it to be true
481+ // since the user is not persisted in the UserStore
482+ // isValid() requires SyncManager.getUserStore().isActive(identity)
483+ // to return true as well.
484+ Token accessToken = syncUser .getAccessToken ();
485+ assertNotNull (accessToken );
486+ // refresh token should expire in 10 years (July 23, 2027)
487+ Calendar calendar = Calendar .getInstance ();
488+ calendar .setTimeInMillis (accessToken .expiresMs ());
489+ int day = calendar .get (Calendar .DAY_OF_MONTH );
490+ int month = calendar .get (Calendar .MONTH );
491+ int year = calendar .get (Calendar .YEAR );
492+
493+ assertEquals (23 , day );
494+ assertEquals (Calendar .JULY , month );
495+ assertEquals (2027 , year );
496+
497+ assertEquals ("http://192.168.1.151:9080/auth" , syncUser .getAuthenticationUrl ().toString ());
498+ }
499+
500+ @ Test
501+ @ Ignore ("until https://github.com/realm/realm-java/issues/5097 is fixed" )
502+ public void logoutUserShouldDeleteRealmAfterRestart () throws InterruptedException {
503+ SyncManager .reset ();
504+ BaseRealm .applicationContext = null ; // Required for Realm.init() to work
505+ Realm .init (InstrumentationRegistry .getTargetContext ());
506+
507+ SyncUser user = createTestUser ();
508+ SyncConfiguration syncConfiguration = new SyncConfiguration
509+ .Builder (user , "realm://127.0.0.1:9080/~/tests" )
510+ .modules (new StringOnlyModule ())
511+ .build ();
512+
513+ Realm realm = Realm .getInstance (syncConfiguration );
514+ realm .executeTransaction (new Realm .Transaction () {
515+ @ Override
516+ public void execute (Realm realm ) {
517+ realm .createObject (StringOnly .class ).setChars ("1" );
518+ }
519+ });
520+ user .logout ();
521+ realm .close ();
522+
523+ final File realmPath = new File (syncConfiguration .getPath ());
524+ assertTrue (realmPath .exists ());
525+
526+ // simulate an app restart
527+ SyncManager .reset ();
528+ BaseRealm .applicationContext = null ;
529+ Realm .init (InstrumentationRegistry .getTargetContext ());
530+
531+ //now the file should be deleted
532+ assertFalse (realmPath .exists ());
533+ }
410534}
0 commit comments