package com.urbanairship.api.push.parse.audience; import com.google.common.collect.Iterables; import com.urbanairship.api.common.parse.APIParsingException; import com.urbanairship.api.push.model.audience.BasicValueSelector; import com.urbanairship.api.push.model.audience.CompoundSelector; import com.urbanairship.api.push.model.audience.Selector; import com.urbanairship.api.push.model.audience.SelectorType; import com.urbanairship.api.push.model.audience.ValueSelector; import com.urbanairship.api.push.parse.PushObjectMapper; import org.codehaus.jackson.map.ObjectMapper; import org.junit.Test; import java.util.Iterator; import java.util.UUID; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; public class SelectorDeserializerTest { private static final ObjectMapper mapper = PushObjectMapper.getInstance(); @Test public void testDeserializeBroadcast() throws Exception { Selector value = mapper.readValue("\"all\"", Selector.class); assertEquals(value.getType(), SelectorType.ALL); } @Test public void testDeserializeTriggered() throws Exception { Selector value = mapper.readValue("\"triggered\"", Selector.class); assertEquals(value.getType(), SelectorType.TRIGGERED); } @Test public void testIosChannelCase() throws Exception { String iosChannel = UUID.randomUUID().toString(); String json = "{\"ios_channel\": \"" + iosChannel + "\"}"; BasicValueSelector value = (BasicValueSelector) mapper.readValue(json, Selector.class); assertTrue(value.getType() == SelectorType.IOS_CHANNEL); assertEquals(value.getValue(), iosChannel); } @Test public void testAndroidChannelCase() throws Exception { String androidChannel = UUID.randomUUID().toString(); String json = "{\"android_channel\": \"" + androidChannel + "\"}"; BasicValueSelector value = (BasicValueSelector) mapper.readValue(json, Selector.class); assertTrue(value.getType() == SelectorType.ANDROID_CHANNEL); assertEquals(value.getValue(), androidChannel); } @Test public void testAmazonChannelCase() throws Exception { String amazonChannel = UUID.randomUUID().toString(); String json = "{\"amazon_channel\": \"" + amazonChannel + "\"}"; BasicValueSelector value = (BasicValueSelector) mapper.readValue(json, Selector.class); assertTrue(value.getType() == SelectorType.AMAZON_CHANNEL); assertEquals(value.getValue(), amazonChannel); } @Test public void testNamedUserCase() throws Exception { String namedUser = "FakeNamedUser"; String json = "{\"named_user\": \"" + namedUser + "\"}"; BasicValueSelector value = (BasicValueSelector) mapper.readValue(json, Selector.class); assertTrue(value.getType() == SelectorType.NAMED_USER); assertEquals(value.getValue(), namedUser); } @Test public void testDeserializeTag() throws Exception { Selector value = mapper.readValue("{ \"tag\" : \"derp\" }", Selector.class); assertTrue(value.getType() == SelectorType.TAG); assertTrue(value instanceof ValueSelector); } @Test public void testTagClass() throws Exception { String json = "{\n" + " \"tag\" : \"1\",\n" + " \"tag_class\" : \"autogroup\"\n" + "}"; Selector value = mapper.readValue(json, Selector.class); assertTrue(value.getType() == SelectorType.TAG); assertTrue(value instanceof ValueSelector); ValueSelector vs = (ValueSelector) value; assertTrue(vs.getAttributes().isPresent()); assertEquals(1, vs.getAttributes().get().size()); assertEquals("autogroup", vs.getAttributes().get().get("tag_class")); } @Test public void testTagGroup() throws Exception { String json = "{\n" + " \"tag\": \"tag1\",\n" + " \"group\": \"group1\"\n" + "}"; Selector value = mapper.readValue(json, Selector.class); assertTrue(value.getType() == SelectorType.TAG); assertTrue(value instanceof ValueSelector); ValueSelector vs = (ValueSelector) value; assertTrue(vs.getAttributes().isPresent()); assertEquals(1, vs.getAttributes().get().size()); assertEquals("group1", vs.getAttributes().get().get("group")); } @Test public void testStaticList() throws Exception { String json = "{\"static_list\":\"list123\"}"; Selector value = mapper.readValue(json, Selector.class); assertNotNull(value); assertEquals(value.getType(), SelectorType.STATIC_LIST); assertEquals(((ValueSelector)value).getValue(), "list123"); } @Test public void testAtomicCaseInsensitivity() throws Exception { assertEquals(SelectorType.ALL, mapper.readValue("\"all\"", Selector.class).getType()); assertEquals(SelectorType.ALL, mapper.readValue("\"ALL\"", Selector.class).getType()); assertEquals(SelectorType.ALL, mapper.readValue("\"aLl\"", Selector.class).getType()); assertEquals(SelectorType.TRIGGERED, mapper.readValue("\"triggered\"", Selector.class).getType()); assertEquals(SelectorType.TRIGGERED, mapper.readValue("\"TRIGGERED\"", Selector.class).getType()); assertEquals(SelectorType.TRIGGERED, mapper.readValue("\"trIGGeRed\"", Selector.class).getType()); } @Test public void testCompoundSelector() throws Exception { String json = "{\n" + " \"and\" : [\n" + " { \"tag\" : \"herp\" }, \n" + " { \"tag\" : \"derp\" }, \n" + " { \"static_list\" : \"test123\"} \n" + " ]\n" + "}"; Selector s = mapper.readValue(json, Selector.class); assertTrue(s instanceof CompoundSelector); assertEquals(SelectorType.AND, s.getType()); CompoundSelector cs = (CompoundSelector) s; assertEquals(3, Iterables.size(cs.getChildren())); Iterator<Selector> i = cs.getChildren().iterator(); Selector c = i.next(); assertTrue(c instanceof ValueSelector); ValueSelector vs = (ValueSelector) c; assertEquals(SelectorType.TAG, c.getType()); assertEquals("herp", vs.getValue()); c = i.next(); assertTrue(c instanceof ValueSelector); vs = (ValueSelector) c; assertEquals(SelectorType.TAG, c.getType()); assertEquals("derp", vs.getValue()); c = i.next(); assertTrue(c instanceof ValueSelector); vs = (ValueSelector) c; assertEquals(SelectorType.STATIC_LIST, c.getType()); assertEquals("test123", vs.getValue()); } @Test public void testGroupCompoundSelector() throws Exception { String json = "{\n" + " \"and\" : [\n" + " { \"tag\" : \"tag1\", \"group\" : \"group1\" }, \n" + " { \"tag\" : \"tag2\", \"group\" : \"group2\" }, \n" + " { \"tag\" : \"tag3\"}\n" + " ]\n" + "}"; Selector s = mapper.readValue(json, Selector.class); assertTrue(s instanceof CompoundSelector); assertEquals(SelectorType.AND, s.getType()); CompoundSelector cs = (CompoundSelector) s; assertEquals(3, Iterables.size(cs.getChildren())); Iterator<Selector> i = cs.getChildren().iterator(); Selector c = i.next(); assertTrue(c instanceof ValueSelector); ValueSelector vs = (ValueSelector) c; assertEquals(SelectorType.TAG, c.getType()); assertEquals("group1", vs.getAttributes().get().get("group")); assertEquals("tag1", vs.getValue()); c = i.next(); assertTrue(c instanceof ValueSelector); vs = (ValueSelector) c; assertEquals(SelectorType.TAG, c.getType()); assertEquals("group2", vs.getAttributes().get().get("group")); assertEquals("tag2", vs.getValue()); c = i.next(); assertTrue(c instanceof ValueSelector); vs = (ValueSelector) c; assertEquals(SelectorType.TAG, c.getType()); assertEquals("tag3", vs.getValue()); } @Test public void testNOT() throws Exception { String json = "{" + " \"not\" : {" + " \"tag\" : \"derp\"" + " }" + "}"; Selector s = mapper.readValue(json, Selector.class); assertTrue(s instanceof CompoundSelector); assertEquals(SelectorType.NOT, s.getType()); CompoundSelector cs = (CompoundSelector) s; assertEquals(1, Iterables.size(cs.getChildren())); } @Test public void testImplicitOR() throws Exception { String json = "{\n" + " \"tag\": [\n" + " \"Joy\",\n" + " \"Division\",\n" + " \"New\",\n" + " \"Order\"\n" + " ]\n" + "}"; Selector s = mapper.readValue(json, Selector.class); assertTrue(s instanceof CompoundSelector); assertEquals(SelectorType.OR, s.getType()); CompoundSelector cs = (CompoundSelector) s; assertEquals(4, Iterables.size(cs.getChildren())); Iterator<Selector> i = cs.getChildren().iterator(); s = i.next(); assertTrue(s instanceof ValueSelector); assertEquals(SelectorType.TAG, s.getType()); assertEquals("Joy", ((ValueSelector) s).getValue()); s = i.next(); assertTrue(s instanceof ValueSelector); assertEquals(SelectorType.TAG, s.getType()); assertEquals("Division", ((ValueSelector) s).getValue()); s = i.next(); assertTrue(s instanceof ValueSelector); assertEquals(SelectorType.TAG, s.getType()); assertEquals("New", ((ValueSelector) s).getValue()); s = i.next(); assertTrue(s instanceof ValueSelector); assertEquals(SelectorType.TAG, s.getType()); assertEquals("Order", ((ValueSelector) s).getValue()); } @Test public void testImplicitORForPlatform() throws Exception { String apid1 = UUID.randomUUID().toString(); String apid2 = UUID.randomUUID().toString(); String json = "{\n" + " \"apid\": [\n" + " \"" + apid1 + "\",\n" + " \"" + apid2 + "\"\n" + " ]\n" + "}"; Selector s = mapper.readValue(json, Selector.class); assertTrue(s instanceof CompoundSelector); assertEquals(SelectorType.OR, s.getType()); CompoundSelector cs = (CompoundSelector) s; assertEquals(2, Iterables.size(cs.getChildren())); Iterator<Selector> i = cs.getChildren().iterator(); s = i.next(); assertTrue(s instanceof ValueSelector); assertEquals(SelectorType.APID, s.getType()); assertEquals(apid1, ((ValueSelector) s).getValue()); s = i.next(); assertTrue(s instanceof ValueSelector); assertEquals(SelectorType.APID, s.getType()); assertEquals(apid2, ((ValueSelector) s).getValue()); } @Test public void testNestedCompound() throws Exception { String json = "{\n" + " \"and\" : [\n" + " { \"or\" : [\n" + " { \"alias\" : \"s1\" },\n" + " { \"alias\" : \"s2\" }\n" + " ] },\n" + " { \"or\" : [\n" + " { \"tag\" : \"t1\" },\n" + " { \"tag\" : \"t2\" }\n" + " ] }\n" + " ]\n" + "}"; Selector s = mapper.readValue(json, Selector.class); assertEquals(SelectorType.AND, s.getType()); assertEquals(2, Iterables.size(((CompoundSelector) s).getChildren())); Iterator<Selector> i = ((CompoundSelector) s).getChildren().iterator(); Selector c = i.next(); assertTrue(c instanceof CompoundSelector); assertEquals(SelectorType.OR, c.getType()); assertEquals(SelectorType.ALIAS, ((CompoundSelector) c).getChildren().iterator().next().getType()); } @Test public void testCase() throws Exception { String json = "{\"and\" : [{\"tag\" : \"t1\"}]}"; Selector s = mapper.readValue(json, Selector.class); assertEquals(SelectorType.AND, s.getType()); json = "{\"AND\" : [{\"TAG\" : \"t1\"}]}"; s = mapper.readValue(json, Selector.class); assertEquals(SelectorType.AND, s.getType()); json = "{\"Or\" : [{\"tag\" : \"t1\"}]}"; s = mapper.readValue(json, Selector.class); assertEquals(SelectorType.OR, s.getType()); } /* * Illegal expressions */ @Test(expected = APIParsingException.class) public void testInvalidAtomicSelector() throws Exception { mapper.readValue("\"derped\"", Selector.class); } @Test(expected = APIParsingException.class) public void testAtomicWithArgument() throws Exception { mapper.readValue("{ \"all\" : \"some\" }", Selector.class); } @Test(expected = APIParsingException.class) public void testBadTagValue() throws Exception { mapper.readValue("{ \"tag\" : 10 }", Selector.class); } @Test(expected = APIParsingException.class) public void testUnknownSelectorType() throws Exception { mapper.readValue("{ \"derp\" : \"value\" }", Selector.class); } @Test(expected = APIParsingException.class) public void testAtomicNestedInCompound() throws Exception { String json = "{\n" + " \"or\" : [\n" + " \"all\",\n" + " \"triggered\"\n" + " ]\n" + "}"; mapper.readValue(json, Selector.class); } @Test(expected = APIParsingException.class) public void testEmptyCompoundExpression() throws Exception { mapper.readValue("{ \"OR\" : [ ] }", Selector.class); } @Test(expected = APIParsingException.class) public void testTooManyArgumentsToNOT() throws Exception { String json = "{\n" + " \"not\" : [\n" + " { \"tag\" : \"wat\" },\n" + " { \"tag\" : \"derp\" }\n" + " ]\n" + "}"; mapper.readValue(json, Selector.class); } @Test(expected = APIParsingException.class) public void testBadImplicitOR() throws Exception { String json = "{\n" + " \"alias\" : [\n" + " \"seg1\",\n" + " { \"tag\" : \"whoops\" }\n" + " ]\n" + "}"; mapper.readValue(json, Selector.class); } @Test(expected = APIParsingException.class) public void testCompoundValidation_AND1() throws Exception { mapper.readValue("{\"and\" : \"foo\"}", Selector.class); } @Test(expected = APIParsingException.class) public void testCompoundValidation_NOT() throws Exception { mapper.readValue("{\"not\" : [ { \"tag\" : \"foo\" }, { \"tag\" : \"bar\" } ] }", Selector.class); } @Test(expected = APIParsingException.class) public void testCompoundValidation_ContainsAtomic() throws Exception { mapper.readValue("{\"or\" : [ \"all\", \"triggered\" ] }", Selector.class); } }