package org.commcare.backend.test;

import org.commcare.test.utilities.MockApp;
import org.commcare.util.SessionFrame;
import org.commcare.util.mocks.SessionWrapper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 *
 * Tests navigating through a CommCareSession (setting datum values and commands, using stepBack(),
 * etc.) for a sample app
 *
 * Created by amstone326 on 8/17/15.
 */
public class SessionNavigationTests {

    MockApp mApp;

    @Before
    public void setUp() throws Exception {
        mApp = new MockApp("/session-tests-template/");
    }

    @Test
    public void testNeedsCommandFirst() {
        SessionWrapper session = mApp.getSession();

        // Before anything is done in the session, should need a command
        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_COMMAND_ID);

        // After setting first command to m0, should still need another command because the 3 forms
        // within m0 have different datum needs, so will prioritize getting the next command first
        session.setCommand("m0");
        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_COMMAND_ID);

        // After choosing the form, will need a case id
        session.setCommand("m0-f1");
        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_DATUM_VAL);
        Assert.assertEquals(session.getNeededDatum().getDataId(), "case_id");

        // Stepping back after choosing a command should go back only 1 level
        session.stepBack();
        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_COMMAND_ID);
        Assert.assertEquals(session.getCommand(), "m0");

        // After choosing registration form, should need computed case id
        session.setCommand("m0-f0");
        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_DATUM_COMPUTED);

        //TODO: Figure out how to run a datum compute from here
    }

    @Test
    public void testNeedsCaseFirst() {
        SessionWrapper session = mApp.getSession();

        // Before anything is done in the session, should need a command
        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_COMMAND_ID);

        // After setting first command to m2, should need a case id, because both forms within m2 need one
        session.setCommand("m2");
        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_DATUM_VAL);
        Assert.assertEquals(session.getNeededDatum().getDataId(), "case_id");

        // After setting case id, should need to choose a form
        session.setDatum("case_id", "case_two");
        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_COMMAND_ID);

        // Should be ready to go after choosing a form
        session.setCommand("m2-f1");
        Assert.assertEquals(session.getNeededData(), null);
    }

    @Test
    public void testStepBack() {
        //TODO: test stepBack() with many different initial configurations of the stack
    }

}

@@ -376,41 +376,23 @@
 %0A * 
-Created by amstone326 on 8/17/15.
+@author amstone
 %0A */
@@ -2888,16 +2888,86 @@
 StepBack
+Basic() %7B%0A%0A    %7D%0A%0A    @Test%0A    public void testStepBackWithExtraValue
 () %7B%0A   
@@ -3051,16 +3051,964 @@
 e stack%0A
+%0A        SessionWrapper session = mApp.getSession();%0A        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_COMMAND_ID);%0A        session.setCommand(%22m1%22);%0A        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_COMMAND_ID);%0A        session.setCommand(%22m1-f1%22);%0A        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_DATUM_VAL);%0A        Assert.assertEquals(session.getNeededDatum().getDataId(), %22case_id%22);%0A        session.setDatum(%22case_id%22, %22case_one%22);%0A        Assert.assertEquals(session.getNeededDatum(), null);%0A        session.setDatum(%22return_to%22, %22m1%22);%0A%0A        // Should pop 2 values off of the session stack in order to return to the last place%0A        // where there was a user-inputted decision%0A        session.stepBack();%0A        Assert.assertEquals(session.getNeededData(), SessionFrame.STATE_DATUM_VAL);%0A        Assert.assertEquals(session.getNeededDatum().getDataId(), %22case_id%22);%0A%0A
     %7D%0A%0A%7D

add stepBack test