/*
 * Copyright (c) Smals
 */
package be.ehealth.business.mycarenetcommons.validator;

import java.util.ArrayList;
import java.util.List;

import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.Test;
import org.unitils.reflectionassert.ReflectionAssert;

import be.ehealth.business.mycarenetcommons.domain.CareReceiverId;
import be.ehealth.business.mycarenetcommons.domain.Period;
import be.ehealth.business.mycarenetcommons.domain.Routing;
import be.ehealth.business.mycarenetcommons.exception.ConnectorValidationException;
import be.ehealth.business.mycarenetcommons.exception.ValidationError;


/**
 * tests the RoutingValidator class.
 * 
 * @author EHP
 * 
 */
public class RoutingValidatorTest {

    @Test
    public void testValidationNullObject() throws ConnectorValidationException {
        Routing invalidRouting = null;
        try {
            RoutingValidator.validate(invalidRouting);
            Assert.fail("invalid routing :should have thrown ConnectorValidationException");
        } catch (ConnectorValidationException e) {
            List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
            expectedValidationErrors.add(new ValidationError("Routing", null));
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }
    }

    @Test
    public void testValidRoutingWithPeriod() throws ConnectorValidationException {
        Routing validRouting = new Routing(new CareReceiverId("1231313"), new DateTime());
        DateTime start = new DateTime();
        Period period = new Period(start, start.plusDays(5));
        validRouting.setPeriod(period);
        RoutingValidator.validate(validRouting);
    }

    @Test
    public void testValidRoutingWithoutPeriod() throws ConnectorValidationException {
        Routing validRoutingCareReceiverWithSsin = new Routing(new CareReceiverId("1231313"), new DateTime());
        RoutingValidator.validate(validRoutingCareReceiverWithSsin);
        Routing validRoutingCareReceiverWithMutualityAndMutualityNumber = new Routing(new CareReceiverId("1231313", "100"), new DateTime());
        RoutingValidator.validate(validRoutingCareReceiverWithMutualityAndMutualityNumber);


    }

    @Test
    public void testValidRoutingWithoutReferenceDate() throws ConnectorValidationException {
        Routing invalidRouting = new Routing(new CareReceiverId("1231313"), null);
        try {
            RoutingValidator.validate(invalidRouting);
            Assert.fail("invalid routing :should have thrown ConnectorValidationException");
        } catch (ConnectorValidationException e) {
            List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
            expectedValidationErrors.add(new ValidationError("Routing->ReferenceDate", null));
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }
    }


    @Test
    public void testInvalidRoutingWithPartiallyFilledPeriod() {
        Routing invalidRouting = new Routing(new CareReceiverId("1231313"), new DateTime());
        DateTime start = new DateTime();
        Period period = new Period(null, start.plusDays(5));
        invalidRouting.setPeriod(period);
        try {
            RoutingValidator.validate(invalidRouting);
            Assert.fail("invalid routing :should have thrown ConnectorValidationException");
        } catch (ConnectorValidationException e) {
            List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
            expectedValidationErrors.add(new ValidationError("Routing->Period", null));
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }
    }

    @Test
    public void testInvalidalidRoutingWithInvalidCareReceiver() throws ConnectorValidationException {
        Routing invalidRouting = new Routing(new CareReceiverId(null), new DateTime());
        try {
            RoutingValidator.validate(invalidRouting);
            Assert.fail("invalid routing :should have thrown ConnectorValidationException");
        } catch (ConnectorValidationException e) {
            List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
            expectedValidationErrors.add(new ValidationError("Routing->CareReceiver", null));
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }

    }

    @Test
    public void testInvalidalidRoutingWithInvalidCareReceiverOnlyMutualityId() throws ConnectorValidationException {
        Routing invalidRouting = new Routing(new CareReceiverId(null, "mutialityId", null), new DateTime());
        try {
            RoutingValidator.validate(invalidRouting);
            Assert.fail("invalid routing :should have thrown ConnectorValidationException");
        } catch (ConnectorValidationException e) {
            List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
            expectedValidationErrors.add(new ValidationError("Routing->CareReceiver", null));
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }

    }

    @Test
    public void testInvalidalidRoutingWithInvalidCareReceiverOnlyMutuality() throws ConnectorValidationException {
        Routing invalidRouting = new Routing(new CareReceiverId(null, null, "100"), new DateTime());
        try {
            RoutingValidator.validate(invalidRouting);
            Assert.fail("invalid routing :should have thrown ConnectorValidationException");
        } catch (ConnectorValidationException e) {
            List<ValidationError> expectedValidationErrors = new ArrayList<ValidationError>();
            expectedValidationErrors.add(new ValidationError("Routing->CareReceiver", null));
            List<ValidationError> validationErrors = e.getValidationErrors();
            ReflectionAssert.assertLenientEquals(expectedValidationErrors, validationErrors);
        }

    }


}
