1. nx
  2. squashtest-tm

Commits

mpagnon  committed 58b1399

sprint 30: 456-03: copie des test suites avec les campagnes et les iterations

  • Participants
  • Parent commits f172197
  • Branches default

Comments (0)

Files changed (19)

File integration-tests/src/it/groovy/org/squashtest/csp/tm/internal/service/CampaignLibraryNavigationServiceIT.groovy

View file
 import javax.inject.Inject;
 
 import org.apache.tools.ant.taskdefs.Copy;
+import org.hibernate.Query
+import org.hibernate.Session
 import org.junit.runner.RunWith;
 import org.spockframework.runtime.Sputnik;
 import org.spockframework.util.NotThreadSafe;
 import org.squashtest.csp.tm.domain.campaign.CampaignFolder;
 import org.squashtest.csp.tm.domain.campaign.CampaignLibraryNode;
 import org.squashtest.csp.tm.domain.campaign.Iteration;
+import org.squashtest.csp.tm.domain.campaign.TestSuite
 import org.squashtest.csp.tm.service.CampaignLibrariesCrudService;
 import org.squashtest.csp.tm.service.CampaignLibraryNavigationService;
 import org.unitils.dbunit.annotation.DataSet;
 		obj.name=="campaign 1"
 		obj.description=="the first campaign"
 	}
-
-	def "should get a clone of the campaign" (){
-		given:
-		def campa = new Campaign(name: "campaign 2", description: "the first campaign")
-		navService.addCampaignToCampaignLibrary(libId, campa)
-
-		def iteration = new Iteration(name:"iteration 2", description: "the first iteration")
-
-		navService.addIterationToCampaign(iteration, campa.id)
-
-		when :
-		def res = navService.createCopyCampaign(campa.id)
-
-		then:
-		res.testPlan.collect { it.referencedTestCase } == campa.testPlan.collect { it.referencedTestCase }
-		res.iterations == []
-	}
 	
 	@DataSet("CampaignLibraryNavigationServiceIT.should copy paste iterations to campaign.xml")
 	def "should copy paste iterations to campaign"(){
 		iterations.size() == 2
 		iterations.get(0).name == "iter - tc1"
 		
+	}
+	
+	@DataSet("CampaignLibraryNavigationServiceIT.should copy paste iterations with testSuites.xml")
+	def "should copy paste iterations with testSuites"(){
+		given:
+		Long[] iterationList = [10012L,2L]
+		Long targetCampaignId = 11L
 		
+		when:
+		List<Iteration> iterations = navService.copyIterationsToCampaign(targetCampaignId , iterationList )
+		
+		then:
+		iterations.size() == 2
+		iterations.find {it.getName()== "iter - tc1" } != null
+		Iteration iteration1 = iterations.find {it.getName() == "iter - tc1" }
+		iteration1.getTestSuites().size() == 2
+		iteration1.getTestSuites().find {it.getName() == "testSuite1"} != null
+		TestSuite testsSuite1 = iteration1.getTestSuites().find {it.getName() == "testSuite1"}
+		testsSuite1.getTestPlan().size() == 1
+		iteration1.getTestPlans().size() == 1
+		iteration1.getTestSuites().find {it.getName() == "testSuite2"} != null
+		TestSuite testsSuite2 = iteration1.getTestSuites().find {it.getName() == "testSuite2"}
+		testsSuite2.getTestPlan().size() == 0
 	}
+	
+	@DataSet("CampaignLibraryNavigationServiceIT.should copy paste campaigns with iterations.xml")
+	def "should copy paste campaigns with iterations"(){
+		given:
+		Long[] targetIds = [10L]
+		Long destinationId = 1L
+		
+		when:
+		List<Campaign> campaigns = navService.copyNodesToFolder(destinationId, targetIds)
+		
+		then:
+		campaigns.get(0).getIterations().size() == 2
+		def iterations = campaigns.get(0).getIterations()
+		iterations.find {it.getName() == "iter - tc1" } != null
+		iterations.find {it.getName() == "iter - tc1 -2" } != null
+	}
+	
+	@DataSet("CampaignLibraryNavigationServiceIT.should copy paste campaigns with testSuites.xml")
+	def "should copy paste campaigns with testSuites"(){
+		given:
+			Long[] targetIds = [10L]
+		Long destinationId = 1L
+		
+		when:
+		List<Campaign> campaigns = navService.copyNodesToFolder(destinationId, targetIds)
+		
+		then:
+		campaigns.get(0).getIterations().size() == 2
+		def iterations = campaigns.get(0).getIterations()
+		Iteration iteration1 = iterations.find {it.getName() == "iter - tc1" }
+		iteration1.getTestSuites().size() == 2
+		iteration1.getTestSuites().find {it.getName() == "testSuite1"} != null
+		TestSuite testsSuite1 = iteration1.getTestSuites().find {it.getName() == "testSuite1"}
+		testsSuite1.getTestPlan().size() == 1
+		iteration1.getTestSuites().find {it.getName() == "testSuite2"} != null
+		TestSuite testsSuite2 = iteration1.getTestSuites().find {it.getName() == "testSuite2"}
+		testsSuite2.getTestPlan().size() == 0
+		Iteration iteration2 = iterations.find {it.getName() == "iter - tc1 -2" }
+		iteration2.getTestSuites().isEmpty()
+	}
+	
 }

File integration-tests/src/it/resources/org/squashtest/csp/tm/internal/service/CampaignLibraryNavigationServiceIT.should copy paste campaigns with iterations.xml

