/* * 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.json.JSONException; import org.json.JSONObject; import org.junit.Test; import org.mockito.internal.util.collections.Sets; import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONCompareMode; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class ParsePushStateTest { //region testDefaults @Test(expected = IllegalArgumentException.class) public void testDefaultsWithoutData() throws Exception { // We have to set data to a state otherwise it will throw an exception JSONObject data = new JSONObject(); ParsePush.State state = new ParsePush.State.Builder() .build(); } @Test public void testDefaultsWithData() throws Exception { // We have to set data to a state otherwise it will throw an exception JSONObject data = new JSONObject(); ParsePush.State state = new ParsePush.State.Builder() .data(data) .build(); assertEquals(null, state.expirationTime()); assertEquals(null, state.expirationTimeInterval()); assertEquals(null, state.channelSet()); JSONAssert.assertEquals(data, state.data(), JSONCompareMode.NON_EXTENSIBLE); assertEquals(null, state.pushToAndroid()); assertEquals(null, state.pushToIOS()); assertEquals(null, state.queryState()); } //endregion @Test public void testCopy() throws JSONException { ParsePush.State state = mock(ParsePush.State.class); when(state.expirationTime()).thenReturn(1L); when(state.expirationTimeInterval()).thenReturn(2L); Set channelSet = Sets.newSet("one", "two"); when(state.channelSet()).thenReturn(channelSet); JSONObject data = new JSONObject(); data.put("foo", "bar"); when(state.data()).thenReturn(data); when(state.pushToAndroid()).thenReturn(true); when(state.pushToIOS()).thenReturn(false); ParseQuery.State<ParseInstallation> queryState = new ParseQuery.State.Builder<>(ParseInstallation.class).build(); when(state.queryState()).thenReturn(queryState); ParsePush.State copy = new ParsePush.State.Builder(state).build(); assertSame(1L, copy.expirationTime()); assertSame(2L, copy.expirationTimeInterval()); Set channelSetCopy = copy.channelSet(); assertNotSame(channelSet, channelSetCopy); assertTrue(channelSetCopy.size() == 2 && channelSetCopy.contains("one")); JSONObject dataCopy = copy.data(); assertNotSame(data, dataCopy); assertEquals("bar", dataCopy.get("foo")); assertTrue(copy.pushToAndroid()); assertFalse(copy.pushToIOS()); ParseQuery.State<ParseInstallation> queryStateCopy = copy.queryState(); assertNotSame(queryState, queryStateCopy); assertEquals("_Installation", queryStateCopy.className()); } //region testExpirationTime @Test public void testExpirationTimeNullTime() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .expirationTime(null) .data(new JSONObject()) .build(); assertEquals(null, state.expirationTime()); } @Test public void testExpirationTimeNormalTime() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .expirationTime(100L) .data(new JSONObject()) .build(); assertEquals(100L, state.expirationTime().longValue()); } //endregion //region testExpirationTimeInterval @Test public void testExpirationTimeIntervalNullInterval() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .expirationTimeInterval(null) .data(new JSONObject()) .build(); assertEquals(null, state.expirationTimeInterval()); } @Test public void testExpirationTimeIntervalNormalInterval() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .expirationTimeInterval(100L) .data(new JSONObject()) .build(); assertEquals(100L, state.expirationTimeInterval().longValue()); } //endregion //region testChannelSet @Test(expected = IllegalArgumentException.class) public void testChannelSetNullChannelSet() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .channelSet(null) .data(new JSONObject()) .build(); } @Test(expected = IllegalArgumentException.class) public void testChannelSetNormalChannelSetWithNullChannel() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); Set<String> channelSet = new HashSet<>(); channelSet.add(null); ParsePush.State state = builder .channelSet(channelSet) .data(new JSONObject()) .build(); } @Test public void testChannelSetNormalChannelSet() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); Set<String> channelSet = new HashSet<>(); channelSet.add("foo"); channelSet.add("bar"); ParsePush.State state = builder .channelSet(channelSet) .data(new JSONObject()) .build(); assertEquals(2, state.channelSet().size()); assertTrue(state.channelSet().contains("foo")); assertTrue(state.channelSet().contains("bar")); } @Test public void testChannelSetOverwrite() { Set<String> channelSet = new HashSet<>(); channelSet.add("foo"); Set<String> channelSetAgain = new HashSet<>(); channelSetAgain.add("bar"); ParsePush.State state = new ParsePush.State.Builder() .channelSet(channelSet) .channelSet(channelSetAgain) .data(new JSONObject()) .build(); assertEquals(1, state.channelSet().size()); assertTrue(state.channelSet().contains("bar")); } @Test public void testChannelSetDuplicateChannel() { final List<String> channelSet = new ArrayList<String>(){{ add("foo"); add("foo"); }}; ParsePush.State state = new ParsePush.State.Builder() .channelSet(channelSet) .data(new JSONObject()) .build(); assertEquals(1, state.channelSet().size()); assertTrue(state.channelSet().contains("foo")); } //endregion //region testData @Test(expected = IllegalArgumentException.class) public void testDataNullData() throws Exception { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .data(null) .build(); } @Test public void testDataNormalData() throws Exception { ParsePush.State.Builder builder = new ParsePush.State.Builder(); JSONObject data = new JSONObject(); data.put("name", "value"); ParsePush.State state = builder .data(data) .build(); JSONObject dataAgain = state.data(); assertEquals(1, dataAgain.length()); assertEquals("value", dataAgain.get("name")); } //endregion //region testPushToAndroid @Test public void testPushToAndroidNullValue() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .pushToAndroid(null) .data(new JSONObject()) .build(); assertEquals(null, state.pushToAndroid()); } @Test public void testPushToAndroidNormalValue() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .pushToAndroid(true) .data(new JSONObject()) .build(); assertTrue(state.pushToAndroid()); } @Test(expected = IllegalArgumentException.class) public void testPushToAndroidQueryAlreadySet() throws Exception { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .query(ParseInstallation.getQuery()) .pushToAndroid(true) .data(new JSONObject()) .build(); } //endregion //region testPushToIOS @Test public void testPushToIOSNullValue() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .pushToIOS(null) .data(new JSONObject()) .build(); assertEquals(null, state.pushToIOS()); } @Test public void testPushToIOSNormalValue() { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .pushToIOS(true) .data(new JSONObject()) .build(); assertTrue(state.pushToIOS()); } @Test(expected = IllegalArgumentException.class) public void testPushToIOSQueryAlreadySet() throws Exception { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .query(ParseInstallation.getQuery()) .pushToIOS(true) .data(new JSONObject()) .build(); } //endregion //region testQuery @Test(expected = IllegalArgumentException.class) public void testQueryNullQuery() throws Exception { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .query(null) .data(new JSONObject()) .build(); } @Test(expected = IllegalArgumentException.class) public void testQueryPushToIOSPushToAndroidAlreadySet() throws Exception { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .pushToAndroid(true) .pushToIOS(false) .query(ParseInstallation.getQuery()) .data(new JSONObject()) .build(); } @Test(expected = IllegalArgumentException.class) public void testQueryNotInstallationQuery() throws Exception { ParsePush.State.Builder builder = new ParsePush.State.Builder(); ParsePush.State state = builder .query(new ParseQuery<ParseInstallation>("test")) .data(new JSONObject()) .build(); } @Test public void testQueryNormalQuery() throws Exception { ParsePush.State.Builder builder = new ParsePush.State.Builder(); // Normal query ParseQuery<ParseInstallation> query = ParseInstallation.getQuery(); // Make test ParseQuery state ParseQuery.State.Builder<ParseObject> subQueryState = new ParseQuery.State.Builder<>("TestObject"); query.getBuilder() .whereEqualTo("foo", "bar") .whereMatchesQuery("subquery", subQueryState) .setLimit(12) .setSkip(34) .orderByAscending("foo").addDescendingOrder("bar") .include("name") .selectKeys(Arrays.asList("name", "blah")) .setTracingEnabled(true) .redirectClassNameForKey("what"); ParsePush.State state = builder .query(query) .data(new JSONObject()) .build(); ParseQuery.State queryStateAgain = state.queryState(); JSONObject queryStateAgainJson = queryStateAgain.toJSON(PointerEncoder.get()); assertEquals("_Installation", queryStateAgainJson.getString("className")); JSONAssert.assertEquals("{" + "\"foo\":\"bar\"," + "\"subquery\":{\"$inQuery\":{\"className\":\"TestObject\",\"where\":{}}}" + "}", queryStateAgainJson.getJSONObject("where"), JSONCompareMode.NON_EXTENSIBLE); assertEquals(12, queryStateAgainJson.getInt("limit")); assertEquals(34, queryStateAgainJson.getInt("skip")); assertEquals("foo,-bar", queryStateAgainJson.getString("order")); assertEquals("name", queryStateAgainJson.getString("include")); assertEquals("name,blah", queryStateAgainJson.getString("fields")); assertEquals(1, queryStateAgainJson.getInt("trace")); assertEquals("what", queryStateAgainJson.getString("redirectClassNameForKey")); } //endregion //region testStateImmutable @Test public void testStateImmutable() throws Exception { JSONObject data = new JSONObject(); data.put("name", "value"); Set<String> channelSet = new HashSet<>(); channelSet.add("foo"); channelSet.add("bar"); ParsePush.State state = new ParsePush.State.Builder() .channelSet(channelSet) .data(data) .build(); // Verify channelSet immutable Set<String> stateChannelSet = state.channelSet(); try { stateChannelSet.add("test"); fail("Should throw an exception"); } catch (UnsupportedOperationException e) { // do nothing } channelSet.add("test"); assertEquals(2, state.channelSet().size()); assertTrue(state.channelSet().contains("foo")); assertTrue(state.channelSet().contains("bar")); // Verify data immutable JSONObject stateData = state.data(); stateData.put("foo", "bar"); JSONObject stateDataAgain = state.data(); assertEquals(1, stateDataAgain.length()); assertEquals("value", stateDataAgain.get("name")); // Verify queryState immutable // TODO(mengyan) add test after t6941155(Convert mutable parameter to immutable) } //endregion }