From b74261583c0091896faab1c9bff8d2b2a37f86cf Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 15:08:12 +0100 Subject: [PATCH 01/35] Supports disco#items --- .../packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java index 138999f8..8ae886f2 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java @@ -129,6 +129,10 @@ private void sendServerDiscoInfo() query.addElement("feature").addAttribute("var", "http://jabber.org/protocol/disco#info"); + + query.addElement("feature").addAttribute("var", + "http://jabber.org/protocol/disco#items"); + outQueue.put(result); } From 9bfe7949f7ca660d02441c1b4cba99d750e9e03c Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 15:08:25 +0100 Subject: [PATCH 02/35] Supports jabber:iq:search --- .../packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java index 8ae886f2..3f279b71 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/discoinfo/DiscoInfoGet.java @@ -132,6 +132,9 @@ private void sendServerDiscoInfo() query.addElement("feature").addAttribute("var", "http://jabber.org/protocol/disco#items"); + + query.addElement("feature").addAttribute("var", + "jabber:iq:search"); outQueue.put(result); } From c18192b93136b0201e1bccde6d02e7911277e5ab Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 15:26:23 +0100 Subject: [PATCH 03/35] Add basic search classes --- .../packetprocessor/iq/IQProcessor.java | 3 + .../iq/namespace/search/Search.java | 65 +++++++++++++++++++ .../iq/namespace/search/SearchGet.java | 26 ++++++++ .../iq/namespace/search/SearchSet.java | 26 ++++++++ 4 files changed, 120 insertions(+) create mode 100644 src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java create mode 100644 src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java create mode 100644 src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/IQProcessor.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/IQProcessor.java index 77453cae..19fd77f8 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/IQProcessor.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/IQProcessor.java @@ -13,6 +13,7 @@ import org.buddycloud.channelserver.packetprocessor.iq.namespace.mam.MessageArchiveManagement; import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.JabberPubsub; import org.buddycloud.channelserver.packetprocessor.iq.namespace.register.JabberRegister; +import org.buddycloud.channelserver.packetprocessor.iq.namespace.search.Search; import org.buddycloud.channelserver.queue.FederatedQueueManager; import org.buddycloud.channelserver.queue.UnknownFederatedPacketException; import org.xmpp.packet.IQ; @@ -49,6 +50,8 @@ public IQProcessor(BlockingQueue outQueue, Configuration conf, processorsPerNamespace.put(JabberPubsub.NS_PUBSUB_OWNER, ps); processorsPerNamespace.put(MessageArchiveManagement.NAMESPACE_MAM, new MessageArchiveManagement(outQueue, channelManager)); + processorsPerNamespace.put(Search.NAMESPACE_URI, + new Search(outQueue, channelManager)); } @Override diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java new file mode 100644 index 00000000..a26cb709 --- /dev/null +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java @@ -0,0 +1,65 @@ +package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; + +import java.util.Collection; +import java.util.concurrent.BlockingQueue; + +import org.apache.log4j.Logger; +import org.buddycloud.channelserver.Configuration; +import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.channel.Conf; +import org.buddycloud.channelserver.db.exception.NodeStoreException; +import org.buddycloud.channelserver.packetprocessor.PacketProcessor; +import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.JabberPubsub; +import org.buddycloud.channelserver.pubsub.accessmodel.AccessModels; +import org.buddycloud.channelserver.pubsub.model.impl.NodeSubscriptionImpl; +import org.buddycloud.channelserver.pubsub.subscription.Subscriptions; +import org.dom4j.Element; +import org.dom4j.QName; +import org.xmpp.packet.IQ; +import org.xmpp.packet.IQ.Type; +import org.xmpp.packet.JID; +import org.xmpp.packet.Packet; +import org.xmpp.packet.PacketError; + +public class Search implements PacketProcessor { + + public static final String ELEMENT_NAME = "query"; + private static final Logger logger = Logger.getLogger(Search.class); + + public static final String NAMESPACE_URI = "jabber:iq:search"; + + private final BlockingQueue outQueue; + private final ChannelManager channelManager; + private IQ request; + + private SearchGet searchGet; + private SearchSet searchSet; + + public Search(BlockingQueue outQueue, + ChannelManager channelManager) { + this.outQueue = outQueue; + this.channelManager = channelManager; + + this.searchGet = new SearchGet(outQueue, channelManager); + this.searchSet = new SearchSet(outQueue, channelManager); + } + + @Override + public void process(IQ reqIQ) throws Exception { + request = reqIQ; + + if (request.getType().equals("get")) { + + } else if (request.getType().equals("set")) { + + } + IQ response = IQ.createResultIQ(request); + response.setType(IQ.Type.error); + PacketError error = new PacketError( + PacketError.Condition.bad_request, + PacketError.Type.modify + ); + response.setError(error); + outQueue.put(response); + } +} \ No newline at end of file diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java new file mode 100644 index 00000000..fc21da6d --- /dev/null +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -0,0 +1,26 @@ +package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; + +import java.util.concurrent.BlockingQueue; + +import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.packetprocessor.PacketProcessor; +import org.xmpp.packet.IQ; +import org.xmpp.packet.Packet; + + +public class SearchGet implements PacketProcessor { + + private ChannelManager channelManager; + private BlockingQueue outQueue; + + public SearchGet(BlockingQueue outQueue, ChannelManager channelManager) { + this.channelManager = channelManager; + this.outQueue = outQueue; + } + + @Override + public void process(IQ packet) throws Exception { + + } + +} diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java new file mode 100644 index 00000000..76513242 --- /dev/null +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -0,0 +1,26 @@ +package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; + +import java.util.concurrent.BlockingQueue; + +import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.packetprocessor.PacketProcessor; +import org.xmpp.packet.IQ; +import org.xmpp.packet.Packet; + + +public class SearchSet implements PacketProcessor { + + private ChannelManager channelManager; + private BlockingQueue outQueue; + + public SearchSet(BlockingQueue outQueue, ChannelManager channelManager) { + this.channelManager = channelManager; + this.outQueue = outQueue; + } + + @Override + public void process(IQ packet) throws Exception { + + } + +} From c9ee351f906cc231cd310af02b5fa2fe2673e99b Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 15:27:35 +0100 Subject: [PATCH 04/35] Call process --- .../packetprocessor/iq/namespace/search/Search.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java index a26cb709..93f5115e 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java @@ -49,9 +49,9 @@ public void process(IQ reqIQ) throws Exception { request = reqIQ; if (request.getType().equals("get")) { - + this.searchGet.process(request); } else if (request.getType().equals("set")) { - + this.searchSet.process(request); } IQ response = IQ.createResultIQ(request); response.setType(IQ.Type.error); From f7d5d480b2b48738cef933c3f57a20ed810b9193 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 15:30:42 +0100 Subject: [PATCH 05/35] Add template test files --- .../iq/namespace/search/SearchGetTest.java | 70 +++++++++++++++++++ .../iq/namespace/search/SearchSetTest.java | 69 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java create mode 100644 src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java new file mode 100644 index 00000000..85c436b3 --- /dev/null +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -0,0 +1,70 @@ +package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import junit.framework.Assert; + +import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.db.ClosableIteratorImpl; +import org.buddycloud.channelserver.db.CloseableIterator; +import org.buddycloud.channelserver.db.exception.NodeStoreException; +import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler; +import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.JabberPubsub; +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.NodeSubscription; +import org.buddycloud.channelserver.pubsub.model.impl.NodeAffiliationImpl; +import org.buddycloud.channelserver.pubsub.model.impl.NodeItemImpl; +import org.buddycloud.channelserver.pubsub.model.impl.NodeSubscriptionImpl; +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.Namespace; +import org.dom4j.QName; +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; +import org.xmpp.resultsetmanagement.ResultSetImpl; + +public class SearchGetTest extends IQTestHandler { + + private IQ request; + private Element element; + private BlockingQueue queue = new LinkedBlockingQueue(); + + private ChannelManager channelManager; + + private String TEST_NODE = "node1"; + private NodeViewAcl nodeViewAclMock; + private SearchGet search; + + @Before + public void setUp() throws Exception { + + queue = new LinkedBlockingQueue(); + channelManager = Mockito.mock(ChannelManager.class); + + search = new SearchGet(queue, channelManager); + } + + @Test + public void testTrueIsTrue() { + Assert.assertTrue(true); + } + +} \ No newline at end of file diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java new file mode 100644 index 00000000..89181b58 --- /dev/null +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java @@ -0,0 +1,69 @@ +package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import junit.framework.Assert; + +import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.db.ClosableIteratorImpl; +import org.buddycloud.channelserver.db.CloseableIterator; +import org.buddycloud.channelserver.db.exception.NodeStoreException; +import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler; +import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.JabberPubsub; +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.NodeSubscription; +import org.buddycloud.channelserver.pubsub.model.impl.NodeAffiliationImpl; +import org.buddycloud.channelserver.pubsub.model.impl.NodeItemImpl; +import org.buddycloud.channelserver.pubsub.model.impl.NodeSubscriptionImpl; +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.Namespace; +import org.dom4j.QName; +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; +import org.xmpp.resultsetmanagement.ResultSetImpl; + +public class SearchSetTest extends IQTestHandler { + + private IQ request; + private Element element; + private BlockingQueue queue = new LinkedBlockingQueue(); + + private ChannelManager channelManager; + + private SearchSet search; + + @Before + public void setUp() throws Exception { + + queue = new LinkedBlockingQueue(); + channelManager = Mockito.mock(ChannelManager.class); + + search = new SearchSet(queue, channelManager); + + } + + @Test + public void testTrueIsTrue() { + Assert.assertTrue(true); + } + +} \ No newline at end of file From 2f5e07b425be7cc0db78e1c5d1ad075875ab4cdc Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 15:55:07 +0100 Subject: [PATCH 06/35] Ensure requests come from local users only --- .../iq/namespace/search/SearchGet.java | 26 ++++++- .../iq/namespace/search/SearchGetTest.java | 76 +++++++++++++++++-- 2 files changed, 93 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index fc21da6d..bffc5e8f 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -6,21 +6,39 @@ import org.buddycloud.channelserver.packetprocessor.PacketProcessor; import org.xmpp.packet.IQ; import org.xmpp.packet.Packet; - +import org.xmpp.packet.PacketError; +import org.xmpp.packet.PacketError.Type; public class SearchGet implements PacketProcessor { private ChannelManager channelManager; private BlockingQueue outQueue; + private IQ response; - public SearchGet(BlockingQueue outQueue, ChannelManager channelManager) { + public SearchGet(BlockingQueue outQueue, + ChannelManager channelManager) { this.channelManager = channelManager; this.outQueue = outQueue; } - + @Override - public void process(IQ packet) throws Exception { + public void process(IQ request) throws Exception { + response = IQ.createResultIQ(request); + + if (false == channelManager.isLocalJID(request.getFrom())) { + sendErrorResponse(PacketError.Type.cancel, + PacketError.Condition.not_allowed); + return; + } + } + private void sendErrorResponse(PacketError.Type type, + PacketError.Condition condition) throws InterruptedException { + response.setType(IQ.Type.error); + PacketError error = new PacketError(PacketError.Condition.not_allowed, + PacketError.Type.cancel); + response.setError(error); + outQueue.put(response); } } diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 85c436b3..2f4d1436 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -49,8 +49,6 @@ public class SearchGetTest extends IQTestHandler { private ChannelManager channelManager; - private String TEST_NODE = "node1"; - private NodeViewAcl nodeViewAclMock; private SearchGet search; @Before @@ -60,11 +58,79 @@ public void setUp() throws Exception { channelManager = Mockito.mock(ChannelManager.class); search = new SearchGet(queue, channelManager); + + request = new IQ(); + request.setFrom("romeo@shakespeare.lit/home"); + request.setType(IQ.Type.get); + request.setTo(new JID("channels.shakespeare.lit")); + Element query = request.getElement().addElement("query"); + query.addNamespace("", Search.NAMESPACE_URI); + + Mockito.when(channelManager.isLocalJID(Mockito.any(JID.class))) + .thenReturn(true); + } @Test - public void testTrueIsTrue() { - Assert.assertTrue(true); - } + public void testOnlyAcceptsPacketsFromLocalUsers() throws Exception { + + Mockito.when(channelManager.isLocalJID(Mockito.any(JID.class))) + .thenReturn(false); + search.process(request); + Packet response = queue.poll(); + PacketError error = response.getError(); + Assert.assertNotNull(error); + Assert.assertEquals(PacketError.Type.cancel, error.getType()); + Assert.assertEquals(PacketError.Condition.not_allowed, + error.getCondition()); + } + /* + * @Test public void testReturnsInstructionsElement() throws Exception { + * + * + * } + * + * @Test public void testReturnsDataFormElement() throws Exception { + * + * + * } + * + * @Test public void testReturnsDataFormTitleElement() throws Exception { + * + * + * } + * + * @Test public void testReturnsDataFormInstructionsElement() throws + * Exception { + * + * + * } + * + * @Test public void testReturnsDataFormTypeElement() throws Exception { + * + * + * } + * + * @Test public void testReturnsDataFormContentElement() throws Exception { + * + * + * } + * + * @Test public void testReturnsDataFormAuthorElement() throws Exception { + * + * + * } + * + * @Test public void testReturnsDataFormResultsPerPageElement() throws + * Exception { + * + * + * } + * + * @Test public void testReturnsDataFormPageElement() throws Exception { + * + * + * } + */ } \ No newline at end of file From 2b92a7b14fde672511658bf1f43c1cb6ddac1158 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 16:16:42 +0100 Subject: [PATCH 07/35] Test for child with correct namespace --- .../iq/namespace/search/SearchGet.java | 6 +++ .../iq/namespace/search/SearchGetTest.java | 45 +++++++++++++++---- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index bffc5e8f..7c472bb9 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -4,6 +4,7 @@ import org.buddycloud.channelserver.channel.ChannelManager; import org.buddycloud.channelserver.packetprocessor.PacketProcessor; +import org.dom4j.Element; import org.xmpp.packet.IQ; import org.xmpp.packet.Packet; import org.xmpp.packet.PacketError; @@ -30,6 +31,11 @@ public void process(IQ request) throws Exception { PacketError.Condition.not_allowed); return; } + + Element query = response.getElement().addElement("query"); + query.addNamespace("", Search.NAMESPACE_URI); + + outQueue.put(response); } private void sendErrorResponse(PacketError.Type type, diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 2f4d1436..5c7f664d 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -50,6 +50,8 @@ public class SearchGetTest extends IQTestHandler { private ChannelManager channelManager; private SearchGet search; + private JID sender; + private JID receiver; @Before public void setUp() throws Exception { @@ -59,16 +61,18 @@ public void setUp() throws Exception { search = new SearchGet(queue, channelManager); + sender = new JID("channels.shakespeare.lit"); + receiver = new JID("romeo@shakespeare.lit/home"); + request = new IQ(); - request.setFrom("romeo@shakespeare.lit/home"); + request.setFrom(receiver); request.setType(IQ.Type.get); - request.setTo(new JID("channels.shakespeare.lit")); + request.setTo(sender); Element query = request.getElement().addElement("query"); query.addNamespace("", Search.NAMESPACE_URI); Mockito.when(channelManager.isLocalJID(Mockito.any(JID.class))) .thenReturn(true); - } @Test @@ -85,12 +89,35 @@ public void testOnlyAcceptsPacketsFromLocalUsers() throws Exception { Assert.assertEquals(PacketError.Condition.not_allowed, error.getCondition()); } - /* - * @Test public void testReturnsInstructionsElement() throws Exception { - * - * - * } - * + + @Test + public void testReturnsQueryChildElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + Element query = response.getElement().element("query"); + Assert.assertNotNull(query); + + Assert.assertEquals( + "", query.asXML() + ); + } + +// @Test +// public void testReturnsInstructionsElement() throws Exception { +// +// } + + /* * @Test public void testReturnsDataFormElement() throws Exception { * * From a5ebdf541c7957688e342dc5e2e27d669db66006 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 16:33:20 +0100 Subject: [PATCH 08/35] Add instruction element --- .../iq/namespace/search/SearchGet.java | 3 +++ .../iq/namespace/search/SearchGetTest.java | 27 +++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index 7c472bb9..f053734e 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -12,6 +12,8 @@ public class SearchGet implements PacketProcessor { + public static final String INSTRUCTIONS = "Search for content/hashtags/mentions"; + private ChannelManager channelManager; private BlockingQueue outQueue; private IQ response; @@ -34,6 +36,7 @@ public void process(IQ request) throws Exception { Element query = response.getElement().addElement("query"); query.addNamespace("", Search.NAMESPACE_URI); + query.addElement("instructions").addText(INSTRUCTIONS); outQueue.put(response); } diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 5c7f664d..9be3f583 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -108,14 +108,31 @@ public void testReturnsQueryChildElement() throws Exception { Assert.assertNotNull(query); Assert.assertEquals( - "", query.asXML() + "", query.asXML().substring(0, 32) ); } -// @Test -// public void testReturnsInstructionsElement() throws Exception { -// -// } + @Test + public void testReturnsInstructionsElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + Element instructions = response.getElement() + .element("query") + .element("instructions"); + Assert.assertEquals( + SearchGet.INSTRUCTIONS, instructions.getTextTrim() + ); + } /* * @Test public void testReturnsDataFormElement() throws Exception { From 373a3fdf7b964a5c0e5aca11efbc00467e3927c7 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 16:41:17 +0100 Subject: [PATCH 09/35] I can haz dataform child :x --- .../iq/namespace/search/SearchGet.java | 7 +++- .../iq/namespace/search/SearchGetTest.java | 38 ++++++++++++------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index f053734e..32c7da12 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -5,6 +5,7 @@ import org.buddycloud.channelserver.channel.ChannelManager; import org.buddycloud.channelserver.packetprocessor.PacketProcessor; import org.dom4j.Element; +import org.xmpp.forms.DataForm; import org.xmpp.packet.IQ; import org.xmpp.packet.Packet; import org.xmpp.packet.PacketError; @@ -35,9 +36,11 @@ public void process(IQ request) throws Exception { } Element query = response.getElement().addElement("query"); - query.addNamespace("", Search.NAMESPACE_URI); + query.addAttribute("xmlns", Search.NAMESPACE_URI); query.addElement("instructions").addText(INSTRUCTIONS); - + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + //addNamespace(null, DataForm.NAMESPACE); outQueue.put(response); } diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 9be3f583..2711c376 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -35,6 +35,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import org.xmpp.forms.DataForm; import org.xmpp.packet.IQ; import org.xmpp.packet.JID; import org.xmpp.packet.Packet; @@ -107,9 +108,7 @@ public void testReturnsQueryChildElement() throws Exception { Element query = response.getElement().element("query"); Assert.assertNotNull(query); - Assert.assertEquals( - "", query.asXML().substring(0, 32) - ); + Assert.assertEquals(Search.NAMESPACE_URI, query.attributeValue("xmlns")); } @Test @@ -126,20 +125,33 @@ public void testReturnsInstructionsElement() throws Exception { Assert.assertEquals(sender, response.getFrom()); Assert.assertEquals(IQ.Type.result, response.getType()); - Element instructions = response.getElement() + String instructions = response.getElement() .element("query") - .element("instructions"); - Assert.assertEquals( - SearchGet.INSTRUCTIONS, instructions.getTextTrim() - ); + .elementText("instructions"); + Assert.assertEquals(SearchGet.INSTRUCTIONS, instructions); } + + @Test public void testReturnsDataFormElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + Element x = response.getElement() + .element("query") + .element("x"); + Assert.assertNotNull(x); + Assert.assertEquals(DataForm.NAMESPACE, x.attributeValue("xmlns")); + } /* - * @Test public void testReturnsDataFormElement() throws Exception { - * - * - * } - * * @Test public void testReturnsDataFormTitleElement() throws Exception { * * From 5c959da04e2d57b63becec98b668cefdb41a8695 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin Date: Fri, 13 Sep 2013 16:44:47 +0100 Subject: [PATCH 10/35] Add child element --- .../iq/namespace/search/SearchGet.java | 4 ++- .../iq/namespace/search/SearchGetTest.java | 34 ++++++++++++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index 32c7da12..da7aef46 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -14,6 +14,8 @@ public class SearchGet implements PacketProcessor<IQ> { public static final String INSTRUCTIONS = "Search for content/hashtags/mentions"; + + public static final String TITLE = "Please populate one or more of the following fields"; private ChannelManager channelManager; private BlockingQueue<Packet> outQueue; @@ -40,7 +42,7 @@ public void process(IQ request) throws Exception { query.addElement("instructions").addText(INSTRUCTIONS); Element x = query.addElement("x"); x.addAttribute("xmlns", DataForm.NAMESPACE); - //addNamespace(null, DataForm.NAMESPACE); + x.addElement("title").addText(TITLE); outQueue.put(response); } diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 2711c376..8a6a8806 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -132,7 +132,8 @@ public void testReturnsInstructionsElement() throws Exception { } - @Test public void testReturnsDataFormElement() throws Exception { + @Test + public void testReturnsDataFormElement() throws Exception { search.process(request); @@ -151,13 +152,30 @@ public void testReturnsInstructionsElement() throws Exception { Assert.assertNotNull(x); Assert.assertEquals(DataForm.NAMESPACE, x.attributeValue("xmlns")); } - /* - * @Test public void testReturnsDataFormTitleElement() throws Exception { - * - * - * } - * - * @Test public void testReturnsDataFormInstructionsElement() throws + + @Test + public void testReturnsDataFormTitleElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + String title = response.getElement() + .element("query") + .element("x") + .elementText("title"); + Assert.assertNotNull(title); + Assert.assertEquals(SearchGet.TITLE, title); + } + + /* @Test public void testReturnsDataFormInstructionsElement() throws * Exception { * * From 8a63261728dca531960d79c27144dfdf3359d9e0 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Fri, 13 Sep 2013 17:08:47 +0100 Subject: [PATCH 11/35] Add tests for first form field: FORM_TYPE --- .../iq/namespace/search/SearchGet.java | 16 ++++- .../iq/namespace/search/SearchGetTest.java | 58 +++++++++++++++---- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index da7aef46..961e3ce0 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -21,6 +21,8 @@ public class SearchGet implements PacketProcessor<IQ> { private BlockingQueue<Packet> outQueue; private IQ response; + private Element x; + public SearchGet(BlockingQueue<Packet> outQueue, ChannelManager channelManager) { this.channelManager = channelManager; @@ -40,10 +42,20 @@ public void process(IQ request) throws Exception { Element query = response.getElement().addElement("query"); query.addAttribute("xmlns", Search.NAMESPACE_URI); query.addElement("instructions").addText(INSTRUCTIONS); - Element x = query.addElement("x"); + x = query.addElement("x"); + addFields(); + outQueue.put(response); + } + + private void addFields() { x.addAttribute("xmlns", DataForm.NAMESPACE); x.addElement("title").addText(TITLE); - outQueue.put(response); + x.addElement("instructions").addText(INSTRUCTIONS); + + Element formType = x.addElement("field"); + formType.addAttribute("type", "hidden"); + formType.addAttribute("var", "FORM_TYPE"); + formType.addElement("value").addText(Search.NAMESPACE_URI); } private void sendErrorResponse(PacketError.Type type, diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 8a6a8806..249813e2 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -175,18 +175,52 @@ public void testReturnsDataFormTitleElement() throws Exception { Assert.assertEquals(SearchGet.TITLE, title); } - /* @Test public void testReturnsDataFormInstructionsElement() throws - * Exception { - * - * - * } - * - * @Test public void testReturnsDataFormTypeElement() throws Exception { - * - * - * } - * - * @Test public void testReturnsDataFormContentElement() throws Exception { + @Test + public void testReturnsDataFormInstructionsElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + String instructions = response.getElement() + .element("query") + .element("x") + .elementText("instructions"); + Assert.assertNotNull(instructions); + Assert.assertEquals(SearchGet.INSTRUCTIONS, instructions); + } + + @Test + public void testReturnsDataFormTypeElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + Element formType = (Element) response.getElement() + .element("query") + .element("x") + .elements("field").get(0); + Assert.assertEquals(Search.NAMESPACE_URI, formType.elementText("value")); + Assert.assertEquals("hidden", formType.attributeValue("type")); + Assert.assertEquals("FORM_TYPE", formType.attributeValue("var")); + } + + /* @Test public void testReturnsDataFormContentElement() throws Exception { * * * } From 8c2c5622ed4598c83060c2edb9ae3e7129f6e5a1 Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 09:36:30 +0100 Subject: [PATCH 12/35] Added tests and code for `content` field --- .../iq/namespace/search/SearchGet.java | 6 ++++ .../iq/namespace/search/SearchGetTest.java | 31 +++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index 961e3ce0..aa064e8d 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -16,6 +16,7 @@ public class SearchGet implements PacketProcessor<IQ> { public static final String INSTRUCTIONS = "Search for content/hashtags/mentions"; public static final String TITLE = "Please populate one or more of the following fields"; + public static final String CONTENT_FIELD_LABEL = "Content search"; private ChannelManager channelManager; private BlockingQueue<Packet> outQueue; @@ -56,6 +57,11 @@ private void addFields() { formType.addAttribute("type", "hidden"); formType.addAttribute("var", "FORM_TYPE"); formType.addElement("value").addText(Search.NAMESPACE_URI); + + Element content = x.addElement("field"); + content.addAttribute("type", "text-multi"); + content.addAttribute("var", "content"); + content.addAttribute("label", CONTENT_FIELD_LABEL); } private void sendErrorResponse(PacketError.Type type, diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 249813e2..2bdc4cee 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -219,12 +219,31 @@ public void testReturnsDataFormTypeElement() throws Exception { Assert.assertEquals("hidden", formType.attributeValue("type")); Assert.assertEquals("FORM_TYPE", formType.attributeValue("var")); } - - /* @Test public void testReturnsDataFormContentElement() throws Exception { - * - * - * } - * + + @Test + public void testReturnsDataFormContentElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + Element formType = (Element) response.getElement() + .element("query") + .element("x") + .elements("field").get(1); + Assert.assertEquals("text-multi", formType.attributeValue("type")); + Assert.assertEquals("content", formType.attributeValue("var")); + Assert.assertEquals(SearchGet.CONTENT_FIELD_LABEL, formType.attributeValue("label")); + + } + /* * @Test public void testReturnsDataFormAuthorElement() throws Exception { * * From d2ec9ecd94b9a06ae139c16937afc971b63534b4 Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 09:40:03 +0100 Subject: [PATCH 13/35] Added test & method for `author` search field --- .../iq/namespace/search/SearchGet.java | 6 ++++ .../iq/namespace/search/SearchGetTest.java | 29 +++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index aa064e8d..8d38cd42 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -17,6 +17,7 @@ public class SearchGet implements PacketProcessor<IQ> { public static final String TITLE = "Please populate one or more of the following fields"; public static final String CONTENT_FIELD_LABEL = "Content search"; + public static final String AUTHOR_FIELD_LABEL = "Author"; private ChannelManager channelManager; private BlockingQueue<Packet> outQueue; @@ -62,6 +63,11 @@ private void addFields() { content.addAttribute("type", "text-multi"); content.addAttribute("var", "content"); content.addAttribute("label", CONTENT_FIELD_LABEL); + + Element author = x.addElement("field"); + author.addAttribute("type", "jid-single"); + author.addAttribute("var", "author"); + author.addAttribute("label", AUTHOR_FIELD_LABEL); } private void sendErrorResponse(PacketError.Type type, diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 2bdc4cee..85bfe620 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -243,12 +243,31 @@ public void testReturnsDataFormContentElement() throws Exception { Assert.assertEquals(SearchGet.CONTENT_FIELD_LABEL, formType.attributeValue("label")); } + + @Test + public void testReturnsDataFormAuthorElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + Element formType = (Element) response.getElement() + .element("query") + .element("x") + .elements("field").get(2); + Assert.assertEquals("jid-single", formType.attributeValue("type")); + Assert.assertEquals("author", formType.attributeValue("var")); + Assert.assertEquals(SearchGet.AUTHOR_FIELD_LABEL, formType.attributeValue("label")); + } + /* - * @Test public void testReturnsDataFormAuthorElement() throws Exception { - * - * - * } - * * @Test public void testReturnsDataFormResultsPerPageElement() throws * Exception { * From db0c9867532320c2b4583dbadc1838f5362a1452 Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 09:42:42 +0100 Subject: [PATCH 14/35] Added test & code for `rpp` form element --- .../iq/namespace/search/SearchGet.java | 6 ++++ .../iq/namespace/search/SearchGetTest.java | 30 +++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index 8d38cd42..94c36b6a 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -18,6 +18,7 @@ public class SearchGet implements PacketProcessor<IQ> { public static final String TITLE = "Please populate one or more of the following fields"; public static final String CONTENT_FIELD_LABEL = "Content search"; public static final String AUTHOR_FIELD_LABEL = "Author"; + public static final String RPP_FIELD_LABEL = "Results per page"; private ChannelManager channelManager; private BlockingQueue<Packet> outQueue; @@ -68,6 +69,11 @@ private void addFields() { author.addAttribute("type", "jid-single"); author.addAttribute("var", "author"); author.addAttribute("label", AUTHOR_FIELD_LABEL); + + Element rpp = x.addElement("field"); + rpp.addAttribute("type", "fixed-single"); + rpp.addAttribute("var", "rpp"); + rpp.addAttribute("label", RPP_FIELD_LABEL); } private void sendErrorResponse(PacketError.Type type, diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 85bfe620..48a201ce 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -267,13 +267,31 @@ public void testReturnsDataFormAuthorElement() throws Exception { Assert.assertEquals(SearchGet.AUTHOR_FIELD_LABEL, formType.attributeValue("label")); } + @Test + public void testReturnsDataFormResultsPerPageElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + Element formType = (Element) response.getElement() + .element("query") + .element("x") + .elements("field").get(3); + Assert.assertEquals("fixed-single", formType.attributeValue("type")); + Assert.assertEquals("rpp", formType.attributeValue("var")); + Assert.assertEquals(SearchGet.RPP_FIELD_LABEL, formType.attributeValue("label")); + + } + /* - * @Test public void testReturnsDataFormResultsPerPageElement() throws - * Exception { - * - * - * } - * * @Test public void testReturnsDataFormPageElement() throws Exception { * * From 85440e8d94a8a6bca24a6a12f5bda097c147cd15 Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 09:45:08 +0100 Subject: [PATCH 15/35] Added test & code for `page` form field --- .../iq/namespace/search/SearchGet.java | 6 ++++ .../iq/namespace/search/SearchGetTest.java | 28 +++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index 94c36b6a..308c1489 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -19,6 +19,7 @@ public class SearchGet implements PacketProcessor<IQ> { public static final String CONTENT_FIELD_LABEL = "Content search"; public static final String AUTHOR_FIELD_LABEL = "Author"; public static final String RPP_FIELD_LABEL = "Results per page"; + public static final String PAGE_FIELD_LABEL = "Page"; private ChannelManager channelManager; private BlockingQueue<Packet> outQueue; @@ -74,6 +75,11 @@ private void addFields() { rpp.addAttribute("type", "fixed-single"); rpp.addAttribute("var", "rpp"); rpp.addAttribute("label", RPP_FIELD_LABEL); + + Element page = x.addElement("field"); + page.addAttribute("type", "fixed-single"); + page.addAttribute("var", "page"); + page.addAttribute("label", PAGE_FIELD_LABEL); } private void sendErrorResponse(PacketError.Type type, diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index 48a201ce..d36ac5fc 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -291,10 +291,26 @@ public void testReturnsDataFormResultsPerPageElement() throws Exception { } - /* - * @Test public void testReturnsDataFormPageElement() throws Exception { - * - * - * } - */ + @Test + public void testReturnsDataFormPageElement() throws Exception { + + search.process(request); + + Assert.assertEquals(1, queue.size()); + + IQ response = (IQ) queue.poll(); + Assert.assertNull(response.getError()); + + Assert.assertEquals(receiver, response.getTo()); + Assert.assertEquals(sender, response.getFrom()); + Assert.assertEquals(IQ.Type.result, response.getType()); + + Element formType = (Element) response.getElement() + .element("query") + .element("x") + .elements("field").get(4); + Assert.assertEquals("fixed-single", formType.attributeValue("type")); + Assert.assertEquals("page", formType.attributeValue("var")); + Assert.assertEquals(SearchGet.PAGE_FIELD_LABEL, formType.attributeValue("label")); + } } \ No newline at end of file From e4ddf7e398e2aa61e376f233a1319b059cd580e4 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Mon, 16 Sep 2013 10:24:31 +0100 Subject: [PATCH 16/35] Add example search set stanza --- .../resources/stanzas/iq/search/set.stanza | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/resources/stanzas/iq/search/set.stanza diff --git a/src/test/resources/stanzas/iq/search/set.stanza b/src/test/resources/stanzas/iq/search/set.stanza new file mode 100644 index 00000000..681391e2 --- /dev/null +++ b/src/test/resources/stanzas/iq/search/set.stanza @@ -0,0 +1,20 @@ +<iq type="set" + from="juliet@capulet.com/balcony" + to="characters.shakespeare.lit" + id="search4" + xml:lang="en"> + <query xmlns="jabber:iq:search"> + <x xmlns="jabber:x:data" type="submit"> + <field type="hidden" var="FORM_TYPE"> + <value>jabber:iq:search</value> + </field> + <field var="author"> + <value>juliet@capulet.lt</value> + </field> + <field var="content"> + <value>dagger</value> + <value>poison</value> + </field> + </x> + </query> +</iq> From e1670f331b52bbc4e563dac50f363360f37bef58 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Mon, 16 Sep 2013 12:10:44 +0100 Subject: [PATCH 17/35] Add `rpp` and `page` to test stanza --- src/test/resources/stanzas/iq/search/set.stanza | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/resources/stanzas/iq/search/set.stanza b/src/test/resources/stanzas/iq/search/set.stanza index 681391e2..899f106b 100644 --- a/src/test/resources/stanzas/iq/search/set.stanza +++ b/src/test/resources/stanzas/iq/search/set.stanza @@ -15,6 +15,12 @@ <value>dagger</value> <value>poison</value> </field> + <field var="rpp"> + <value>50</value> + </field> + <field var="page"> + <value>2</value> + </field> </x> </query> </iq> From 42ed12a204f8c71de8cf2801a64eef1f3034d957 Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 12:20:50 +0100 Subject: [PATCH 18/35] Added test for Set validation and assurance --- .../iq/namespace/search/SearchSet.java | 195 ++++++++++++++- .../iq/namespace/search/SearchSetTest.java | 231 +++++++++++++++++- 2 files changed, 420 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index 76513242..8d36d42e 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -1,26 +1,213 @@ package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.concurrent.BlockingQueue; import org.buddycloud.channelserver.channel.ChannelManager; import org.buddycloud.channelserver.packetprocessor.PacketProcessor; +import org.dom4j.Element; +import org.xmpp.forms.DataForm; +import org.xmpp.forms.FormField; import org.xmpp.packet.IQ; import org.xmpp.packet.Packet; - +import org.xmpp.packet.PacketError; public class SearchSet implements PacketProcessor<IQ> { private ChannelManager channelManager; private BlockingQueue<Packet> outQueue; + private IQ responseIq; + private Element x; + private Element query; + private IQ requestIq; + private ArrayList<String> content; + private String author; + private int page = 1; + private int rpp = 25; - public SearchSet(BlockingQueue<Packet> outQueue, ChannelManager channelManager) { + public SearchSet(BlockingQueue<Packet> outQueue, + ChannelManager channelManager) { this.channelManager = channelManager; this.outQueue = outQueue; } - + @Override - public void process(IQ packet) throws Exception { + public void process(IQ request) throws Exception { + responseIq = IQ.createResultIQ(request); + this.requestIq = request; + + if (false == isValidRequest()) { + return; + } + + if ( false == processForm() ) { + return; + } + + query = responseIq.getElement().addElement("query"); + query.addAttribute("xmlns", Search.NAMESPACE_URI); + + outQueue.put(responseIq); + } + + private boolean isValidRequest() throws Exception { + + if (false == channelManager.isLocalJID(requestIq.getFrom())) { + sendErrorResponse(PacketError.Type.cancel, + PacketError.Condition.not_allowed); + return false; + } + + if (false == hasDataForm() || false == dataFormCorrect()) { + return false; + } + + return true; + } + + private boolean hasDataForm() throws Exception { + x = requestIq.getElement().element("query").element("x"); + + if (null == x || !DataForm.NAMESPACE.equals(x.attributeValue("xmlns")) + || !"submit".equals(x.attributeValue("type"))) { + sendErrorResponse(PacketError.Type.modify, + PacketError.Condition.bad_request); + return false; + } + + return true; + } + + private boolean dataFormCorrect() throws Exception { + if (!hasCorrectFormElement() || !hasEnoughFormFields()) { + sendErrorResponse(PacketError.Type.modify, + PacketError.Condition.bad_request); + return false; + } + + return true; } + private boolean hasCorrectFormElement() throws Exception { + + List<Element> elements = x.elements("field"); + + if (elements.size() > 0) { + for (Element field : elements) { + if (!"FORM_TYPE".equals(field.attributeValue("var"))) { + continue; + } + + String value = field.elementText("value"); + + if (null == value || !DataForm.NAMESPACE.equals(value)) { + return false; + } + + return true; + } + } + + return false; + } + + private boolean hasEnoughFormFields() throws Exception { + List<Element> elements = x.elements("field"); + if (elements.size() < 2) { + return false; + } + + boolean hasContentOrAuthor = false; + + String var; + for (Element field : elements) { + var = field.attributeValue("var"); + if ("content".equals(var) || "author".equals(var)) { + hasContentOrAuthor = true; + } + } + + return hasContentOrAuthor; + } + + private boolean processForm() throws Exception { + try { + extractFieldValues(); + } catch ( NumberFormatException e ) { + return false; + } + + if ( false == checkFieldValues() ) { + return false; + } + + return true; + } + + private void extractFieldValues() { + List<Element> elements = x.elements("field"); + String var; + for (Element field : elements) { + var = field.attributeValue("var"); + if ( "content".equals(var) ) { + content = getValuesAsList( field ); + } else if ( "author".equals(var) ) { + author = field.elementText("value"); + } else if ( "page".equals(var) ) { + page = getValueAsNumber( field ); + } else if ( "rpp".equals(var) ) { + rpp = getValueAsNumber( field ); + } + } + } + + private boolean checkFieldValues() throws Exception { + if ( ( null != content && content.size() > 0 ) || + ( null != author && author.length() > 0 ) ) { + return true; + } + + sendErrorResponse(PacketError.Type.modify, + PacketError.Condition.bad_request); + return false; + + } + + private ArrayList<String> getValuesAsList( Element field ) { + ArrayList<String> rtn = new ArrayList<String>(); + String valueText; + for ( Element value : (List<Element>) field.elements("value") ) { + valueText = value.getText(); + if ( valueText.length() == 0 ) { + continue; + } + rtn.add( valueText ); + } + return rtn; + } + + private Integer getValueAsNumber( Element field ) throws NumberFormatException { + String valueStr = field.elementText("value"); + return Integer.parseInt(valueStr); + } + + private void sendErrorResponse(PacketError.Type type, + PacketError.Condition condition) throws InterruptedException { + responseIq.setType(IQ.Type.error); + PacketError error = new PacketError(condition, type); + responseIq.setError(error); + + outQueue.put(responseIq); + } + + // private void processForm() { // throws Something + // Element element; + // DataForm dataForm = new DataForm(element); + // List<FormField> fields = dataForm.getFields(); + // // do something with fields; + // } + } diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java index 89181b58..7b048fbb 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java @@ -35,12 +35,14 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import org.xmpp.forms.DataForm; import org.xmpp.packet.IQ; import org.xmpp.packet.JID; import org.xmpp.packet.Packet; import org.xmpp.packet.PacketError; import org.xmpp.resultsetmanagement.ResultSetImpl; + public class SearchSetTest extends IQTestHandler { private IQ request; @@ -50,6 +52,9 @@ public class SearchSetTest extends IQTestHandler { private ChannelManager channelManager; private SearchSet search; + private JID sender; + private JID receiver; + @Before public void setUp() throws Exception { @@ -59,11 +64,233 @@ public void setUp() throws Exception { search = new SearchSet(queue, channelManager); + sender = new JID("channels.shakespeare.lit"); + receiver = new JID("romeo@shakespeare.lit/home"); + + request = new IQ(); + request.setFrom(receiver); + request.setType(IQ.Type.set); + request.setTo(sender); + Element query = request.getElement().addElement("query"); + query.addNamespace("", Search.NAMESPACE_URI); + + Mockito.when(channelManager.isLocalJID(Mockito.any(JID.class))) + .thenReturn(true); + } + + @Test + public void testOnlyAcceptsPacketsFromLocalUsers() throws Exception { + + Mockito.when(channelManager.isLocalJID(Mockito.any(JID.class))) + .thenReturn(false); + + search.process(request); + Packet response = queue.poll(); + PacketError error = response.getError(); + Assert.assertNotNull(error); + Assert.assertEquals(PacketError.Type.cancel, error.getType()); + Assert.assertEquals(PacketError.Condition.not_allowed, + error.getCondition()); + } + + @Test + public void testReturnsErrorIfDataFormAbsent() throws Exception { + + search.process(request); + 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 testReturnsErrorIfNamespaceIncorrect() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", "some:other:namespace"); + + search.process(request); + 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 testReturnsErrorIfTypeIncorrect() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + x.addAttribute("type", "wrongtype"); + + search.process(request); + 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 testReturnsErrorIfFieldFormTypeIsIncorrect() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + x.addAttribute("type", "submit"); + + Element field = x.addElement("field"); + field.addAttribute("var", "NOT_FORM_TYPE"); + search.process(request); + 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 testTrueIsTrue() { - Assert.assertTrue(true); + public void testReturnsErrorIfFieldFormTypeValueIsIncorrect() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + x.addAttribute("type", "submit"); + + Element field = x.addElement("field"); + field.addAttribute("var", "FORM_TYPE"); + field.addElement("value").addText("not:search:type"); + + search.process(request); + 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 testReturnsErrorIfTooFewFields() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + x.addAttribute("type", "submit"); + + Element field = x.addElement("field"); + field.addAttribute("var", "FORM_TYPE"); + field.addElement("value").addText(DataForm.NAMESPACE); + + Element singleField = x.addElement("field"); + singleField.addAttribute("var", "page"); + search.process(request); + 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 testReturnsErrorIfContentValueIncorrect() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + x.addAttribute("type", "submit"); + + Element field = x.addElement("field"); + field.addAttribute("var", "FORM_TYPE"); + field.addElement("value").addText(DataForm.NAMESPACE); + + Element singleField = x.addElement("field"); + singleField.addAttribute("var", "content"); + singleField.addElement("value"); + + search.process(request); + 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 testReturnsErrorIfAuthorValueIncorrect() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + x.addAttribute("type", "submit"); + + Element field = x.addElement("field"); + field.addAttribute("var", "FORM_TYPE"); + field.addElement("value").addText(DataForm.NAMESPACE); + + Element singleField = x.addElement("field"); + singleField.addAttribute("var", "author"); + singleField.addElement("value"); + + search.process(request); + 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 testReturnsErrorIfPageValueIncorrect() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + x.addAttribute("type", "submit"); + + Element field = x.addElement("field"); + field.addAttribute("var", "FORM_TYPE"); + field.addElement("value").addText(DataForm.NAMESPACE); + + Element singleField = x.addElement("field"); + singleField.addAttribute("var", "page"); + singleField.addElement("value").setText("sausages"); + + search.process(request); + 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 testReturnsErrorIfRppValueIncorrect() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + x.addAttribute("type", "submit"); + + Element field = x.addElement("field"); + field.addAttribute("var", "FORM_TYPE"); + field.addElement("value").addText(DataForm.NAMESPACE); + + Element singleField = x.addElement("field"); + singleField.addAttribute("var", "rpp"); + singleField.addElement("value").setText("bananas"); + + search.process(request); + 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()); + } } \ No newline at end of file From 29d76c39e3f51a9857ba10e6facbc3290a20e2a5 Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 12:53:41 +0100 Subject: [PATCH 19/35] Added ChannelManager#performSearch and added stub in ChannelManagerImpl#performSearch. Added associated tests. Changed .getAttribute("xmlns") to .getNamespaceUri() where appropriate --- .../channelserver/channel/ChannelManager.java | 24 ++++- .../channel/ChannelManagerImpl.java | 8 ++ .../iq/namespace/search/SearchSet.java | 85 ++++++++------- .../iq/namespace/search/SearchSetTest.java | 101 +++++++++--------- 4 files changed, 127 insertions(+), 91 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java b/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java index 78645e8f..1c10b401 100644 --- a/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java +++ b/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java @@ -1,8 +1,12 @@ package org.buddycloud.channelserver.channel; +import java.util.List; + +import org.buddycloud.channelserver.db.CloseableIterator; import org.buddycloud.channelserver.db.NodeStore; import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.pubsub.affiliation.Affiliations; +import org.buddycloud.channelserver.pubsub.model.NodeItem; import org.xmpp.packet.JID; public interface ChannelManager extends NodeStore { @@ -47,9 +51,25 @@ public interface ChannelManager extends NodeStore { /** * Gets the default affiliation for a node - * @return + * + * @return * * @throws NodeStoreException */ - Affiliations getDefaultNodeAffiliation(String nodeId) throws NodeStoreException; + Affiliations getDefaultNodeAffiliation(String nodeId) + throws NodeStoreException; + + /** + * Searches for the provided content or author, or both, across nodes + * the searcher has access to + * + * @param searcher + * @param content + * @param author + * @param page + * @param rpp + * @return + */ + CloseableIterator<NodeItem> performSearch(JID searcher, List content, String author, int page, + int rpp) throws NodeStoreException; } \ No newline at end of file diff --git a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java index c4d510c6..30b6f0c7 100644 --- a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java +++ b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.Map; import java.util.Properties; @@ -431,4 +432,11 @@ public Affiliations getDefaultNodeAffiliation(String nodeId) return Affiliations.member; } + + @Override + public CloseableIterator<NodeItem> performSearch(JID searcher, + List content, String author, int page, int rpp) throws NodeStoreException { + // TODO Auto-generated method stub + return null; + } } \ No newline at end of file diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index 8d36d42e..0badfd2c 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -6,11 +6,13 @@ import java.util.concurrent.BlockingQueue; import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.packetprocessor.PacketProcessor; import org.dom4j.Element; import org.xmpp.forms.DataForm; import org.xmpp.forms.FormField; import org.xmpp.packet.IQ; +import org.xmpp.packet.JID; import org.xmpp.packet.Packet; import org.xmpp.packet.PacketError; @@ -26,6 +28,7 @@ public class SearchSet implements PacketProcessor<IQ> { private String author; private int page = 1; private int rpp = 25; + private JID searcher; public SearchSet(BlockingQueue<Packet> outQueue, ChannelManager channelManager) { @@ -35,6 +38,7 @@ public SearchSet(BlockingQueue<Packet> outQueue, @Override public void process(IQ request) throws Exception { + searcher = request.getFrom(); responseIq = IQ.createResultIQ(request); this.requestIq = request; @@ -42,7 +46,15 @@ public void process(IQ request) throws Exception { return; } - if ( false == processForm() ) { + if (false == processForm()) { + return; + } + + try { + runSearch(); + } catch (NodeStoreException e) { + sendErrorResponse(PacketError.Type.wait, + PacketError.Condition.internal_server_error); return; } @@ -54,7 +66,7 @@ public void process(IQ request) throws Exception { private boolean isValidRequest() throws Exception { - if (false == channelManager.isLocalJID(requestIq.getFrom())) { + if (false == channelManager.isLocalJID(searcher)) { sendErrorResponse(PacketError.Type.cancel, PacketError.Condition.not_allowed); return false; @@ -70,7 +82,7 @@ private boolean isValidRequest() throws Exception { private boolean hasDataForm() throws Exception { x = requestIq.getElement().element("query").element("x"); - if (null == x || !DataForm.NAMESPACE.equals(x.attributeValue("xmlns")) + if (null == x || !DataForm.NAMESPACE.equals(x.getNamespaceURI()) || !"submit".equals(x.attributeValue("type"))) { sendErrorResponse(PacketError.Type.modify, PacketError.Condition.bad_request); @@ -82,7 +94,6 @@ private boolean hasDataForm() throws Exception { private boolean dataFormCorrect() throws Exception { if (!hasCorrectFormElement() || !hasEnoughFormFields()) { - sendErrorResponse(PacketError.Type.modify, PacketError.Condition.bad_request); return false; @@ -103,7 +114,7 @@ private boolean hasCorrectFormElement() throws Exception { String value = field.elementText("value"); - if (null == value || !DataForm.NAMESPACE.equals(value)) { + if (null == value || !Search.NAMESPACE_URI.equals(value)) { return false; } @@ -136,78 +147,80 @@ private boolean hasEnoughFormFields() throws Exception { private boolean processForm() throws Exception { try { extractFieldValues(); - } catch ( NumberFormatException e ) { + } catch (NumberFormatException e) { return false; } - - if ( false == checkFieldValues() ) { + + if (false == checkFieldValues()) { return false; } - + return true; } - + + private void runSearch() throws NodeStoreException { + channelManager.performSearch(searcher, content, author, page, rpp); + } + private void extractFieldValues() { List<Element> elements = x.elements("field"); String var; for (Element field : elements) { var = field.attributeValue("var"); - if ( "content".equals(var) ) { - content = getValuesAsList( field ); - } else if ( "author".equals(var) ) { + if ("content".equals(var)) { + content = getValuesAsList(field); + } else if ("author".equals(var)) { author = field.elementText("value"); - } else if ( "page".equals(var) ) { - page = getValueAsNumber( field ); - } else if ( "rpp".equals(var) ) { - rpp = getValueAsNumber( field ); + } else if ("page".equals(var)) { + page = getValueAsNumber(field); + } else if ("rpp".equals(var)) { + rpp = getValueAsNumber(field); } } } - + private boolean checkFieldValues() throws Exception { - if ( ( null != content && content.size() > 0 ) || - ( null != author && author.length() > 0 ) ) { + if (((null != content && content.size() > 0) || (null != author && author + .length() > 0)) && (page > 0 && rpp > 0)) { return true; } sendErrorResponse(PacketError.Type.modify, PacketError.Condition.bad_request); return false; - + } - - private ArrayList<String> getValuesAsList( Element field ) { + + private ArrayList<String> getValuesAsList(Element field) { ArrayList<String> rtn = new ArrayList<String>(); String valueText; - for ( Element value : (List<Element>) field.elements("value") ) { + for (Element value : (List<Element>) field.elements("value")) { valueText = value.getText(); - if ( valueText.length() == 0 ) { + if (valueText.length() == 0) { continue; } - rtn.add( valueText ); + rtn.add(valueText); } return rtn; } - - private Integer getValueAsNumber( Element field ) throws NumberFormatException { + + private Integer getValueAsNumber(Element field) + throws NumberFormatException { String valueStr = field.elementText("value"); return Integer.parseInt(valueStr); } private void sendErrorResponse(PacketError.Type type, PacketError.Condition condition) throws InterruptedException { +// try { +// throw new Exception(); +// } catch ( Exception e ) { +// e.printStackTrace(); +// } responseIq.setType(IQ.Type.error); PacketError error = new PacketError(condition, type); responseIq.setError(error); outQueue.put(responseIq); } - - // private void processForm() { // throws Something - // Element element; - // DataForm dataForm = new DataForm(element); - // List<FormField> fields = dataForm.getFields(); - // // do something with fields; - // } - } diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java index 7b048fbb..9bf96a3a 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java @@ -1,37 +1,15 @@ package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; import junit.framework.Assert; import org.buddycloud.channelserver.channel.ChannelManager; -import org.buddycloud.channelserver.db.ClosableIteratorImpl; -import org.buddycloud.channelserver.db.CloseableIterator; import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler; -import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.JabberPubsub; -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.NodeSubscription; -import org.buddycloud.channelserver.pubsub.model.impl.NodeAffiliationImpl; -import org.buddycloud.channelserver.pubsub.model.impl.NodeItemImpl; -import org.buddycloud.channelserver.pubsub.model.impl.NodeSubscriptionImpl; -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.Namespace; -import org.dom4j.QName; -import org.dom4j.tree.BaseElement; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; @@ -40,8 +18,6 @@ import org.xmpp.packet.JID; import org.xmpp.packet.Packet; import org.xmpp.packet.PacketError; -import org.xmpp.resultsetmanagement.ResultSetImpl; - public class SearchSetTest extends IQTestHandler { @@ -55,7 +31,6 @@ public class SearchSetTest extends IQTestHandler { private JID sender; private JID receiver; - @Before public void setUp() throws Exception { @@ -66,7 +41,7 @@ public void setUp() throws Exception { sender = new JID("channels.shakespeare.lit"); receiver = new JID("romeo@shakespeare.lit/home"); - + request = new IQ(); request.setFrom(receiver); request.setType(IQ.Type.set); @@ -92,7 +67,7 @@ public void testOnlyAcceptsPacketsFromLocalUsers() throws Exception { Assert.assertEquals(PacketError.Condition.not_allowed, error.getCondition()); } - + @Test public void testReturnsErrorIfDataFormAbsent() throws Exception { @@ -104,7 +79,7 @@ public void testReturnsErrorIfDataFormAbsent() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } - + @Test public void testReturnsErrorIfNamespaceIncorrect() throws Exception { Element query = request.getElement().element("query"); @@ -119,7 +94,7 @@ public void testReturnsErrorIfNamespaceIncorrect() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } - + @Test public void testReturnsErrorIfTypeIncorrect() throws Exception { Element query = request.getElement().element("query"); @@ -135,14 +110,14 @@ public void testReturnsErrorIfTypeIncorrect() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } - + @Test public void testReturnsErrorIfFieldFormTypeIsIncorrect() throws Exception { Element query = request.getElement().element("query"); Element x = query.addElement("x"); x.addAttribute("xmlns", DataForm.NAMESPACE); x.addAttribute("type", "submit"); - + Element field = x.addElement("field"); field.addAttribute("var", "NOT_FORM_TYPE"); @@ -154,14 +129,15 @@ public void testReturnsErrorIfFieldFormTypeIsIncorrect() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } - + @Test - public void testReturnsErrorIfFieldFormTypeValueIsIncorrect() throws Exception { + public void testReturnsErrorIfFieldFormTypeValueIsIncorrect() + throws Exception { Element query = request.getElement().element("query"); Element x = query.addElement("x"); x.addAttribute("xmlns", DataForm.NAMESPACE); x.addAttribute("type", "submit"); - + Element field = x.addElement("field"); field.addAttribute("var", "FORM_TYPE"); field.addElement("value").addText("not:search:type"); @@ -174,18 +150,18 @@ public void testReturnsErrorIfFieldFormTypeValueIsIncorrect() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } - + @Test public void testReturnsErrorIfTooFewFields() throws Exception { Element query = request.getElement().element("query"); Element x = query.addElement("x"); x.addAttribute("xmlns", DataForm.NAMESPACE); x.addAttribute("type", "submit"); - + Element field = x.addElement("field"); field.addAttribute("var", "FORM_TYPE"); field.addElement("value").addText(DataForm.NAMESPACE); - + Element singleField = x.addElement("field"); singleField.addAttribute("var", "page"); @@ -197,18 +173,18 @@ public void testReturnsErrorIfTooFewFields() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } - + @Test public void testReturnsErrorIfContentValueIncorrect() throws Exception { Element query = request.getElement().element("query"); Element x = query.addElement("x"); x.addAttribute("xmlns", DataForm.NAMESPACE); x.addAttribute("type", "submit"); - + Element field = x.addElement("field"); field.addAttribute("var", "FORM_TYPE"); - field.addElement("value").addText(DataForm.NAMESPACE); - + field.addElement("value").addText(Search.NAMESPACE_URI); + Element singleField = x.addElement("field"); singleField.addAttribute("var", "content"); singleField.addElement("value"); @@ -221,18 +197,18 @@ public void testReturnsErrorIfContentValueIncorrect() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } - + @Test public void testReturnsErrorIfAuthorValueIncorrect() throws Exception { Element query = request.getElement().element("query"); Element x = query.addElement("x"); x.addAttribute("xmlns", DataForm.NAMESPACE); x.addAttribute("type", "submit"); - + Element field = x.addElement("field"); field.addAttribute("var", "FORM_TYPE"); - field.addElement("value").addText(DataForm.NAMESPACE); - + field.addElement("value").addText(Search.NAMESPACE_URI); + Element singleField = x.addElement("field"); singleField.addAttribute("var", "author"); singleField.addElement("value"); @@ -245,18 +221,18 @@ public void testReturnsErrorIfAuthorValueIncorrect() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } - + @Test public void testReturnsErrorIfPageValueIncorrect() throws Exception { Element query = request.getElement().element("query"); Element x = query.addElement("x"); x.addAttribute("xmlns", DataForm.NAMESPACE); x.addAttribute("type", "submit"); - + Element field = x.addElement("field"); field.addAttribute("var", "FORM_TYPE"); - field.addElement("value").addText(DataForm.NAMESPACE); - + field.addElement("value").addText(Search.NAMESPACE_URI); + Element singleField = x.addElement("field"); singleField.addAttribute("var", "page"); singleField.addElement("value").setText("sausages"); @@ -269,18 +245,18 @@ public void testReturnsErrorIfPageValueIncorrect() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } - + @Test public void testReturnsErrorIfRppValueIncorrect() throws Exception { Element query = request.getElement().element("query"); Element x = query.addElement("x"); x.addAttribute("xmlns", DataForm.NAMESPACE); x.addAttribute("type", "submit"); - + Element field = x.addElement("field"); field.addAttribute("var", "FORM_TYPE"); - field.addElement("value").addText(DataForm.NAMESPACE); - + field.addElement("value").addText(Search.NAMESPACE_URI); + Element singleField = x.addElement("field"); singleField.addAttribute("var", "rpp"); singleField.addElement("value").setText("bananas"); @@ -293,4 +269,23 @@ public void testReturnsErrorIfRppValueIncorrect() throws Exception { Assert.assertEquals(PacketError.Condition.bad_request, error.getCondition()); } + + @Test + public void testReturnsErrorOnChannelManagerException() throws Exception { + Mockito.when( + channelManager.performSearch(Mockito.any(JID.class), + Mockito.any(List.class), Mockito.anyString(), + Mockito.anyInt(), Mockito.anyInt())).thenThrow( + new NodeStoreException()); + + IQ stanza = readStanzaAsIq("/iq/search/set.stanza"); + search.process(stanza); + + 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()); + } } \ No newline at end of file From 166fa1c9cfdbbbab5dc26467e03874c355c070cc Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 14:03:29 +0100 Subject: [PATCH 20/35] Added empty result response & test --- .../iq/namespace/search/SearchSet.java | 29 +++++++++++++++--- .../iq/namespace/search/SearchSetTest.java | 30 +++++++++++++++++-- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index 0badfd2c..9b0564a6 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -6,9 +6,12 @@ import java.util.concurrent.BlockingQueue; import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.db.CloseableIterator; import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.packetprocessor.PacketProcessor; +import org.buddycloud.channelserver.pubsub.model.NodeItem; import org.dom4j.Element; +import org.dom4j.tree.DefaultElement; import org.xmpp.forms.DataForm; import org.xmpp.forms.FormField; import org.xmpp.packet.IQ; @@ -58,9 +61,6 @@ public void process(IQ request) throws Exception { return; } - query = responseIq.getElement().addElement("query"); - query.addAttribute("xmlns", Search.NAMESPACE_URI); - outQueue.put(responseIq); } @@ -159,7 +159,28 @@ private boolean processForm() throws Exception { } private void runSearch() throws NodeStoreException { - channelManager.performSearch(searcher, content, author, page, rpp); + CloseableIterator<NodeItem> results = channelManager.performSearch(searcher, content, author, page, rpp); + + Element x = new DefaultElement("x"); + int resultCounter = 0; + while ( results.hasNext() ) { + if ( 0 == resultCounter ) { + addFormField(x); + addReportedFields(x); + } + } + + query = responseIq.getElement().addElement("query"); + System.out.println(query.getClass().getName()); + query.addAttribute("xmlns", Search.NAMESPACE_URI); + } + + private void addFormField( Element x ) { + // + } + + private void addReportedFields( Element x ) { + // } private void extractFieldValues() { diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java index 9bf96a3a..4f887e15 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java @@ -1,5 +1,6 @@ package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; +import java.util.Arrays; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -7,8 +8,11 @@ import junit.framework.Assert; import org.buddycloud.channelserver.channel.ChannelManager; +import org.buddycloud.channelserver.db.ClosableIteratorImpl; +import org.buddycloud.channelserver.db.CloseableIterator; import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler; +import org.buddycloud.channelserver.pubsub.model.NodeItem; import org.dom4j.Element; import org.junit.Before; import org.junit.Test; @@ -30,6 +34,7 @@ public class SearchSetTest extends IQTestHandler { private SearchSet search; private JID sender; private JID receiver; + private IQ setStanza; @Before public void setUp() throws Exception { @@ -51,6 +56,8 @@ public void setUp() throws Exception { Mockito.when(channelManager.isLocalJID(Mockito.any(JID.class))) .thenReturn(true); + + setStanza = readStanzaAsIq("/iq/search/set.stanza"); } @Test @@ -278,8 +285,7 @@ public void testReturnsErrorOnChannelManagerException() throws Exception { Mockito.anyInt(), Mockito.anyInt())).thenThrow( new NodeStoreException()); - IQ stanza = readStanzaAsIq("/iq/search/set.stanza"); - search.process(stanza); + search.process(setStanza); Packet response = queue.poll(); PacketError error = response.getError(); @@ -288,4 +294,24 @@ public void testReturnsErrorOnChannelManagerException() throws Exception { Assert.assertEquals(PacketError.Condition.internal_server_error, error.getCondition()); } + + @Test + public void testNoResultsReturnsExpectedStanza() throws Exception { + NodeItem[] items = new NodeItem[0]; + CloseableIterator<NodeItem> itemList = new ClosableIteratorImpl<NodeItem>( + Arrays.asList(items).iterator()); + + Mockito.doReturn(itemList) + .when(channelManager).performSearch(Mockito.any(JID.class), + Mockito.any(List.class), Mockito.anyString(), + Mockito.anyInt(), Mockito.anyInt()); + + search.process(setStanza); + + Packet response = queue.poll(); + Element query = response.getElement().element("query"); + Assert.assertNotNull(query); + Assert.assertEquals(Search.NAMESPACE_URI, query.getNamespaceURI()); + Assert.assertEquals(0, query.elements().size()); + } } \ No newline at end of file From d36c7caf9bc54be9e6ff0e94a6bc314ad5216c9b Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 16:03:43 +0100 Subject: [PATCH 21/35] Added in no-result response test and two-item response test Added response construction --- .../iq/namespace/search/SearchSet.java | 70 +++++++++++++-- .../iq/namespace/search/SearchSetTest.java | 89 ++++++++++++++++++- 2 files changed, 153 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index 9b0564a6..58867dc5 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -1,5 +1,6 @@ package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; +import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -10,7 +11,9 @@ import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.packetprocessor.PacketProcessor; import org.buddycloud.channelserver.pubsub.model.NodeItem; +import org.dom4j.DocumentException; import org.dom4j.Element; +import org.dom4j.io.SAXReader; import org.dom4j.tree.DefaultElement; import org.xmpp.forms.DataForm; import org.xmpp.forms.FormField; @@ -161,26 +164,83 @@ private boolean processForm() throws Exception { private void runSearch() throws NodeStoreException { CloseableIterator<NodeItem> results = channelManager.performSearch(searcher, content, author, page, rpp); + Element query = responseIq.getElement().addElement("query"); + query.addAttribute("xmlns", Search.NAMESPACE_URI); + Element x = new DefaultElement("x"); int resultCounter = 0; + NodeItem nodeItem; + Element entry; + + SAXReader xmlReader = new SAXReader(); while ( results.hasNext() ) { if ( 0 == resultCounter ) { addFormField(x); addReportedFields(x); } + + nodeItem = results.next(); + + try { + entry = xmlReader.read( + new StringReader(nodeItem.getPayload())) + .getRootElement(); + + Element item = x.addElement("item"); + + item.addElement("field") + .addAttribute("var", "node") + .addElement("value") + .setText(nodeItem.getNodeId()); + + item.addElement("field") + .addAttribute("var", "id") + .addElement("value") + .setText(nodeItem.getId()); + + item.addElement("field") + .addAttribute("var", "entry") + .addElement("value") + .add(entry); + } catch (DocumentException e) { +// logger.error("Error parsing a node entry, ignoring. " +// + nodeItem); + } + + resultCounter++; + } + + if ( resultCounter > 0 ) { + query.add(x); } - query = responseIq.getElement().addElement("query"); - System.out.println(query.getClass().getName()); - query.addAttribute("xmlns", Search.NAMESPACE_URI); } private void addFormField( Element x ) { - // + x.addElement("field") + .addAttribute("type", "hidden") + .addAttribute("var", "FORM_TYPE") + .addElement("value") + .setText(Search.NAMESPACE_URI); } private void addReportedFields( Element x ) { - // + Element reported = x.addElement("reported"); + + reported.addElement("field") + .addAttribute("var", "node") + .addAttribute("label", "Node") + .addAttribute("type", "text-single"); + + reported.addElement("field") + .addAttribute("var", "id") + .addAttribute("label", "Item ID") + .addAttribute("type", "text-single"); + + reported.addElement("field") + .addAttribute("var", "entry") + .addAttribute("label", "Item") + .addAttribute("type", "http://www.w3.org/2005/Atom"); } private void extractFieldValues() { diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java index 4f887e15..e0228001 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java @@ -1,6 +1,7 @@ package org.buddycloud.channelserver.packetprocessor.iq.namespace.search; import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -13,6 +14,7 @@ import org.buddycloud.channelserver.db.exception.NodeStoreException; import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler; import org.buddycloud.channelserver.pubsub.model.NodeItem; +import org.buddycloud.channelserver.pubsub.model.impl.NodeItemImpl; import org.dom4j.Element; import org.junit.Before; import org.junit.Test; @@ -35,6 +37,11 @@ public class SearchSetTest extends IQTestHandler { private JID sender; private JID receiver; private IQ setStanza; + + private String nodeItemNodeId1 = "/users/romeo@montague.lit/home"; + private String nodeItemNodeId2 = "/users/julet@capulet.lit/home"; + private String nodeItemId1 = "5w382609806986536982502859083409"; + private String nodeItemId2 = "fg455g542hg4hhtfgh4554hg5g5g54h4F"; @Before public void setUp() throws Exception { @@ -311,7 +318,87 @@ public void testNoResultsReturnsExpectedStanza() throws Exception { Packet response = queue.poll(); Element query = response.getElement().element("query"); Assert.assertNotNull(query); - Assert.assertEquals(Search.NAMESPACE_URI, query.getNamespaceURI()); + Assert.assertEquals(Search.NAMESPACE_URI, query.attributeValue("xmlns")); Assert.assertEquals(0, query.elements().size()); } + + @Test + public void testReturnsDataInExpectedFormat() throws Exception { + NodeItemImpl item1 = new NodeItemImpl(nodeItemNodeId1, nodeItemId1, new Date(), "<entry/>"); + NodeItemImpl item2 = new NodeItemImpl(nodeItemNodeId2, nodeItemId2, new Date(), "<entry2/>"); + + NodeItem[] itemArray = new NodeItem[2]; + itemArray[0] = item1; + itemArray[1] = item2; + + CloseableIterator<NodeItem> itemList = new ClosableIteratorImpl<NodeItem>( + Arrays.asList(itemArray).iterator()); + + Mockito.doReturn(itemList) + .when(channelManager).performSearch(Mockito.any(JID.class), + Mockito.any(List.class), Mockito.anyString(), + Mockito.anyInt(), Mockito.anyInt()); + + search.process(setStanza); + + Packet response = queue.poll(); + Element query = response.getElement().element("query"); + Assert.assertNotNull(query); + + Element x = query.element("x"); + Assert.assertNotNull(x); + + Element field = x.element("field"); + Assert.assertNotNull(field); + Assert.assertEquals("FORM_TYPE", field.attributeValue("var")); + Assert.assertEquals(Search.NAMESPACE_URI, field.element("value").getText()); + + Element reported = x.element("reported"); + Assert.assertNotNull(reported); + + List<Element> fields = reported.elements("field"); + Assert.assertEquals(3, fields.size()); + + Assert.assertEquals("node", fields.get(0).attributeValue("var")); + Assert.assertEquals("Node", fields.get(0).attributeValue("label")); + Assert.assertEquals("text-single", fields.get(0).attributeValue("type")); + + Assert.assertEquals("id", fields.get(1).attributeValue("var")); + Assert.assertEquals("Item ID", fields.get(1).attributeValue("label")); + Assert.assertEquals("text-single", fields.get(1).attributeValue("type")); + + Assert.assertEquals("entry", fields.get(2).attributeValue("var")); + Assert.assertEquals("Item", fields.get(2).attributeValue("label")); + Assert.assertEquals("http://www.w3.org/2005/Atom", fields.get(2).attributeValue("type")); + + List<Element> items = x.elements("item"); + Assert.assertEquals(2, items.size()); + + List<Element> itemFields = items.get(0).elements("field"); + Assert.assertEquals(3, itemFields.size()); + Assert.assertEquals("node", itemFields.get(0).attributeValue("var")); + Assert.assertEquals(nodeItemNodeId1, itemFields.get(0).element("value").getText()); + + Assert.assertEquals("id", itemFields.get(1).attributeValue("var")); + Assert.assertEquals(nodeItemId1, itemFields.get(1).element("value").getText()); + + Assert.assertEquals("entry", itemFields.get(2).attributeValue("var")); + Assert.assertEquals(1, itemFields.get(2).element("value").elements("entry").size()); + + itemFields = items.get(1).elements("field"); + Assert.assertEquals(3, itemFields.size()); + Assert.assertEquals("node", itemFields.get(0).attributeValue("var")); + Assert.assertEquals(nodeItemNodeId2, itemFields.get(0).element("value").getText()); + + Assert.assertEquals("id", itemFields.get(1).attributeValue("var")); + Assert.assertEquals(nodeItemId2, itemFields.get(1).element("value").getText()); + + Assert.assertEquals("entry", itemFields.get(2).attributeValue("var")); + Assert.assertEquals(1, itemFields.get(2).element("value").elements("entry2").size()); + } + + @Test + public void testBadlyFormedSourceDataIsIgnored() throws Exception { + + } } \ No newline at end of file From 8a17243aeb81cc2deb82df5556e3668f045019aa Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 16:07:01 +0100 Subject: [PATCH 22/35] Added test for ignoring of malformed payloads --- .../iq/namespace/search/SearchSetTest.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java index e0228001..10982ed0 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java @@ -399,6 +399,44 @@ public void testReturnsDataInExpectedFormat() throws Exception { @Test public void testBadlyFormedSourceDataIsIgnored() throws Exception { + NodeItemImpl item1 = new NodeItemImpl(nodeItemNodeId1, nodeItemId1, new Date(), "<entry><open>"); + NodeItemImpl item2 = new NodeItemImpl(nodeItemNodeId2, nodeItemId2, new Date(), "<entry2/>"); + + NodeItem[] itemArray = new NodeItem[2]; + itemArray[0] = item1; + itemArray[1] = item2; + + CloseableIterator<NodeItem> itemList = new ClosableIteratorImpl<NodeItem>( + Arrays.asList(itemArray).iterator()); + + Mockito.doReturn(itemList) + .when(channelManager).performSearch(Mockito.any(JID.class), + Mockito.any(List.class), Mockito.anyString(), + Mockito.anyInt(), Mockito.anyInt()); + + search.process(setStanza); + + Packet response = queue.poll(); + Element query = response.getElement().element("query"); + + Assert.assertNotNull(query); + + Element x = query.element("x"); + Assert.assertNotNull(x); + + List<Element> items = x.elements("item"); + Assert.assertEquals(1, items.size()); + + List<Element> itemFields = items.get(0).elements("field"); + Assert.assertEquals(3, itemFields.size()); + Assert.assertEquals("node", itemFields.get(0).attributeValue("var")); + Assert.assertEquals(nodeItemNodeId2, itemFields.get(0).element("value").getText()); + + Assert.assertEquals("id", itemFields.get(1).attributeValue("var")); + Assert.assertEquals(nodeItemId2, itemFields.get(1).element("value").getText()); + + Assert.assertEquals("entry", itemFields.get(2).attributeValue("var")); + Assert.assertEquals(1, itemFields.get(2).element("value").elements("entry2").size()); } } \ No newline at end of file From 78e67d3fa518c8f142aea4644a3af83237db553d Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Mon, 16 Sep 2013 16:12:04 +0100 Subject: [PATCH 23/35] Add performSearch() method --- .../channelserver/channel/ChannelManagerImpl.java | 3 +-- .../org/buddycloud/channelserver/db/NodeStore.java | 14 ++++++++++++++ .../channelserver/db/jdbc/JDBCNodeStore.java | 8 ++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java index 30b6f0c7..d6c0ed8e 100644 --- a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java +++ b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java @@ -436,7 +436,6 @@ public Affiliations getDefaultNodeAffiliation(String nodeId) @Override public CloseableIterator<NodeItem> performSearch(JID searcher, List content, String author, int page, int rpp) throws NodeStoreException { - // TODO Auto-generated method stub - return null; + return nodeStore.performSearch(searcher, content, author, page, rpp); } } \ No newline at end of file diff --git a/src/main/java/org/buddycloud/channelserver/db/NodeStore.java b/src/main/java/org/buddycloud/channelserver/db/NodeStore.java index 143b64ee..5dad803c 100644 --- a/src/main/java/org/buddycloud/channelserver/db/NodeStore.java +++ b/src/main/java/org/buddycloud/channelserver/db/NodeStore.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.Iterator; +import java.util.List; import java.util.Map; import org.buddycloud.channelserver.db.exception.NodeStoreException; @@ -539,6 +540,19 @@ void deleteNodeItemById(String nodeId, String nodeItemId) */ ArrayList<String> getNodeList() throws NodeStoreException; + /** + * Search subscribed nodes for content + * + * @param searcher JID of user performing the search + * @param content Keywords upon which to search + * @param author JID of the content author + * @param page Page number of results (>= 1) + * @param rpp Results per page (>= 1) + * @return + */ + CloseableIterator<NodeItem> performSearch(JID searcher, List content, + String author, int page, int rpp); + /** * Retrieves a list of items from public channels "firehose" * diff --git a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java index 6f01d99c..d5f32324 100644 --- a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java +++ b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java @@ -14,6 +14,7 @@ import java.util.Deque; import java.util.HashMap; import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -1480,6 +1481,13 @@ public void purgeNodeItems(String nodeId) throws NodeStoreException { close(stmt); // Will implicitly close the resultset if required } } + + @Override + public CloseableIterator<NodeItem> performSearch(JID searcher, + List content, String author, int page, int rpp) { + // TODO Auto-generated method stub + return null; + } @Override public ArrayList<String> getNodeList() throws NodeStoreException { From 80720e7f5676d8569955f9c49117acb1073768dc Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 16:13:01 +0100 Subject: [PATCH 24/35] Cmd+shift+f --- .../iq/namespace/search/SearchSet.java | 99 +++++++-------- .../iq/namespace/search/SearchSetTest.java | 120 ++++++++++-------- 2 files changed, 111 insertions(+), 108 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index 58867dc5..cc84641a 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -162,7 +162,8 @@ private boolean processForm() throws Exception { } private void runSearch() throws NodeStoreException { - CloseableIterator<NodeItem> results = channelManager.performSearch(searcher, content, author, page, rpp); + CloseableIterator<NodeItem> results = channelManager.performSearch( + searcher, content, author, page, rpp); Element query = responseIq.getElement().addElement("query"); query.addAttribute("xmlns", Search.NAMESPACE_URI); @@ -173,74 +174,62 @@ private void runSearch() throws NodeStoreException { Element entry; SAXReader xmlReader = new SAXReader(); - while ( results.hasNext() ) { - if ( 0 == resultCounter ) { + while (results.hasNext()) { + if (0 == resultCounter) { addFormField(x); addReportedFields(x); } - + nodeItem = results.next(); try { - entry = xmlReader.read( - new StringReader(nodeItem.getPayload())) + entry = xmlReader.read(new StringReader(nodeItem.getPayload())) .getRootElement(); - + Element item = x.addElement("item"); - - item.addElement("field") - .addAttribute("var", "node") - .addElement("value") - .setText(nodeItem.getNodeId()); - - item.addElement("field") - .addAttribute("var", "id") - .addElement("value") - .setText(nodeItem.getId()); - - item.addElement("field") - .addAttribute("var", "entry") - .addElement("value") - .add(entry); + + item.addElement("field").addAttribute("var", "node") + .addElement("value").setText(nodeItem.getNodeId()); + + item.addElement("field").addAttribute("var", "id") + .addElement("value").setText(nodeItem.getId()); + + item.addElement("field").addAttribute("var", "entry") + .addElement("value").add(entry); } catch (DocumentException e) { -// logger.error("Error parsing a node entry, ignoring. " -// + nodeItem); + // logger.error("Error parsing a node entry, ignoring. " + // + nodeItem); } - + resultCounter++; } - - if ( resultCounter > 0 ) { + + if (resultCounter > 0) { query.add(x); } } - - private void addFormField( Element x ) { - x.addElement("field") - .addAttribute("type", "hidden") - .addAttribute("var", "FORM_TYPE") - .addElement("value") + + private void addFormField(Element x) { + x.addElement("field").addAttribute("type", "hidden") + .addAttribute("var", "FORM_TYPE").addElement("value") .setText(Search.NAMESPACE_URI); } - - private void addReportedFields( Element x ) { + + private void addReportedFields(Element x) { Element reported = x.addElement("reported"); - - reported.addElement("field") - .addAttribute("var", "node") - .addAttribute("label", "Node") - .addAttribute("type", "text-single"); - - reported.addElement("field") - .addAttribute("var", "id") - .addAttribute("label", "Item ID") - .addAttribute("type", "text-single"); - - reported.addElement("field") - .addAttribute("var", "entry") - .addAttribute("label", "Item") - .addAttribute("type", "http://www.w3.org/2005/Atom"); + + reported.addElement("field").addAttribute("var", "node") + .addAttribute("label", "Node") + .addAttribute("type", "text-single"); + + reported.addElement("field").addAttribute("var", "id") + .addAttribute("label", "Item ID") + .addAttribute("type", "text-single"); + + reported.addElement("field").addAttribute("var", "entry") + .addAttribute("label", "Item") + .addAttribute("type", "http://www.w3.org/2005/Atom"); } private void extractFieldValues() { @@ -293,11 +282,11 @@ private Integer getValueAsNumber(Element field) private void sendErrorResponse(PacketError.Type type, PacketError.Condition condition) throws InterruptedException { -// try { -// throw new Exception(); -// } catch ( Exception e ) { -// e.printStackTrace(); -// } + // try { + // throw new Exception(); + // } catch ( Exception e ) { + // e.printStackTrace(); + // } responseIq.setType(IQ.Type.error); PacketError error = new PacketError(condition, type); responseIq.setError(error); diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java index 10982ed0..cf38c1c5 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java @@ -37,7 +37,7 @@ public class SearchSetTest extends IQTestHandler { private JID sender; private JID receiver; private IQ setStanza; - + private String nodeItemNodeId1 = "/users/romeo@montague.lit/home"; private String nodeItemNodeId2 = "/users/julet@capulet.lit/home"; private String nodeItemId1 = "5w382609806986536982502859083409"; @@ -63,7 +63,7 @@ public void setUp() throws Exception { Mockito.when(channelManager.isLocalJID(Mockito.any(JID.class))) .thenReturn(true); - + setStanza = readStanzaAsIq("/iq/search/set.stanza"); } @@ -291,9 +291,9 @@ public void testReturnsErrorOnChannelManagerException() throws Exception { Mockito.any(List.class), Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt())).thenThrow( new NodeStoreException()); - + search.process(setStanza); - + Packet response = queue.poll(); PacketError error = response.getError(); Assert.assertNotNull(error); @@ -301,142 +301,156 @@ public void testReturnsErrorOnChannelManagerException() throws Exception { Assert.assertEquals(PacketError.Condition.internal_server_error, error.getCondition()); } - + @Test public void testNoResultsReturnsExpectedStanza() throws Exception { NodeItem[] items = new NodeItem[0]; CloseableIterator<NodeItem> itemList = new ClosableIteratorImpl<NodeItem>( Arrays.asList(items).iterator()); - + Mockito.doReturn(itemList) - .when(channelManager).performSearch(Mockito.any(JID.class), - Mockito.any(List.class), Mockito.anyString(), - Mockito.anyInt(), Mockito.anyInt()); + .when(channelManager) + .performSearch(Mockito.any(JID.class), Mockito.any(List.class), + Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); search.process(setStanza); - + Packet response = queue.poll(); Element query = response.getElement().element("query"); Assert.assertNotNull(query); Assert.assertEquals(Search.NAMESPACE_URI, query.attributeValue("xmlns")); Assert.assertEquals(0, query.elements().size()); } - + @Test public void testReturnsDataInExpectedFormat() throws Exception { - NodeItemImpl item1 = new NodeItemImpl(nodeItemNodeId1, nodeItemId1, new Date(), "<entry/>"); - NodeItemImpl item2 = new NodeItemImpl(nodeItemNodeId2, nodeItemId2, new Date(), "<entry2/>"); - + NodeItemImpl item1 = new NodeItemImpl(nodeItemNodeId1, nodeItemId1, + new Date(), "<entry/>"); + NodeItemImpl item2 = new NodeItemImpl(nodeItemNodeId2, nodeItemId2, + new Date(), "<entry2/>"); + NodeItem[] itemArray = new NodeItem[2]; itemArray[0] = item1; itemArray[1] = item2; - + CloseableIterator<NodeItem> itemList = new ClosableIteratorImpl<NodeItem>( Arrays.asList(itemArray).iterator()); - + Mockito.doReturn(itemList) - .when(channelManager).performSearch(Mockito.any(JID.class), - Mockito.any(List.class), Mockito.anyString(), - Mockito.anyInt(), Mockito.anyInt()); + .when(channelManager) + .performSearch(Mockito.any(JID.class), Mockito.any(List.class), + Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); search.process(setStanza); - + Packet response = queue.poll(); Element query = response.getElement().element("query"); Assert.assertNotNull(query); - + Element x = query.element("x"); Assert.assertNotNull(x); - + Element field = x.element("field"); Assert.assertNotNull(field); Assert.assertEquals("FORM_TYPE", field.attributeValue("var")); - Assert.assertEquals(Search.NAMESPACE_URI, field.element("value").getText()); - + Assert.assertEquals(Search.NAMESPACE_URI, field.element("value") + .getText()); + Element reported = x.element("reported"); Assert.assertNotNull(reported); - + List<Element> fields = reported.elements("field"); Assert.assertEquals(3, fields.size()); - + Assert.assertEquals("node", fields.get(0).attributeValue("var")); Assert.assertEquals("Node", fields.get(0).attributeValue("label")); Assert.assertEquals("text-single", fields.get(0).attributeValue("type")); - + Assert.assertEquals("id", fields.get(1).attributeValue("var")); Assert.assertEquals("Item ID", fields.get(1).attributeValue("label")); Assert.assertEquals("text-single", fields.get(1).attributeValue("type")); Assert.assertEquals("entry", fields.get(2).attributeValue("var")); Assert.assertEquals("Item", fields.get(2).attributeValue("label")); - Assert.assertEquals("http://www.w3.org/2005/Atom", fields.get(2).attributeValue("type")); - + Assert.assertEquals("http://www.w3.org/2005/Atom", fields.get(2) + .attributeValue("type")); + List<Element> items = x.elements("item"); Assert.assertEquals(2, items.size()); - + List<Element> itemFields = items.get(0).elements("field"); Assert.assertEquals(3, itemFields.size()); Assert.assertEquals("node", itemFields.get(0).attributeValue("var")); - Assert.assertEquals(nodeItemNodeId1, itemFields.get(0).element("value").getText()); + Assert.assertEquals(nodeItemNodeId1, itemFields.get(0).element("value") + .getText()); Assert.assertEquals("id", itemFields.get(1).attributeValue("var")); - Assert.assertEquals(nodeItemId1, itemFields.get(1).element("value").getText()); + Assert.assertEquals(nodeItemId1, itemFields.get(1).element("value") + .getText()); Assert.assertEquals("entry", itemFields.get(2).attributeValue("var")); - Assert.assertEquals(1, itemFields.get(2).element("value").elements("entry").size()); + Assert.assertEquals(1, + itemFields.get(2).element("value").elements("entry").size()); itemFields = items.get(1).elements("field"); Assert.assertEquals(3, itemFields.size()); Assert.assertEquals("node", itemFields.get(0).attributeValue("var")); - Assert.assertEquals(nodeItemNodeId2, itemFields.get(0).element("value").getText()); + Assert.assertEquals(nodeItemNodeId2, itemFields.get(0).element("value") + .getText()); Assert.assertEquals("id", itemFields.get(1).attributeValue("var")); - Assert.assertEquals(nodeItemId2, itemFields.get(1).element("value").getText()); + Assert.assertEquals(nodeItemId2, itemFields.get(1).element("value") + .getText()); Assert.assertEquals("entry", itemFields.get(2).attributeValue("var")); - Assert.assertEquals(1, itemFields.get(2).element("value").elements("entry2").size()); + Assert.assertEquals(1, + itemFields.get(2).element("value").elements("entry2").size()); } - + @Test public void testBadlyFormedSourceDataIsIgnored() throws Exception { - NodeItemImpl item1 = new NodeItemImpl(nodeItemNodeId1, nodeItemId1, new Date(), "<entry><open>"); - NodeItemImpl item2 = new NodeItemImpl(nodeItemNodeId2, nodeItemId2, new Date(), "<entry2/>"); - + NodeItemImpl item1 = new NodeItemImpl(nodeItemNodeId1, nodeItemId1, + new Date(), "<entry><open>"); + NodeItemImpl item2 = new NodeItemImpl(nodeItemNodeId2, nodeItemId2, + new Date(), "<entry2/>"); + NodeItem[] itemArray = new NodeItem[2]; itemArray[0] = item1; itemArray[1] = item2; - + CloseableIterator<NodeItem> itemList = new ClosableIteratorImpl<NodeItem>( Arrays.asList(itemArray).iterator()); - + Mockito.doReturn(itemList) - .when(channelManager).performSearch(Mockito.any(JID.class), - Mockito.any(List.class), Mockito.anyString(), - Mockito.anyInt(), Mockito.anyInt()); + .when(channelManager) + .performSearch(Mockito.any(JID.class), Mockito.any(List.class), + Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); search.process(setStanza); - + Packet response = queue.poll(); Element query = response.getElement().element("query"); - + Assert.assertNotNull(query); - + Element x = query.element("x"); Assert.assertNotNull(x); List<Element> items = x.elements("item"); Assert.assertEquals(1, items.size()); - + List<Element> itemFields = items.get(0).elements("field"); Assert.assertEquals(3, itemFields.size()); Assert.assertEquals("node", itemFields.get(0).attributeValue("var")); - Assert.assertEquals(nodeItemNodeId2, itemFields.get(0).element("value").getText()); + Assert.assertEquals(nodeItemNodeId2, itemFields.get(0).element("value") + .getText()); Assert.assertEquals("id", itemFields.get(1).attributeValue("var")); - Assert.assertEquals(nodeItemId2, itemFields.get(1).element("value").getText()); + Assert.assertEquals(nodeItemId2, itemFields.get(1).element("value") + .getText()); Assert.assertEquals("entry", itemFields.get(2).attributeValue("var")); - Assert.assertEquals(1, itemFields.get(2).element("value").elements("entry2").size()); - + Assert.assertEquals(1, + itemFields.get(2).element("value").elements("entry2").size()); } } \ No newline at end of file From 104fb213c1c09a03f3617d554daa0bc921255cce Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Mon, 16 Sep 2013 16:58:23 +0100 Subject: [PATCH 25/35] JID not string --- .../org/buddycloud/channelserver/channel/ChannelManager.java | 2 +- .../buddycloud/channelserver/channel/ChannelManagerImpl.java | 2 +- src/main/java/org/buddycloud/channelserver/db/NodeStore.java | 3 ++- .../org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java | 2 +- .../buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java | 1 + 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java b/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java index 1c10b401..02a58e14 100644 --- a/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java +++ b/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java @@ -70,6 +70,6 @@ Affiliations getDefaultNodeAffiliation(String nodeId) * @param rpp * @return */ - CloseableIterator<NodeItem> performSearch(JID searcher, List content, String author, int page, + CloseableIterator<NodeItem> performSearch(JID searcher, List content, JID author, int page, int rpp) throws NodeStoreException; } \ No newline at end of file diff --git a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java index d6c0ed8e..737f69ab 100644 --- a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java +++ b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java @@ -435,7 +435,7 @@ public Affiliations getDefaultNodeAffiliation(String nodeId) @Override public CloseableIterator<NodeItem> performSearch(JID searcher, - List content, String author, int page, int rpp) throws NodeStoreException { + List content, JID author, int page, int rpp) throws NodeStoreException { return nodeStore.performSearch(searcher, content, author, page, rpp); } } \ No newline at end of file diff --git a/src/main/java/org/buddycloud/channelserver/db/NodeStore.java b/src/main/java/org/buddycloud/channelserver/db/NodeStore.java index 5dad803c..d72b0200 100644 --- a/src/main/java/org/buddycloud/channelserver/db/NodeStore.java +++ b/src/main/java/org/buddycloud/channelserver/db/NodeStore.java @@ -549,9 +549,10 @@ void deleteNodeItemById(String nodeId, String nodeItemId) * @param page Page number of results (>= 1) * @param rpp Results per page (>= 1) * @return + * @throws NodeStoreException */ CloseableIterator<NodeItem> performSearch(JID searcher, List content, - String author, int page, int rpp); + JID author, int page, int rpp) throws NodeStoreException; /** * Retrieves a list of items from public channels "firehose" diff --git a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java index d5f32324..14b64747 100644 --- a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java +++ b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java @@ -1484,7 +1484,7 @@ public void purgeNodeItems(String nodeId) throws NodeStoreException { @Override public CloseableIterator<NodeItem> performSearch(JID searcher, - List content, String author, int page, int rpp) { + List content, JID author, int page, int rpp) { // TODO Auto-generated method stub return null; } diff --git a/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java b/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java index f6b4de16..77dd954e 100644 --- a/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java +++ b/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Map.Entry; From fd9d3980f585534a093e9670c3d18dcf0b48ad36 Mon Sep 17 00:00:00 2001 From: Martin Hewitt <martin.hewitt@surevine.com> Date: Mon, 16 Sep 2013 17:05:36 +0100 Subject: [PATCH 26/35] Changed ChannelManger#performSearch to use a JID instead of a string for author. Added test to check for malformed author JID --- .../channelserver/channel/ChannelManager.java | 2 +- .../channel/ChannelManagerImpl.java | 2 +- .../channelserver/db/NodeStore.java | 3 +- .../channelserver/db/jdbc/JDBCNodeStore.java | 2 +- .../iq/namespace/search/SearchSet.java | 11 ++++--- .../iq/namespace/search/SearchSetTest.java | 32 ++++++++++++++++--- 6 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java b/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java index 1c10b401..02a58e14 100644 --- a/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java +++ b/src/main/java/org/buddycloud/channelserver/channel/ChannelManager.java @@ -70,6 +70,6 @@ Affiliations getDefaultNodeAffiliation(String nodeId) * @param rpp * @return */ - CloseableIterator<NodeItem> performSearch(JID searcher, List content, String author, int page, + CloseableIterator<NodeItem> performSearch(JID searcher, List content, JID author, int page, int rpp) throws NodeStoreException; } \ No newline at end of file diff --git a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java index d6c0ed8e..737f69ab 100644 --- a/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java +++ b/src/main/java/org/buddycloud/channelserver/channel/ChannelManagerImpl.java @@ -435,7 +435,7 @@ public Affiliations getDefaultNodeAffiliation(String nodeId) @Override public CloseableIterator<NodeItem> performSearch(JID searcher, - List content, String author, int page, int rpp) throws NodeStoreException { + List content, JID author, int page, int rpp) throws NodeStoreException { return nodeStore.performSearch(searcher, content, author, page, rpp); } } \ No newline at end of file diff --git a/src/main/java/org/buddycloud/channelserver/db/NodeStore.java b/src/main/java/org/buddycloud/channelserver/db/NodeStore.java index 5dad803c..d72b0200 100644 --- a/src/main/java/org/buddycloud/channelserver/db/NodeStore.java +++ b/src/main/java/org/buddycloud/channelserver/db/NodeStore.java @@ -549,9 +549,10 @@ void deleteNodeItemById(String nodeId, String nodeItemId) * @param page Page number of results (>= 1) * @param rpp Results per page (>= 1) * @return + * @throws NodeStoreException */ CloseableIterator<NodeItem> performSearch(JID searcher, List content, - String author, int page, int rpp); + JID author, int page, int rpp) throws NodeStoreException; /** * Retrieves a list of items from public channels "firehose" diff --git a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java index d5f32324..14b64747 100644 --- a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java +++ b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java @@ -1484,7 +1484,7 @@ public void purgeNodeItems(String nodeId) throws NodeStoreException { @Override public CloseableIterator<NodeItem> performSearch(JID searcher, - List content, String author, int page, int rpp) { + List content, JID author, int page, int rpp) { // TODO Auto-generated method stub return null; } diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index cc84641a..eb9f53c0 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -31,9 +31,9 @@ public class SearchSet implements PacketProcessor<IQ> { private Element query; private IQ requestIq; private ArrayList<String> content; - private String author; private int page = 1; private int rpp = 25; + private JID author; private JID searcher; public SearchSet(BlockingQueue<Packet> outQueue, @@ -240,7 +240,10 @@ private void extractFieldValues() { if ("content".equals(var)) { content = getValuesAsList(field); } else if ("author".equals(var)) { - author = field.elementText("value"); + String authorStr = field.elementText("value"); + if ( authorStr.length() > 0 ) { + author = new JID(authorStr); + } } else if ("page".equals(var)) { page = getValueAsNumber(field); } else if ("rpp".equals(var)) { @@ -250,8 +253,8 @@ private void extractFieldValues() { } private boolean checkFieldValues() throws Exception { - if (((null != content && content.size() > 0) || (null != author && author - .length() > 0)) && (page > 0 && rpp > 0)) { + if (((null != content && content.size() > 0) || (null != author && + author.toFullJID().length() > 0)) && (page > 0 && rpp > 0)) { return true; } diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java index cf38c1c5..1f6f106c 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java @@ -236,6 +236,30 @@ public void testReturnsErrorIfAuthorValueIncorrect() throws Exception { error.getCondition()); } + @Test + public void testReturnsErrorIfAuthorValueInvalid() throws Exception { + Element query = request.getElement().element("query"); + Element x = query.addElement("x"); + x.addAttribute("xmlns", DataForm.NAMESPACE); + x.addAttribute("type", "submit"); + + Element field = x.addElement("field"); + field.addAttribute("var", "FORM_TYPE"); + field.addElement("value").addText(Search.NAMESPACE_URI); + + Element singleField = x.addElement("field"); + singleField.addAttribute("var", "author"); + singleField.addElement("value").setText("user@broken@jid.com"); + + search.process(request); + 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 testReturnsErrorIfPageValueIncorrect() throws Exception { Element query = request.getElement().element("query"); @@ -288,7 +312,7 @@ public void testReturnsErrorIfRppValueIncorrect() throws Exception { public void testReturnsErrorOnChannelManagerException() throws Exception { Mockito.when( channelManager.performSearch(Mockito.any(JID.class), - Mockito.any(List.class), Mockito.anyString(), + Mockito.any(List.class), Mockito.any(JID.class), Mockito.anyInt(), Mockito.anyInt())).thenThrow( new NodeStoreException()); @@ -311,7 +335,7 @@ public void testNoResultsReturnsExpectedStanza() throws Exception { Mockito.doReturn(itemList) .when(channelManager) .performSearch(Mockito.any(JID.class), Mockito.any(List.class), - Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); + Mockito.any(JID.class), Mockito.anyInt(), Mockito.anyInt()); search.process(setStanza); @@ -339,7 +363,7 @@ public void testReturnsDataInExpectedFormat() throws Exception { Mockito.doReturn(itemList) .when(channelManager) .performSearch(Mockito.any(JID.class), Mockito.any(List.class), - Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); + Mockito.any(JID.class), Mockito.anyInt(), Mockito.anyInt()); search.process(setStanza); @@ -424,7 +448,7 @@ public void testBadlyFormedSourceDataIsIgnored() throws Exception { Mockito.doReturn(itemList) .when(channelManager) .performSearch(Mockito.any(JID.class), Mockito.any(List.class), - Mockito.anyString(), Mockito.anyInt(), Mockito.anyInt()); + Mockito.any(JID.class), Mockito.anyInt(), Mockito.anyInt()); search.process(setStanza); From c1a7f6291db2a174e46bbccf9b7b6ed0bfd9e7be Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Tue, 17 Sep 2013 10:42:20 +0100 Subject: [PATCH 27/35] First database search test complete --- .../channelserver/db/jdbc/JDBCNodeStore.java | 59 ++++++++++- .../db/jdbc/JDBCNodeStoreTest.java | 18 ++++ .../testing/jdbc/scripts/search-test-1.sql | 99 +++++++++++++++++++ 3 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-1.sql diff --git a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java index 14b64747..3421f601 100644 --- a/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java +++ b/src/main/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStore.java @@ -1484,9 +1484,62 @@ public void purgeNodeItems(String nodeId) throws NodeStoreException { @Override public CloseableIterator<NodeItem> performSearch(JID searcher, - List content, JID author, int page, int rpp) { - // TODO Auto-generated method stub - return null; + List content, JID author, int page, int rpp) throws NodeStoreException { + PreparedStatement stmt = null; + try { + String sql = "SELECT * FROM \"items\" " + + "LEFT JOIN \"subscriptions\" ON \"items\".\"node\" = \"subscriptions\".\"node\" " + + "WHERE " + + "\"subscriptions\".\"user\" = ? " + + "AND \"subscriptions\".\"subscription\" = 'subscribed' " + + "AND RIGHT(\"items\".\"node\", 6) = '/posts' " + + " $searchParameters " + + "ORDER BY \"items\".\"updated\" DESC " + + "LIMIT ? OFFSET ?;"; + ArrayList<String> parameterValues = new ArrayList<String>(); + parameterValues.add(searcher.toBareJID()); + String searchParameters = ""; + + for (String term : (List<String>) content) { + searchParameters += "AND (\"items\".\"xml\" LIKE ?) "; + parameterValues.add("%<content%>%" + term + "%</content>%"); + } + + if (null != author) { + searchParameters += "AND (\"items\".\"xml\" LIKE ?)"; + parameterValues.add("%<name>" + author.toBareJID() + "</name>%"); + } + stmt = conn.prepareStatement(sql.replace("$searchParameters", searchParameters)); + + int counter = 0; + for (String value : parameterValues) { + ++counter; + stmt.setString(counter, value); + } + stmt.setInt(parameterValues.size() + 1, rpp); + stmt.setInt(parameterValues.size() + 2, (page - 1) * rpp); + + java.sql.ResultSet rs = stmt.executeQuery(); + + stmt = null; // Prevent the finally block from closing the + // statement + + return new ResultSetIterator<NodeItem>(rs, + new ResultSetIterator.RowConverter<NodeItem>() { + @Override + public NodeItem convertRow(java.sql.ResultSet rs) + throws SQLException { + return new NodeItemImpl(rs.getString(1), + rs.getString(2), rs.getTimestamp(3), + rs.getString(4), rs.getString(5)); + } + }); + } catch (SQLException e) { + e.printStackTrace(); + throw new NodeStoreException(e); + } finally { + close(stmt); // Will implicitly close the resultset if required + } } @Override diff --git a/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java b/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java index 77dd954e..fa1876ed 100644 --- a/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java +++ b/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java @@ -23,6 +23,8 @@ import java.util.Map; import java.util.Map.Entry; +import junit.framework.Assert; + import org.apache.commons.collections.CollectionUtils; import org.buddycloud.channelserver.db.ClosableIteratorImpl; import org.buddycloud.channelserver.db.CloseableIterator; @@ -2158,6 +2160,22 @@ public void testCanGetFirehostItemCountWithPrivateItemsAsAdmin() store.setNodeConf(TEST_SERVER2_NODE1_ID, remoteNodeConf); assertEquals(7, store.getFirehoseItemCount(true)); } + + @Test + public void testOnlySeeSearchResultsFromSubscribedPostsNodes() throws Exception { + dbTester.loadData("search-test-1"); + CloseableIterator<NodeItem> items = store.performSearch( + new JID("user1@server1"), new ArrayList<String>(), new JID("author@server1"), 1, 25 + ); + int counter = 0; + while (items.hasNext()) { + ++counter; + NodeItem item = items.next(); + assertEquals("a1", item.getId()); + assertEquals("/users/subscribed@server1/posts", item.getNodeId()); + } + assertEquals(1, counter); + } @Test public void testBeginTransaction() throws Exception { diff --git a/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-1.sql b/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-1.sql new file mode 100644 index 00000000..f86c8ba7 --- /dev/null +++ b/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-1.sql @@ -0,0 +1,99 @@ +INSERT INTO "nodes" ("node") VALUES ('/users/subscribed@server1/posts'); +INSERT INTO "nodes" ("node") VALUES ('/users/unsubscribed@server1/posts'); +INSERT INTO "nodes" ("node") VALUES ('/users/pending@server1/posts'); +INSERT INTO "nodes" ("node") VALUES ('/users/subscribed@server1/status'); + +INSERT INTO "subscriptions" ("node", "user", "listener", "subscription", "updated") + VALUES ('/users/subscribed@server1/posts', 'user1@server1', 'user1@server1', 'subscribed', current_timestamp - interval '4' second); +INSERT INTO "subscriptions" ("node", "user", "listener", "subscription", "updated") + VALUES ('/users/subscribed@server1/status', 'user2@server1', 'user2@server1', 'subscribed', current_timestamp - interval '3' second); +INSERT INTO "subscriptions" ("node", "user", "listener", "subscription", "updated") + VALUES ('/users/pending@server1/posts', 'user2@server1', 'user2@server1', 'pending', current_timestamp - interval '3' second); + +-- The strange order of insertion of the items is deliberate + +-- author@server1 +-- not-author@server1 +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a1', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">Test 5</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/unsubscribed@server1/posts', 'a2', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">Test 5</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/pending@server1/posts', 'a3', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">Test 5</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/status', 'a4', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">Test 5</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); \ No newline at end of file From e764c1dd0717851706adc331a361143a35cf3b4e Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Tue, 17 Sep 2013 12:47:39 +0100 Subject: [PATCH 28/35] Unit tests complete for search functionality --- .../db/jdbc/JDBCNodeStoreTest.java | 76 ++++++++++ .../testing/jdbc/scripts/search-test-2.sql | 74 ++++++++++ .../testing/jdbc/scripts/search-test-3.sql | 95 ++++++++++++ .../testing/jdbc/scripts/search-test-4.sql | 138 ++++++++++++++++++ 4 files changed, 383 insertions(+) create mode 100644 src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-2.sql create mode 100644 src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-3.sql create mode 100644 src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-4.sql diff --git a/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java b/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java index fa1876ed..b4860f4a 100644 --- a/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java +++ b/src/test/java/org/buddycloud/channelserver/db/jdbc/JDBCNodeStoreTest.java @@ -2176,6 +2176,82 @@ public void testOnlySeeSearchResultsFromSubscribedPostsNodes() throws Exception } assertEquals(1, counter); } + + @Test + public void testOnlySeeSearchResultsFromRequestedAuthor() throws Exception { + dbTester.loadData("search-test-2"); + CloseableIterator<NodeItem> items = store.performSearch( + new JID("user1@server1"), new ArrayList<String>(), new JID("author@server1"), 1, 25 + ); + int counter = 0; + NodeItem item; + while (items.hasNext()) { + ++counter; + item = items.next(); + if (1 == counter) { + assertEquals("b1", item.getId()); + assertEquals("/users/another-subscribed@server1/posts", item.getNodeId()); + } else if (2 == counter) { + assertEquals("a1", item.getId()); + assertEquals("/users/subscribed@server1/posts", item.getNodeId()); + } + } + assertEquals(2, counter); + } + + @Test + public void testOnlySeeSearchResultsWithSpecificContent() throws Exception { + dbTester.loadData("search-test-3"); + + ArrayList<String> searchTerms = new ArrayList<String>(); + searchTerms.add("keyword"); + searchTerms.add("post"); + + CloseableIterator<NodeItem> items = store.performSearch( + new JID("user1@server1"), searchTerms, new JID("author@server1"), 1, 25 + ); + int counter = 0; + NodeItem item; + while (items.hasNext()) { + ++counter; + item = items.next(); + if (1 == counter) { + assertEquals("a3", item.getId()); + assertEquals("/users/subscribed@server1/posts", item.getNodeId()); + } else if (2 == counter) { + assertEquals("a1", item.getId()); + assertEquals("/users/subscribed@server1/posts", item.getNodeId()); + } + } + assertEquals(2, counter); + } + + @Test + public void testOnlySeeSearchResultsWithSpecificContentAndAuthor() throws Exception { + dbTester.loadData("search-test-4"); + + ArrayList<String> searchTerms = new ArrayList<String>(); + searchTerms.add("keyword"); + searchTerms.add("post"); + + CloseableIterator<NodeItem> items = store.performSearch( + new JID("user1@server1"), searchTerms, new JID("author@server1"), 1, 25 + ); + int counter = 0; + NodeItem item; + while (items.hasNext()) { + ++counter; + item = items.next(); + if (1 == counter) { + assertEquals("a3", item.getId()); + assertEquals("/users/subscribed@server1/posts", item.getNodeId()); + } else if (2 == counter) { + assertEquals("a1", item.getId()); + assertEquals("/users/subscribed@server1/posts", item.getNodeId()); + } + } + assertEquals(2, counter); + } @Test public void testBeginTransaction() throws Exception { diff --git a/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-2.sql b/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-2.sql new file mode 100644 index 00000000..f06d38ef --- /dev/null +++ b/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-2.sql @@ -0,0 +1,74 @@ +INSERT INTO "nodes" ("node") VALUES ('/users/subscribed@server1/posts'); +INSERT INTO "nodes" ("node") VALUES ('/users/another-subscribed@server1/posts'); + +INSERT INTO "subscriptions" ("node", "user", "listener", "subscription", "updated") + VALUES ('/users/subscribed@server1/posts', 'user1@server1', 'user1@server1', 'subscribed', current_timestamp - interval '4' second); +INSERT INTO "subscriptions" ("node", "user", "listener", "subscription", "updated") + VALUES ('/users/another-subscribed@server1/posts', 'user1@server1', 'user1@server1', 'subscribed', current_timestamp - interval '3' second); + +-- The strange order of insertion of the items is deliberate + +-- author@server1 +-- not-author@server1 +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a1', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">Test 5</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a2', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>not-author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">Test 5</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/another-subscribed@server1/posts', 'b1', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">Test 5</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); \ No newline at end of file diff --git a/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-3.sql b/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-3.sql new file mode 100644 index 00000000..76ef22cd --- /dev/null +++ b/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-3.sql @@ -0,0 +1,95 @@ +INSERT INTO "nodes" ("node") VALUES ('/users/subscribed@server1/posts'); +INSERT INTO "nodes" ("node") VALUES ('/users/pending@server1/posts'); + +INSERT INTO "subscriptions" ("node", "user", "listener", "subscription", "updated") + VALUES ('/users/subscribed@server1/posts', 'user1@server1', 'user1@server1', 'subscribed', current_timestamp - interval '4' second); +INSERT INTO "subscriptions" ("node", "user", "listener", "subscription", "updated") + VALUES ('/users/pending@server1/posts', 'user1@server1', 'user1@server1', 'pending', current_timestamp - interval '4' second); + +-- The strange order of insertion of the items is deliberate + +-- author@server1 +-- not-author@server1 +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a1', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">A post which contains a certain keyword.</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a2', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">Only one keyword in this... item</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a3', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">There is also a keyword in this post.</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/pending@server1/posts', 'a3', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">There is also a keyword in this post.</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); \ No newline at end of file diff --git a/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-4.sql b/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-4.sql new file mode 100644 index 00000000..f72478b9 --- /dev/null +++ b/src/test/resources/org/buddycloud/channelserver/testing/jdbc/scripts/search-test-4.sql @@ -0,0 +1,138 @@ +INSERT INTO "nodes" ("node") VALUES ('/users/subscribed@server1/posts'); +INSERT INTO "nodes" ("node") VALUES ('/users/pending@server1/posts'); + +INSERT INTO "subscriptions" ("node", "user", "listener", "subscription", "updated") + VALUES ('/users/subscribed@server1/posts', 'user1@server1', 'user1@server1', 'subscribed', current_timestamp - interval '4' second); +INSERT INTO "subscriptions" ("node", "user", "listener", "subscription", "updated") + VALUES ('/users/pending@server1/posts', 'user1@server1', 'user1@server1', 'pending', current_timestamp - interval '4' second); + +-- The strange order of insertion of the items is deliberate + +-- author@server1 +-- not-author@server1 +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a1', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">A post which contains a certain keyword.</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a2', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">Only one keyword in this... item</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a3', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">There is also a keyword in this post.</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/pending@server1/posts', 'a4', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">There is also a keyword in this post.</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a4', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>not-author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">A post which contains a certain keyword.</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); + +INSERT INTO "items" ("node", "id", "updated", "xml") +VALUES ('/users/subscribed@server1/posts', 'a5', TIMESTAMP '2010-01-08 11:45:12', + '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> + <published>2010-01-08T11:45:12Z</published> + <author> + <name>author@server1</name> + <jid xmlns="http://buddycloud.com/atom-elements-0">user2@server1</jid> + </author> + <content type="text">A contains only one keyword.</content> + <geoloc xmlns="http://jabber.org/protocol/geoloc"> + <text>London, England</text> + <locality>London</locality> + <country>England</country> + </geoloc> + + <activity:verb>post</activity:verb> + <activity:object> + <activity:object-type>note</activity:object-type> + </activity:object> + </entry>'); \ No newline at end of file From a42038087665e484667e572c91a01a6271233f3d Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Tue, 17 Sep 2013 17:10:25 +0100 Subject: [PATCH 29/35] Add branch name --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 491e0d1b..5e1a6525 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ <groupId>org.buddycloud</groupId> <artifactId>channelserver</artifactId> <packaging>jar</packaging> - <version>0.12.0</version> + <version>0.12.0-search</version> <name>Buddycloud Java Server</name> <scm> <url>https://github.com/buddycloud/buddycloud-server-java</url> From 022542f6e77ecddcde5b7dba07d4decbef62a875 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Tue, 17 Sep 2013 18:05:32 +0100 Subject: [PATCH 30/35] Check types correctly --- .../packetprocessor/iq/namespace/search/Search.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java index 93f5115e..590b243f 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/Search.java @@ -47,11 +47,14 @@ public Search(BlockingQueue<Packet> outQueue, @Override public void process(IQ reqIQ) throws Exception { request = reqIQ; - - if (request.getType().equals("get")) { + if (request.getType().equals(Type.get)) { + logger.trace("Using search processor: SearchGet"); this.searchGet.process(request); - } else if (request.getType().equals("set")) { + return; + } else if (request.getType().equals(Type.set)) { + logger.trace("Using search processor: SearchSet"); this.searchSet.process(request); + return; } IQ response = IQ.createResultIQ(request); response.setType(IQ.Type.error); From 85a5f9868d25011d57cc1c3561c1df2c2489031c Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Thu, 19 Sep 2013 15:50:42 +0100 Subject: [PATCH 31/35] Update search fields --- .../packetprocessor/iq/namespace/search/SearchGet.java | 4 ++-- .../packetprocessor/iq/namespace/search/SearchSet.java | 7 +------ .../packetprocessor/iq/namespace/search/SearchGetTest.java | 4 ++-- .../packetprocessor/iq/namespace/search/SearchSetTest.java | 2 +- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java index 308c1489..60258d5b 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGet.java @@ -72,12 +72,12 @@ private void addFields() { author.addAttribute("label", AUTHOR_FIELD_LABEL); Element rpp = x.addElement("field"); - rpp.addAttribute("type", "fixed-single"); + rpp.addAttribute("type", "fixed"); rpp.addAttribute("var", "rpp"); rpp.addAttribute("label", RPP_FIELD_LABEL); Element page = x.addElement("field"); - page.addAttribute("type", "fixed-single"); + page.addAttribute("type", "fixed"); page.addAttribute("var", "page"); page.addAttribute("label", PAGE_FIELD_LABEL); } diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index eb9f53c0..c1e989b0 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -229,7 +229,7 @@ private void addReportedFields(Element x) { reported.addElement("field").addAttribute("var", "entry") .addAttribute("label", "Item") - .addAttribute("type", "http://www.w3.org/2005/Atom"); + .addAttribute("type", "xml"); } private void extractFieldValues() { @@ -285,11 +285,6 @@ private Integer getValueAsNumber(Element field) private void sendErrorResponse(PacketError.Type type, PacketError.Condition condition) throws InterruptedException { - // try { - // throw new Exception(); - // } catch ( Exception e ) { - // e.printStackTrace(); - // } responseIq.setType(IQ.Type.error); PacketError error = new PacketError(condition, type); responseIq.setError(error); diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java index d36ac5fc..d81df66f 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchGetTest.java @@ -285,7 +285,7 @@ public void testReturnsDataFormResultsPerPageElement() throws Exception { .element("query") .element("x") .elements("field").get(3); - Assert.assertEquals("fixed-single", formType.attributeValue("type")); + Assert.assertEquals("fixed", formType.attributeValue("type")); Assert.assertEquals("rpp", formType.attributeValue("var")); Assert.assertEquals(SearchGet.RPP_FIELD_LABEL, formType.attributeValue("label")); @@ -309,7 +309,7 @@ public void testReturnsDataFormPageElement() throws Exception { .element("query") .element("x") .elements("field").get(4); - Assert.assertEquals("fixed-single", formType.attributeValue("type")); + Assert.assertEquals("fixed", formType.attributeValue("type")); Assert.assertEquals("page", formType.attributeValue("var")); Assert.assertEquals(SearchGet.PAGE_FIELD_LABEL, formType.attributeValue("label")); } diff --git a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java index 1f6f106c..38cd07fb 100644 --- a/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java +++ b/src/test/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSetTest.java @@ -396,7 +396,7 @@ public void testReturnsDataInExpectedFormat() throws Exception { Assert.assertEquals("entry", fields.get(2).attributeValue("var")); Assert.assertEquals("Item", fields.get(2).attributeValue("label")); - Assert.assertEquals("http://www.w3.org/2005/Atom", fields.get(2) + Assert.assertEquals("xml", fields.get(2) .attributeValue("type")); List<Element> items = x.elements("item"); From 93e2b97125822fdd62e0980dbc777044b4fcced1 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Thu, 19 Sep 2013 16:32:08 +0100 Subject: [PATCH 32/35] BareJID not full JID --- .../packetprocessor/iq/namespace/search/SearchSet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index c1e989b0..854a978d 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -254,7 +254,7 @@ private void extractFieldValues() { private boolean checkFieldValues() throws Exception { if (((null != content && content.size() > 0) || (null != author && - author.toFullJID().length() > 0)) && (page > 0 && rpp > 0)) { + author.toBareJID().length() > 0)) && (page > 0 && rpp > 0)) { return true; } From a7e5c561bf026f398c5875dca048ae3eea70f2ea Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Thu, 19 Sep 2013 16:42:53 +0100 Subject: [PATCH 33/35] Initialise variable --- .../packetprocessor/iq/namespace/search/SearchSet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index 854a978d..97fb592e 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -30,7 +30,7 @@ public class SearchSet implements PacketProcessor<IQ> { private Element x; private Element query; private IQ requestIq; - private ArrayList<String> content; + private ArrayList<String> content = new ArrayList<String>(); private int page = 1; private int rpp = 25; private JID author; From 1e3db4a34dd027227edd8ab56fcabeb14c6807f1 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Thu, 19 Sep 2013 16:43:03 +0100 Subject: [PATCH 34/35] Code formatting --- .../iq/namespace/search/SearchSet.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index 97fb592e..a97aa91e 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -197,8 +197,8 @@ private void runSearch() throws NodeStoreException { item.addElement("field").addAttribute("var", "entry") .addElement("value").add(entry); } catch (DocumentException e) { - // logger.error("Error parsing a node entry, ignoring. " - // + nodeItem); + logger.error("Error parsing a node entry, ignoring. " + + nodeItem); } resultCounter++; @@ -228,8 +228,7 @@ private void addReportedFields(Element x) { .addAttribute("type", "text-single"); reported.addElement("field").addAttribute("var", "entry") - .addAttribute("label", "Item") - .addAttribute("type", "xml"); + .addAttribute("label", "Item").addAttribute("type", "xml"); } private void extractFieldValues() { @@ -241,7 +240,7 @@ private void extractFieldValues() { content = getValuesAsList(field); } else if ("author".equals(var)) { String authorStr = field.elementText("value"); - if ( authorStr.length() > 0 ) { + if (authorStr.length() > 0) { author = new JID(authorStr); } } else if ("page".equals(var)) { @@ -253,8 +252,8 @@ private void extractFieldValues() { } private boolean checkFieldValues() throws Exception { - if (((null != content && content.size() > 0) || (null != author && - author.toBareJID().length() > 0)) && (page > 0 && rpp > 0)) { + if (((null != content && content.size() > 0) || (null != author && author + .toBareJID().length() > 0)) && (page > 0 && rpp > 0)) { return true; } From 00323af3b2f3ceb59c481ae2fced1b039d2c58d1 Mon Sep 17 00:00:00 2001 From: Lloyd Watkin <lloyd.watkin@surevine.com> Date: Thu, 19 Sep 2013 16:49:09 +0100 Subject: [PATCH 35/35] Include logger --- .../packetprocessor/iq/namespace/search/SearchSet.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java index a97aa91e..d6539c75 100644 --- a/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java +++ b/src/main/java/org/buddycloud/channelserver/packetprocessor/iq/namespace/search/SearchSet.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.concurrent.BlockingQueue; +import org.apache.log4j.Logger; import org.buddycloud.channelserver.channel.ChannelManager; import org.buddycloud.channelserver.db.CloseableIterator; import org.buddycloud.channelserver.db.exception.NodeStoreException; @@ -35,6 +36,8 @@ public class SearchSet implements PacketProcessor<IQ> { private int rpp = 25; private JID author; private JID searcher; + + public static Logger logger = Logger.getLogger(SearchSet.class); public SearchSet(BlockingQueue<Packet> outQueue, ChannelManager channelManager) {