/** * *************************************************************************** * Copyright (c) 2010 Qcadoo Limited * Project: Qcadoo MES * Version: 1.4 * * This file is part of Qcadoo. * * Qcadoo 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, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************** */ package com.qcadoo.mes.technologies.tree; import static com.google.common.collect.Lists.newArrayList; import static com.qcadoo.mes.technologies.constants.TechnologyOperationComponentFields.NODE_NUMBER; import static com.qcadoo.mes.technologies.constants.TechnologyOperationComponentFields.OPERATION_PRODUCT_IN_COMPONENTS; import static com.qcadoo.mes.technologies.constants.TechnologyOperationComponentFields.OPERATION_PRODUCT_OUT_COMPONENTS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.test.util.ReflectionTestUtils; import com.google.common.collect.ImmutableList; import com.qcadoo.model.api.DataDefinition; import com.qcadoo.model.api.DataDefinitionService; import com.qcadoo.model.api.Entity; import com.qcadoo.model.api.EntityList; import com.qcadoo.model.api.EntityTree; import com.qcadoo.model.api.EntityTreeNode; public class TechnologyTreeValidationServiceImplTest { private TechnologyTreeValidationService technologyTreeValidationService; private static final List<EntityTreeNode> EMPTY_TREE_NODES_LIST = new ImmutableList.Builder<EntityTreeNode>().build(); @Mock private DataDefinitionService dataDefinitionService; @Mock private DataDefinition dataDefinition; @Mock private EntityTree tree; private Map<String, Set<String>> resultMap; @Before public final void init() { MockitoAnnotations.initMocks(this); technologyTreeValidationService = new TechnologyTreeValidationServiceImpl(); given(tree.isEmpty()).willReturn(false); resultMap = null; ReflectionTestUtils.setField(technologyTreeValidationService, "dataDefinitionService", dataDefinitionService); given(dataDefinitionService.get("basic", "product")).willReturn(dataDefinition); } @Test public final void shouldReturnEmptyMapForNullTree() { // when resultMap = technologyTreeValidationService.checkConsumingManyProductsFromOneSubOp(null); // then assertNotNull(resultMap); assertTrue(resultMap.isEmpty()); } @Test public final void shouldReturnEmptyMapForEmptyTree() { // given given(tree.isEmpty()).willReturn(true); // when resultMap = technologyTreeValidationService.checkConsumingManyProductsFromOneSubOp(tree); // then assertNotNull(resultMap); assertTrue(resultMap.isEmpty()); } @Test public final void shouldReturnNotEmptyMapIfParentOpConsumeManyOutputsFromOneSubOp() { // given Entity product1 = mockProductComponent(1L); Entity product2 = mockProductComponent(2L); Entity product3 = mockProductComponent(3L); Entity product4 = mockProductComponent(4L); Entity product5 = mockProductComponent(5L); Entity product6 = mockProductComponent(6L); EntityTreeNode node3 = mockOperationComponent("3.", newArrayList(product6), newArrayList(product3, product4, product5)); EntityTreeNode node2 = mockOperationComponent("2.", newArrayList(product3, product4), newArrayList(product2), newArrayList(node3)); EntityTreeNode node1 = mockOperationComponent("1.", newArrayList(product2), newArrayList(product1), newArrayList(node2)); given(tree.getRoot()).willReturn(node1); // when resultMap = technologyTreeValidationService.checkConsumingManyProductsFromOneSubOp(tree); // then assertNotNull(resultMap); assertFalse(resultMap.isEmpty()); assertEquals(1, resultMap.size()); hasNodeNumbersFor(node2, node3); } @Test public final void shouldReturnNotEmptyMapIfSubOpsProduceTheSameOutputsWhichAreConsumed() { // given Entity product1 = mockProductComponent(1L); Entity product2 = mockProductComponent(2L); Entity product3 = mockProductComponent(3L); Entity product4 = mockProductComponent(4L); Entity product5 = mockProductComponent(5L); Entity product6 = mockProductComponent(6L); EntityTreeNode node3 = mockOperationComponent(3L, "3.", newArrayList(product5), newArrayList(product2, product3)); EntityTreeNode node2 = mockOperationComponent(2L, "2.", newArrayList(product6), newArrayList(product2, product4)); EntityTreeNode node1 = mockOperationComponent(1L, "1.", newArrayList(product2), newArrayList(product1), newArrayList(node2, node3)); given(tree.getRoot()).willReturn(node1); // when Map<String, Set<Entity>> returnedMap = technologyTreeValidationService .checkConsumingTheSameProductFromManySubOperations(tree); // then assertNotNull(returnedMap); assertFalse(returnedMap.isEmpty()); assertEquals(1, returnedMap.size()); assertTrue(returnedMap.containsKey("1.")); assertTrue(returnedMap.get("1.").contains(product2)); } @Test public final void shouldReturnNotEmptyMapIfManyParentOpConsumesManyOutputsFromOneSubOp() { // given Entity product1 = mockProductComponent(1L); Entity product2 = mockProductComponent(2L); Entity product3 = mockProductComponent(3L); Entity product4 = mockProductComponent(4L); Entity product5 = mockProductComponent(5L); Entity product6 = mockProductComponent(6L); Entity product7 = mockProductComponent(7L); Entity product8 = mockProductComponent(8L); Entity product9 = mockProductComponent(9L); Entity product10 = mockProductComponent(10L); Entity product11 = mockProductComponent(11L); Entity product12 = mockProductComponent(12L); EntityTreeNode node1A3 = mockOperationComponent("1.A.3.", newArrayList(product11, product12), newArrayList(product10)); EntityTreeNode node1A2 = mockOperationComponent("1.A.2.", newArrayList(product10), newArrayList(product7, product8, product9), newArrayList(node1A3)); EntityTreeNode node1A1 = mockOperationComponent("1.A.1.", newArrayList(product7, product8, product9), newArrayList(product2, product3), newArrayList(node1A2)); EntityTreeNode node1B1 = mockOperationComponent("1.B.1.", newArrayList(product6), newArrayList(product4, product5)); EntityTreeNode node1 = mockOperationComponent("1.", newArrayList(product2, product3, product4, product5), newArrayList(product1), newArrayList(node1A1, node1B1)); given(tree.getRoot()).willReturn(node1); // when resultMap = technologyTreeValidationService.checkConsumingManyProductsFromOneSubOp(tree); // then assertNotNull(resultMap); assertFalse(resultMap.isEmpty()); assertEquals(2, resultMap.size()); assertEquals(2, resultMap.get(node1.getStringField(NODE_NUMBER)).size()); hasNodeNumbersFor(node1, node1A1); hasNodeNumbersFor(node1, node1B1); hasNodeNumbersFor(node1A1, node1A2); } @Test public final void shouldReturnEmptyMapIfParentOpNotConsumeManyOutputsFromOneSubOp() { // given Entity product1 = mockProductComponent(1L); Entity product2 = mockProductComponent(2L); Entity product3 = mockProductComponent(3L); Entity product4 = mockProductComponent(4L); Entity product5 = mockProductComponent(5L); Entity product6 = mockProductComponent(6L); EntityTreeNode node2B = mockOperationComponent("2.B.", newArrayList(product6), newArrayList(product4)); EntityTreeNode node2A = mockOperationComponent("2.A.", newArrayList(product5), newArrayList(product3)); EntityTreeNode node2 = mockOperationComponent("2.", newArrayList(product3, product4), newArrayList(product2), newArrayList(node2A, node2B)); EntityTreeNode node1 = mockOperationComponent("1.", newArrayList(product2), newArrayList(product1), newArrayList(node2)); given(tree.getRoot()).willReturn(node1); // when resultMap = technologyTreeValidationService.checkConsumingManyProductsFromOneSubOp(tree); // then assertNotNull(resultMap); assertTrue(resultMap.isEmpty()); } /* MAP ASSERTION HELPERS */ private void hasNodeNumbersFor(final Entity parentOperation, final Entity subOperation) { String parentOpNodeNumber = parentOperation.getStringField(NODE_NUMBER); String subOpNodeNumber = subOperation.getStringField(NODE_NUMBER); assertFalse(resultMap.get(parentOpNodeNumber).isEmpty()); assertTrue(resultMap.get(parentOpNodeNumber).contains(subOpNodeNumber)); } /* TREE MOCKING & STUBBING HELPERS */ private EntityTreeNode mockOperationComponent(final String nodeNumber, final Collection<Entity> inputProducts, final Collection<Entity> outputProducts) { return mockOperationComponent(nodeNumber, inputProducts, outputProducts, EMPTY_TREE_NODES_LIST); } private EntityTreeNode mockOperationComponent(final Long id, final String nodeNumber, final Collection<Entity> inputProducts, final Collection<Entity> outputProducts) { return mockOperationComponent(id, nodeNumber, inputProducts, outputProducts, EMPTY_TREE_NODES_LIST); } private EntityTreeNode mockOperationComponent(final Long id, final String nodeNumber, final Collection<Entity> inputProducts, final Collection<Entity> outputProducts, final List<EntityTreeNode> subOperations) { EntityTreeNode operationComponent = mock(EntityTreeNode.class); given(operationComponent.getId()).willReturn(id); EntityList inputProductsList = mockProductComponentsList(inputProducts); given(operationComponent.getHasManyField(OPERATION_PRODUCT_IN_COMPONENTS)).willReturn(inputProductsList); given(operationComponent.getField(OPERATION_PRODUCT_IN_COMPONENTS)).willReturn(inputProductsList); EntityList outputProductsList = mockProductComponentsList(outputProducts); given(operationComponent.getHasManyField(OPERATION_PRODUCT_OUT_COMPONENTS)).willReturn(outputProductsList); given(operationComponent.getField(OPERATION_PRODUCT_OUT_COMPONENTS)).willReturn(outputProductsList); given(operationComponent.getField(NODE_NUMBER)).willReturn(nodeNumber); given(operationComponent.getStringField(NODE_NUMBER)).willReturn(nodeNumber); given(operationComponent.getChildren()).willReturn(subOperations); return operationComponent; } private EntityTreeNode mockOperationComponent(final String nodeNumber, final Collection<Entity> inputProducts, final Collection<Entity> outputProducts, final List<EntityTreeNode> subOperations) { return mockOperationComponent(null, nodeNumber, inputProducts, outputProducts, subOperations); } private EntityList mockProductComponentsList(final Collection<Entity> productComponents) { EntityList productComponentsList = mock(EntityList.class); given(productComponentsList.iterator()).willReturn(productComponents.iterator()); given(productComponentsList.isEmpty()).willReturn(productComponents.isEmpty()); return productComponentsList; } private Entity mockProductComponent(final Long productId) { Entity productComponent = mock(Entity.class); Entity product = mock(Entity.class); given(product.getField("id")).willReturn(productId); given(product.getId()).willReturn(productId); given(productComponent.getField("product")).willReturn(product); given(productComponent.getBelongsToField("product")).willReturn(product); given(dataDefinition.get(productId)).willReturn(productComponent); return productComponent; } }