11
11
import org .json .JSONArray ;
12
12
import org .json .JSONException ;
13
13
import org .json .JSONObject ;
14
+ import org .junit .After ;
14
15
import org .junit .Rule ;
15
16
import org .junit .Test ;
16
17
import org .junit .rules .ExpectedException ;
17
18
19
+ import java .util .ArrayList ;
18
20
import java .util .Arrays ;
21
+ import java .util .Collections ;
19
22
import java .util .Date ;
20
23
import java .util .HashMap ;
21
24
import java .util .List ;
22
25
import java .util .Map ;
23
26
import java .util .Set ;
24
27
28
+ import bolts .Task ;
29
+
25
30
import static org .junit .Assert .assertEquals ;
26
31
import static org .junit .Assert .assertFalse ;
27
32
import static org .junit .Assert .assertNull ;
28
33
import static org .junit .Assert .assertTrue ;
34
+ import static org .mockito .Matchers .any ;
35
+ import static org .mockito .Matchers .anyString ;
29
36
import static org .mockito .Mockito .mock ;
30
37
import static org .mockito .Mockito .when ;
31
38
@@ -34,6 +41,11 @@ public class ParseObjectTest {
34
41
@ Rule
35
42
public ExpectedException thrown = ExpectedException .none ();
36
43
44
+ @ After
45
+ public void tearDown () {
46
+ ParseCorePlugins .getInstance ().reset ();
47
+ }
48
+
37
49
@ Test
38
50
public void testFromJSONPayload () throws JSONException {
39
51
JSONObject json = new JSONObject (
@@ -72,6 +84,151 @@ public void testFromJSONPayloadWithoutClassname() throws JSONException {
72
84
assertNull (parseObject );
73
85
}
74
86
87
+ //region testRevert
88
+
89
+ @ Test
90
+ public void testRevert () throws ParseException {
91
+ List <Task <Void >> tasks = new ArrayList <>();
92
+
93
+ // Mocked to let save work
94
+ ParseCurrentUserController userController = mock (ParseCurrentUserController .class );
95
+ when (userController .getAsync ()).thenReturn (Task .<ParseUser >forResult (null ));
96
+ ParseCorePlugins .getInstance ().registerCurrentUserController (userController );
97
+
98
+ // Mocked to simulate in-flight save
99
+ Task <ParseObject .State >.TaskCompletionSource tcs = Task .create ();
100
+ ParseObjectController objectController = mock (ParseObjectController .class );
101
+ when (objectController .saveAsync (
102
+ any (ParseObject .State .class ),
103
+ any (ParseOperationSet .class ),
104
+ anyString (),
105
+ any (ParseDecoder .class )))
106
+ .thenReturn (tcs .getTask ());
107
+ ParseCorePlugins .getInstance ().registerObjectController (objectController );
108
+
109
+ // New clean object
110
+ ParseObject object = new ParseObject ("TestObject" );
111
+ object .revert ("foo" );
112
+
113
+ // Reverts changes on new object
114
+ object .put ("foo" , "bar" );
115
+ object .put ("name" , "grantland" );
116
+ object .revert ();
117
+ assertNull (object .get ("foo" ));
118
+ assertNull (object .get ("name" ));
119
+
120
+ // Object from server
121
+ ParseObject .State state = mock (ParseObject .State .class );
122
+ when (state .className ()).thenReturn ("TestObject" );
123
+ when (state .objectId ()).thenReturn ("test_id" );
124
+ when (state .keySet ()).thenReturn (Collections .singleton ("foo" ));
125
+ when (state .get ("foo" )).thenReturn ("bar" );
126
+ object = ParseObject .from (state );
127
+ object .revert ();
128
+ assertFalse (object .isDirty ());
129
+ assertEquals ("bar" , object .get ("foo" ));
130
+
131
+ // Reverts changes on existing object
132
+ object .put ("foo" , "baz" );
133
+ object .put ("name" , "grantland" );
134
+ object .revert ();
135
+ assertFalse (object .isDirty ());
136
+ assertEquals ("bar" , object .get ("foo" ));
137
+ assertFalse (object .isDataAvailable ("name" ));
138
+
139
+ // Shouldn't revert changes done before last call to `save`
140
+ object .put ("foo" , "baz" );
141
+ object .put ("name" , "nlutsenko" );
142
+ tasks .add (object .saveInBackground ());
143
+ object .revert ();
144
+ assertFalse (object .isDirty ());
145
+ assertEquals ("baz" , object .get ("foo" ));
146
+ assertEquals ("nlutsenko" , object .get ("name" ));
147
+
148
+ // Should revert changes done after last call to `save`
149
+ object .put ("foo" , "qux" );
150
+ object .put ("name" , "grantland" );
151
+ object .revert ();
152
+ assertFalse (object .isDirty ());
153
+ assertEquals ("baz" , object .get ("foo" ));
154
+ assertEquals ("nlutsenko" , object .get ("name" ));
155
+
156
+ // Allow save to complete
157
+ tcs .setResult (state );
158
+ ParseTaskUtils .wait (Task .whenAll (tasks ));
159
+ }
160
+
161
+ @ Test
162
+ public void testRevertKey () throws ParseException {
163
+ List <Task <Void >> tasks = new ArrayList <>();
164
+
165
+ // Mocked to let save work
166
+ ParseCurrentUserController userController = mock (ParseCurrentUserController .class );
167
+ when (userController .getAsync ()).thenReturn (Task .<ParseUser >forResult (null ));
168
+ ParseCorePlugins .getInstance ().registerCurrentUserController (userController );
169
+
170
+ // Mocked to simulate in-flight save
171
+ Task <ParseObject .State >.TaskCompletionSource tcs = Task .create ();
172
+ ParseObjectController objectController = mock (ParseObjectController .class );
173
+ when (objectController .saveAsync (
174
+ any (ParseObject .State .class ),
175
+ any (ParseOperationSet .class ),
176
+ anyString (),
177
+ any (ParseDecoder .class )))
178
+ .thenReturn (tcs .getTask ());
179
+ ParseCorePlugins .getInstance ().registerObjectController (objectController );
180
+
181
+ // New clean object
182
+ ParseObject object = new ParseObject ("TestObject" );
183
+ object .revert ("foo" );
184
+
185
+ // Reverts changes on new object
186
+ object .put ("foo" , "bar" );
187
+ object .put ("name" , "grantland" );
188
+ object .revert ("foo" );
189
+ assertNull (object .get ("foo" ));
190
+ assertEquals ("grantland" , object .get ("name" ));
191
+
192
+ // Object from server
193
+ ParseObject .State state = mock (ParseObject .State .class );
194
+ when (state .className ()).thenReturn ("TestObject" );
195
+ when (state .objectId ()).thenReturn ("test_id" );
196
+ when (state .keySet ()).thenReturn (Collections .singleton ("foo" ));
197
+ when (state .get ("foo" )).thenReturn ("bar" );
198
+ object = ParseObject .from (state );
199
+ object .revert ("foo" );
200
+ assertFalse (object .isDirty ());
201
+ assertEquals ("bar" , object .get ("foo" ));
202
+
203
+ // Reverts changes on existing object
204
+ object .put ("foo" , "baz" );
205
+ object .put ("name" , "grantland" );
206
+ object .revert ("foo" );
207
+ assertEquals ("bar" , object .get ("foo" ));
208
+ assertEquals ("grantland" , object .get ("name" ));
209
+
210
+ // Shouldn't revert changes done before last call to `save`
211
+ object .put ("foo" , "baz" );
212
+ object .put ("name" , "nlutsenko" );
213
+ tasks .add (object .saveInBackground ());
214
+ object .revert ("foo" );
215
+ assertEquals ("baz" , object .get ("foo" ));
216
+ assertEquals ("nlutsenko" , object .get ("name" ));
217
+
218
+ // Should revert changes done after last call to `save`
219
+ object .put ("foo" , "qux" );
220
+ object .put ("name" , "grantland" );
221
+ object .revert ("foo" );
222
+ assertEquals ("baz" , object .get ("foo" ));
223
+ assertEquals ("grantland" , object .get ("name" ));
224
+
225
+ // Allow save to complete
226
+ tcs .setResult (state );
227
+ ParseTaskUtils .wait (Task .whenAll (tasks ));
228
+ }
229
+
230
+ //endregion
231
+
75
232
//region testGetter
76
233
77
234
@ Test ( expected = IllegalStateException .class )
0 commit comments