package org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.get; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import junit.framework.Assert; import org.buddycloud.channelserver.channel.ChannelManager; import org.buddycloud.channelserver.db.ClosableIteratorImpl; import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler; import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.PubSubElementProcessorAbstract; import org.buddycloud.channelserver.pubsub.accessmodel.AccessModels; import org.buddycloud.channelserver.pubsub.affiliation.Affiliations; import org.buddycloud.channelserver.pubsub.model.NodeItem; import org.buddycloud.channelserver.pubsub.model.impl.NodeItemImpl; import org.buddycloud.channelserver.pubsub.model.impl.NodeMembershipImpl; import org.buddycloud.channelserver.pubsub.subscription.Subscriptions; import org.buddycloud.channelserver.utils.node.NodeAclRefuseReason; import org.buddycloud.channelserver.utils.node.NodeViewAcl; import org.dom4j.Element; import org.dom4j.tree.BaseElement; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.xmpp.packet.IQ; import org.xmpp.packet.JID; import org.xmpp.packet.Packet; import org.xmpp.packet.PacketError; public class RepliesGetTest extends IQTestHandler { private static final Integer TOTAL_RESULTS = 4; private IQ request; private PubSubElementProcessorAbstract repliesGet; private Element element; private BlockingQueue<Packet> queue = new LinkedBlockingQueue<Packet>(); private String node = "/user/pamela@denmark.lit/posts"; private JID jid = new JID("juliet@shakespeare.lit"); private ChannelManager channelManager; private static final String TEST_NODE = "node1"; private NodeViewAcl nodeViewAcl; @Before public void setUp() throws Exception { queue = new LinkedBlockingQueue<Packet>(); channelManager = Mockito.mock(ChannelManager.class); repliesGet = new RepliesGet(queue, channelManager); request = readStanzaAsIq("/iq/pubsub/replies/request.stanza"); element = new BaseElement("replies"); Mockito.when(channelManager.nodeExists(Mockito.anyString())).thenReturn(true); Mockito.doReturn(new HashMap<String, String>()).when(channelManager).getNodeConf(Mockito.anyString()); Mockito.when(channelManager.getCountNodeItemReplies(Mockito.anyString(), Mockito.anyString())).thenReturn(TOTAL_RESULTS); Mockito.when(channelManager.getNodeItem(Mockito.anyString(), Mockito.anyString())).thenReturn( new NodeItemImpl(TEST_NODE, "1", new Date(), "payload")); nodeViewAcl = Mockito.mock(NodeViewAcl.class); repliesGet.setNodeViewAcl(nodeViewAcl); Mockito.doReturn(true).when(nodeViewAcl) .canViewNode(Mockito.anyString(), Mockito.any(NodeMembershipImpl.class), Mockito.any(AccessModels.class), Mockito.anyBoolean()); NodeMembershipImpl membership = new NodeMembershipImpl(node, request.getFrom(), Subscriptions.subscribed, Affiliations.member, null); Mockito.when(channelManager.getNodeMembership(Mockito.anyString(), Mockito.any(JID.class))).thenReturn(membership); } @Test public void testPassingRecentItemsAsElementNameReturnsTrue() { Assert.assertTrue(repliesGet.accept(element)); } @Test public void testPassingNotRecentItemsAsElementNameReturnsFalse() { Element element = new BaseElement("not-replies"); Assert.assertFalse(repliesGet.accept(element)); } @Test public void testMissingNodeAttributeReturnsErrorStanza() throws Exception { request.getChildElement().element("replies").addAttribute("node", null); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); PacketError error = response.getError(); Assert.assertNotNull(error); Assert.assertEquals(PacketError.Type.modify, error.getType()); Assert.assertEquals("nodeid-required", error.getApplicationConditionName()); } @Test public void testMissingItemIdAttributeReturnsErrorStanza() throws Exception { request.getChildElement().element("replies").addAttribute("item_id", null); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); PacketError error = response.getError(); Assert.assertNotNull(error); Assert.assertEquals(PacketError.Type.modify, error.getType()); Assert.assertEquals("itemid-required", error.getApplicationConditionName()); } @Test public void testNodeStoreExceptionGeneratesAnErrorStanza() throws Exception { Mockito.when(channelManager.nodeExists(Mockito.anyString())).thenThrow(new NodeStoreException()); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); PacketError error = response.getError(); Assert.assertNotNull(error); Assert.assertEquals(PacketError.Type.wait, error.getType()); Assert.assertEquals(PacketError.Condition.internal_server_error, error.getCondition()); } @Test public void userWhoCantAccessChannelGetsPermissionErrorStanzaReply() throws Exception { Mockito.doReturn(false).when(nodeViewAcl) .canViewNode(Mockito.anyString(), Mockito.any(NodeMembershipImpl.class), Mockito.any(AccessModels.class), Mockito.anyBoolean()); NodeAclRefuseReason refusalReason = new NodeAclRefuseReason(PacketError.Type.auth, PacketError.Condition.forbidden, "pending-subscription"); Mockito.when(nodeViewAcl.getReason()).thenReturn(refusalReason); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); PacketError error = response.getError(); Assert.assertNotNull(error); Assert.assertEquals(PacketError.Type.auth, error.getType()); Assert.assertEquals(PacketError.Condition.forbidden, error.getCondition()); } @Test public void testIfItemDoesNotExistErrorStanzaIsReturned() throws Exception { Mockito.when(channelManager.getNodeItem(Mockito.anyString(), Mockito.anyString())).thenReturn(null); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); PacketError error = response.getError(); Assert.assertNotNull(error); Assert.assertEquals(PacketError.Type.modify, error.getType()); Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } @Test public void testNoRepliesReturnsEmptyStanza() throws Exception { Mockito.when(channelManager.getNodeItemReplies(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.eq(true), Mockito.anyInt())).thenReturn( new ClosableIteratorImpl<NodeItem>(new ArrayList<NodeItem>().iterator())); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); Element items = response.getElement().element("pubsub").element("items"); Assert.assertEquals("/user/channeluser@example.com/posts", items.attributeValue("node")); Assert.assertEquals(0, items.elements("item").size()); } @Test public void testOutgoingStanzaFormattedAsExpected() throws Exception { ArrayList<NodeItem> expectedResults = new ArrayList<NodeItem>(); expectedResults.add(new NodeItemImpl(TEST_NODE, "1", new Date(), "<entry>value1</entry>")); expectedResults.add(new NodeItemImpl(TEST_NODE, "2", new Date(), "<entry>value2</entry>")); Mockito.when(channelManager.getNodeItemReplies(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.eq(true), Mockito.anyInt())).thenReturn( new ClosableIteratorImpl<NodeItem>(expectedResults.iterator())); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); Element items = response.getElement().element("pubsub").element("items"); Assert.assertEquals("/user/channeluser@example.com/posts", items.attributeValue("node")); Assert.assertEquals(2, items.elements("item").size()); Assert.assertEquals("1", items.element("item").attributeValue("id")); Assert.assertEquals("value1", items.element("item").elementText("entry")); } @Test public void testUnparsableItemEntriesAreSimplyIgnored() throws Exception { ArrayList<NodeItem> expectedResults = new ArrayList<NodeItem>(); expectedResults.add(new NodeItemImpl(TEST_NODE, "1", new Date(), "<entry>value1</entry>")); expectedResults.add(new NodeItemImpl(TEST_NODE, "2", new Date(), "<entry>value2")); Mockito.when(channelManager.getNodeItemReplies(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.eq(true), Mockito.anyInt())).thenReturn( new ClosableIteratorImpl<NodeItem>(expectedResults.iterator())); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); Element items = response.getElement().element("pubsub").element("items"); Assert.assertEquals("/user/channeluser@example.com/posts", items.attributeValue("node")); Assert.assertEquals(1, items.elements("item").size()); Assert.assertEquals("1", items.element("item").attributeValue("id")); Assert.assertEquals("value1", items.element("item").elementText("entry")); } @Test public void testRsmElementIsAddedCorrectly() throws Exception { Element rsm = request.getChildElement().addElement("set"); rsm.addNamespace("", RepliesGet.NS_RSM); rsm.addElement("max").setText("4"); rsm.addElement("after").setText("1"); ArrayList<NodeItem> expectedResults = new ArrayList<NodeItem>(); expectedResults.add(new NodeItemImpl(TEST_NODE, "1", new Date(), "<entry>value1</entry>")); expectedResults.add(new NodeItemImpl(TEST_NODE, "2", new Date(), "<entry>value2</entry>")); expectedResults.add(new NodeItemImpl(TEST_NODE, "3", new Date(), "<entry>value3</entry>")); expectedResults.add(new NodeItemImpl(TEST_NODE, "4", new Date(), "<entry>value4</entry>")); Mockito.when(channelManager.getNodeItemReplies(Mockito.anyString(), Mockito.anyString(), Mockito.eq("1"), Mockito.eq(true), Mockito.eq(4))).thenReturn( new ClosableIteratorImpl<NodeItem>(expectedResults.iterator())); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); Element items = response.getElement().element("pubsub").element("items"); Assert.assertEquals("/user/channeluser@example.com/posts", items.attributeValue("node")); Assert.assertEquals(4, items.elements("item").size()); Element rsmResult = response.getElement().element("pubsub").element("set"); Assert.assertEquals("1", rsmResult.elementText("first")); Assert.assertEquals("4", rsmResult.elementText("last")); Assert.assertEquals(String.valueOf(TOTAL_RESULTS), rsmResult.elementText("count")); } @Test public void rsmStillAddedWhenThereAreNoResults() throws Exception { Element rsm = request.getChildElement().addElement("set"); rsm.addNamespace("", RepliesGet.NS_RSM); rsm.addElement("max").setText("4"); rsm.addElement("after").setText("1"); ArrayList<NodeItem> expectedResults = new ArrayList<NodeItem>(); Mockito.when(channelManager.getNodeItemReplies(Mockito.anyString(), Mockito.anyString(), Mockito.eq("1"), Mockito.eq(true), Mockito.eq(4))).thenReturn( new ClosableIteratorImpl<NodeItem>(expectedResults.iterator())); Mockito.when(channelManager.getCountNodeItemReplies(Mockito.anyString(), Mockito.anyString())).thenReturn(0); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); Element items = response.getElement().element("pubsub").element("items"); Assert.assertEquals("/user/channeluser@example.com/posts", items.attributeValue("node")); Assert.assertEquals(0, items.elements("item").size()); Element rsmResult = response.getElement().element("pubsub").element("set"); Assert.assertNull(rsmResult.elementText("first")); Assert.assertNull(rsmResult.elementText("last")); Assert.assertEquals("0", rsmResult.elementText("count")); } @Test public void providingBeforeValueInRsmElementInvokesPastItemLookup() throws Exception { Element rsm = request.getChildElement().addElement("set"); rsm.addNamespace("", RepliesGet.NS_RSM); rsm.addElement("max").setText("4"); rsm.addElement("after").setText("1"); rsm.addElement("before").setText("2"); ArrayList<NodeItem> expectedResults = new ArrayList<NodeItem>(); expectedResults.add(new NodeItemImpl(TEST_NODE, "1", new Date(), "<entry>value1</entry>")); expectedResults.add(new NodeItemImpl(TEST_NODE, "2", new Date(), "<entry>value2</entry>")); expectedResults.add(new NodeItemImpl(TEST_NODE, "3", new Date(), "<entry>value3</entry>")); expectedResults.add(new NodeItemImpl(TEST_NODE, "4", new Date(), "<entry>value4</entry>")); Mockito.when(channelManager.getNodeItemReplies(Mockito.anyString(), Mockito.anyString(), Mockito.eq("2"), Mockito.eq(false), Mockito.eq(4))).thenReturn( new ClosableIteratorImpl<NodeItem>(expectedResults.iterator())); repliesGet.process(element, jid, request, null); Packet response = queue.poll(); Element items = response.getElement().element("pubsub").element("items"); Assert.assertEquals(4, items.elements("item").size()); } }