package org.buddycloud.channelserver.packetprocessor.message.event;

import java.util.ArrayList;
import java.util.Properties;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import junit.framework.Assert;

import org.buddycloud.channelserver.channel.ChannelManager;
import org.buddycloud.channelserver.db.exception.NodeStoreException;
import org.buddycloud.channelserver.packetHandler.iq.IQTestHandler;
import org.buddycloud.channelserver.packetprocessor.iq.namespace.pubsub.JabberPubsub;
import org.buddycloud.channelserver.pubsub.affiliation.Affiliations;
import org.buddycloud.channelserver.pubsub.model.NodeSubscription;
import org.buddycloud.channelserver.pubsub.model.impl.NodeSubscriptionImpl;
import org.buddycloud.channelserver.pubsub.subscription.Subscriptions;
import org.dom4j.Element;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
import org.xmpp.resultsetmanagement.ResultSetImpl;

public class AffiliationProcessorTest extends IQTestHandler {
	private Message message;
	private AffiliationProcessor affiliationProcessor;
	private Element subscription;
	private Element affiliation;

	private BlockingQueue<Packet> queue = new LinkedBlockingQueue<Packet>();
	private ChannelManager channelManager;

	private JID jid = new JID("juliet@shakespeare.lit");

	@Before
	public void setUp() throws Exception {

		Properties configuration = new Properties();
		configuration.setProperty("server.domain.channels",
				"chgnnels.shakespeare.lit");

		channelManager = Mockito.mock(ChannelManager.class);
		Mockito.when(channelManager.isLocalNode(Mockito.anyString()))
				.thenReturn(false);
		Mockito.when(channelManager.isLocalJID(Mockito.any(JID.class)))
				.thenReturn(true);

		ArrayList<NodeSubscription> subscribers = new ArrayList<NodeSubscription>();
		subscribers.add(new NodeSubscriptionImpl(
				"/users/romeo@shakespeare.lit/posts", jid,
				Subscriptions.subscribed));
		Mockito.doReturn(new ResultSetImpl<NodeSubscription>(subscribers))
				.when(channelManager).getNodeSubscriptions(Mockito.anyString());

		affiliationProcessor = new AffiliationProcessor(queue, configuration,
				channelManager);

		message = new Message();
		message.setType(Message.Type.headline);
		Element event = message.addChildElement("event",
				JabberPubsub.NS_PUBSUB_EVENT);

		affiliation = event.addElement("affiliation");
		affiliation.addAttribute("jid", "romeo@shakespeare.lit");
		affiliation.addAttribute("node", "/users/juliet@shakespeare.lit/posts");
		affiliation.addAttribute("affiliation",
				Affiliations.publisher.toString());
	}

	@Test(expected = IllegalArgumentException.class)
	public void testInvalidAffiliationValueThrowsException() throws Exception {
		Message badAffiliationValue = message.createCopy();
		badAffiliationValue.getElement().element("event")
				.element("affiliation").addAttribute("affiliation", "invalid");
		affiliationProcessor.process(badAffiliationValue);
	}

	@Test
	public void testMissingAffiliationElementDoesNotCauseError()
			throws Exception {
		Message noAffiliationElement = message.createCopy();
		noAffiliationElement.getElement().element("event")
				.element("affiliation").detach();
		affiliationProcessor.process(noAffiliationElement);
	}

	@Test
	public void testEventForLocalNodeIsIgnored() throws Exception {

		Mockito.when(channelManager.isLocalNode(Mockito.anyString()))
				.thenReturn(true);
		affiliationProcessor.process(message);
		Assert.assertEquals(0, queue.size());
	}

	@Test(expected = NodeStoreException.class)
	public void testNodeStoreExceptionIsThrownWhenExpected() throws Exception {

		Mockito.doThrow(new NodeStoreException())
				.when(channelManager)
				.setUserAffiliation(Mockito.anyString(),
						Mockito.any(JID.class), Mockito.any(Affiliations.class));
		affiliationProcessor.process(message);
	}

	@Test
	public void testNotificationsAreSentOutAsExpected() throws Exception {

		affiliationProcessor.process(message);

		Assert.assertEquals(1, queue.size());
		message.setTo(jid.toString());
		Assert.assertEquals(message.toString(), queue.poll().toString());
	}
}
@@ -1256,16 +1256,48 @@
 iation;%0A
+%09private Element affiliations;%0A%09
 %0A%09privat
@@ -2481,16 +2481,17 @@
 iliation
+s
  = event
@@ -2514,16 +2514,17 @@
 iliation
+s
 %22);%0A%09%09af
@@ -2524,32 +2524,33 @@
 );%0A%09%09affiliation
+s
 .addAttribute(%22j
@@ -2552,36 +2552,110 @@
 te(%22
-jid%22, %22romeo@shakespeare.lit
+node%22, %22/users/juliet@shakespeare.lit/posts%22);%0A%09%09%0A%09%09affiliation = affiliations.addElement(%22affiliation
 %22);%0A
@@ -2682,37 +2682,28 @@
 ribute(%22
-node%22, %22/users/juliet
+jid%22, %22romeo
 @shakesp
@@ -2706,30 +2706,24 @@
 kespeare.lit
-/posts
 %22);%0A%09%09affili
@@ -3024,32 +3024,56 @@
 element(%22event%22)
+.element(%22affiliations%22)
 %0A%09%09%09%09.element(%22a
@@ -3380,16 +3380,40 @@
 %22event%22)
+.element(%22affiliations%22)
 %0A%09%09%09%09.el

Fix unit tests with affilaitions notification fix