/*
* Copyright (c) 2015-present, Parse, LLC.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.parse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import bolts.Task;
import bolts.TaskCompletionSource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class CachedCurrentInstallationControllerTest {
private static final String KEY_DEVICE_TYPE = "deviceType";
@Before
public void setUp() {
ParseObject.registerSubclass(ParseInstallation.class);
}
@After
public void tearDown() {
ParseObject.unregisterSubclass(ParseInstallation.class);
}
//region testSetAsync
@Test
public void testSetAsyncWithNotCurrentInstallation() throws Exception {
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(null, null);
ParseInstallation currentInstallationInMemory = mock(ParseInstallation.class);
controller.currentInstallation = currentInstallationInMemory;
ParseInstallation testInstallation = mock(ParseInstallation.class);
ParseTaskUtils.wait(controller.setAsync(testInstallation));
// Make sure the in memory currentInstallation not change
assertSame(currentInstallationInMemory, controller.currentInstallation);
assertNotSame(controller.currentInstallation, testInstallation);
}
@Test
public void testSetAsyncWithCurrentInstallation() throws Exception {
InstallationId installationId = mock(InstallationId.class);
//noinspection unchecked
ParseObjectStore<ParseInstallation> store = mock(ParseObjectStore.class);
// Create test controller
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(store, installationId);
ParseInstallation currentInstallation = mock(ParseInstallation.class);
when(currentInstallation.getInstallationId()).thenReturn("testInstallationId");
controller.currentInstallation = currentInstallation;
ParseTaskUtils.wait(controller.setAsync(currentInstallation));
// Verify that we persist it
verify(store, times(1)).setAsync(currentInstallation);
// Make sure installationId is updated
verify(installationId, times(1)).set("testInstallationId");
}
//endregion
//region testGetAsync
@Test
public void testGetAsyncFromMemory() throws Exception {
// Create test controller
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(null, null);
ParseInstallation currentInstallationInMemory = new ParseInstallation();
controller.currentInstallation = currentInstallationInMemory;
ParseInstallation currentInstallation = ParseTaskUtils.wait(controller.getAsync());
assertSame(currentInstallationInMemory, currentInstallation);
}
@Test
public void testGetAsyncFromStore() throws Exception {
// Mock installationId
InstallationId installationId = mock(InstallationId.class);
//noinspection unchecked
ParseObjectStore<ParseInstallation> store = mock(ParseObjectStore.class);
ParseInstallation installation = mock(ParseInstallation.class);
when(installation.getInstallationId()).thenReturn("testInstallationId");
when(store.getAsync()).thenReturn(Task.forResult(installation));
// Create test controller
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(store, installationId);
ParseInstallation currentInstallation = ParseTaskUtils.wait(controller.getAsync());
verify(store, times(1)).getAsync();
// Make sure installationId is updated
verify(installationId, times(1)).set("testInstallationId");
// Make sure controller state is update to date
assertSame(installation, controller.currentInstallation);
// Make sure the installation we get is correct
assertSame(installation, currentInstallation);
}
@Test
public void testGetAsyncWithNoInstallation() throws Exception {
// Mock installationId
InstallationId installationId = mock(InstallationId.class);
when(installationId.get()).thenReturn("testInstallationId");
//noinspection unchecked
ParseObjectStore<ParseInstallation> store = mock(ParseObjectStore.class);
when(store.getAsync()).thenReturn(Task.<ParseInstallation>forResult(null));
// Create test controller
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(store, installationId);
ParseInstallation currentInstallation = ParseTaskUtils.wait(controller.getAsync());
verify(store, times(1)).getAsync();
// Make sure controller state is update to date
assertSame(controller.currentInstallation, currentInstallation);
// Make sure device info is updated
assertEquals("testInstallationId", currentInstallation.getInstallationId());
assertEquals("android", currentInstallation.get(KEY_DEVICE_TYPE));
}
@Test
public void testGetAsyncWithNoInstallationRaceCondition() throws ParseException {
// Mock installationId
InstallationId installationId = mock(InstallationId.class);
when(installationId.get()).thenReturn("testInstallationId");
//noinspection unchecked
ParseObjectStore<ParseInstallation> store = mock(ParseObjectStore.class);
TaskCompletionSource<ParseInstallation> tcs = new TaskCompletionSource();
when(store.getAsync()).thenReturn(tcs.getTask());
// Create test controller
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(store, installationId);
Task<ParseInstallation> taskA = controller.getAsync();
Task<ParseInstallation> taskB = controller.getAsync();
tcs.setResult(null);
ParseInstallation installationA = ParseTaskUtils.wait(taskA);
ParseInstallation installationB = ParseTaskUtils.wait(taskB);
verify(store, times(1)).getAsync();
assertSame(controller.currentInstallation, installationA);
assertSame(controller.currentInstallation, installationB);
// Make sure device info is updated
assertEquals("testInstallationId", installationA.getInstallationId());
assertEquals("android", installationA.get(KEY_DEVICE_TYPE));
}
//endregion
//region testExistsAsync
@Test
public void testExistAsyncFromMemory() throws Exception {
// Create test controller
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(null, null);
controller.currentInstallation = mock(ParseInstallation.class);
assertTrue(ParseTaskUtils.wait(controller.existsAsync()));
}
@Test
public void testExistAsyncFromStore() throws Exception {
//noinspection unchecked
ParseObjectStore<ParseInstallation> store = mock(ParseObjectStore.class);
when(store.existsAsync()).thenReturn(Task.forResult(true));
// Create test controller
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(store, null);
assertTrue(ParseTaskUtils.wait(controller.existsAsync()));
verify(store, times(1)).existsAsync();
}
//endregion
@Test
public void testClearFromMemory() throws Exception {
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(null, null);
controller.currentInstallation = mock(ParseInstallation.class);
controller.clearFromMemory();
assertNull(controller.currentInstallation);
}
@Test
public void testClearFromDisk() throws Exception {
// Mock installationId
InstallationId installationId = mock(InstallationId.class);
//noinspection unchecked
ParseObjectStore<ParseInstallation> store = mock(ParseObjectStore.class);
when(store.deleteAsync()).thenReturn(Task.<Void>forResult(null));
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(store, installationId);
controller.currentInstallation = mock(ParseInstallation.class);
controller.clearFromDisk();
assertNull(controller.currentInstallation);
// Make sure the in LDS currentInstallation is cleared
verify(store, times(1)).deleteAsync();
// Make sure installationId is cleared
verify(installationId, times(1)).clear();
}
@Test
public void testIsCurrent() throws Exception {
// Create test controller
CachedCurrentInstallationController controller =
new CachedCurrentInstallationController(null, null);
ParseInstallation installation = mock(ParseInstallation.class);
controller.currentInstallation = installation;
assertTrue(controller.isCurrent(installation));
assertFalse(controller.isCurrent(new ParseInstallation()));
}
}