package edu.northwestern.bioinformatics.studycalendar.xml.writers;

import edu.northwestern.bioinformatics.studycalendar.dao.delta.ChangeDao;
import edu.northwestern.bioinformatics.studycalendar.domain.Epoch;
import static edu.northwestern.bioinformatics.studycalendar.domain.Fixtures.setGridId;
import edu.northwestern.bioinformatics.studycalendar.domain.Study;
import edu.northwestern.bioinformatics.studycalendar.domain.delta.Add;
import edu.northwestern.bioinformatics.studycalendar.testing.StudyCalendarXmlTestCase;
import org.dom4j.Element;
import static org.easymock.EasyMock.expect;

public class AddXmlSerializerTest extends StudyCalendarXmlTestCase {
    private AddXmlSerializer serializer;
    private Add add;
    private Element element;
    private ChangeDao changeDao;

    protected void setUp() throws Exception {
        super.setUp();

        element = registerMockFor(Element.class);
        changeDao = registerMockFor(ChangeDao.class);

        serializer = new AddXmlSerializer(new Study());
        serializer.setChangeDao(changeDao);

        add = setGridId("grid0", Add.create(setGridId("grid1", new Epoch()), 0));
    }

    public void testCreateElement() {
        Element element = serializer.createElement(add);
        
        assertEquals("Wrong grid id", "grid0", element.attributeValue("id"));
        assertEquals("Wrong index", "0", element.attributeValue("index"));
        assertFalse("Wrong child id", element.elements("epoch").isEmpty());
    }

    public void testReadElementWhenAddExists() {
        expect(element.attributeValue("id")).andReturn("grid0");
        expect(changeDao.getByGridId("grid0")).andReturn(add);
        replayMocks();

        Add actual = (Add) serializer.readElement(element);
        verifyMocks();
        
        assertSame("Change objects should be the same", add, actual);
    }

    public void testReadElementWhenAddIsNew() {
        expect(element.attributeValue("id")).andReturn("grid0");
        expect(changeDao.getByGridId("grid0")).andReturn(null);
        expect(element.attributeValue("index")).andReturn("0");
        replayMocks();

        Add actual = (Add) serializer.readElement(element);
        verifyMocks();

        assertEquals("Wrong grid id", "grid0", actual.getGridId());
        assertEquals("Wrong grid index", 0, (int) actual.getIndex());
    }
}

@@ -356,16 +356,90 @@
 .Study;%0A
+import edu.northwestern.bioinformatics.studycalendar.domain.PlanTreeNode;%0A
 import e
@@ -659,16 +659,47 @@
 xpect;%0A%0A
+import java.util.Collections;%0A%0A
 public c
@@ -887,238 +887,826 @@
 ao;%0A
-%0A    protected void setUp() throws Exception %7B%0A        super.setUp();%0A%0A        element = registerMockFor(Element.class);%0A        changeDao = registerMockFor(ChangeDao.class);%0A%0A        serializer = new AddXmlSerializer(new Study())
+    private AbstractChangeXmlSerializer.PlanTreeNodeXmlSerializerFactory planTreeNodeSerializerFactory;%0A    private AbstractPlanTreeNodeXmlSerializer planTreeNodeSerializer;%0A    private Epoch epoch;%0A%0A    protected void setUp() throws Exception %7B%0A        super.setUp();%0A%0A        element = registerMockFor(Element.class);%0A        changeDao = registerMockFor(ChangeDao.class);%0A        planTreeNodeSerializer = registerMockFor(AbstractPlanTreeNodeXmlSerializer.class);%0A        planTreeNodeSerializerFactory = registerMockFor(AbstractChangeXmlSerializer.PlanTreeNodeXmlSerializerFactory.class);%0A%0A        serializer = new AddXmlSerializer(new Study()) %7B%0A%0A            protected PlanTreeNodeXmlSerializerFactory getPlanTreeNodeSerializerFactory() %7B%0A                return planTreeNodeSerializerFactory;%0A            %7D%0A        %7D
 ;%0A  
@@ -1756,19 +1756,21 @@
         
-add
+epoch
  = setGr
@@ -1783,23 +1783,40 @@
 grid
-0%22, Add.create(
+1%22, new Epoch());%0A        add = 
 setG
@@ -1826,32 +1826,36 @@
 Id(%22grid
-1%22, new E
+0%22, Add.create(e
 poch
-())
 , 0));%0A 
@@ -2807,24 +2807,321 @@
 eturn(%220%22);%0A
+        expect(element.elements()).andReturn(Collections.singletonList(element));%0A        expect(planTreeNodeSerializerFactory.createPlanTreeNodeXmlSerializer(element)).andReturn(planTreeNodeSerializer);%0A        expect(planTreeNodeSerializer.readElement(element)).andReturn((PlanTreeNode) epoch);%0A
         repl

Add change will now de-serialize a PlanTreeNode children when readElement is called.