View file
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+
+        This file is part of the Squashtest platform.
+        Copyright (C) 2010 - 2011 Squashtest TM, Squashtest.org
+
+        See the NOTICE file distributed with this work for additional
+        information regarding copyright ownership.
+
+        This is free software: you can redistribute it and/or modify
+        it under the terms of the GNU Lesser General Public License as published by
+        the Free Software Foundation, either version 3 of the License, or
+        (at your option) any later version.
+
+        this software 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 Lesser General Public License for more details.
+
+        You should have received a copy of the GNU Lesser General Public License
+        along with this software.  If not, see <http://www.gnu.org/licenses/>.
+
+-->
+<dataset>
+
+
+	<!-- parent folder -->
+	<campaign_library_node cln_id="1" name="a folder"
+		created_on="2010-02-01" created_by="dbu" />
+	<campaign_folder cln_id="1" />
+
+	<!-- folder content -->
+	<!-- source -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="10" />
+	<campaign_library_node cln_id="10" name="foo"
+		created_on="2010-02-01" created_by="dbu" />
+	<campaign cln_id="10" actual_start_auto="true"
+		actual_end_auto="true" ATTACHMENT_LIST_ID="10" />
+	<cln_relationship ancestor_id="1" descendant_id="10" />
+	<!-- target -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="11" />
+	<campaign_library_node cln_id="11" name="bar"
+		created_on="2010-02-02" created_by="gte" />
+	<campaign cln_id="11" actual_start_auto="false"
+		actual_end_auto="true" ATTACHMENT_LIST_ID="11" />
+	<cln_relationship ancestor_id="1" descendant_id="11" />
+
+	<!-- campaign library -->
+	<campaign_library cl_id="1" />
+	<campaign_library_content library_id="1"
+		content_id="1" />
+
+	<!-- Testcase -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="1" />
+	<test_case_library_node tcln_id="1" name="test case 1"
+		created_by="dbu" created_on="2010-02-01" />
+	<test_case tcln_id="1" version="1" attachment_list_id="1" />
+
+	<!-- iteration 1 -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="12" />
+	<iteration name="iter - tc1" iteration_id="10012"
+		actual_end_auto="false" actual_start_auto="false" actual_start_date="2011-01-01"
+		actual_end_date="2011-01-02" scheduled_start_date="2011-01-01"
+		scheduled_end_date="2011-01-02" created_by="dbu" created_on="2010-02-01"
+		attachment_list_id="12" />
+	<campaign_iteration campaign_id="10" iteration_id="10012"
+		iteration_order="0" />
+	
+	<!-- test plan of iteration 1 -->
+	<iteration_test_plan_item item_test_plan_id="1"
+		execution_status="READY" tcln_id="1" created_by="dbu" created_on="2011-01-01" />
+	<item_test_plan_list iteration_id="10012"
+		item_test_plan_id="1" item_test_plan_order="0" />
+
+	<!-- iteration 2 -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="13" />
+	<iteration name="iter - tc1 -2" iteration_id="2"
+		actual_end_auto="true" actual_start_auto="true" actual_start_date="2011-01-01"
+		actual_end_date="2011-01-02" scheduled_start_date="2011-01-02"
+		scheduled_end_date="2012-01-02" created_by="dbu" created_on="2010-02-08"
+		attachment_list_id="13" />
+
+	<!-- test plan of iteration 2 -->
+	<iteration_test_plan_item item_test_plan_id="2"
+		execution_status="SUCCESS" tcln_id="1" created_by="dbu" created_on="2011-01-01" />
+	<item_test_plan_list iteration_id="2"
+		item_test_plan_id="2" item_test_plan_order="0" />
+	<campaign_iteration campaign_id="10" iteration_id="2"
+		iteration_order="1" />
+	
+</dataset>

File integration-tests/src/it/resources/org/squashtest/csp/tm/internal/service/CampaignLibraryNavigationServiceIT.should copy paste campaigns with testSuites.xml

View file
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+
+        This file is part of the Squashtest platform.
+        Copyright (C) 2010 - 2011 Squashtest TM, Squashtest.org
+
+        See the NOTICE file distributed with this work for additional
+        information regarding copyright ownership.
+
+        This is free software: you can redistribute it and/or modify
+        it under the terms of the GNU Lesser General Public License as published by
+        the Free Software Foundation, either version 3 of the License, or
+        (at your option) any later version.
+
+        this software 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 Lesser General Public License for more details.
+
+        You should have received a copy of the GNU Lesser General Public License
+        along with this software.  If not, see <http://www.gnu.org/licenses/>.
+
+-->
+<dataset>
+
+
+	<!-- parent folder -->
+	<campaign_library_node cln_id="1" name="a folder"
+		created_on="2010-02-01" created_by="dbu" />
+	<campaign_folder cln_id="1" />
+
+	<!-- folder content -->
+	<!-- source -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="10" />
+	<campaign_library_node cln_id="10" name="foo"
+		created_on="2010-02-01" created_by="dbu" />
+	<campaign cln_id="10" actual_start_auto="true"
+		actual_end_auto="true" ATTACHMENT_LIST_ID="10" />
+	<cln_relationship ancestor_id="1" descendant_id="10" />
+	<!-- target -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="11" />
+	<campaign_library_node cln_id="11" name="bar"
+		created_on="2010-02-02" created_by="gte" />
+	<campaign cln_id="11" actual_start_auto="false"
+		actual_end_auto="true" ATTACHMENT_LIST_ID="11" />
+	<cln_relationship ancestor_id="1" descendant_id="11" />
+
+	<!-- campaign library -->
+	<campaign_library cl_id="1" />
+	<campaign_library_content library_id="1"
+		content_id="1" />
+
+	<!-- Testcase -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="1" />
+	<test_case_library_node tcln_id="1" name="test case 1"
+		created_by="dbu" created_on="2010-02-01" />
+	<test_case tcln_id="1" version="1" attachment_list_id="1" />
+
+	<!-- iteration 1 -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="12" />
+	<iteration name="iter - tc1" iteration_id="10012"
+		actual_end_auto="false" actual_start_auto="false" actual_start_date="2011-01-01"
+		actual_end_date="2011-01-02" scheduled_start_date="2011-01-01"
+		scheduled_end_date="2011-01-02" created_by="dbu" created_on="2010-02-01"
+		attachment_list_id="12" />
+	<campaign_iteration campaign_id="10" iteration_id="10012"
+		iteration_order="0" />
+	<!-- test suite of iteration 1 -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="75454" />
+	<test_suite id="1" name="testSuite1" description=""
+		attachment_list_id="75454" created_on="2010-02-01" created_by="" />
+	<iteration_test_suite iteration_id="10012"
+		test_suite_id="1" />
+		<ATTACHMENT_LIST ATTACHMENT_LIST_id="75455" />
+	<test_suite id="2" name="testSuite2" description=""
+		attachment_list_id="75455" created_on="2010-02-01" created_by="" />
+	<iteration_test_suite iteration_id="10012"
+		test_suite_id="2" />
+		
+	<!-- test plan of iteration 1 -->
+	<iteration_test_plan_item item_test_plan_id="1"
+		execution_status="READY" tcln_id="1" created_by="dbu" created_on="2011-01-01"
+		test_suite="1" />
+	<item_test_plan_list iteration_id="10012"
+		item_test_plan_id="1" item_test_plan_order="0" />
+
+	<!-- iteration 2 -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="13" />
+	<iteration name="iter - tc1 -2" iteration_id="2"
+		actual_end_auto="true" actual_start_auto="true" actual_start_date="2011-01-01"
+		actual_end_date="2011-01-02" scheduled_start_date="2011-01-02"
+		scheduled_end_date="2012-01-02" created_by="dbu" created_on="2010-02-08"
+		attachment_list_id="13" />
+
+	<!-- test plan of iteration 2 -->
+	<iteration_test_plan_item item_test_plan_id="2"
+		execution_status="SUCCESS" tcln_id="1" created_by="dbu" created_on="2011-01-01" />
+	<item_test_plan_list iteration_id="2"
+		item_test_plan_id="2" item_test_plan_order="0" />
+	<campaign_iteration campaign_id="10" iteration_id="2"
+		iteration_order="1" />
+	
+</dataset>

File integration-tests/src/it/resources/org/squashtest/csp/tm/internal/service/CampaignLibraryNavigationServiceIT.should copy paste iterations with testSuites.xml

