Package org.libreplan.web.test.ws.resources.api

Source Code of org.libreplan.web.test.ws.resources.api.ResourceServiceTest

/*
* This file is part of LibrePlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
*                         Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.libreplan.web.test.ws.resources.api;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.libreplan.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_CONFIG_FILE;
import static org.libreplan.web.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_FILE;
import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_CONFIG_TEST_FILE;
import static org.libreplan.web.test.WebappGlobalNames.WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE;
import static org.libreplan.web.test.ws.common.Util.assertNoConstraintViolations;
import static org.libreplan.web.test.ws.common.Util.assertOneConstraintViolation;
import static org.libreplan.web.test.ws.common.Util.assertOneConstraintViolationPerInstance;
import static org.libreplan.web.test.ws.common.Util.assertOneRecoverableError;
import static org.libreplan.web.test.ws.common.Util.getUniqueName;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.joda.time.LocalDate;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.libreplan.business.calendars.daos.IBaseCalendarDAO;
import org.libreplan.business.calendars.entities.BaseCalendar;
import org.libreplan.business.calendars.entities.ResourceCalendar;
import org.libreplan.business.common.IAdHocTransactionService;
import org.libreplan.business.common.IOnTransaction;
import org.libreplan.business.common.daos.IConfigurationDAO;
import org.libreplan.business.common.entities.IConfigurationBootstrap;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.costcategories.daos.ICostCategoryDAO;
import org.libreplan.business.costcategories.entities.CostCategory;
import org.libreplan.business.resources.daos.ICriterionTypeDAO;
import org.libreplan.business.resources.daos.IMachineDAO;
import org.libreplan.business.resources.daos.IResourceDAO;
import org.libreplan.business.resources.daos.IWorkerDAO;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.CriterionSatisfaction;
import org.libreplan.business.resources.entities.CriterionType;
import org.libreplan.business.resources.entities.Machine;
import org.libreplan.business.resources.entities.Resource;
import org.libreplan.business.resources.entities.ResourceEnum;
import org.libreplan.business.resources.entities.Worker;
import org.libreplan.ws.common.api.InstanceConstraintViolationsDTO;
import org.libreplan.ws.resources.api.CriterionSatisfactionDTO;
import org.libreplan.ws.resources.api.IResourceService;
import org.libreplan.ws.resources.api.MachineDTO;
import org.libreplan.ws.resources.api.ResourceCalendarDTO;
import org.libreplan.ws.resources.api.ResourceDTO;
import org.libreplan.ws.resources.api.ResourceListDTO;
import org.libreplan.ws.resources.api.ResourcesCostCategoryAssignmentDTO;
import org.libreplan.ws.resources.api.WorkerDTO;
import org.libreplan.ws.resources.impl.ResourceConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

/**
* Tests for <code>IResourceService</code>.
*
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
        WEBAPP_SPRING_CONFIG_FILE, WEBAPP_SPRING_CONFIG_TEST_FILE,
        WEBAPP_SPRING_SECURITY_CONFIG_FILE,
        WEBAPP_SPRING_SECURITY_CONFIG_TEST_FILE })
public class ResourceServiceTest {

    @Autowired
    private IResourceService resourceService;

    @Autowired
    private IResourceDAO resourceDAO;

    @Autowired
    private IMachineDAO machineDAO;

    @Autowired
    private IWorkerDAO workerDAO;

    @Autowired
    private ICriterionTypeDAO criterionTypeDAO;

    @Autowired
    private IConfigurationDAO configurationDAO;

    @Autowired
    private IBaseCalendarDAO baseCalendarDAO;

    @Autowired
    private ICostCategoryDAO costCategoryDAO;

    @Autowired
    private IConfigurationBootstrap configurationBootstrap;

    @Autowired
    private IAdHocTransactionService transactionService;

    @Before
    public void loadConfiguration() {

        IOnTransaction<Void> load =
            new IOnTransaction<Void>() {

            @Override
            public Void execute() {
                configurationBootstrap.loadRequiredData();
                return null;
            }
        };

        transactionService.runOnAnotherTransaction(load);

    }

    @Test
    @Transactional
    public void testAddResourcesWithBasicContraintViolations() {

        /* Create resource DTOs. */
        MachineDTO m1 = new MachineDTO("name", "desc");
        MachineDTO m2 = new MachineDTO(" ", null, ""); // Missing code and name
                                                      // (description is
                                                      // optional).

        WorkerDTO w1 = new WorkerDTO(getUniqueName(), "w1-surname", "w1-nif");
        WorkerDTO w2 = new WorkerDTO(null, "", null, ""); // Missing code, first
                                                          // name, surname, and
                                                          // nif.

        /* Test. */
        List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
            resourceService.addResources(
                createResourceListDTO(m1, m2, w1, w2)).
                    instanceConstraintViolationsList;

        assertTrue(
            instanceConstraintViolationsList.toString(),
            instanceConstraintViolationsList.size() == 2);
        assertTrue(
            instanceConstraintViolationsList.get(0).
            constraintViolations.toString(),
            instanceConstraintViolationsList.get(0).
            constraintViolations.size() == 2); // m2 constraint violations.
        assertTrue(
            instanceConstraintViolationsList.get(1).
            constraintViolations.toString(),
            instanceConstraintViolationsList.get(1).
            constraintViolations.size() == 4); // w2 constraint violations.
        assertTrue(resourceDAO.existsByCode(m1.code));
        assertTrue(resourceDAO.existsByCode(w1.code));

    }

    @Test
    @Transactional
    public void testAddWorkerWithExistingFirstNameSurnameAndNif() {

        /* Create a worker. */
        Worker w1 = Worker.createUnvalidated(getUniqueName(), getUniqueName(),
            "surname", "nif");
        saveResource(w1);

        /*
         * Create a worker DTO with the same first name, surname, and ID as
         * the previous one.
         */
        WorkerDTO w2 = new WorkerDTO(w1.getFirstName(), w1.getSurname(),
            w1.getNif());

        /* Test. */
        assertOneConstraintViolation(
            resourceService.addResources(createResourceListDTO(w2)));
        assertFalse(resourceDAO.existsByCode(w2.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithCriterionSatisfactions() {

        /* Create a criterion type. */
        CriterionType ct = createCriterionType(ResourceEnum.MACHINE);

        /* Create a resource DTO. */
        MachineDTO m1 = new MachineDTO("name", "desc");
        CriterionSatisfactionDTO cs1m1 =
            new CriterionSatisfactionDTO(
                ' ' + ct.getName().toUpperCase() // Upper case and blank
                ' ', " C1 ",                        // spaces intentionally
                                                    // added (OK).
                getDate(2001, 1, 1), getDate(2001, 2, 1));
        m1.criterionSatisfactions.add(cs1m1);
        m1.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(ct.getName(), "c2",
                getDate(2001, 1, 1), null));

        MachineDTO m2 = new MachineDTO("name", "desc");
        m2.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(cs1m1.code, ct.getName(), "c1",
                getDate(2001, 1, 1), null)); // Repeated criterion satisfaction
                                             // code (used by another machine).
        m2.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(null, ct.getName(), "c2",
                getDate(2001, 1, 1), null)); // Missing criterion satisfaction
        // code.(autogenerated code)

        MachineDTO m3 = new MachineDTO("name", "desc");
        CriterionSatisfactionDTO cs1m3 =
            new CriterionSatisfactionDTO(ct.getName(), "c1",
                getDate(2001, 1, 1), getDate(2001, 2, 1));
        m3.criterionSatisfactions.add(cs1m3);
        m3.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(
                cs1m3.code, // Repeated criterion satisfaction code in this
                            // machine.
                ct.getName(), "c2",
                getDate(2001, 1, 1), null));

        /* Test. */
        List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList =
        resourceService.addResources(createResourceListDTO(m1, m2, m3)).
            instanceConstraintViolationsList;

        assertTrue(
            instanceConstraintViolationsList.toString(),
            instanceConstraintViolationsList.size() == 2);
        assertTrue(
            instanceConstraintViolationsList.get(0).
            constraintViolations.toString(),
            instanceConstraintViolationsList.get(0).
constraintViolations
                        .size() == 1); // m2 constraint violations.
        assertTrue(
            instanceConstraintViolationsList.get(1).
            constraintViolations.toString(),
            instanceConstraintViolationsList.get(1).
            constraintViolations.size() == 1); // m3 constraint violations.
        assertFalse(resourceDAO.existsByCode(m2.code));
        assertFalse(resourceDAO.existsByCode(m3.code));

        Machine machine = machineDAO.findExistingEntityByCode(m1.code);
        assertTrue(machine.getCriterionSatisfactions().size() == 2);

        for (CriterionSatisfaction cs : machine.getCriterionSatisfactions()) {
            if (!(cs.getCriterion().getName().equals("c1") ||
                cs.getCriterion().getName().equals("c2"))) {
                fail("Criterion not expected");
            }
        }

        assertFalse(resourceDAO.existsByCode(m2.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithCriterionSatisfactionWithoutStartDate() {

        /* Create a criterion type. */
        CriterionType ct = createCriterionType(ResourceEnum.MACHINE);

        /* Create a machine DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(ct.getName() , "c1",
                null, getDate(2001, 1, 1))); // Missing start date.

        /* Test. */
        assertOneConstraintViolation(
            resourceService.addResources(createResourceListDTO(machineDTO)));
        assertFalse(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithCriterionSatisfactionWithNegativeInterval() {

        /* Create a criterion type. */
        CriterionType ct = createCriterionType(ResourceEnum.MACHINE);

        /* Create a machine DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(ct.getName() , "c1",
                getDate(2000, 2, 1), getDate(2000, 1, 1)));

        /* Test. */
        assertOneConstraintViolation(
            resourceService.addResources(createResourceListDTO(machineDTO)));
        assertFalse(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithOverlappingCriterionSatisfactionsAllowed() {

        /* Create a criterion type. */
        CriterionType ct = createCriterionType(ResourceEnum.MACHINE);

        /*
         * Create a machine DTO. OK, because
         * ct.isAllowSimultaneousCriterionsPerResource() is true.
         */
        MachineDTO machineDTO = createMachineDTOWithTwoCriterionSatisfactions(
            "machine", ct.getName(),
            "c1", getDate(2000, 1, 1), getDate(2000, 2, 1),
            "c2", getDate(2000, 1, 15), getDate(2000, 2, 1));

        /* Test. */
        assertNoConstraintViolations(
            resourceService.addResources(createResourceListDTO(machineDTO)));
        assertTrue(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithOverlappingCriterionSatisfactions() {

        /* Create criterion types. */
        CriterionType ct1 = createCriterionType(ResourceEnum.MACHINE);
        CriterionType ct2 = createCriterionType(ResourceEnum.MACHINE, false);

        /*
         * Create resource DTOs. Each resource contains one criterion
         * satisfaction overlapping.
         *
         */
        MachineDTO m1 = createMachineDTOWithTwoCriterionSatisfactions(
            "m1", ct1.getName(), // Interval overlapping in "c1".
            "c1", getDate(2000, 1, 1), getDate(2000, 2, 1),
            "c1", getDate(2000, 1, 15), getDate(2000, 2, 1));

        MachineDTO m2 = createMachineDTOWithTwoCriterionSatisfactions(
            "m2", ct2.getName(), // Overlapping because "ct2" does not allow
                                 // simultaneous criterion satisfactions in
                                 // intervals that overlap.
            "c1", getDate(2000, 1, 1), getDate(2000, 2, 1),
            "c2", getDate(2000, 1, 15), getDate(2000, 2, 1));

        /* Test. */
        ResourceListDTO resourceDTOs = createResourceListDTO(
            m1, m2);

        assertOneConstraintViolationPerInstance(
            resourceService.addResources(resourceDTOs),
            resourceDTOs.resources.size());

        for (ResourceDTO r : resourceDTOs.resources) {
            MachineDTO m = (MachineDTO) r;
            assertFalse(
                "Machine " + m.name + " not expected",
                resourceDAO.existsByCode(((MachineDTO) r).code));
        }

    }

    @Test
    @Transactional
    public void testAddResourcesWithCriterionSatisfactionsWithIncorrectCriterionType() {

        /* Create two criterion types. */
        CriterionType machineCt = createCriterionType(ResourceEnum.MACHINE);
        CriterionType workerCt = createCriterionType(ResourceEnum.WORKER);

        /* Create resource DTOs. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(workerCt.getName() , "c1",
                getDate(2001, 1, 1), null)); // Incorrect type.
        WorkerDTO workerDTO = new WorkerDTO(getUniqueName(), "surname",
                getUniqueName());
        workerDTO.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(machineCt.getName() , "c1",
                getDate(2001, 1, 1), null)); // Incorrect type.

        /* Test. */
        assertOneConstraintViolation(
            resourceService.addResources(createResourceListDTO(machineDTO)));
        assertFalse(
            resourceDAO.existsByCode(machineDTO.code));
        assertOneConstraintViolation(
            resourceService.addResources(createResourceListDTO(workerDTO)));
        assertFalse(resourceDAO.existsByCode(workerDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourcesWithCriterionSatisfactionsWithMissingNames() {

        /* Create a criterion type. */
        CriterionType ct = createCriterionType();

        /* Create machines DTOs. */
        MachineDTO m1 = new MachineDTO("m1", "desc");
        m1.criterionSatisfactions.add(
            new CriterionSatisfactionDTO("", "X", // Missing criterion type.
                getDate(2001, 1, 1), null));
        MachineDTO m2 = new MachineDTO("m2", "desc");
        m2.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(ct.getName(), // Missing criterion.
                null, getDate(2001, 1, 1), null));

        /* Test. */
        ResourceListDTO resourceDTOs = createResourceListDTO(m1, m2);

        assertOneConstraintViolationPerInstance(
            resourceService.addResources(resourceDTOs),
            resourceDTOs.resources.size());

        for (ResourceDTO r : resourceDTOs.resources) {
            MachineDTO m = (MachineDTO) r;
            assertFalse(
                "Machine " + m.name + " not expected",
                resourceDAO.existsByCode(((MachineDTO) r).code));
        }

    }

    @Test
    @Transactional
    public void testAddResourceWithCriterionSatisfactionsWithNonExistentCriterionType() {

        /* Create a machine DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(getUniqueName() , "c1",
                getDate(2000, 1, 1), null));

        /* Test. */
        assertOneRecoverableError(
            resourceService.addResources(createResourceListDTO(machineDTO)));
        assertFalse(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithCriterionSatisfactionsWithNonExistentCriterion() {

        /* Create a criterion type. */
        CriterionType ct = createCriterionType();

        /* Create a machine DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(ct.getName(), getUniqueName(),
                getDate(2000, 1, 1), null));

        /* Test. */
        assertOneRecoverableError(
            resourceService.addResources(createResourceListDTO(machineDTO)));
        assertFalse(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithDefaultCalendar() {

        /* Create a machine DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");

        /* Test. */
        assertNoConstraintViolations(resourceService.
             addResources(createResourceListDTO(machineDTO)));
        Machine machine = machineDAO.findExistingEntityByCode(machineDTO.code);
        assertEquals(getDefaultCalendar().getId(),
            machine.getCalendar().getParent().getId());

    }

    @Test
    @Transactional
    public void testAddResourceWithSpecificCalendar() {

        /* Create a resource calendar DTO. */
        BaseCalendar baseCalendar = createBaseCalendar();
        ResourceCalendar resourceCalendar = baseCalendar
                .newDerivedResourceCalendar();
        ResourceCalendarDTO resourceCalendarDTO = ResourceConverter
                .toDTO(resourceCalendar);

        /* Create a machine DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.calendar = resourceCalendarDTO;

        /* Test. */
        assertNoConstraintViolations(resourceService
                .addResources(createResourceListDTO(machineDTO)));
        Machine machine = machineDAO.findExistingEntityByCode(machineDTO.code);
        assertEquals(baseCalendar.getId(), machine.getCalendar().getParent()
                .getId());

    }

    @Test
    @Transactional
    public void testAddResourceWithNonExistentCalendar() {

        /* Create invalid calendar */
        ResourceCalendarDTO calendarDTO = new ResourceCalendarDTO("",
                "ParentNoExist", null,
                null, null, null);
        /* Create a machine DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.calendar = calendarDTO;

        /* Test. */
        assertOneRecoverableError(resourceService
                .addResources(createResourceListDTO(machineDTO)));
        assertFalse(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithCostAssignments() {

        /* Create a CostCategory. */
        CostCategory costCategory = createCostCategory();

        /* Create resource DTOs. */
        MachineDTO m1 = new MachineDTO("name", "desc");
        ResourcesCostCategoryAssignmentDTO a1m1 = new ResourcesCostCategoryAssignmentDTO(
                ' ' + costCategory.getName().toUpperCase() + ' ', getDate(2001,
                        1, 1), null);
        m1.resourcesCostCategoryAssignments.add(a1m1);
        m1.resourcesCostCategoryAssignments
                .add(new ResourcesCostCategoryAssignmentDTO(costCategory
                        .getName(), getDate(2000, 1, 1), getDate(2000, 4, 1)));

        MachineDTO m2 = new MachineDTO("name", "desc");
        m2.resourcesCostCategoryAssignments
                .add(new ResourcesCostCategoryAssignmentDTO(a1m1.code,
                        costCategory.getName().toUpperCase(), getDate(2001, 1,
                                1), null)); // Repeated assignment code
        // (used by another machine).
        m2.resourcesCostCategoryAssignments
                .add(new ResourcesCostCategoryAssignmentDTO(null, costCategory
                        .getName().toUpperCase(), getDate(2000, 1, 1), getDate(
                        2000, 4, 1))); // Missing
        // assignment code (autogenerated code).

        MachineDTO m3 = new MachineDTO("name", "desc");
        ResourcesCostCategoryAssignmentDTO a1m3 = new ResourcesCostCategoryAssignmentDTO(
                costCategory.getName(), getDate(2001, 1, 1), null);
        m3.resourcesCostCategoryAssignments.add(a1m3);
        m3.resourcesCostCategoryAssignments
                .add(new ResourcesCostCategoryAssignmentDTO(a1m3.code, // Repeated
                                                                       // assignment
                                                                       // code
                                                                       // in
                                                                       // this
                                                                       // machine.
                        costCategory.getName(), getDate(2000, 1, 1), getDate(
                                2000, 4, 1)));

        /* Test. */
        List<InstanceConstraintViolationsDTO> instanceConstraintViolationsList = resourceService
                .addResources(createResourceListDTO(m1, m2, m3)).instanceConstraintViolationsList;

        assertTrue(instanceConstraintViolationsList.toString(),
                instanceConstraintViolationsList.size() == 2);
        assertTrue(instanceConstraintViolationsList.get(0).constraintViolations
                .toString(),
                instanceConstraintViolationsList.get(0).constraintViolations
                        .size() == 1); // m2 constraint violations.
        assertTrue(instanceConstraintViolationsList.get(1).constraintViolations
                .toString(),
                instanceConstraintViolationsList.get(1).constraintViolations
                        .size() == 1); // m3 constraint violations.

        assertTrue(resourceDAO.existsByCode(m1.code));
        assertFalse(resourceDAO.existsByCode(m2.code));

    }

    @Test
    @Transactional
    public void testAddResourcesWithCostAssignmentWithMissingCostCategoryName() {

        /* Create a resource DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.resourcesCostCategoryAssignments
                .add(new ResourcesCostCategoryAssignmentDTO("", null, getDate(
                        2000, 1, 1), null));

        /* Test. */
        assertOneConstraintViolation(resourceService
                .addResources(createResourceListDTO(machineDTO)));
        assertFalse(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourcesWithCostAssignmentWithNonExistentCostCategory() {

        /* Create a resource DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.resourcesCostCategoryAssignments
                .add(new ResourcesCostCategoryAssignmentDTO(getUniqueName(),
                        getDate(2000, 1, 1), null));

        /* Test. */
        assertOneRecoverableError(resourceService
                .addResources(createResourceListDTO(machineDTO)));
        assertFalse(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithCostAssignmentWithoutStartDate() {

        /* Create a CostCategory. */
        CostCategory costCategory = createCostCategory();

        /* Create a resource DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.resourcesCostCategoryAssignments
                .add(new ResourcesCostCategoryAssignmentDTO(costCategory
                        .getName(), null, // Start date not specified.
                        getDate(2000, 1, 1)));

        /* Test. */
        assertOneConstraintViolation(resourceService
                .addResources(createResourceListDTO(machineDTO)));
        assertFalse(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourceWithCostAssignmentWithNegativeInterval() {

        /* Create a CostCategory. */
        CostCategory costCategory = createCostCategory();

        /* Create a resource DTO. */
        MachineDTO machineDTO = new MachineDTO("name", "desc");
        machineDTO.resourcesCostCategoryAssignments
                .add(new ResourcesCostCategoryAssignmentDTO(costCategory
                        .getName(), getDate(2000, 2, 1), getDate(2000, 1, 1)));

        /* Test. */
        assertOneConstraintViolation(resourceService
                .addResources(createResourceListDTO(machineDTO)));
        assertFalse(resourceDAO.existsByCode(machineDTO.code));

    }

    @Test
    @Transactional
    public void testAddResourcesWithOverlappingInCostAssignments() {

        /* Create a CostCategory. */
        CostCategory costCategory = createCostCategory();

        /*
         * Create a resource DTOs. Each resource contains one cost assignment
         * overlapping.
         */
        MachineDTO m1 = createMachineDTOWithTwoCostsAssignments("m1",
                costCategory.getName(), getDate(2000, 1, 1), null, getDate(
                        2000, 2, 1), null);

        MachineDTO m2 = createMachineDTOWithTwoCostsAssignments("m2",
                costCategory.getName(), getDate(2000, 2, 1), null, getDate(
                        2000, 1, 1), getDate(2000, 3, 1));

        MachineDTO m3 = createMachineDTOWithTwoCostsAssignments("m3",
                costCategory.getName(), getDate(2000, 2, 1),
                getDate(2000, 4, 1), getDate(2000, 3, 1), null);

        MachineDTO m4 = createMachineDTOWithTwoCostsAssignments("m4",
                costCategory.getName(), getDate(2000, 2, 1),
                getDate(2000, 5, 1), getDate(2000, 1, 1), getDate(2000, 3, 1));

        MachineDTO m5 = createMachineDTOWithTwoCostsAssignments("m5",
                costCategory.getName(), getDate(2000, 2, 1),
                getDate(2000, 5, 1), getDate(2000, 3, 1), getDate(2000, 4, 1));

        MachineDTO m6 = createMachineDTOWithTwoCostsAssignments("m6",
                costCategory.getName(), getDate(2000, 2, 1),
                getDate(2000, 5, 1), getDate(2000, 4, 1), getDate(2000, 6, 1));

        MachineDTO m7 = createMachineDTOWithTwoCostsAssignments("m7",
                costCategory.getName(), getDate(2000, 2, 1),
                getDate(2000, 5, 1), getDate(2000, 1, 1), getDate(2000, 2, 1));

        MachineDTO m8 = createMachineDTOWithTwoCostsAssignments("m8",
                costCategory.getName(), getDate(2000, 2, 1),
                getDate(2000, 5, 1), getDate(2000, 5, 1), getDate(2000, 6, 1));

        MachineDTO m9 = createMachineDTOWithTwoCostsAssignments("m9",
                costCategory.getName(), getDate(2000, 2, 1),
                getDate(2000, 5, 1), getDate(2000, 2, 1), getDate(2000, 5, 1));

        /* Test. */
        ResourceListDTO resourceDTOs = createResourceListDTO(m1, m2, m3, m4,
                m5, m6, m7, m8, m9);

        assertOneConstraintViolationPerInstance(resourceService
                .addResources(resourceDTOs), resourceDTOs.resources.size());

        for (ResourceDTO r : resourceDTOs.resources) {
            MachineDTO m = (MachineDTO) r;
            assertFalse("Machine " + m.name + " not expected", resourceDAO
                    .existsByCode(((MachineDTO) r).code));
        }

    }

    @Test
    @Transactional
    public void testUpdateResources() throws InstanceNotFoundException {

        CriterionType ctMachine = createCriterionType(ResourceEnum.MACHINE);
        CriterionType ctWorker = createCriterionType(ResourceEnum.WORKER);
        CostCategory costCategory = createCostCategory();

        /* Create a machine DTO. */
        MachineDTO m1 = new MachineDTO("name", "desc");
        CriterionSatisfactionDTO m1s1 = new CriterionSatisfactionDTO(
                ctMachine
                .getName(), "c1", getDate(2000, 1, 1), getDate(2000, 2, 1));
        m1.criterionSatisfactions.add(m1s1);
        ResourcesCostCategoryAssignmentDTO m1a1 = new ResourcesCostCategoryAssignmentDTO(
                costCategory.getName(), getDate(2000, 1, 1),
                getDate(2000, 2, 1));
        m1.resourcesCostCategoryAssignments.add(m1a1);

        /* Create a worker DTO. */
        String nif = getUniqueName();
        WorkerDTO w1 = new WorkerDTO(getUniqueName(), "surname", nif);
        CriterionSatisfactionDTO w1s1 = new CriterionSatisfactionDTO(
                ctWorker
                .getName(), "c1", getDate(2000, 1, 1), getDate(2000, 2, 1));
        w1.criterionSatisfactions.add(w1s1);
        ResourcesCostCategoryAssignmentDTO w1a1 = new ResourcesCostCategoryAssignmentDTO(
                costCategory.getName(), getDate(2000, 1, 1),
                getDate(2000, 2, 1));
        w1.resourcesCostCategoryAssignments.add(w1a1);

        /* Add resources. */
        assertNoConstraintViolations(resourceService
                .addResources(createResourceListDTO(m1, w1)));

        /*
         * Build DTOs for making the following update: + m1: update name, m1s1's
         * start date, and add a new cost category assignment. + w1: update
         * surname, w1a1's start date, and add a new criterion satisfaction.
         */
        MachineDTO m1Updated = new MachineDTO(m1.code, "name" + "UPDATED", null);
        CriterionSatisfactionDTO m1s1Updated = new CriterionSatisfactionDTO(
                m1s1.code, null, null, getDate(2000, 1, 2), null);
        m1Updated.criterionSatisfactions.add(m1s1Updated);
        ResourcesCostCategoryAssignmentDTO m1a2 = new ResourcesCostCategoryAssignmentDTO(
                costCategory.getName(), getDate(2000, 3, 1),
                getDate(2000, 4, 1));
        m1Updated.resourcesCostCategoryAssignments.add(m1a2);

        WorkerDTO w1Updated = new WorkerDTO(w1.code, null, "surname"
                + "UPDATED", null);
        CriterionSatisfactionDTO w1s2 = new CriterionSatisfactionDTO(
                ctWorker
                .getName(), "c1", getDate(2000, 3, 1), getDate(2000, 4, 1));
        w1Updated.criterionSatisfactions.add(w1s2);
        ResourcesCostCategoryAssignmentDTO w1a1Updated = new ResourcesCostCategoryAssignmentDTO(
                w1a1.code, null, getDate(2000, 2, 1), null);
        w1Updated.resourcesCostCategoryAssignments.add(w1a1Updated);

        /* Update resources and test. */
        assertNoConstraintViolations(resourceService
                .addResources(createResourceListDTO(m1Updated, w1Updated)));

        /* Test machine update. */
        Machine m1Entity = machineDAO.findByCode(m1.code);

        assertEquals(m1Updated.name, m1Entity.getName()); // Modified.
        assertEquals(m1.description, m1Entity.getDescription()); //Not modified.
        assertTrue(datesEquals( // Modified.
            m1s1Updated.startDate,
            m1Entity.getCriterionSatisfactionByCode(m1s1.code).getStartDate()));
        assertTrue(datesEquals( // Not modified.
            m1s1.endDate,
            m1Entity.getCriterionSatisfactionByCode(m1s1.code).getEndDate()));
        m1Entity.getResourcesCostCategoryAssignmentByCode(m1a2.code); // New.

        /* Test worker update. */
        Worker w1Entity = workerDAO.findByCode(w1.code);

        assertEquals(w1Updated.surname, w1Entity.getSurname()); // Modified.
        assertEquals(w1.firstName, w1Entity.getFirstName()); // Not modified.
        w1Entity.getCriterionSatisfactionByCode(w1s2.code); // New.
        assertTrue(datesEquals( // Modified.
            w1a1Updated.startDate,
            w1Entity.getResourcesCostCategoryAssignmentByCode(w1a1.code).
                getInitDate()));
        assertTrue(datesEquals( // Not modified.
            w1a1.endDate,
            w1Entity.getResourcesCostCategoryAssignmentByCode(w1a1.code).
                getEndDate()));

    }

    private CriterionType createCriterionType() {
        return createCriterionType(ResourceEnum.WORKER, true);
    }

    private CriterionType createCriterionType(final ResourceEnum resourceType) {
        return createCriterionType(resourceType, true);
    }

    private CriterionType createCriterionType(final ResourceEnum resourceType,
        final boolean allowSimultaneousCriterionsPerResource) {

        IOnTransaction<CriterionType> createCriterionType =
            new IOnTransaction<CriterionType>() {

            @Override
            public CriterionType execute() {

                CriterionType ct = CriterionType.create(getUniqueName(),
                    "desc");
                ct.setAllowSimultaneousCriterionsPerResource(
                    allowSimultaneousCriterionsPerResource);
                ct.setResource(resourceType);
                Criterion c1 = Criterion.create("c1", ct);
                Criterion c2 = Criterion.create("c2", ct);
                ct.getCriterions().add(c1);
                ct.getCriterions().add(c2);
                criterionTypeDAO.save(ct);

                return ct;

            }
        };

        return transactionService.runOnAnotherTransaction(createCriterionType);

    }

    private void saveResource(final Resource resource) {

        IOnTransaction<Void> save = new IOnTransaction<Void>() {

            @Override
            public Void execute() {
                resourceDAO.save(resource);
                return null;
            }
        };

        transactionService.runOnAnotherTransaction(save);

    }

    private BaseCalendar getDefaultCalendar() {

        IOnTransaction<BaseCalendar> find = new IOnTransaction<BaseCalendar>() {

            @Override
            public BaseCalendar execute() {
                return configurationDAO.getConfiguration().getDefaultCalendar();
            }
        };

        return transactionService.runOnAnotherTransaction(find);

    }

    private BaseCalendar createBaseCalendar() {

        IOnTransaction<BaseCalendar> create = new IOnTransaction<BaseCalendar>() {

            @Override
            public BaseCalendar execute() {
                BaseCalendar baseCalendar = BaseCalendar.createBasicCalendar();
                baseCalendar.setName(getUniqueName());
                baseCalendarDAO.save(baseCalendar);
                return baseCalendar;
            }
        };

        return transactionService.runOnAnotherTransaction(create);

    }

    private ResourceListDTO createResourceListDTO(ResourceDTO... resources) {

        List<ResourceDTO> resourceList = new ArrayList<ResourceDTO>();

        for (ResourceDTO r : resources) {
            resourceList.add(r);
        }


        return new ResourceListDTO(resourceList);

    }

    private CostCategory createCostCategory() {

        IOnTransaction<CostCategory> create =
            new IOnTransaction<CostCategory>() {

            @Override
            public CostCategory execute() {
                CostCategory costCategory =
                    CostCategory.create(getUniqueName());
                costCategoryDAO.save(costCategory);
                return costCategory;
            }
        };

        return transactionService.runOnAnotherTransaction(create);

    }


    private MachineDTO createMachineDTOWithTwoCriterionSatisfactions(
        String machineName, String criterionTypeName,
        String criterionName1, XMLGregorianCalendar startDate1,
        XMLGregorianCalendar endDate1,
        String criterionName2, XMLGregorianCalendar startDate2,
        XMLGregorianCalendar endDate2) {

        MachineDTO machineDTO = new MachineDTO(machineName, "desc");

        machineDTO.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(criterionTypeName, criterionName1,
                startDate1, endDate1));
        machineDTO.criterionSatisfactions.add(
            new CriterionSatisfactionDTO(criterionTypeName, criterionName2,
                startDate2, endDate2));

        return machineDTO;

    }

    private MachineDTO createMachineDTOWithTwoCostsAssignments(
        String machineName, String costCategoryName,
        XMLGregorianCalendar startDate1, XMLGregorianCalendar endDate1,
        XMLGregorianCalendar startDate2, XMLGregorianCalendar endDate2) {

        MachineDTO machineDTO = new MachineDTO(machineName, "desc");

        machineDTO.resourcesCostCategoryAssignments.add(
            new ResourcesCostCategoryAssignmentDTO(
                costCategoryName, startDate1, endDate1));
        machineDTO.resourcesCostCategoryAssignments.add(
            new ResourcesCostCategoryAssignmentDTO(
                costCategoryName, startDate2, endDate2));

        return machineDTO;

    }

    private XMLGregorianCalendar getDate(int year, int month, int day) {

        try {
            return DatatypeFactory.newInstance().newXMLGregorianCalendarDate(
                year, month, day, DatatypeConstants.FIELD_UNDEFINED);
        } catch (DatatypeConfigurationException e) {
            throw new RuntimeException(e);
        }

    }

    private boolean datesEquals(XMLGregorianCalendar date1, Date date2) {

        GregorianCalendar date2AsGC = new GregorianCalendar();
        date2AsGC.setTime(date2);

        return datesEquals(date1.toGregorianCalendar(), date2AsGC);

    }

    private boolean datesEquals(XMLGregorianCalendar date1, LocalDate date2) {

        GregorianCalendar date2AsGC = new GregorianCalendar(
            date2.getYear(), date2.getMonthOfYear()-1, date2.getDayOfMonth());

        return datesEquals(date1.toGregorianCalendar(), date2AsGC);


    }

    public boolean datesEquals(GregorianCalendar date1,
        GregorianCalendar date2) {

        return date1.get(Calendar.YEAR) == date2.get(Calendar.YEAR) &&
            date1.get(Calendar.MONTH) == date2.get(Calendar.MONTH) &&
            date1.get(Calendar.DAY_OF_MONTH) ==
                date2.get(Calendar.DAY_OF_MONTH);

    }

}
TOP

Related Classes of org.libreplan.web.test.ws.resources.api.ResourceServiceTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.