View file
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+
+        This file is part of the Squashtest platform.
+        Copyright (C) 2010 - 2011 Squashtest TM, Squashtest.org
+
+        See the NOTICE file distributed with this work for additional
+        information regarding copyright ownership.
+
+        This is free software: you can redistribute it and/or modify
+        it under the terms of the GNU Lesser General Public License as published by
+        the Free Software Foundation, either version 3 of the License, or
+        (at your option) any later version.
+
+        this software 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 Lesser General Public License for more details.
+
+        You should have received a copy of the GNU Lesser General Public License
+        along with this software.  If not, see <http://www.gnu.org/licenses/>.
+
+-->
+<dataset>
+
+
+	<!-- parent folder -->
+	<campaign_library_node cln_id="1" name="a folder"
+		created_on="2010-02-01" created_by="dbu" />
+	<campaign_folder cln_id="1" />
+
+	<!-- folder content -->
+	<!-- source -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="10" />
+	<campaign_library_node cln_id="10" name="foo"
+		created_on="2010-02-01" created_by="dbu" />
+	<campaign cln_id="10" actual_start_auto="true"
+		actual_end_auto="true" ATTACHMENT_LIST_ID="10" />
+	<cln_relationship ancestor_id="1" descendant_id="10" />
+	<!-- target -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="11" />
+	<campaign_library_node cln_id="11" name="bar"
+		created_on="2010-02-02" created_by="gte" />
+	<campaign cln_id="11" actual_start_auto="false"
+		actual_end_auto="true" ATTACHMENT_LIST_ID="11" />
+	<cln_relationship ancestor_id="1" descendant_id="11" />
+
+	<!-- campaign library -->
+	<campaign_library cl_id="1" />
+	<campaign_library_content library_id="1"
+		content_id="10" />
+
+	<!-- Testcase -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="1" />
+	<test_case_library_node tcln_id="1" name="test case 1"
+		created_by="dbu" created_on="2010-02-01" />
+	<test_case tcln_id="1" version="1" attachment_list_id="1" />
+
+	<!-- iteration 1 -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="12" />
+	<iteration name="iter - tc1" iteration_id="10012"
+		actual_end_auto="false" actual_start_auto="false" actual_start_date="2011-01-01"
+		actual_end_date="2011-01-02" scheduled_start_date="2011-01-01"
+		scheduled_end_date="2011-01-02" created_by="dbu" created_on="2010-02-01"
+		attachment_list_id="12" />
+	<campaign_iteration campaign_id="10" iteration_id="10012"
+		iteration_order="0" />
+	<!-- test suite of iteration 1 -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="75454" />
+	<test_suite id="1" name="testSuite1" description=""
+		attachment_list_id="75454" created_on="2010-02-01" created_by="" />
+	<iteration_test_suite iteration_id="10012"
+		test_suite_id="1" />
+		<ATTACHMENT_LIST ATTACHMENT_LIST_id="75455" />
+	<test_suite id="2" name="testSuite2" description=""
+		attachment_list_id="75455" created_on="2010-02-01" created_by="" />
+	<iteration_test_suite iteration_id="10012"
+		test_suite_id="2" />
+		
+	<!-- test plan of iteration 1 -->
+	<iteration_test_plan_item item_test_plan_id="1"
+		execution_status="READY" tcln_id="1" created_by="dbu" created_on="2011-01-01"
+		test_suite="1" />
+	<item_test_plan_list iteration_id="10012"
+		item_test_plan_id="1" item_test_plan_order="0" />
+
+	<!-- iteration 2 -->
+	<ATTACHMENT_LIST ATTACHMENT_LIST_id="13" />
+	<iteration name="iter - tc1 -2" iteration_id="2"
+		actual_end_auto="true" actual_start_auto="true" actual_start_date="2011-01-01"
+		actual_end_date="2011-01-02" scheduled_start_date="2011-01-02"
+		scheduled_end_date="2012-01-02" created_by="dbu" created_on="2010-02-08"
+		attachment_list_id="13" />
+
+	<!-- test plan of iteration 2 -->
+	<iteration_test_plan_item item_test_plan_id="2"
+		execution_status="SUCCESS" tcln_id="1" created_by="dbu" created_on="2011-01-01" />
+	<item_test_plan_list iteration_id="2"
+		item_test_plan_id="2" item_test_plan_order="0" />
+	<campaign_iteration campaign_id="10" iteration_id="2"
+		iteration_order="1" />
+	
+</dataset>

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/domain/campaign/Iteration.java

View file
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Map;
 import java.util.Set;
 
 import javax.persistence.Basic;
 import javax.persistence.OrderColumn;
 import javax.validation.constraints.NotNull;
 
+import org.hibernate.mapping.Array;
 import org.hibernate.validator.constraints.NotBlank;
 import org.squashtest.csp.core.security.annotation.AclConstrainedObject;
 import org.squashtest.csp.tm.domain.DuplicateNameException;
 		throw new UnknownEntityException(testPlanId, IterationTestPlanItem.class);
 	}
 
+	/**
+	 * <p>
+	 * copy of iteration <u>doesn't contain test-suites</u> !!<br>
+	 * </p>
+	 * 
+	 * @return
+	 */
 	public Iteration createCopy() {
 		Iteration clone = new Iteration();
 		clone.setName(this.getName());
 		clone.setDescription(this.getDescription());
 		copyPlanning(clone);
-
 		for (IterationTestPlanItem itemTestPlan : testPlans) {
 			clone.addTestPlan(itemTestPlan.createCopy());
+
 		}
 		for (Attachment attach : this.getAttachmentList().getAllAttachments()) {
 			Attachment copyAttach = attach.hardCopy();
 		}
 	}
 
+	/**
+	 * this method is used in case of copy paste of an iteration with test suites.<br>
+	 * 
+	 * @return A map of test suite and indexes<br>
+	 *         One entry-set contains
+	 *         <ul>
+	 *         <li>a copied test suite (without it's test plan)</li>
+	 *         <li>and the indexes of the copied test plan that are to be linked with it
+	 *         <em>(taking into account test_plan_items that are test_case deleted)</em></li>
+	 */
+	public Map<TestSuite, List<Integer>> createTestSuitesPastableCopy() {
+		Map<TestSuite, List<Integer>> resultMap = new HashMap<TestSuite, List<Integer>>();
+		List<IterationTestPlanItem> testPlanWithoutDeletedTestCases = getTestPlanWithoutDeletedTestCases();
+		for (TestSuite testSuite : getTestSuites()) {
+			List<IterationTestPlanItem> testSuiteTestPlan = testSuite.getTestPlan();
+			TestSuite testSuiteCopy = testSuite.createPastableCopy();
+			List<Integer> testPlanIndex = new ArrayList<Integer>();
+			for (IterationTestPlanItem iterationTestPlanItem : testSuiteTestPlan) {
+				int testPlanItemIndex = testPlanWithoutDeletedTestCases.indexOf(iterationTestPlanItem);
+				testPlanIndex.add(testPlanItemIndex);
+			}
+			resultMap.put(testSuiteCopy, testPlanIndex);
+		}
+		return resultMap;
+	}
+
+	private List<IterationTestPlanItem> getTestPlanWithoutDeletedTestCases() {
+		List<IterationTestPlanItem> testPlanResult = getTestPlans();
+		Iterator<IterationTestPlanItem> iterator = testPlanResult.iterator();
+		while (iterator.hasNext()) {
+			IterationTestPlanItem itpi = iterator.next();
+			if (itpi.isTestCaseDeleted()) {
+				testPlanResult.remove(itpi);
+			}
+		}
+		return testPlanResult;
+	}
+
 }

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/internal/service/AbstractLibraryNavigationService.java

View file
 			// identity holder
 			for (Long id : sourceNodesIds) {
 				NODE node = getLibraryNodeDao().findById(id);
-				checkPermission(new SecurityCheckableObject(container, "WRITE"), new SecurityCheckableObject(
-						node, "READ"));
+				checkPermission(new SecurityCheckableObject(container, "WRITE"), new SecurityCheckableObject(node,
+						"READ"));
 			}
 
 			// proceed
 
 			for (Long id : sourceNodesIds) {
 				NODE node = getLibraryNodeDao().findById(id);
-				
+
 				String tempName = node.getName();
 				String newName = tempName;
 
 				if (!container.isContentNameAvailable(tempName)) {
 					List<String> copiesNames = findNamesInContainerStartingWith(containerId, tempName);
 					int newCopy = generateUniqueCopyNumber(copiesNames);
-					newName = tempName + "-Copie" + newCopy;
+					newName = tempName + COPY_TOKEN + newCopy;
 				}
 
 				NODE copy = createPastableCopy(node);
 
 			return nodeList;
 		}
-		
+
 		protected abstract CONTAINER findContainerById(long id);
+
 		protected abstract List<String> findNamesInContainerStartingWith(long containerId, String tempName);
 
 	}
 
+	/**
+	 * token appended to the name of a copy
+	 */
+	protected static final String COPY_TOKEN = "-Copie";
+
 	private PermissionEvaluationService permissionService;
 
 	private final PasteStrategy<FOLDER> pasteToFolderStrategy = new PasteStrategy<FOLDER>() {
 	/* ********************************* copy operations ****************************** */
 
 	@Override
-	public List<NODE> copyNodesToFolder(long destinationId, Long[] targetId) {
-		return pasteToFolderStrategy.pasteNodes(destinationId, targetId);
+	public List<NODE> copyNodesToFolder(long destinationId, Long[] sourceNodesIds) {
+		return pasteToFolderStrategy.pasteNodes(destinationId, sourceNodesIds);
 	}
 
 	@Override
 
 		int lastCopy = 0;
 		// we want to match one or more digits following the first instance of substring -Copie
-		Pattern pattern = Pattern.compile("-Copie(\\d+)");
+		Pattern pattern = Pattern.compile(COPY_TOKEN + "(\\d+)");
 
 		for (String copyName : copiesNames) {
 

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/internal/service/CampaignLibraryNavigationServiceImpl.java

View file
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.inject.Inject;
 
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.squashtest.csp.core.infrastructure.dynamicmanager.FindByIdHandler;
 import org.squashtest.csp.tm.domain.DuplicateNameException;
 import org.squashtest.csp.tm.domain.campaign.Campaign;
 import org.squashtest.csp.tm.domain.campaign.CampaignFolder;
 import org.squashtest.csp.tm.domain.campaign.CampaignLibrary;
 import org.squashtest.csp.tm.domain.campaign.CampaignLibraryNode;
 import org.squashtest.csp.tm.domain.campaign.Iteration;
+import org.squashtest.csp.tm.domain.campaign.IterationTestPlanItem;
 import org.squashtest.csp.tm.domain.campaign.TestSuite;
 import org.squashtest.csp.tm.domain.projectfilter.ProjectFilter;
 import org.squashtest.csp.tm.internal.infrastructure.strategy.LibrarySelectionStrategy;
 import org.squashtest.csp.tm.internal.repository.IterationDao;
 import org.squashtest.csp.tm.internal.repository.LibraryNodeDao;
 import org.squashtest.csp.tm.internal.repository.TestSuiteDao;
+import org.squashtest.csp.tm.internal.service.campaign.IterationTestPlanManager;
 import org.squashtest.csp.tm.service.CampaignLibraryNavigationService;
 import org.squashtest.csp.tm.service.IterationModificationService;
 import org.squashtest.csp.tm.service.ProjectFilterModificationService;
 		AbstractLibraryNavigationService<CampaignLibrary, CampaignFolder, CampaignLibraryNode> implements
 		CampaignLibraryNavigationService {
 
-	/**
-	 * token appended to the name of a copy
-	 */
-	private static final String COPY_TOKEN = "-Copie";
 	@Inject
 	private CampaignLibraryDao campaignLibraryDao;
 
 	@Inject
+	private IterationTestPlanManager iterationTestPlanManager;
+
+	@Inject
 	private CampaignFolderDao campaignFolderDao;
 
 	@Inject
 			+ "and hasPermission(#iterationId, 'org.squashtest.csp.tm.domain.campaign.Iteration', 'READ'))"
 			+ "or hasRole('ROLE_ADMIN')")
 	public int copyIterationToCampaign(long campaignId, long iterationId) {
+		Iteration originalIteration = iterationDao.findById(iterationId);
+		Campaign campaign = campaignDao.findById(campaignId);
+		copyIterationToCampaign(campaign, originalIteration);
+		return 0;
+	}
 
-		Iteration newIteration = createCopyIteration(iterationId);
-		Campaign campaign = campaignDao.findById(campaignId);
-		if (!campaign.isContentNameAvailable(newIteration.getName())) {
-			renameIterationCopy(newIteration, campaign);
+	private void copyIterationToCampaign(Campaign campaign, Iteration iterationSource) {
+		Iteration iterationCopy = createCopyIteration(iterationSource);
+		if (!campaign.isContentNameAvailable(iterationCopy.getName())) {
+			renameIterationCopy(iterationCopy, campaign);
 		}
-
-		// persist
-		iterationDao.persistIterationAndTestPlan(newIteration);
-
-		// link to campaign
-		campaign.addIteration(newIteration);
-		return 0;
+		campaign.addIteration(iterationCopy);
 	}
 
 	private void renameIterationCopy(Iteration newIteration, Campaign campaign) {
 		return iterationModificationService.findIterationsByCampaignId(campaignId);
 	}
 
-	/*
-	 * //TODO : investigate why that method is public and exposed in the interface.
-	 * 
-	 * (non-Javadoc)
-	 * 
-	 * @see org.squashtest.csp.tm.service.CampaignLibraryNavigationService#createCopyCampaign(long)
-	 */
 	@Override
-	@PreAuthorize("hasPermission(#campaignId,'org.squashtest.csp.tm.domain.campaign.Campaign','READ') or hasRole('ROLE_ADMIN')")
-	public Campaign createCopyCampaign(long campaignId) {
-		Campaign original = campaignDao.findByIdWithInitializedIterations(campaignId);
-		Campaign clone = original.createPastableCopy();
-
-		/*
-		 * The mapping imposes us to persist the iterations first, since persisting the campaign only won't cascade
-		 * properly and generate an exception. See the comment in Iteration.campaign.
-		 * 
-		 * If you don't understand the comment above, just don't touch this.
-		 */
-		for (Iteration iteration : clone.getIterations()) {
-			iterationDao.persistIterationAndTestPlan(iteration);
+	protected CampaignLibraryNode createPastableCopy(CampaignLibraryNode original) {
+		if (original instanceof Campaign) {
+			Campaign clone = (Campaign) original.createPastableCopy();
+			campaignDao.persist(clone);
+			for (Iteration iterationSource : ((Campaign) original).getIterations()) {
+				copyIterationToCampaign(clone, iterationSource);
+			}
+			return clone;
+		} else {
+			return original.createPastableCopy();
 		}
 
-		campaignDao.persist(clone);
-		return clone;
 	}
 
 	/*
-	 * //TODO : if the TODO for createCopyCampaign just above concludes that it really has a purpose, then find why
-	 * createCopyIteration is not exposed in the interface too.
+	 * //TODO : investigate why is public and find why createCopyIteration is not exposed in the interface too.
+	 * 
+	 * mpagnon says : my guess is that the method is public so that we can check authorizations through @PreAuthorize
+	 * for each iteration id because this couldn't be done with a list of ids in copyIterationsToCampaign. I suppose we
+	 * need to remove the public attribute and add a check step to the method copyIterationToCampaign
 	 */
 	@PreAuthorize("hasPermission(#iterationId, 'org.squashtest.csp.tm.domain.campaign.Iteration', 'READ') or hasRole('ROLE_ADMIN')")
 	public Iteration createCopyIteration(long iterationId) {
-		Iteration original = iterationModificationService.findById(iterationId);
-		Iteration clone = original.createCopy();
-		iterationDao.persistIterationAndTestPlan(clone);
+		Iteration originalIteration = iterationModificationService.findById(iterationId);
+		return createCopyIteration(originalIteration);
+	}
 
-		return clone;
+	private Iteration createCopyIteration(Iteration originalIteration) {
+		Iteration iterationCopy = originalIteration.createCopy();
+		iterationDao.persistIterationAndTestPlan(iterationCopy);
+		copyIterationTestSuites(originalIteration, iterationCopy);
+		return iterationCopy;
+	}
+
+	private void copyIterationTestSuites(Iteration originalIteration, Iteration iterationCopy) {
+		Map<TestSuite, List<Integer>> testSuitesPastableCopiesMap = originalIteration.createTestSuitesPastableCopy();
+		for (Entry<TestSuite, List<Integer>> testSuitePastableCopyEntry : testSuitesPastableCopiesMap.entrySet()) {
+			TestSuite testSuiteCopy = testSuitePastableCopyEntry.getKey();
+			iterationTestPlanManager.addTestSuite(iterationCopy, testSuiteCopy);
+			bindTestPlanOfCopiedTestSuite(iterationCopy, testSuitePastableCopyEntry, testSuiteCopy);
+		}
+	}
+
+	private void bindTestPlanOfCopiedTestSuite(Iteration iterationCopy,
+			Entry<TestSuite, List<Integer>> testSuitePastableCopyEntry, TestSuite testSuiteCopy) {
+		List<Integer> testSuiteTpiIndexesInIterationList = testSuitePastableCopyEntry.getValue();
+		List<IterationTestPlanItem> testPlanItemsToBind = new ArrayList<IterationTestPlanItem>();
+		List<IterationTestPlanItem> iterationTestPlanCopy = iterationCopy.getTestPlans();
+		for (Integer testSuiteTpiIndexInIterationList : testSuiteTpiIndexesInIterationList) {
+			IterationTestPlanItem testPlanItemToBind = iterationTestPlanCopy.get(testSuiteTpiIndexInIterationList);
+			testPlanItemsToBind.add(testPlanItemToBind);
+		}
+		testSuiteCopy.bindTestPlanItems(testPlanItemsToBind);
 	}
 
 	@Override
 
 	@Override
 	@PostAuthorize("hasPermission(returnObject, 'READ') or hasRole('ROLE_ADMIN')")
-	public Iteration findIteration(long IterationId) {
-		return iterationDao.findById(IterationId);
+	public Iteration findIteration(long iterationId) {
+		return iterationDao.findById(iterationId);
 
 	}
 

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/internal/service/CustomIterationModificationServiceImpl.java

View file
 
 	/****
 	 * Method which change the index of test case in the selected iteration
-	 *
+	 * 
 	 * @param iterationId
 	 *            the iteration at which the test case is attached
 	 * @param testCaseId
 
 	/**
 	 * see doc in the interface
-	 *
+	 * 
 	 */
 	@Override
 	@PreAuthorize("hasPermission(#iterationId, 'org.squashtest.csp.tm.domain.campaign.Iteration', 'WRITE') "
 			+ "or hasRole('ROLE_ADMIN')")
 	public void addTestSuite(long iterationId, TestSuite suite) {
 		Iteration iteration = iterationDao.findById(iterationId);
+		addTestSuite(iteration, suite);
+	}
+
+	@Override
+	public void addTestSuite(Iteration iteration, TestSuite suite) {
 		suiteDao.persist(suite);
 		iteration.addTestSuite(suite);
+
 	}
 
 	@Override
 		int numberOfCopy = 0;
 		while (!iteration.checkSuiteNameAvailable(newName)) {
 			numberOfCopy++;
-			newName = originalSuiteName + "_Copie" + numberOfCopy;
+			newName = originalSuiteName + AbstractLibraryNavigationService.COPY_TOKEN + numberOfCopy;
 		}
 		copyOfTestSuite.setName(newName);
 	}

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/internal/service/CustomTestSuiteModificationServiceImpl.java

View file
 import org.squashtest.csp.tm.service.CustomTestSuiteModificationService;
 
 @Service("CustomTestSuiteModificationService")
-public class CustomTestSuiteModificationServiceImpl implements
-		CustomTestSuiteModificationService {
-	
+public class CustomTestSuiteModificationServiceImpl implements CustomTestSuiteModificationService {
+
 	@Inject
 	private TestSuiteDao testSuiteDao;
-	
-
 
 	@Override
-	@PreAuthorize("hasPermission(#suiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite', 'WRITE') or hasRole('ROLE_ADMIN')")		
-	public void rename(long suiteId, String newName)
-			throws DuplicateNameException {
+	@PreAuthorize("hasPermission(#suiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite', 'WRITE') or hasRole('ROLE_ADMIN')")
+	public void rename(long suiteId, String newName) throws DuplicateNameException {
 		TestSuite suite = testSuiteDao.findById(suiteId);
 		suite.rename(newName);
 	}
-	
+
 	@Override
-	@PreAuthorize("hasPermission(#suiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite', 'WRITE') or hasRole('ROLE_ADMIN')")		
+	@PreAuthorize("hasPermission(#suiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite', 'WRITE') or hasRole('ROLE_ADMIN')")
 	public void bindTestPlan(long suiteId, List<Long> itemTestPlanIds) {
-		//that implementation relies on how the TestSuite will do the job (regarding the checks on whether the itps belong to the 
-		//same iteration of not
+		// that implementation relies on how the TestSuite will do the job (regarding the checks on whether the itps
+		// belong to the
+		// same iteration of not
 		TestSuite suite = testSuiteDao.findById(suiteId);
 		suite.bindTestPlanItemsById(itemTestPlanIds);
 	}
-	
+
 	@Override
-	@PreAuthorize("hasPermission(#testSuite, 'WRITE') or hasRole('ROLE_ADMIN')")		
+	@PreAuthorize("hasPermission(#testSuite, 'WRITE') or hasRole('ROLE_ADMIN')")
 	public void bindTestPlanObj(TestSuite testSuite, List<IterationTestPlanItem> itemTestPlans) {
-		//the test plans have already been associated to the Iteration
+		// the test plans have already been associated to the Iteration
 		testSuite.bindTestPlanItems(itemTestPlans);
 	}
-	
-	
+
 	@Override
-	@PreAuthorize("hasPermission(#testSuite, 'WRITE') or hasRole('ROLE_ADMIN')")		
+	@PreAuthorize("hasPermission(#testSuite, 'WRITE') or hasRole('ROLE_ADMIN')")
 	public void unbindTestPlanObj(TestSuite testSuite, List<IterationTestPlanItem> itemTestPlans) {
-		//the test plans have already been associated to the Iteration
+		// the test plans have already been associated to the Iteration
 		testSuite.unBindTestPlan(itemTestPlans);
 	}
-	
+
 	@Override
-	@PreAuthorize("hasPermission(#suiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite','WRITE') or hasRole('ROLE_ADMIN')")		
+	@PreAuthorize("hasPermission(#suiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite','WRITE') or hasRole('ROLE_ADMIN')")
 	public TestSuite findById(long suiteId) {
 		TestSuite suite = testSuiteDao.findById(suiteId);
 		return suite;
 	}
-	
+
 	@Override
 	@PreAuthorize("hasPermission(#suiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite','READ') or hasRole('ROLE_ADMIN')")
 	public PagedCollectionHolder<List<IterationTestPlanItem>> findTestSuiteTestPlan(long suiteId, Paging paging) {
-		
+
 		List<IterationTestPlanItem> testPlan = testSuiteDao.findAllTestPlanItemsPaged(suiteId, paging);
-		
+
 		long count = testSuiteDao.countTestPlanItems(suiteId);
-		
-		return new PagingBackedPagedCollectionHolder<List<IterationTestPlanItem>> (paging, count, testPlan);
+
+		return new PagingBackedPagedCollectionHolder<List<IterationTestPlanItem>>(paging, count, testPlan);
 	}
 
 	@Override
-	@PreAuthorize("hasPermission(#suiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite','WRITE') or hasRole('ROLE_ADMIN')")		
-	public TestSuiteStatistics findTestSuiteStatistics(long suiteId){
+	@PreAuthorize("hasPermission(#suiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite','WRITE') or hasRole('ROLE_ADMIN')")
+	public TestSuiteStatistics findTestSuiteStatistics(long suiteId) {
 		TestSuiteStatistics stats = testSuiteDao.getTestSuiteStatistics(suiteId);
 		return stats;
 	}
-	
-	
-	
+
 	@Override
-	@PreAuthorize("hasPermission(#testSuiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite','WRITE') or hasRole('ROLE_ADMIN')")		
-	public void changeTestPlanPosition(Long testSuiteId, int newIndex, List<Long>itemIds){
-		
-		TestSuite suite = testSuiteDao.findById(testSuiteId);		
-		
+	@PreAuthorize("hasPermission(#testSuiteId, 'org.squashtest.csp.tm.domain.campaign.TestSuite','WRITE') or hasRole('ROLE_ADMIN')")
+	public void changeTestPlanPosition(Long testSuiteId, int newIndex, List<Long> itemIds) {
+
+		TestSuite suite = testSuiteDao.findById(testSuiteId);
+
 		List<IterationTestPlanItem> items = testSuiteDao.findTestPlanPartition(testSuiteId, itemIds);
-		
+
 		suite.reorderTestPlan(newIndex, items);
 	}
-	
-
-
-
 
 }

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/internal/service/campaign/IterationTestPlanManager.java

View file
 
 import org.springframework.stereotype.Service;
 import org.squashtest.csp.tm.domain.TestPlanItemNotExecutableException;
+import org.squashtest.csp.tm.domain.campaign.Iteration;
 import org.squashtest.csp.tm.domain.campaign.IterationTestPlanItem;
+import org.squashtest.csp.tm.domain.campaign.TestSuite;
 import org.squashtest.csp.tm.domain.execution.Execution;
 
 /**
  * @author Gregory Fouquet
- *
+ * 
  */
 @Service
 public interface IterationTestPlanManager {
+
 	Execution addExecution(IterationTestPlanItem item) throws TestPlanItemNotExecutableException;
+
+	void addTestSuite(Iteration iteration, TestSuite suite);
 }

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/service/CampaignLibraryNavigationService.java

View file
 import org.squashtest.csp.tm.domain.campaign.TestSuite;
 import org.squashtest.csp.tm.service.deletion.SuppressionPreviewReport;
 
-
 public interface CampaignLibraryNavigationService extends
-LibraryNavigationService<CampaignLibrary, CampaignFolder, CampaignLibraryNode> {
-
+		LibraryNavigationService<CampaignLibrary, CampaignFolder, CampaignLibraryNode> {
 
 	void addCampaignToCampaignLibrary(long libraryId, Campaign campaign);
 
-
 	void addCampaignToCampaignFolder(long folderId, Campaign campaign);
 
 	Campaign findCampaign(long campaignId);
 	List<Iteration> findIterationsByCampaignId(long campaignId);
 
 	int copyIterationToCampaign(long campaignId, long iterationId);
-	
 
-	List<Iteration> copyIterationsToCampaign(long campaignId,
-			Long[] iterationsIds);
+	List<Iteration> copyIterationsToCampaign(long campaignId, Long[] iterationsIds);
 
-	int moveIterationToNewCampaign(long newCampaignId, long oldCampaignId,
-			long iterationId);
+	int moveIterationToNewCampaign(long newCampaignId, long oldCampaignId, long iterationId);
 
 	Iteration findIteration(long iterationId);
-	
+
 	List<TestSuite> findIterationContent(long iterationId);
 
-	Campaign createCopyCampaign(long campaignId);
-	
 	List<CampaignLibrary> findLinkableCampaignLibraries();
-	
-	
+
 	/**
-	 * that method should investigate the consequences of the deletion request of iterations, and return a report
-	 * about what will happen.
+	 * that method should investigate the consequences of the deletion request of iterations, and return a report about
+	 * what will happen.
 	 * 
 	 * @param targetIds
 	 * @return
 	 */
 	List<SuppressionPreviewReport> simulateIterationDeletion(List<Long> targetIds);
-	
+
 	/**
-	 * that method should delete the iterations. It still takes care of non deletable iterations so
-	 * the implementation should filter out the ids who can't be deleted.
+	 * that method should delete the iterations. It still takes care of non deletable iterations so the implementation
+	 * should filter out the ids who can't be deleted.
 	 * 
 	 * 
 	 * @param targetIds
 	 * @return
 	 */
 	List<Long> deleteIterations(List<Long> targetIds);
-	
-	
+
 	List<SuppressionPreviewReport> simulateSuiteDeletion(List<Long> targetIds);
 
 	/**

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/service/CustomIterationModificationService.java

View file
 package org.squashtest.csp.tm.service;
 
 import java.util.List;
+import java.util.Set;
 
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.transaction.annotation.Transactional;
 import org.squashtest.csp.tm.domain.campaign.Iteration;
+import org.squashtest.csp.tm.domain.campaign.IterationTestPlanItem;
 import org.squashtest.csp.tm.domain.campaign.TestSuite;
 import org.squashtest.csp.tm.domain.execution.Execution;
 import org.squashtest.csp.tm.domain.testcase.TestCase;
+import org.squashtest.csp.tm.infrastructure.filter.CollectionSorting;
+import org.squashtest.csp.tm.infrastructure.filter.FilteredCollectionHolder;
 import org.squashtest.csp.tm.service.deletion.SuppressionPreviewReport;
 
 /**

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/service/IterationModificationService.java

View file
 
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.transaction.annotation.Transactional;
+import org.squashtest.csp.tm.domain.campaign.Iteration;
 import org.squashtest.csp.tm.domain.campaign.TestSuite;
 
 @Transactional
 			+ "or hasRole('ROLE_ADMIN')")
 	void changeActualEndAuto(long iterationId, boolean isAuto);
 
-	
 }

File tm/org.squashtest.csp.tm.service/src/main/java/org/squashtest/csp/tm/service/LibraryNavigationService.java

View file
 /**
  * Defines common methods for a library navigation service, mainly library access and folder manipulation.
  * 
- * TODO Move all methods which modify a folder's content to another service 
+ * TODO Move all methods which modify a folder's content to another service
  * 
  * @author Gregory Fouquet
  * 
  */
 public interface LibraryNavigationService<LIBRARY extends Library<? extends NODE>, FOLDER extends Folder<? extends NODE>, NODE extends LibraryNode> {
 
-
 	/**
-	 * will create a deep copy of the given LibraryNodes, paste them 
-	 * in the target folder, and return the copies.
+	 * will create a deep copy of the given LibraryNodes, paste them in the destination folder, and return the copies.
 	 * 
 	 * 
-	 * @param destinationId the id of the folder where you need to copy to.
-	 * @param targetId the list of the librarynodes we want copies of.
+	 * @param destinationId
+	 *            the id of the folder where you need to copy to.
+	 * @param sourceNodesIds
+	 *            the list of the librarynodes we want copies of.
 	 * @return the list of the copies themselves.
 	 */
-	List<NODE> copyNodesToFolder(long destinationId, Long[] targetId);
-	
+	List<NODE> copyNodesToFolder(long destinationId, Long[] sourceNodesIds);
+
 	/**
 	 * same, when the destination is a Library.
 	 * 
 	 * 
-	 * @param destinationId the id of the library where you need to copy to.
-	 * @param targetId the list of the librarynodes we want copies of.
+	 * @param destinationId
+	 *            the id of the library where you need to copy to.
+	 * @param targetId
+	 *            the list of the librarynodes we want copies of.
 	 * @return the list of the copies themselves.
 	 */
 	List<NODE> copyNodesToLibrary(long destinationId, Long[] targetId);
-	
-	
+
 	void modeNodesToFolder(long destinationId, Long[] targetId);
-	
+
 	void moveNodesToLibrary(long destinationId, Long[] targetId);
-	
-
 
 	void addFolderToLibrary(long destinationId, FOLDER newFolder);
 
 
 	FOLDER findFolder(long folderId);
 
-
 	List<NODE> findLibraryRootContent(long libraryId);
 
 	/**
 	 */
 	List<NODE> findFolderContent(long folderId);
 
-
 	@Deprecated
 	void renameFolder(long folderId, String newName);
 
+	LIBRARY findLibrary(long libraryId);
 
-	LIBRARY findLibrary(long libraryId);
-	
-	
 	/**
-	 * that method should investigate the consequences of the deletion request, and return a report
-	 * about what will happen.
+	 * that method should investigate the consequences of the deletion request, and return a report about what will
+	 * happen.
 	 * 
 	 * @param targetIds
 	 * @return
 	 */
 	List<SuppressionPreviewReport> simulateDeletion(List<Long> targetIds);
-	
+
 	/**
-	 * that method should delete the nodes. It still takes care of non deletable nodes so
-	 * the implementation should filter out the ids who can't be deleted.
+	 * that method should delete the nodes. It still takes care of non deletable nodes so the implementation should
+	 * filter out the ids who can't be deleted.
 	 * 
 	 * 
 	 * @param targetIds
 	 * @return
 	 */
 	List<Long> deleteNodes(List<Long> targetIds);
-	
-	
 
 }

File tm/org.squashtest.csp.tm.service/src/test/groovy/org/squashtest/csp/tm/domain/campaign/IterationTest.groovy

View file
  *     You should have received a copy of the GNU Lesser General Public License
  *     along with this software.  If not, see <http://www.gnu.org/licenses/>.
  */
+
 package org.squashtest.csp.tm.domain.campaign
 
 import org.h2.util.New
 		copy.getDescription() == copySource.getDescription()
 		copy.getName() == copySource.getName()
 	}
+
+
 	def "copy of an Iteration should copy it's planning infos"() {
 		given:
 		SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy")
 		list.size() == 1
 		list.asList() == [attachCopy]
 	}
+	def "copy of test suites should return the indexes of test-plan-items to bind in iteration-copied-test-plan"(){
+		TestCase tc1 = new TestCase()
+		IterationTestPlanItem testPlanItem1 = new IterationTestPlanItem()
+		testPlanItem1.setLabel("testPlanItem1")
+		testPlanItem1.setReferencedTestCase(tc1)
+		IterationTestPlanItem testPlanItemWithoutTestCase = new IterationTestPlanItem()
+		TestCase tc2 = new TestCase()
+		IterationTestPlanItem testPlanItem2 = new IterationTestPlanItem()
+		testPlanItem2.setReferencedTestCase(tc2)
+		testPlanItem2.setLabel("testPlanItem2")
+		copySource.addTestPlan(testPlanItem1)
+		copySource.addTestPlan(testPlanItemWithoutTestCase)
+		copySource.addTestPlan(testPlanItem2)
+		TestSuite testSuite = new TestSuite()
+		copySource.addTestSuite(testSuite)
+		testSuite.setName("testSuite")
+		testSuite.bindTestPlanItems([testPlanItem1, testPlanItem2])
 
+		when:
+		Map<TestSuite, List<Integer>> testSuitesPastableCopies = copySource.createTestSuitesPastableCopy()
+
+		then:
+		testSuitesPastableCopies.size() == 1
+		testSuitesPastableCopies.entrySet().find {it.getKey().getName() == "testSuite"} != null
+		def entry = testSuitesPastableCopies.entrySet().find {it.getKey().getName() == "testSuite"}
+		entry.getValue().size() == 2
+		entry.getValue().find {it == 0} != null
+		entry.getValue().find {it == 1} != null
+	}
 	def "should add a test plan"(){
 
 		given :
 		Iteration iteration = new Iteration()
 		iteration.testSuites = [
 			new TestSuite(name:"suite1"),
-			new TestSuite(name:"suite2")] as Set
+			new TestSuite(name:"suite2")
+		]as Set
 
 		when :
 		def res =iteration.checkSuiteNameAvailable("suite3")
 		Iteration iteration = new Iteration()
 		iteration.testSuites = [
 			new TestSuite(name:"suite1"),
-			new TestSuite(name:"suite2")] as Set
+			new TestSuite(name:"suite2")
+		]as Set
 
 		when :
 		def res =iteration.checkSuiteNameAvailable("suite2")
 		Iteration iteration = new Iteration()
 		iteration.testSuites = [
 			new TestSuite(name:"suite1"),
-			new TestSuite(name:"suite2")] as Set
+			new TestSuite(name:"suite2")
+		]as Set
 
 		when :
 		def suite = new TestSuite(name:"suite3")
 		Iteration iteration = new Iteration()
 		iteration.testSuites = [
 			new TestSuite(name:"suite1"),
-			new TestSuite(name:"suite2")] as Set
+			new TestSuite(name:"suite2")
+		]as Set
 
 		when :
 		def suite = new TestSuite(name:"suite2")

File tm/org.squashtest.csp.tm.service/src/test/groovy/org/squashtest/csp/tm/internal/service/CampaignLibraryNavigationServiceImplTest.groovy

View file
  */
 package org.squashtest.csp.tm.internal.service
 
-import org.squashtest.csp.core.service.security.PermissionEvaluationService;
-import org.squashtest.csp.tm.domain.DuplicateNameException;
-import org.squashtest.csp.tm.domain.campaign.Campaign;
-import org.squashtest.csp.tm.domain.campaign.CampaignFolder;
-import org.squashtest.csp.tm.domain.campaign.CampaignLibrary;
-import org.squashtest.csp.tm.internal.repository.CampaignDao;
-import org.squashtest.csp.tm.internal.repository.CampaignFolderDao;
-import org.squashtest.csp.tm.internal.repository.CampaignLibraryDao;
-import org.squashtest.csp.tm.internal.service.CampaignLibraryNavigationServiceImpl;
+import org.squashtest.csp.core.service.security.PermissionEvaluationService
+import org.squashtest.csp.tm.domain.DuplicateNameException
+import org.squashtest.csp.tm.domain.campaign.Campaign
+import org.squashtest.csp.tm.domain.campaign.CampaignFolder
+import org.squashtest.csp.tm.domain.campaign.CampaignLibrary
+import org.squashtest.csp.tm.domain.campaign.IterationTestPlanItem;
+import org.squashtest.csp.tm.domain.campaign.TestSuite
+import org.squashtest.csp.tm.internal.repository.CampaignDao
+import org.squashtest.csp.tm.internal.repository.CampaignFolderDao
+import org.squashtest.csp.tm.internal.repository.CampaignLibraryDao
+import org.squashtest.csp.tm.internal.repository.IterationDao;
+import org.squashtest.csp.tm.internal.service.CampaignLibraryNavigationServiceImpl
+import org.squashtest.csp.tm.internal.service.campaign.IterationTestPlanManager;
+import org.squashtest.csp.tm.service.IterationModificationService;
 import org.squashtest.csp.tm.domain.campaign.CampaignLibraryNode
-
+import org.squashtest.csp.tm.domain.campaign.Iteration
+import java.util.List
+import java.util.ArrayList
 
 import spock.lang.Specification;
 
 
 	CampaignLibraryNavigationServiceImpl service = new CampaignLibraryNavigationServiceImpl();
 
-	CampaignLibraryDao campaignLibraryDao = Mock();
-	CampaignFolderDao campaignFolderDao = Mock();
-	CampaignDao campaignDao = Mock();
-	PermissionEvaluationService permissionService = Mock();
+	CampaignLibraryDao campaignLibraryDao = Mock()
+	CampaignFolderDao campaignFolderDao = Mock()
+	CampaignDao campaignDao = Mock()
+	PermissionEvaluationService permissionService = Mock()
+	IterationModificationService iterationModificationService = Mock()
+	IterationDao iterationDao = Mock()
+	IterationTestPlanManager iterationTestPlanManager = Mock()
 
 	def setup() {
 		service.campaignLibraryDao = campaignLibraryDao
 		service.campaignFolderDao = campaignFolderDao
 		service.campaignDao = campaignDao
-		service.permissionService = permissionService;
+		service.permissionService = permissionService
 		permissionService.hasRoleOrPermissionOnObject(_, _, _) >> true
+		service.iterationModificationService = iterationModificationService
+		service.iterationDao = iterationDao
+		service.iterationTestPlanManager = iterationTestPlanManager
 	}
 
 
 		CampaignLibrary l = Mock()
 		campaignLibraryDao.findById(10) >> l
 
-
 		when:
 		def found = service.findLibrary(10)
 

File tm/org.squashtest.csp.tm.web/src/main/java/org/squashtest/csp/tm/web/internal/controller/campaign/CampaignLibraryNavigationController.java

View file
 	}	
 	
 	
-	@RequestMapping(value="/copy", method= RequestMethod.POST)
+	@RequestMapping(value="/copy-iterations", method= RequestMethod.POST)
 	public @ResponseBody List<JsTreeNode> copyIterations(@RequestParam("object-ids[]") Long[] iterationsIds, 
 							  @RequestParam("destination-id") long campaignId, 
 							  @RequestParam("destination-type") String destType,

File tm/org.squashtest.csp.tm.web/src/main/java/org/squashtest/csp/tm/web/internal/controller/campaign/TestSuiteModificationController.java

View file
 		ModelAndView mav = new ModelAndView("fragment/test-suites/edit-test-suite");
 		mav.addObject("testSuite", testSuite);
 		mav.addObject("statistics", testSuiteStats);
-
 		return mav;
 	}
 

File tm/org.squashtest.csp.tm.web/src/main/webapp/WEB-INF/tags/treepopups/copy-paste-node.tag

View file
 <s:url var="copyUrl" value="/{workspace}-browser/copy">
 	<s:param name="workspace" value="${resourceName}" />
 </s:url>
-<s:url var="copyIterationUrl" value="/{workspace}-browser/copyIteration">
+<s:url var="copyIterationUrl" value="/{workspace}-browser/copy-iterations">
 	<s:param name="workspace" value="${resourceName}" />
 </s:url>