Salome HOME
New checkIn functionality is implemented. Now some files can be checkedIn simultaneously.
[tools/siman.git] / Workspace / Siman-Common / src / test / splat / service / TestScenarioService.java
1 /*****************************************************************************
2  * Company         OPEN CASCADE
3  * Application     SIMAN
4  * File            $Id$ 
5  * Creation date   12 Oct 2012
6  * @author         $Author$
7  * @version        $Revision$
8  *****************************************************************************/
9 package test.splat.service;
10
11 import java.io.File;
12 import java.io.FileNotFoundException;
13 import java.io.FileWriter;
14 import java.io.IOException;
15 import java.sql.SQLException;
16 import java.util.ArrayList;
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.splat.dal.bo.kernel.Relation;
26 import org.splat.dal.bo.kernel.User;
27 import org.splat.dal.bo.som.ConvertsRelation;
28 import org.splat.dal.bo.som.Document;
29 import org.splat.dal.bo.som.DocumentType;
30 import org.splat.dal.bo.som.KnowledgeElementType;
31 import org.splat.dal.bo.som.Publication;
32 import org.splat.dal.bo.som.Scenario;
33 import org.splat.dal.bo.som.SimulationContext;
34 import org.splat.dal.bo.som.SimulationContextType;
35 import org.splat.dal.bo.som.Study;
36 import org.splat.dal.bo.som.UsedByRelation;
37 import org.splat.dal.bo.som.UsesRelation;
38 import org.splat.dal.bo.som.ValidationCycle;
39 import org.splat.dal.bo.som.ValidationCycleRelation;
40 import org.splat.dal.bo.som.ValidationStep;
41 import org.splat.dal.bo.som.VersionsRelation;
42 import org.splat.dal.bo.som.Document.Properties;
43 import org.splat.dal.dao.kernel.UserDAO;
44 import org.splat.dal.dao.som.Database;
45 import org.splat.dal.dao.som.ScenarioDAO;
46 import org.splat.dal.dao.som.StudyDAO;
47 import org.splat.dal.dao.som.ValidationCycleDAO;
48 import org.splat.exception.BusinessException;
49 import org.splat.exception.InvalidParameterException;
50 import org.splat.i18n.I18nUtils;
51 import org.splat.kernel.InvalidPropertyException;
52 import org.splat.kernel.MismatchException;
53 import org.splat.kernel.MissedPropertyException;
54 import org.splat.kernel.MultiplyDefinedException;
55 import org.splat.kernel.NotApplicableException;
56 import org.splat.log.AppLogger;
57 import org.splat.service.DocumentTypeService;
58 import org.splat.service.KnowledgeElementTypeService;
59 import org.splat.service.ProjectElementService;
60 import org.splat.service.PublicationService;
61 import org.splat.service.ScenarioService;
62 import org.splat.service.SimulationContextService;
63 import org.splat.service.StepService;
64 import org.splat.service.StudyService;
65 import org.splat.service.dto.DocumentDTO;
66 import org.splat.service.dto.FileDTO;
67 import org.splat.service.dto.ScenarioDTO;
68 import org.splat.service.dto.StepDTO;
69 import org.splat.service.technical.ProjectSettingsService;
70 import org.splat.service.technical.RepositoryService;
71 import org.splat.service.technical.StepsConfigService;
72 import org.splat.service.technical.ProjectSettingsService.Step;
73 import org.springframework.beans.factory.annotation.Autowired;
74 import org.springframework.beans.factory.annotation.Qualifier;
75 import org.springframework.orm.hibernate3.HibernateTemplate;
76 import org.testng.Assert;
77 import org.testng.annotations.Test;
78 import org.testng.reporters.Files;
79
80 import test.splat.common.BaseTest;
81 import test.splat.util.TestEntitiesGenerator;
82
83 /**
84  * Test class for ScenarioService.
85  * 
86  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
87  * 
88  */
89 public class TestScenarioService extends BaseTest {
90
91         /**
92          * Logger for the class.
93          */
94         private static final AppLogger LOG = AppLogger
95                         .getLogger(TestScenarioService.class);
96
97         /**
98          * The tested ScenarioService. Later injected by Spring.
99          */
100         @Autowired
101         @Qualifier("scenarioService")
102         private transient ScenarioService _scenarioService;
103
104         /**
105          * The RepositoryService. Later injected by Spring.
106          */
107         @Autowired
108         @Qualifier("repositoryService")
109         private transient RepositoryService _repositoryService;
110
111         /**
112          * The Scenario DAO. Later injected by Spring.
113          */
114         @Autowired
115         @Qualifier("scenarioDAO")
116         private transient ScenarioDAO _scenarioDAO;
117
118         /**
119          * The PublicationService. Later injected by Spring.
120          */
121         @Autowired
122         @Qualifier("publicationService")
123         private transient PublicationService _publicationService;
124
125         /**
126          * The StepService. Later injected by Spring.
127          */
128         @Autowired
129         @Qualifier("stepService")
130         private transient StepService _stepService;
131
132         /**
133          * The SimulationContextService. Later injected by Spring.
134          */
135         @Autowired
136         @Qualifier("simulationContextService")
137         private transient SimulationContextService _simulationContextService;
138
139         /**
140          * The ProjectSettingsService. Later injected by Spring.
141          */
142         @Autowired
143         @Qualifier("projectSettings")
144         private transient ProjectSettingsService _projectSettings;
145
146         /**
147          * The StepsConfigService. Later injected by Spring.
148          */
149         @Autowired
150         @Qualifier("stepsConfigService")
151         private transient StepsConfigService _stepsConfigService;
152
153         /**
154          * The DocumentTypeService. Later injected by Spring.
155          */
156         @Autowired
157         @Qualifier("documentTypeService")
158         private transient DocumentTypeService _documentTypeService;
159
160         /**
161          * The KnowledgeElementTypeService. Later injected by Spring.
162          */
163         @Autowired
164         @Qualifier("knowledgeElementTypeService")
165         private transient KnowledgeElementTypeService _knowledgeElementTypeService;
166
167         /**
168          * The UserDAO. Later injected by Spring.
169          */
170         @Autowired
171         @Qualifier("userDAO")
172         private transient UserDAO _userDAO;
173
174         /**
175          * The StudyService. Later injected by Spring.
176          */
177         @Autowired
178         @Qualifier("studyService")
179         private transient StudyService _studyService;
180
181         /**
182          * The StudyDAO. Later injected by Spring.
183          */
184         @Autowired
185         @Qualifier("studyDAO")
186         private transient StudyDAO _studyDAO;
187
188         /**
189          * The ValidationCycleDAO. Later injected by Spring.
190          */
191         @Autowired
192         @Qualifier("validationCycleDAO")
193         private transient ValidationCycleDAO _validationCycleDAO;
194
195         /**
196          * The ProjectElementService. Later injected by Spring.
197          */
198         @Autowired
199         @Qualifier("projectElementService")
200         private transient ProjectElementService _projectElementService;
201
202         /**
203          * Test of getting a scenario content for building siman-salome.conf.<BR>
204          * <B>Description :</B> <BR>
205          * <i>Create a scenario and try to get an info for it.</i><BR>
206          * <B>Action : </B><BR>
207          * <i>1. call the method for an existing scenario id.</i><BR>
208          * <i>2. call the method for a not existing scenario id.</i><BR>
209          * <B>Test data : </B><BR>
210          * <i>no input parameters</i><BR>
211          * <i>no input parameters</i><BR>
212          * 
213          * <B>Outcome results:</B><BR>
214          * <i>
215          * <ul>
216          * <li>result DTO must contain list of all documents and files<BR>
217          * </li>
218          * <li>Exception is thrown<BR>
219          * </li>
220          * </ul>
221          * </i>
222          * 
223          * @throws InvalidPropertyException
224          *             if an invalid property is used when creating objects
225          * @throws MultiplyDefinedException
226          *             when trying to create an object with already existing id
227          * @throws MissedPropertyException
228          *             if a mandatory property is not defined for an object to be created
229          * @throws IOException
230          *             if scenario creation is failed
231          * @throws SQLException
232          *             if scenario creation is failed
233          */
234         @Test(groups = { "checkout", "sevice", "functional", "business" })
235         public void testGetScenarioInfo() throws InvalidPropertyException,
236                         MissedPropertyException, MultiplyDefinedException, IOException,
237                         SQLException {
238                 LOG.debug(">>>>> BEGIN testGetScenarioInfo()");
239                 startNestedTransaction();
240
241                 long scenarioId = createScenario();
242                 // Call DAO's create method for a good transient knowledge element.
243                 List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
244                 Assert.assertNotNull(steps, "List of steps must not be null.");
245                 Assert.assertTrue(steps.size() > 0, "No steps are read.");
246
247                 List<Step> projSteps = _stepsConfigService.getStepsOf(Scenario.class);
248                 Assert.assertEquals(steps.size(), projSteps.size(),
249                                 "Not all steps are listed.");
250                 int docIndex = 0;
251                 for (StepDTO step : steps) {
252                         LOG.debug("check the step " + step.getNumber() + ":\n" + step);
253                         Assert.assertNotNull(step, "Step DTO must not be null.");
254                         Assert.assertNotNull(step.getKey(), "Step name must not be null.");
255                         Assert.assertFalse(step.getKey().isEmpty(),
256                                         "Step name must not empty.");
257                         Assert.assertTrue(step.getNumber() > 0,
258                                         "Step number must be positive integer.");
259                         Assert.assertNotNull(step.getDocs(),
260                                         "Step documents list must not be null.");
261
262                         Step aProjStep = null;
263                         for (Step projStep : projSteps) {
264                                 if (projStep.getNumber() == step.getNumber()) {
265                                         aProjStep = projStep;
266                                         break;
267                                 }
268                         }
269
270                         List<DocumentType> dtypes = _documentTypeService
271                                         .selectTypesOf(aProjStep);
272                         for (DocumentType dtype : dtypes) {
273                                 Assert.assertTrue(step.getDocs().size() > 0,
274                                                 "Step documents list must not be empty.");
275                                 String docName = "document" + docIndex;
276                                 for (DocumentDTO doc : step.getDocs()) {
277                                         if (docName.equals(doc.getTitle())) {
278                                                 Assert.assertTrue(doc.getId() > 0,
279                                                                 "Document id must be positive integer.");
280                                                 Assert.assertEquals(doc.getTitle(), docName);
281                                                 Assert.assertNotNull(doc.getFiles(),
282                                                                 "Document files list must not be null.");
283                                                 Assert
284                                                                 .assertTrue(doc.getFiles().size() > 1,
285                                                                                 "Document must have more then 1 attached file.");
286
287                                                 for (FileDTO file : doc.getFiles()) {
288                                                         Assert.assertNotNull(file.getPath(),
289                                                                         "File path must not be null.");
290                                                         Assert.assertFalse(file.getPath().isEmpty(),
291                                                                         "File path must not be empty.");
292                                                         /*
293                                                          * <mappings> <document type="geometry"> <import format="brep"/> <!-- Result Shape --> </document> <document
294                                                          * type="model"> <import format="med"/> <!-- Result mesh without input parameters --> </document> <document
295                                                          * type="loads"> <import format="c3m"/> <!-- Input data created interactively --> </document> <document
296                                                          * type="results"> <import format="med"/> <!-- Calculation results source file --> </document> </mappings>
297                                                          */
298                                                         // Check state and processing instruction
299                                                         String fileFormat = file.getPath().substring(
300                                                                         file.getPath().lastIndexOf('.') + 1);
301                                                         /*
302                                                          * if (_projectSettings.doImport(dtype.getName(), fileFormat)) { Assert.assertTrue(file.isResult(), "The file
303                                                          * must be a result file."); } else { Assert.assertFalse(file.isResult(), "The file must be a source file."); }
304                                                          */if ((docIndex % 2) == 0) { // New
305                                                                 Assert.assertEquals(file.getState(), 'Y',
306                                                                                 "File state must be actual ('Y').");
307                                                                 if (_projectSettings.doImport(dtype.getName(),
308                                                                                 fileFormat)) {
309                                                                         Assert.assertEquals(file.getProcessing(),
310                                                                                         "file-import",
311                                                                                         "File must be imported.");
312                                                                 } else {
313                                                                         Assert.assertEquals(file.getProcessing(),
314                                                                                         "file-download",
315                                                                                         "File must be downloaded.");
316                                                                 }
317                                                         } else { // Outdated
318                                                                 Assert.assertEquals(file.getState(), 'O',
319                                                                                 "File state must be outdated ('O').");
320                                                                 Assert
321                                                                                 .assertEquals(file.getProcessing(),
322                                                                                                 "file-download",
323                                                                                                 "Outdated document should not be imported but downloaded.");
324                                                         }
325                                                 }
326                                         }
327                                 }
328                                 docIndex++;
329                         }
330                 }
331
332                 // Call DAO's get method for a not existing id.
333                 try {
334                         steps = _scenarioService.getScenarioInfo(-1L);
335                         // getHibernateTemplate().flush();
336                         Assert
337                                         .fail("Getting an object with not existing id must be failed.");
338                 } catch (Exception e) {
339                         LOG.debug("Expected exception is thrown: "
340                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
341                 }
342                 rollbackNestedTransaction();
343                 LOG.debug(">>>>> END testGetScenarioInfo()");
344         }
345
346         /**
347          * Test check-in scenario operation to be performed after SALOME session.<BR>
348          * <B>Description :</B> <BR>
349          * <i>Create a scenario and try to check-in it with some simulated SALOME results data.<BR>
350          * After check-in verify following points:
351          * <ul>
352          * <li>scenario is no more marked as checked out</li>
353          * <li>new document versions are created for checked in documents</li>
354          * <li>presentation of the previous version is removed</li>
355          * <li>uses relations are copied correctly</li>
356          * <li>files are moved correctly</li>
357          * <li>formats of files are new if they are according to the document's type on the study step</li>
358          * <li>new documents are created for new data</li>
359          * <li>new documents have correctly generated names</li>
360          * <li>uses relations are created correctly</li>
361          * <li>files are moved correctly</li>
362          * </ul>
363          * </i><BR>
364          * <B>Action : </B><BR>
365          * <i>1. call the method for an existing scenario id.</i><BR>
366          * <i>2. call the method for a not existing scenario id.</i><BR>
367          * <B>Test data : </B><BR>
368          * <i>no input parameters</i><BR>
369          * <i>no input parameters</i><BR>
370          * 
371          * <B>Outcome results:</B><BR>
372          * <i>
373          * <ul>
374          * <li>New version of existing documents must be created and new documents must be imported for documents with zero id. Correct
375          * relations must be created.<BR>
376          * </li>
377          * <li>Exception is thrown<BR>
378          * </li>
379          * </ul>
380          * </i>
381          * 
382          * @throws InvalidPropertyException
383          *             if an invalid property is used when creating objects
384          * @throws MultiplyDefinedException
385          *             when trying to create an object with already existing id
386          * @throws MissedPropertyException
387          *             if a mandatory property is not defined for an object to be created
388          * @throws IOException
389          *             if scenario creation is failed
390          * @throws SQLException
391          *             if scenario creation is failed
392          * @throws NotApplicableException
393          *             if checkin failed
394          * @throws MismatchException
395          *             if checkin failed
396          */
397         @Test(groups = { "checkin", "sevice", "functional", "business" })
398         public void testCheckin() throws InvalidPropertyException,
399                         MissedPropertyException, MultiplyDefinedException, IOException,
400                         SQLException, MismatchException, NotApplicableException {
401                 LOG.debug(">>>>> BEGIN testCheckin()");
402                 startNestedTransaction();
403
404                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
405                 _projectSettings.configure("classpath:test/som.xml");
406                 getHibernateTemplate().flush();
407                 long scenarioId = createScenario();
408                 Scenario aScen = _scenarioDAO.get(scenarioId);
409                 User user = aScen.getAuthor();
410                 long userId = user.getIndex();
411
412                 // ////////////////////////////////////////////////////////
413                 // Call checkin method for empty list of modules.
414
415                 // Simulate checkout
416                 _scenarioService.checkout(aScen, user);
417                 _scenarioDAO.flush();
418                 // Check that scenario is no more marked as checked out
419                 aScen = _scenarioDAO.get(scenarioId);
420                 Assert.assertTrue(aScen.isCheckedout(),
421                                 "Scenario is not marked as checked out after checkout.");
422
423                 // Prepare test data for checkin
424                 // Checkin only two first steps (geom and mesh)
425                 List<StepDTO> stepsToCheckin = new ArrayList<StepDTO>();
426                 // Do test checkin
427                 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
428
429                 _scenarioDAO.flush();
430                 // Check that scenario is no more marked as checked out
431                 aScen = _scenarioDAO.get(scenarioId);
432                 Assert.assertFalse(aScen.isCheckedout(),
433                                 "Scenario is still marked as checked out after checkin.");
434
435                 // ///////////////////////////////////////////////////////////
436                 // Different test cases
437                 
438                 //Fancy but compact way to iterate over all possible combinations without missing any of them.
439                 List<Boolean> trueFalse = new ArrayList<Boolean>();
440                 trueFalse.add(false);
441                 trueFalse.add(true);
442                 long testCaseNumber = 1;        //To provide some uniqueness to files content.
443                 
444                 for (boolean hasSource : trueFalse) {
445                         for (boolean hasAttachments : trueFalse) {
446                                 for (boolean checkinSource : trueFalse) {
447                                         for (boolean checkinAttachments : trueFalse) {
448                                                 if (hasAttachments && !hasSource) {             // Impossible test cases
449                                                         continue;
450                                                 }
451                                                 if (!checkinAttachments && !checkinSource) {    // Unnecessary test cases
452                                                         continue;
453                                                 }
454                                                 
455                                                 //startNestedTransaction();
456                                                 Set<String> res = testCheckinTestcase(testCaseNumber++,
457                                                                 scenarioId, userId,
458                                                                 hasSource, hasAttachments,
459                                                                 checkinSource, checkinAttachments);
460                                                 //rollbackNestedTransaction();
461                                                 
462                                                 // These combinations are dictated by assertCheckinValidity logic
463                                                 Assert.assertEquals(!hasSource && (checkinSource || checkinAttachments),
464                                                                 res.contains("aNewSourceCreated"));
465                                                 Assert.assertEquals(hasSource && checkinSource,
466                                                                 res.contains("oldSourceVersioned"));
467                                                 Assert.assertEquals(checkinAttachments && hasSource && checkinSource,
468                                                                 res.contains("fileAttachedToAVersionedDoc"));
469                                                 Assert.assertEquals(checkinAttachments && hasSource && !checkinSource,
470                                                                 res.contains("fileAttachedToAnOldDoc"));
471                                                 Assert.assertEquals(checkinAttachments && !hasSource,
472                                                                 res.contains("fileAttachedToANewDoc"));
473                                                 
474                                         }
475                                 }
476                         }
477                 }
478                 
479                 // ///////////////////////////////////////////////////////////
480                 // Call checkin method for a not existing id.
481                 try {
482                         _scenarioService.checkin(-1, userId, stepsToCheckin);
483                         Assert
484                                         .fail("Check in for scenario with not existing id must be failed.");
485                 } catch (Exception e) {
486                         LOG.debug("Expected exception is thrown: "
487                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
488                 }
489
490                 // Test checkin with empty list of steps
491                 stepsToCheckin.clear();
492                 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
493
494                 rollbackNestedTransaction();
495                 LOG.debug(">>>>> END testCheckin()");
496         }
497         
498         
499         /**
500          * Performs necessary checks after checkin.
501          * @param testCaseNumber
502          *                      the test case number
503          * @param stepsToCheckin
504          *                      stepDTOs which has been checked in
505          * @param aScen
506          *                      the scenario
507          * @param dates
508          *                      modification dates
509          * @return
510          *                      set of strings indicating which cases has occurred
511          * @throws IOException
512          *                      if something is wrong
513          */
514         private Set<String> assertCheckinValidity(final long testCaseNumber,
515                         final List<StepDTO> stepsToCheckin, final Scenario aScen,
516                         final Map<Long, Date> dates) throws IOException{
517                 Set<String> result = new HashSet<String>();
518                 Assert.assertFalse(aScen.isCheckedout(),
519                                 "Scenario is still marked as checked out after checkin.");
520                 // Check that new document versions are created for checked in documents
521                 for (StepDTO step : stepsToCheckin) {
522                         for (DocumentDTO docDTO : step.getDocs()) {
523                                 for (FileDTO fileDTO : docDTO.getFiles()) {
524                                         
525                                         if ((docDTO.getId() != 0) && (docDTO.getId() != null)) {
526                                                 boolean prevVersFound = false;
527                                                 boolean versionedWithThisFile = false;
528                                                 Document prevDoc = null;
529                                                 Document curDoc = null;
530                                                 Publication newPub = null;
531         
532                                                 // If previous version is found then the format must be the same
533                                                 String newFormat = fileDTO.getPath()
534                                                                 .substring(fileDTO.getPath().lastIndexOf('.') + 1);
535                                                 for (Publication pub : aScen.getDocums()) {
536                                                         prevDoc = pub.value().getPreviousVersion();
537                                                         if (prevDoc != null) {
538                                                                 prevVersFound = (prevDoc.getIndex() == docDTO.getId());
539                                                                 if (prevVersFound) { // Found next published version of the checked in document
540                                                                         newPub = pub;
541                                                                         if(pub.value().getFormat().equals(newFormat)) {
542                                                                                 versionedWithThisFile = true;
543                                                                         }
544                                                                         break;
545                                                                 }
546                                                         }
547                                                         if (pub.value().getIndex() == docDTO.getId()) {
548                                                                 // Document version was not changed, old document is still published
549                                                                 curDoc = pub.value();
550                                                                 break;
551                                                         }
552                                                 }
553                                                 Assert.assertTrue(prevVersFound || (curDoc != null),
554                                                                 "New version or new attached file of the existing checked in document \""
555                                                                                 + docDTO.getTitle() + "\" (id="
556                                                                                 + docDTO.getId()
557                                                                                 + ") is not found in the scenario.");
558                                                 
559                                                 if (prevVersFound && versionedWithThisFile) {
560                                                         result.add("oldSourceVersioned");
561                                                         Assert.assertFalse(aScen.publishes(prevDoc));
562                                                         // Check that presentation of the previous version is removed
563                                                         checkFiles(docDTO, newPub);
564         
565                                                         // Formats of files are new if they are according to the document's type on the study step
566                                                                 Assert.assertEquals(newPub.getSourceFile()
567                                                                                 .getFormat(), newFormat);
568                                                                 Assert.assertEquals(newPub.getSourceFile()
569                                                                                 .getRelativePath().substring(
570                                                                                                 newPub.getSourceFile()
571                                                                                                                 .getRelativePath()
572                                                                                                                 .lastIndexOf('.') + 1),
573                                                                                 newFormat);
574         
575                                                         // Check that uses relations are copied correctly
576         
577                                                         // 1. Get all uses relations of the previous document version
578                                                         for (Relation rel : prevDoc
579                                                                         .getRelations(UsesRelation.class)) {
580                                                                 Document used = ((UsesRelation) rel).getTo();
581                                                                 // 2.1. Get the latest version of the document published in this scenario
582                                                                 Publication toBeUsed = aScen.getPublication(used);
583                                                                 if (toBeUsed == null) {
584                                                                         // Find the latest published version
585                                                                         for (Publication lastPub : aScen.getDocums()) {
586                                                                                 if ((lastPub.value().getPreviousVersion() != null)
587                                                                                                 && (lastPub.value()
588                                                                                                                 .getPreviousVersion()
589                                                                                                                 .getIndex() == used
590                                                                                                                 .getIndex())) {
591                                                                                         toBeUsed = lastPub;
592                                                                                         break;
593                                                                                 }
594                                                                         }
595                                                                 }
596                                                                 if ((toBeUsed != null) && (!toBeUsed.isOutdated())) {
597                                                                         // 2.2. For each used document check that its latest not outdated version
598                                                                         // is used by the new checked in document version.
599                                                                         checkUsesRelation(newPub, toBeUsed);
600                                                                 }
601                                                         }
602                                                         // 1. Get all usedBy relations of the previous document version
603                                                         for (Relation rel : prevDoc
604                                                                         .getRelations(UsedByRelation.class)) {
605                                                                 Document using = ((UsedByRelation) rel).getTo();
606                                                                 // Check that not checked in dependent documents became outdated
607                                                                 Publication usingPub = aScen.getPublication(using);
608                                                                 if (usingPub != null) { // if the document using the old version is still published
609                                                                         Assert.assertTrue(usingPub.isOutdated(),
610                                                                                         "Not checked in dependent document "
611                                                                                                         + using.getTitle() + " ("
612                                                                                                         + using.getType().getName()
613                                                                                                         + ") must become outdated.");
614                                                                 }
615                                                         }
616         
617                                                         // Check that a correct comment is generated for VersionsRelation
618                                                         VersionsRelation versRel = (VersionsRelation) newPub
619                                                                         .value().getFirstRelation(
620                                                                                         VersionsRelation.class);
621                                                         Assert.assertNotNull(versRel,
622                                                                         "VersionsRelation must be created.");
623                                                         Assert
624                                                                         .assertNotNull(versRel.getDescription(),
625                                                                                         "VersionsRelation description was not generated.");
626                                                         int descrLen = versRel.getDescription().length();
627                                                         Assert.assertTrue(descrLen > 0,
628                                                                         "VersionsRelation description is empty.");
629                                                         LOG.debug("Version description: "
630                                                                         + versRel.getDescription());
631                                                 } else {
632                                                         // Otherwise the file is attached to some other document,
633                                                         // which has been or has not been versioned during checkin
634                                                         Document targetDoc = null;
635                                                         if(prevVersFound) { // if the document has been versioned
636                                                                 Assert.assertEquals(Long.valueOf(prevDoc.getIndex()),
637                                                                                 docDTO.getId());
638                                                                 targetDoc = newPub.value();
639                                                                 result.add("fileAttachedToAVersionedDoc");
640                                                         } else {
641                                                                 targetDoc = curDoc;
642                                                                 result.add("fileAttachedToAnOldDoc");
643                                                         }
644                                                         Assert.assertFalse(newFormat.equals(targetDoc.getFormat()));
645                                                         
646                                                         // Check file content
647                                                         Assert.assertTrue(Files.readFile(targetDoc.getAttachedFile(newFormat).asFile())
648                                                                         .contains(new File(fileDTO.getPath()).getName()));
649                                                 
650                                                         // Otherwise the new file format must differ from the previous one
651                                                         // and the new file must be attached to the same document
652                                                         org.splat.dal.bo.som.File attFile = targetDoc
653                                                                         .getAttachedFile(newFormat);
654                                                         Assert.assertNotNull(attFile, "File "
655                                                                         + fileDTO.getPath()
656                                                                         + " must be attached to the document "
657                                                                         + docDTO.getTitle() + "#" + docDTO.getId());
658                                                         Assert.assertTrue(attFile.asFile().exists(), "File "
659                                                                         + fileDTO.getPath()
660                                                                         + " attached to the document "
661                                                                         + docDTO.getTitle() + "#" + docDTO.getId()
662                                                                         + " doesn't exist");
663                                                         LOG.debug("Source format: " + targetDoc.getFormat()
664                                                                         + ", new format: " + newFormat);
665                                                         // Check that attachment with the same format is not duplicated.
666                                                         int attachNb = 0;
667                                                         for (Relation conv : targetDoc
668                                                                         .getRelations(ConvertsRelation.class)) {
669                                                                 if (newFormat.equals(((ConvertsRelation) conv)
670                                                                                 .getTo().getFormat())) {
671                                                                         attachNb++;
672                                                                 }
673                                                         }
674                                                         Assert
675                                                                         .assertEquals(attachNb, 1,
676                                                                                         "Attachment with the same format must be only one.");
677         
678                                                         // Check that the attached file date is updated
679                                                         if (dates.containsKey(attFile.getIndex())) {
680                                                                 Assert
681                                                                                 .assertTrue(attFile.getDate().compareTo(
682                                                                                                 dates.get(attFile.getIndex())) > 0,
683                                                                                                 "Attachment modification date is not updated.");
684                                                                 result.add("modifDatesChecked");
685                                                         }
686                                                 }
687         
688                                         } else {
689                                                 // here file may be attached to a newly created one,
690                                                 // or it may be a source of new doc itself.
691                                                 
692                                                 // Check that new documents are created for new data
693                                                 boolean foundAsSource = false;
694                                                 boolean foundAsAttachment = false;
695                                                 Publication newPub = null;
696                                                 for (Publication pub : aScen.getDocums()) {
697                                                         if (pub.value().getPreviousVersion() == null) {
698                                                                 // TODO: is it correct? type  name here?
699                                                                 foundAsSource = (pub.value().getTitle().startsWith(pub
700                                                                                 .value().getType().getName()));
701                                                                 if (foundAsSource) { // Found next published version of the checked in document
702                                                                         String fcontent = Files.readFile(pub
703                                                                                         .getSourceFile().asFile());
704                                                                         foundAsSource = fcontent.contains(
705                                                                                         new File(fileDTO.getPath()).getName());
706                                                                         if (foundAsSource) {
707                                                                                 LOG
708                                                                                                 .debug("Found new document with generated title: "
709                                                                                                                 + pub.value().getTitle());
710                                                                                 newPub = pub;
711                                                                                 break;
712                                                                         }
713                                                                 }
714         
715                                                                 String format = fileDTO.getPath().substring(
716                                                                                                 fileDTO.getPath().lastIndexOf('.') + 1);
717                                                                 org.splat.dal.bo.som.File attachment = pub.value().getAttachedFile(format);
718                                                                 if (attachment != null) {
719                                                                         String fcontent = Files.readFile(attachment.asFile());
720                                                                         if (fcontent.contains(new File(fileDTO.getPath()).getName())) {
721                                                                                 foundAsAttachment = true;
722                                                                                 Assert.assertFalse(new File(fileDTO.getPath()).exists(), "File"
723                                                                                                 + fileDTO.getPath()
724                                                                                                 + " was not removed from downloads directory.");
725                                                                                 result.add("fileAttachedToANewDoc");
726                                                                                 break;
727                                                                         }
728                                                                 }
729                                                         }
730                                                 }
731                                                 Assert.assertTrue(foundAsSource || foundAsAttachment,
732                                                                 "New document or attachment is not created for checked in document \""
733                                                                                 + docDTO.getTitle() + "\".");
734         
735                                                 if (foundAsSource) {
736                                                         
737                                                         // TODO: check that all the conditions for this file to be chosen
738                                                         // as fileToAttachTo are present.
739                                                                 //probably, drop some unimportant
740         
741                                                         // Check file content
742                                                         Assert.assertTrue(Files.readFile(newPub.getSourceFile().asFile())
743                                                                         .contains(new File(fileDTO.getPath()).getName()));
744                                                         
745                                                         result.add("aNewSourceCreated");
746                                                         // Check that uses relations are created correctly
747                                                         Assert.assertTrue(newPub.value().getTitle().startsWith(
748                                                                         newPub.value().getType().getName() + "_"),
749                                                                         "Document title newPub.value().getTitle() must start with "
750                                                                                         + newPub.value().getType().getName() + "_");
751                 
752                                                         // 1. Find the document type used by this document type
753                                                         Set<DocumentType> usedTypes = newPub.value().getType()
754                                                                         .getDefaultUses();
755                                                         // 2. Find documents of used types in the current study step and previous study steps
756                                                         for (Publication pub : aScen.getDocums()) {
757                                                                 if ((pub.getStep().getNumber() <= step.getNumber())
758                                                                                 && (!pub.isOutdated())
759                                                                                 && usedTypes.contains(pub.value().getType())
760                                                                                 && !newPub.equals(pub)) {
761                                                                         // 3. Check that there is uses relation to the found document
762                                                                         // if it is not outdated.
763                                                                         checkUsesRelation(newPub, pub);
764                                                                 }
765                                                         }
766                 
767                                                         // Check that files are moved correctly
768                                                         checkFiles(docDTO, newPub);
769                                                 }
770                                         }
771                                 }
772                         }
773                 }
774                 return result;
775         }
776
777         /**
778          * Check if there is uses relation from the newPub to pub.
779          * 
780          * @param newPub
781          *            the new publication
782          * @param pub
783          *            the publication to be used
784          */
785         private void checkUsesRelation(final Publication newPub,
786                         final Publication pub) {
787                 boolean uses = false;
788                 boolean usesExist = false;
789                 for (Publication usesPub : newPub.getRelations(UsesRelation.class)) {
790                         usesExist = true;
791                         uses = (usesPub.equals(pub));
792                         if (uses) {
793                                 break;
794                         }
795                 }
796                 Assert.assertTrue(usesExist && uses, "The created document "
797                                 + newPub.value().getTitle() + "("
798                                 + newPub.value().getType().getName() + ")"
799                                 + " has no uses relation to the document "
800                                 + pub.value().getTitle() + "("
801                                 + pub.value().getType().getName() + ")");
802         }
803
804         /**
805          * Check that files are moved correctly.
806          * 
807          * @param docDTO
808          *            checked in document DTO
809          * @param newPub
810          *            the created document publication
811          */
812         private void checkFiles(final DocumentDTO docDTO, final Publication newPub) {
813                 // Check that original files are deleted
814                 for (int j = 0; j < docDTO.getFiles().size(); j++) {
815                         FileDTO fileDTO = docDTO.getFiles().get(j);
816                         Assert.assertFalse(new File(fileDTO.getPath()).exists(), "File"
817                                         + fileDTO.getPath()
818                                         + " was not removed from downloads directory.");
819                         String format = fileDTO.getPath().substring(
820                                         fileDTO.getPath().lastIndexOf('.') + 1);
821                 }
822                 // TODO: Check file by its internal content
823                 Assert.assertTrue(newPub.getSourceFile().exists(), "File "
824                                 + newPub.getSourceFile().asFile().getAbsolutePath()
825                                 + " for the document " + docDTO.getTitle()
826                                 + " was not created.");
827         }
828
829         /**
830          * Prepare a document with a file for check-in.
831          * 
832          * @param stepTo
833          *            step DTO with data for check-in
834          * @param module
835          *            SALOME module name
836          * @param format
837          *            file extension
838          * @param userId
839          *            download directory
840          * @param stepFrom
841          *            checked out stepDTO
842          * @param stepsToCheckin
843          *            DTO for check-in
844          * @throws IOException
845          *             if file creation failed
846          * @return step DTO with data prepared for check-in (stepTo or new if stepTo is null)
847          */
848         private StepDTO createDocDTOForModule(final StepDTO stepTo,
849                         final String module, final String format, final long userId,
850                         final StepDTO stepFrom, final List<StepDTO> stepsToCheckin)
851                         throws IOException {
852                 StepDTO stepToCheckin = stepTo;
853                 if (stepToCheckin == null) {
854                         stepToCheckin = new StepDTO();
855                 }
856                 if (module.equals(stepFrom.getModule())) {
857                         stepsToCheckin.add(stepToCheckin);
858                         stepToCheckin.setNumber(stepFrom.getNumber());
859                         for (DocumentDTO doc : stepFrom.getDocs()) {
860                                 if (doc.getFiles().get(0).getState() != 'O') {
861                                         DocumentDTO docToCheckin = stepToCheckin.addDoc(
862                                                         doc.getId(), doc.getTitle());
863                                         for (FileDTO file : doc.getFiles()) {
864                                                 if (file.getPath().endsWith(format)
865                                                                 || (file.getPath().endsWith("py") && (format
866                                                                                 .equals("brep") || format.equals("med")))) {
867                                                         // Create a file in the download directory
868                                                         if ("GEOM".equals(module)) {
869                                                                 // New version case
870                                                                 docToCheckin.addFile(createDownloadedFile(
871                                                                                 userId, doc.getTitle() + "_newvers",
872                                                                                 "py"));
873                                                         } else {
874                                                                 // Attached generated result case
875                                                                 docToCheckin.addFile(createDownloadedFile(
876                                                                                 userId, doc.getTitle() + "_result",
877                                                                                 format));
878                                                         }
879                                                 }
880                                         }
881                                 }
882                         }
883                         // Prepare new data
884                         stepToCheckin.addDoc(0, "newdoc" + stepFrom.getNumber()).addFile(
885                                         createDownloadedFile(userId, "newdoc"
886                                                         + stepFrom.getNumber(), "brep"));
887                 }
888                 return stepToCheckin;
889         }
890         
891         /**
892          * Tests a checkin testcase.
893          * @param testCaseNumber
894          *                      the test case number
895          * @param scenarioId
896          *                      the scenrio id
897          * @param userId
898          *                      the user id
899          * @param hasSource
900          *                      whether the scenario is supposed to have a source file in this test case befor checkin
901          * @param hasAttachments
902          *                      whether the scenario is supposed to have files attached to the source
903          *                      in this test case befor checkin
904          * @param checkinSource
905          *                      whether the "comm" file should be checked in
906          * @param checkinAttachment
907          *                      whether the "resu" and "mess" files should be checked in
908          * @return
909          *                      set of strings indicating which cases has occurred
910          * @throws IOException
911          *                      if something is wrong
912          * @throws InvalidPropertyException
913          *                      if something is wrong
914          * @throws MultiplyDefinedException
915          *                      if something is wrong
916          * @throws MissedPropertyException
917          *                      if something is wrong
918          * @throws SQLException
919          *                      if something is wrong
920          * @throws NotApplicableException
921          *                      if something is wrong
922          * @throws MismatchException
923          *                      if something is wrong
924          */
925         private Set<String> testCheckinTestcase(final long testCaseNumber,
926                         final long scenarioId, final long userId,
927                         final boolean hasSource, final boolean hasAttachments,
928                         final boolean checkinSource, final boolean checkinAttachment)
929                         throws IOException, InvalidPropertyException, MultiplyDefinedException,
930                         MissedPropertyException, SQLException, NotApplicableException, MismatchException{
931                 
932                 Scenario aScen = _scenarioDAO.get(scenarioId);
933                 User user = _userDAO.get(userId);
934
935                 List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
936                 
937                 // ////////////////////////////////////////////////////////
938                 // Call checkin method for good prepared transient data.
939
940                 // Simulate checkout
941                 steps = _scenarioService.getScenarioInfo(scenarioId);
942                 _scenarioService.checkout(aScen, user);
943
944                 // Remember modification dates of all attached files
945                 Map<Long, Date> dates = new HashMap<Long, Date>();
946                 for (Publication p : aScen.getDocums()) {
947                         for (Relation r : p.value().getRelations(ConvertsRelation.class)) {
948                                 org.splat.dal.bo.som.File attach = ((ConvertsRelation) r)
949                                                 .getTo();
950                                 dates.put(attach.getIndex(), attach.getDate());
951                         }
952                 }
953                 
954                 long targetDocId = 
955                         addMecaDocsToScenario(testCaseNumber, aScen, user, hasAttachments, hasSource);
956                 
957                 List<StepDTO> stepsToCheckin = new ArrayList<StepDTO>();
958                 for(StepDTO step : steps) {
959                         createDocDTOForMeca(testCaseNumber, targetDocId, null, userId, step, stepsToCheckin,
960                                         checkinSource, checkinAttachment);
961                 }
962
963                 // /////////////////////////////////////////////////////////////////
964                 // Do test checkin
965                 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
966
967                 // Check that scenario is no more marked as checked out
968                 aScen = _scenarioDAO.get(scenarioId);
969                 return assertCheckinValidity(testCaseNumber, stepsToCheckin, aScen, dates);
970         }
971
972         /**
973          * It will delete any "comm" publications in the scenario, and then create a new one,
974          * with attachments if specified.
975          * @param testCaseNumber
976          *                      the test case number
977          * @param aScen
978          *                      the scenario
979          * @param user
980          *                      user who will be used as an author for the added documents
981          * @param hasAttachments
982          *                      whether to add the "comm" doc to the scenario
983          * @param hasSource
984          *                      whether to add "resu" and "mess" docs to the scenario
985          * @return
986          *                      the source document id, if exists, 0 otherwise.
987          * @throws IOException
988          *                      if something is wrong
989          * @throws InvalidPropertyException
990          *                      if something is wrong
991          * @throws MissedPropertyException
992          *                      if something is wrong
993          * @throws MultiplyDefinedException
994          *                      if something is wrong
995          */
996         private long addMecaDocsToScenario(final long testCaseNumber,
997                         final Scenario aScen, final User user,
998                         final boolean hasAttachments, final boolean hasSource) 
999                         throws IOException, InvalidPropertyException, MissedPropertyException,
1000                         MultiplyDefinedException {
1001                 
1002                 long res = 0;
1003                 org.splat.som.Step mecaStep = null;
1004                 for (org.splat.som.Step step : _projectElementService.getSteps(aScen)) {
1005                         if ("SALOME_MECA".equals(step.getStep().getModule())) {
1006                                 mecaStep = step;
1007                         }
1008                 }
1009                 
1010                 //remove comm documents
1011                 List<Publication> toRemove = new ArrayList<Publication>();
1012                 for (Publication pub : mecaStep.getDocuments()) {
1013                         if ("comm".equals(pub.value().getFormat())) {
1014                                 toRemove.add(pub);
1015                         }
1016                 }
1017                 for (Publication pub : toRemove) {
1018                         // remove relations so the publication can be removed correctly
1019                         List<Relation> relations = new ArrayList<Relation>();
1020                         relations.addAll(pub.value().getAllRelations());
1021                         for (Relation rel : relations) {
1022                                 pub.value().removeRelation(UsesRelation.class, rel.getTo());
1023                         }
1024                         aScen.remove(pub);
1025                 }
1026                 
1027                 if (hasSource) {
1028                         // Select result document type for Meca step
1029                         List<DocumentType> dtypes = _documentTypeService
1030                                         .selectTypesOf(mecaStep.getStep());
1031                         DocumentType resultType = null;
1032                         for (DocumentType doctype : dtypes) {
1033                                 if(doctype.isResultOf(mecaStep.getStep())) {
1034                                         resultType = doctype;
1035                                         break;
1036                                 }
1037                         }
1038                         
1039                         Document.Properties dprop = new Document.Properties();
1040                         File directory = _repositoryService.getDownloadDirectory(user);
1041                         directory.mkdirs();
1042                         dprop.setName("commDoc" + testCaseNumber)
1043                                         .setFormat("comm")
1044                                         .setAuthor(user)
1045                                         .setDate(new Date())
1046                                         .setType(resultType)
1047                                         .setLocalPath(dprop.getName() + "." + dprop.getFormat());
1048                         
1049                         Publication commPub = createDoc(aScen, mecaStep, dprop, "", false);
1050                         // The following is necessary because createDoc does not do all required work
1051                         // (and PublicationServiceImpl.createDoc() is complicated so it's harder to make it work)
1052                         commPub.setStep(mecaStep);
1053                         aScen.getDocums().add(commPub);
1054                         mecaStep.getDocuments().add(commPub);
1055                         
1056                         res = commPub.value().getIndex();
1057                         
1058                         // add attachments
1059                         if (hasAttachments) {
1060                                 // Create new "resu" file
1061                                 FileDTO resuFileDTO = createDownloadedFile(user.getIndex(), "resuFile", "resu");
1062                                 ConvertsRelation export = _publicationService.attach(commPub, "resu");
1063                                 File resuFile = new File(resuFileDTO.getPath());
1064                                 File dest = export.getTo().asFile();
1065                                 dest.delete();
1066                                 Assert.assertTrue(resuFile.renameTo(dest));
1067
1068                                 // Create new "mess" file
1069                                 FileDTO messFileDTO = createDownloadedFile(user.getIndex(), "messFile", "mess");
1070                                 export = _publicationService.attach(commPub, "mess");
1071                                 File messFile = new File(messFileDTO.getPath());
1072                                 dest = export.getTo().asFile();
1073                                 dest.delete();
1074                                 Assert.assertTrue(messFile.renameTo(dest));
1075                         }
1076                 }
1077                 
1078                 return res;
1079         }
1080         
1081         /**
1082          * Prepare a document with a file for check-in.
1083          * 
1084          * @param stepTo
1085          *            step DTO with data for check-in
1086          * @param userId
1087          *            download directory
1088          * @param stepFrom
1089          *            checked out stepDTO
1090          * @param stepsToCheckin
1091          *            DTO for check-in
1092          * @param createSource
1093          *                        whether to add the COMM file to the DTO
1094          * @param createAttachment
1095          *                        whether to add the RESU and MESS files to the DTO
1096          * @throws IOException
1097          *             if file creation failed
1098          * @return step DTO with data prepared for check-in (stepTo or new if stepTo is null)
1099          */
1100         private StepDTO createDocDTOForMeca(final long testCaseNumber,
1101                         final long targetDocId, final StepDTO stepTo,
1102                         final long userId, final StepDTO stepFrom, final List<StepDTO> stepsToCheckin,
1103                         final boolean createSource, final boolean createAttachment)
1104                         throws IOException {
1105                 StepDTO stepToCheckin = stepTo;
1106                 if (stepToCheckin == null) {
1107                         stepToCheckin = new StepDTO();
1108                 }
1109                 if ("SALOME_MECA".equals(stepFrom.getModule())) {
1110                         
1111                         stepsToCheckin.add(stepToCheckin);
1112                         stepToCheckin.setNumber(stepFrom.getNumber());
1113                         
1114                         DocumentDTO docToCheckin = stepToCheckin.addDoc(
1115                                         targetDocId, "newCommDoc");
1116                         
1117                         if(createSource) {
1118                                 docToCheckin.addFile(createDownloadedFile(
1119                                                 userId, "newCommDoc" + testCaseNumber + "_result",
1120                                                 "comm"));
1121                         }
1122                         if(createAttachment) {
1123                                 docToCheckin.addFile(createDownloadedFile(
1124                                                 userId, "newResuDoc" + testCaseNumber + "_result",
1125                                                 "resu"));
1126                                 docToCheckin.addFile(createDownloadedFile(
1127                                                 userId, "newMessDoc" + testCaseNumber + "_result",
1128                                                 "mess"));
1129                         }
1130                 }
1131                 return stepToCheckin;
1132         }
1133
1134         /**
1135          * Create a file in the user's repository downloads directory.
1136          * 
1137          * @param userId
1138          *            user id
1139          * @param name
1140          *            file name
1141          * @param format
1142          *            file extension
1143          * @return created file DTO
1144          * @throws IOException
1145          *             if file creation failed
1146          */
1147         private FileDTO createDownloadedFile(final long userId, final String name,
1148                         final String format) throws IOException {
1149                 // Create a file in the download directory
1150                 return createDownloadedFile(userId, name + "." + format);
1151         }
1152
1153         /**
1154          * Create a file in the user's repository downloads directory.
1155          * 
1156          * @param userId
1157          *            user id
1158          * @param fname
1159          *            file name
1160          * @return created file DTO
1161          * @throws IOException
1162          *             if file creation failed
1163          */
1164         private FileDTO createDownloadedFile(final long userId, final String fname)
1165                         throws IOException {
1166                 // Create a file in the download directory
1167                 String filePath = getDownloadPath(userId) + fname;
1168                 FileWriter fw = new FileWriter(filePath);
1169                 fw.write("Simulation of " + fname + " file for checkin at "
1170                                 + new Date());
1171                 fw.close();
1172                 return new FileDTO(filePath);
1173         }
1174
1175         /**
1176          * Create a persistent scenario for tests.
1177          * 
1178          * @return a persistent scenario
1179          * @throws InvalidPropertyException
1180          *             if an invalid property is used when creating objects
1181          * @throws MultiplyDefinedException
1182          *             when trying to create an object with already existing id
1183          * @throws MissedPropertyException
1184          *             if a mandatory property is not defined for an object to be created
1185          * @throws IOException
1186          *             if document creation is failed
1187          * @throws SQLException
1188          *             if project settings loading is failed
1189          */
1190         private long createScenario() throws InvalidPropertyException,
1191                         MissedPropertyException, MultiplyDefinedException, IOException,
1192                         SQLException {
1193                 // Create a scenario for tests
1194                 HibernateTemplate ht = getHibernateTemplate();
1195
1196                 Database.getInstance().reset();
1197                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1198                 // Load workflow customization
1199                 try {
1200                         _projectSettings.configure("classpath:test/som.xml");
1201                 } catch (FileNotFoundException e) {
1202                         Assert.fail("Can't find som.xml: ", e);
1203                 }
1204                 List<Step> steps = _stepsConfigService.getStepsOf(Scenario.class);
1205                 Assert.assertTrue(steps.size() > 0, "No steps are created.");
1206
1207                 // Create a test user
1208                 User.Properties uprop = new User.Properties();
1209                 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
1210                                 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
1211                                 .addRole("TST_user").setMailAddress(
1212                                                 "noreply@salome-platform.org");
1213                 uprop.disableCheck();
1214                 User anAuthor = new User(uprop);
1215                 ht.saveOrUpdate(anAuthor);
1216
1217                 // Create a test study
1218                 Study.Properties stprops = new Study.Properties().setReference(
1219                                 "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
1220                 Study aStudy = new Study(stprops);
1221                 ht.saveOrUpdate(aStudy);
1222
1223                 // Create a test scenario
1224                 Scenario.Properties sprops = new Scenario.Properties().setTitle(
1225                                 "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
1226                 Scenario aScenario = new Scenario(sprops);
1227                 aStudy.getScenariiList().add(aScenario);
1228                 ht.saveOrUpdate(anAuthor);
1229                 ht.saveOrUpdate(aStudy);
1230                 ht.saveOrUpdate(aScenario);
1231
1232                 // Create documents for each scenario step
1233                 Document.Properties dprop = new Document.Properties().setAuthor(
1234                                 anAuthor).setDate(new Date());
1235                 int i = 0;
1236                 Publication usedPub = null;
1237                 Map<Long, Long> usedMap = new HashMap<Long, Long>();
1238                 for (Step step : steps) {
1239                         LOG.debug("Create scenario step: " + i);
1240
1241                         org.splat.som.Step aScStep = new org.splat.som.Step(step, aScenario);
1242                         List<DocumentType> dtypes = _documentTypeService
1243                                         .selectTypesOf(step);
1244                         for (DocumentType dtype : dtypes) {
1245                                 // Create a document published in the scenario
1246                                 // document<i>: document type[0] - first type used on the step
1247                                 // <source-file>.brep
1248                                 // <attached-file>.med
1249                                 dprop.setName("document" + i++).setType(dtype);
1250                                 /*
1251                                  * if (step.getNumber() > 3) { dprop.setFormat("med"); } else {
1252                                  */dprop.setFormat("py");
1253                                 // }
1254                                 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
1255                                 Publication pub = createDoc(aScenario, aScStep, dprop, "med",
1256                                                 false);
1257                                 if (usedPub != null) {
1258                                         pub.addDependency(usedPub);
1259                                         ht.saveOrUpdate(pub.value());
1260
1261                                         usedMap.put(pub.getIndex(), usedPub.getIndex());
1262                                 }
1263                                 usedPub = pub;
1264
1265                                 // Create another document with outdated publication
1266                                 dprop.setName("document" + i++).setType(dtype).setFormat("py");
1267                                 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
1268                                 createDoc(aScenario, aScStep, dprop, "med", true);
1269
1270                         }
1271                         if (dtypes.size() <= 0) {
1272                                 LOG.debug("No document types are found for scenario step " + i);
1273                         }
1274                 }
1275
1276                 // Check that the scenario and its documents have been created correctly.
1277
1278                 Assert.assertNotNull(ht.find("from Document"),
1279                                 "No documents in the database.");
1280                 Assert.assertTrue(ht.find("from Document").size() > 0,
1281                                 "No documents in the database.");
1282
1283                 Assert.assertNotNull(ht.find("from Publication where owner="
1284                                 + aScenario.getIndex()), "No publications in the database.");
1285                 Assert.assertTrue(
1286                                 ht.find("from Publication where owner=" + aScenario.getIndex())
1287                                                 .size() > 0, "No publications in the database.");
1288
1289                 for (Publication p : (List<Publication>) ht
1290                                 .find("from Publication where owner=" + aScenario.getIndex())) {
1291                         LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
1292                                         + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
1293                                         + "]");
1294                         Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
1295                                         "The publication was not attached to the scenario.");
1296                 }
1297
1298                 // Remove the scenario from the current hibernate session.
1299                 ht.evict(aScenario);
1300                 // Check that the scenario is created in the database.
1301                 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
1302                 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
1303                 Assert.assertTrue(aScen.getDocums().size() > 0,
1304                                 "No publications in the scenario.");
1305
1306                 Assert.assertTrue(i > 0,
1307                                 "More then one document must be in the database");
1308
1309                 // Check created uses relations
1310                 Assert
1311                                 .assertTrue(usedMap.size() > 0,
1312                                                 "Uses relations must be created.");
1313                 boolean foundAny = false;
1314                 for (Long usingId : usedMap.keySet()) {
1315                         for (Publication pub : aScen.getDocums()) {
1316                                 if (pub.getIndex() == usingId) {
1317                                         boolean found = false;
1318                                         for (Publication used : aScen.getDocums()) {
1319                                                 found = (used.getIndex() == usedMap.get(usingId));
1320                                                 if (found) {
1321                                                         break;
1322                                                 }
1323                                         }
1324                                         Assert.assertTrue(found,
1325                                                         "Uses relation was not created in the database.");
1326                                         foundAny = foundAny || found;
1327                                 }
1328                         }
1329                 }
1330                 Assert.assertTrue(foundAny,
1331                                 "No Uses relation was created in the database.");
1332
1333                 return aScenario.getIndex();
1334         }
1335
1336         /**
1337          * Create a document published in the scenario. <BR>
1338          * document:<BR>
1339          * document type[0] - first type used on the step <BR>
1340          * &lt;source-file&gt;.brep <BR>
1341          * &lt;attached-file&gt;.med
1342          * 
1343          * @param aScenario
1344          *            the scenario to add the document to
1345          * @param aScStep
1346          *            scenario step where the document to be published
1347          * @param dprop
1348          *            document properties
1349          * @param attachedFileExt
1350          *            extension of the secon attached (exported) file
1351          * @param isOutdated
1352          *            outdated document flag
1353          * @return the publication of the created document
1354          * @throws IOException
1355          * @throws MultiplyDefinedException
1356          * @throws InvalidPropertyException
1357          * @throws MissedPropertyException
1358          */
1359         private Publication createDoc(final Scenario aScenario,
1360                         final org.splat.som.Step aScStep, final Properties dprop,
1361                         final String attachedFileExt, final boolean isOutdated)
1362                         throws MissedPropertyException, InvalidPropertyException,
1363                         MultiplyDefinedException, IOException {
1364                 // Create a document published in the scenario
1365                 // document<i>: document type[0] - first type used on the step
1366                 // <source-file>.brep
1367                 // <attached-file>.med
1368                 createDownloadedFile(aScenario.getAuthor().getIndex(), dprop
1369                                 .getLocalPath());
1370                 Publication pub = _stepService.createDocument(aScStep, dprop);
1371                 Assert.assertNotNull(pub.getOwner(),
1372                                 "The publication must be attached to the scenario.");
1373                 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
1374                                 "The publication was not attached to the scenario.");
1375
1376                 if (isOutdated) {
1377                         pub.setIsnew('O');
1378                 }
1379                 aScenario.add(pub);
1380                 HibernateTemplate ht = getHibernateTemplate();
1381                 ht.saveOrUpdate(pub);
1382
1383                 // Attach a file
1384                 createDownloadedFile(aScenario.getAuthor().getIndex(), dprop
1385                                 .getLocalPath().substring(0,
1386                                                 dprop.getLocalPath().lastIndexOf(".") - 1),
1387                                 attachedFileExt);
1388                 ht.save(pub.value());
1389                 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
1390
1391                 return pub;
1392         }
1393
1394         /**
1395          * Test study creation.<BR>
1396          * <B>Description :</B> <BR>
1397          * <i>Create a study.</i><BR>
1398          * <B>Action : </B><BR>
1399          * <i>1. call the method for a not existing product.</i><BR>
1400          * <i>2. call the method for an existing username and an existing product.</i><BR>
1401          * <i>3. call the method for a not existing username expecting an exception.</i><BR>
1402          * <B>Test data : </B><BR>
1403          * <i>no input parameters</i><BR>
1404          * 
1405          * <B>Outcome results:</B><BR>
1406          * <i>
1407          * <ul>
1408          * <li>1: The new study must be created. The new product simulation context must be created.</li>
1409          * <li>2: The new study must be created.</li>
1410          * <li>3: The new study must not be created. Exception must be thrown.</li>
1411          * </ul>
1412          * </i>
1413          * 
1414          * @throws IOException
1415          *             if application configuration loading is failed
1416          * @throws SQLException
1417          *             if application configuration loading is failed
1418          * @throws BusinessException
1419          *             if test data creation is failed
1420          */
1421         @Test(groups = { "study", "sevice", "functional", "business" })
1422         public void testCreateStudy() throws BusinessException, IOException,
1423                         SQLException {
1424                 LOG.debug(">>>>> BEGIN testCreateStudy()");
1425                 startNestedTransaction();
1426
1427                 Database.getInstance().reset();
1428                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1429                 _projectSettings.configure("classpath:test/som.xml");
1430
1431                 // Create a test user
1432                 User.Properties uprop = new User.Properties();
1433                 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
1434                                 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
1435                                 .addRole("TST_user").setMailAddress(
1436                                                 "noreply@salome-platform.org");
1437                 uprop.disableCheck();
1438                 User anAuthor = new User(uprop);
1439
1440                 getHibernateTemplate().saveOrUpdate(anAuthor);
1441                 KnowledgeElementType ucase = _knowledgeElementTypeService
1442                                 .selectType("usecase");
1443                 Assert.assertNotNull(ucase,
1444                                 "Knowledge type 'usecase' must be created in the database.");
1445                 SimulationContextType prodtype = _simulationContextService
1446                                 .selectType("product");
1447                 Assert
1448                                 .assertNotNull(prodtype,
1449                                                 "Simulation context type 'product' must be created in the database.");
1450
1451                 // Create admin
1452                 uprop.clear();
1453                 uprop.setUsername("TST_Admin").setName("TST_SimanUnitTestsAdmin")
1454                                 .setFirstName("TST_AdminFirstName").setDisplayName(
1455                                                 "TST_test.admin").addRole("TST_user,sysadmin")
1456                                 .setMailAddress("noreply@salome-platform.org");
1457                 uprop.disableCheck();
1458
1459                 getHibernateTemplate().saveOrUpdate(new User(uprop));
1460                 getHibernateTemplate().flush();
1461
1462                 Study.Properties sprop = new Study.Properties();
1463                 sprop.setTitle("Test study creation").setManager(anAuthor);
1464                 Scenario.Properties oprop = new Scenario.Properties();
1465                 oprop.setTitle("Test scenario for the created study");
1466
1467                 // Addition of the entered project context
1468                 SimulationContext.Properties cprop = new SimulationContext.Properties();
1469                 // Input of new project context
1470                 cprop.setType(_simulationContextService.selectType("product"))
1471                                 .setValue("Test Simulation Context: Product");
1472                 Study study = _scenarioService.createStudy(sprop, oprop, cprop);
1473
1474                 Assert.assertNotNull(study);
1475                 Assert.assertTrue(study.getIndex() > 0);
1476
1477                 rollbackNestedTransaction();
1478                 LOG.debug(">>>>> END testCreateStudy()");
1479         }
1480
1481         /**
1482          * Test study creation.<BR>
1483          * <B>Description :</B> <BR>
1484          * <i>Create a study.</i><BR>
1485          * <B>Action : </B><BR>
1486          * <i>1. call the method for a not existing product.</i><BR>
1487          * <i>2. call the method for an existing username and an existing product.</i><BR>
1488          * <i>3. call the method for a not existing username expecting an exception.</i><BR>
1489          * <B>Test data : </B><BR>
1490          * <i>no input parameters</i><BR>
1491          * 
1492          * <B>Outcome results:</B><BR>
1493          * <i>
1494          * <ul>
1495          * <li>1: The new study must be created. The new product simulation context must be created.</li>
1496          * <li>2: The new study must be created.</li>
1497          * <li>3: The new study must not be created. Exception must be thrown.</li>
1498          * </ul>
1499          * </i>
1500          * 
1501          * @throws IOException
1502          *             if application configuration loading is failed
1503          * @throws SQLException
1504          *             if application configuration loading is failed
1505          * @throws BusinessException
1506          *             if test data creation is failed
1507          */
1508         @Test(groups = { "study", "sevice", "functional", "business" })
1509         public void testCreateStudyFromPython() throws IOException, SQLException,
1510                         BusinessException {
1511                 LOG.debug(">>>>> BEGIN testCreateStudyFromPython()");
1512                 startNestedTransaction();
1513
1514                 HibernateTemplate ht = getHibernateTemplate();
1515
1516                 Database.getInstance().reset();
1517                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1518                 _projectSettings.configure("classpath:test/som.xml");
1519
1520                 // Create a test user
1521                 User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
1522                 _userDAO.create(goodUser);
1523                 SimulationContextType prodtype = _simulationContextService
1524                                 .selectType("product");
1525                 Assert
1526                                 .assertNotNull(prodtype,
1527                                                 "Simulation context type 'product' must be created in the database.");
1528
1529                 String productName = "New Test Product " + new Date().toString();
1530
1531                 ht.flush();
1532                 ht.clear();
1533                 long studyId1 = _scenarioService.createStudy("goodUser",
1534                                 "Test Study 1", productName, "Test description");
1535                 Assert.assertTrue(studyId1 > 0);
1536
1537                 ht.flush();
1538                 ht.clear();
1539                 try {
1540                         _scenarioService.createStudy("badbadUser", "Test Study 2",
1541                                         productName, "Test description");
1542                         Assert.fail("Study must not be created for not existing user.");
1543                 } catch (InvalidPropertyException ipe) {
1544                         LOG.debug("Expected exception: " + ipe.getMessage());
1545                 }
1546
1547                 ht.flush();
1548                 ht.clear();
1549                 long studyId3 = _scenarioService.createStudy("goodUser",
1550                                 "Test Study 3", productName, "Test description");
1551                 Assert.assertTrue(studyId3 > 0);
1552
1553                 // Check that the simulation context is the same
1554                 Study study1 = _studyService.selectStudy(studyId1);
1555                 Study study3 = _studyService.selectStudy(studyId3);
1556                 Assert.assertEquals(study1.SimulationContextIterator().next(), study3
1557                                 .SimulationContextIterator().next());
1558
1559                 // Check the title of the created scenario
1560                 String scTitle = study1.getScenarii()[0].getTitle();
1561                 Assert.assertEquals(scTitle, I18nUtils
1562                                 .getMessageLocaleDefault("label.scenario")
1563                                 + " 1");
1564                 Assert.assertFalse(scTitle.equals("label.scenario 1"));
1565
1566                 rollbackNestedTransaction();
1567                 LOG.debug(">>>>> END testCreateStudyFromPython()");
1568         }
1569
1570         /**
1571          * Test study content copy.<BR>
1572          * <B>Description :</B> <BR>
1573          * <i>Create a study.</i><BR>
1574          * <B>Action : </B><BR>
1575          * <i>1. call the method for a not existing source study.</i><BR>
1576          * <i>2. call the method for a not existing source scenario with not evolving step.</i><BR>
1577          * <i>3. call the method for a not existing source scenario with evolving step.</i><BR>
1578          * <i>4. call the method for an existing source scenario with evolving step.</i><BR>
1579          * <B>Test data : </B><BR>
1580          * <i>no input parameters</i><BR>
1581          * 
1582          * <B>Outcome results:</B><BR>
1583          * <i>
1584          * <ul>
1585          * <li>1: Exception must be thrown.</li>
1586          * <li>2: The study content must be copied.</li>
1587          * <li>3: Exception must be thrown.</li>
1588          * <li>4: The study content must be copied.</li>
1589          * </ul>
1590          * </i>
1591          * 
1592          * @throws IOException
1593          *             if application configuration loading is failed
1594          * @throws SQLException
1595          *             if application configuration loading is failed
1596          * @throws BusinessException
1597          *             if test data creation is failed
1598          */
1599         @Test(groups = { "study", "sevice", "functional", "business" })
1600         public void testCopyStudyContent() throws IOException, SQLException,
1601                         BusinessException {
1602                 LOG.debug(">>>>> BEGIN testCopyStudyContent()");
1603                 startNestedTransaction();
1604
1605                 HibernateTemplate ht = getHibernateTemplate();
1606
1607                 Database.getInstance().reset();
1608                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1609                 _projectSettings.configure("classpath:test/som.xml");
1610
1611                 User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
1612                 _userDAO.create(goodUser);
1613                 User otherUser = TestEntitiesGenerator.getTestUser("otherUser");
1614                 _userDAO.create(otherUser);
1615
1616                 // Create private study
1617                 Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
1618                 aStudy.setTitle("0.This is private study");
1619                 Long studyId = _studyDAO.create(aStudy);
1620
1621                 // Add a scenario to the study
1622                 Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
1623                 _scenarioDAO.create(scen);
1624                 ht.flush();
1625                 // Add a second scenario to the study
1626                 scen = TestEntitiesGenerator.getTestScenario(aStudy);
1627                 Long aScenId = _scenarioDAO.create(scen);
1628                 ht.flush();
1629
1630                 // Add a validation cycle with otherUser as a reviewer
1631                 ValidationCycle.Properties vprop = new ValidationCycle.Properties();
1632                 DocumentType dtype = _documentTypeService.selectType("minutes");
1633                 vprop.setDocumentType(dtype);
1634                 vprop.setActor(ValidationStep.REVIEW, otherUser);
1635                 ValidationCycle cycle = new ValidationCycle(aStudy, vprop);
1636                 _validationCycleDAO.create(cycle);
1637                 ValidationCycleRelation link = cycle.getContext();
1638                 aStudy.addRelation(link);
1639                 ht.flush();
1640
1641                 // Add documents to the first study activity
1642                 // Add a converts relations
1643                 Map<Integer, org.splat.som.Step> stSteps = _projectElementService
1644                                 .getStepsMap(aStudy);
1645                 org.splat.som.Step aStep = stSteps.get(1);
1646                 Publication pub1 = addDoc(aStudy, aStep, "document1", dtype);
1647                 Publication pub2 = addDoc(aStudy, aStep, "document2", dtype);
1648                 Publication pub3 = addDoc(aStudy, aStep, "document3", dtype);
1649                 ht.flush();
1650
1651                 LOG.debug("pub1 version doc: " + pub1.value().getTitle() + " ["
1652                                 + pub1.value().getReference() + "]" + " ["
1653                                 + pub1.value().getRid() + "]");
1654                 LOG.debug("pub2 version doc: " + pub2.value().getTitle() + " ["
1655                                 + pub2.value().getReference() + "]" + " ["
1656                                 + pub2.value().getRid() + "]");
1657                 LOG.debug("pub3 version doc: " + pub3.value().getTitle() + " ["
1658                                 + pub3.value().getReference() + "]" + " ["
1659                                 + pub3.value().getRid() + "]");
1660
1661                 ht.update(aStudy);
1662
1663                 ht.flush();
1664                 LOG.debug("Before versioning:");
1665                 for (Publication doc : _projectElementService.getFirstStep(aStudy)
1666                                 .getAllDocuments()) {
1667                         LOG.debug("Study doc: " + doc.value().getTitle() + " ["
1668                                         + doc.value().getReference() + "]" + " ["
1669                                         + doc.value().getRid() + "]");
1670                 }
1671                 // Add a version relations
1672                 Publication pub31 = version(pub3);
1673                 ht.flush();
1674                 //
1675                 // LOG.debug("pub31 version doc: " + pub31.value().getTitle() + " ["
1676                 // + pub31.value().getReference() + "]" + " ["
1677                 // + pub31.value().getRid() + "]");
1678                 // ht.saveOrUpdate(aStudy);
1679
1680                 // LOG.debug("After versioning:");
1681                 // for (Publication doc : aStudy.getDocums()) {
1682                 // LOG.debug("Study doc: " + doc.value().getTitle() + " ["
1683                 // + doc.value().getReference() + "]" + " ["
1684                 // + doc.value().getRid() + "]");
1685                 // }
1686
1687                 // Add documents to the first scenario activity
1688                 Map<Integer, org.splat.som.Step> scSteps = _projectElementService
1689                                 .getStepsMap(scen);
1690                 aStep = scSteps.get(2);
1691                 Publication spub1 = addDoc(scen, aStep, "sdocument1", dtype);
1692                 Publication spub2 = addDoc(scen, aStep, "sdocument2", dtype);
1693                 Publication spub3 = addDoc(scen, aStep, "sdocument3", dtype);
1694                 LOG.debug("spub1 version doc: " + spub1.value().getTitle() + " ["
1695                                 + spub1.value().getReference() + "]" + " ["
1696                                 + spub1.value().getRid() + "]");
1697                 LOG.debug("spub2 version doc: " + spub2.value().getTitle() + " ["
1698                                 + spub2.value().getReference() + "]" + " ["
1699                                 + spub2.value().getRid() + "]");
1700                 LOG.debug("spub3 version doc: " + spub3.value().getTitle() + " ["
1701                                 + spub3.value().getReference() + "]" + " ["
1702                                 + spub3.value().getRid() + "]");
1703                 ht.flush();
1704
1705                 // Create a scenario document version
1706                 Publication spub31 = version(spub3);
1707                 // LOG.debug("spub31 version doc: " + spub31.value().getTitle() + " ["
1708                 // + spub31.value().getReference() + "]" + " ["
1709                 // + spub31.value().getRid() + "]");
1710                 ht.flush();
1711
1712                 // Add uses relations
1713                 pub2.addDependency(pub1);
1714                 ht.saveOrUpdate(pub2.value());
1715                 pub3.addDependency(pub2);
1716                 ht.saveOrUpdate(pub3.value());
1717
1718                 spub2.addDependency(pub1);
1719                 spub2.addDependency(spub1);
1720                 spub2.addDependency(pub2);
1721                 spub2.addDependency(pub3);
1722                 ht.saveOrUpdate(spub2.value());
1723                 spub3.addDependency(spub2);
1724                 ht.saveOrUpdate(spub3.value());
1725                 spub31.addDependency(pub31);
1726                 ht.saveOrUpdate(spub31.value());
1727                 ht.flush();
1728
1729                 // Create target study1
1730                 Study aStudy1 = TestEntitiesGenerator.getTestStudy(goodUser);
1731                 aStudy1.setTitle("1.This is a target study1");
1732                 aStudy1.setReference("tst1");
1733                 Long studyId1 = _studyDAO.create(aStudy1);
1734
1735                 // Add a scenario to the study
1736                 Scenario scen1 = TestEntitiesGenerator.getTestScenario(aStudy1);
1737                 _scenarioDAO.create(scen1);
1738                 ht.flush();
1739
1740                 // Create target study2
1741                 Study aStudy2 = TestEntitiesGenerator.getTestStudy(goodUser);
1742                 aStudy2.setTitle("2.This is a target study2");
1743                 aStudy2.setReference("tst2");
1744                 Long studyId2 = _studyDAO.create(aStudy2);
1745
1746                 // Add a scenario to the study
1747                 Scenario scen2 = TestEntitiesGenerator.getTestScenario(aStudy2);
1748                 _scenarioDAO.create(scen2);
1749                 ht.flush();
1750                 ht.clear();
1751
1752                 // //////////////////// TEST CALL /////////////////////////////////////
1753                 // 1. call the method for a not existing source study.
1754                 try {
1755                         _scenarioService.copyStudyContent(-1, -1, -1, -1);
1756                         Assert.fail("Exception must be thrown for not existing study id.");
1757                 } catch (InvalidParameterException e) {
1758                         LOG.debug("Expected exception: " + e.getClass().getSimpleName()
1759                                         + ": " + e.getMessage());
1760                 }
1761
1762                 ht.flush();
1763                 ht.clear();
1764
1765                 // 2. call the method for a not existing source scenario with not evolving step.
1766                 _scenarioService.copyStudyContent(studyId, -1, 1, studyId1);
1767
1768                 ht.flush();
1769                 ht.clear();
1770
1771                 aStudy = _studyService.selectStudy(studyId);
1772                 aStudy1 = _studyService.selectStudy(studyId1);
1773                 for (Publication pub : aStudy.getDocums()) {
1774                         // Find the same document in the created copy of the study
1775                         Publication found = null;
1776                         for (Publication newPub : aStudy1.getDocums()) {
1777                                 if (pub.value().getTitle().equals(newPub.value().getTitle())
1778                                                 && pub.value().getType().equals(
1779                                                                 newPub.value().getType())) {
1780                                         found = newPub;
1781                                         break;
1782                                 }
1783                         }
1784                         Assert.assertNotNull(found, "The document "
1785                                         + pub.value().getTitle() + "is not copied");
1786                         // Check that all files are copied (source and attached)
1787                 }
1788
1789                 // 3. call the method for a not existing source scenario with evolving step.
1790                 try {
1791                         _scenarioService.copyStudyContent(studyId, -1, 2, studyId2);
1792                         Assert
1793                                         .fail("Exception must be thrown for not existing scenario id and evolving step.");
1794                 } catch (InvalidParameterException e) {
1795                         LOG.debug("Expected exception: " + e.getClass().getSimpleName()
1796                                         + ": " + e.getMessage());
1797                 }
1798
1799                 ht.flush();
1800                 ht.clear();
1801
1802                 // 4. call the method for an existing source scenario with evolving step.
1803                 _scenarioService.copyStudyContent(studyId, aScenId, 9, studyId2);
1804                 ht.flush();
1805
1806                 rollbackNestedTransaction();
1807                 LOG.debug(">>>>> END testCopyStudyContent()");
1808         }
1809
1810         /**
1811          * Test assigning a simulation context to a study.<BR>
1812          * <B>Description :</B> <BR>
1813          * <i>Create a study and assign a simulation context to it.</i><BR>
1814          * <B>Action : </B><BR>
1815          * <i>1. call the method for not existing study id.</i><BR>
1816          * <i>2. call the method for not existing context type and context value.</i><BR>
1817          * <i>3. call the method for existing context type and context value.</i><BR>
1818          * <i>4. call the method for existing context type and not existing context value.</i><BR>
1819          * <i>5. call the method for empty context type.</i><BR>
1820          * <i>6. call the method for empty context value.</i><BR>
1821          * <B>Test data : </B><BR>
1822          * <i>no input parameters</i><BR>
1823          * 
1824          * <B>Outcome results:</B><BR>
1825          * <i>
1826          * <ul>
1827          * <li>1: Exception must be thrown.</li>
1828          * <li>2: The new context type and value must be created. The new context must be assigned to the study first step.</li>
1829          * <li>3: The existing context must be assigned to the study first step.</li>
1830          * <li>4: The new context value must be created. The new context must be assigned to the study first step.</li>
1831          * <li>5: Exception must be thrown.</li>
1832          * <li>6: Exception must be thrown.</li>
1833          * </ul>
1834          * </i>
1835          * 
1836          * @throws IOException
1837          *             if application configuration loading is failed
1838          * @throws SQLException
1839          *             if application configuration loading is failed
1840          * @throws BusinessException
1841          *             if test data creation is failed
1842          */
1843         @Test(groups = { "study", "sevice", "functional", "business" })
1844         public void testAssignStudyContextFromPython() throws IOException,
1845                         SQLException, BusinessException {
1846                 LOG.debug(">>>>> BEGIN testAssignStudyContextFromPython()");
1847                 startNestedTransaction();
1848
1849                 HibernateTemplate ht = getHibernateTemplate();
1850
1851                 Database.getInstance().reset();
1852                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1853                 _projectSettings.configure("classpath:test/som.xml");
1854
1855                 // Create a test user
1856                 User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
1857                 _userDAO.create(goodUser);
1858                 SimulationContextType prodtype = _simulationContextService
1859                                 .selectType("product");
1860                 Assert
1861                                 .assertNotNull(prodtype,
1862                                                 "Simulation context type 'product' must be created in the database.");
1863
1864                 String productName = "New Test Product " + new Date().toString();
1865
1866                 ht.flush();
1867                 ht.clear();
1868                 long studyId1 = _scenarioService.createStudy("goodUser",
1869                                 "Test Study 1", productName, "Test description");
1870                 Assert.assertTrue(studyId1 > 0);
1871
1872                 ht.flush();
1873                 ht.clear();
1874
1875                 // //////// START OF TESTS
1876                 // 1. call the method for not existing study id.</i><BR>
1877                 try {
1878                         _scenarioService.assignStudyContext(-1L, "new context type",
1879                                         "new context value");
1880                         Assert.fail("Not existing study must not be found.");
1881                 } catch (InvalidPropertyException ipe) {
1882                         LOG.debug("Expected exception: " + ipe.getMessage());
1883                 }
1884
1885                 // 2. call the method for not existing context type and context value.</i><BR>
1886                 _scenarioService.assignStudyContext(studyId1, "new context type",
1887                                 "new context value");
1888
1889                 ht.flush();
1890                 ht.clear();
1891
1892                 // Check the assigned simulation context
1893                 checkCtx(studyId1, "new context type", "new context value");
1894
1895                 // 3. call the method for existing context type and context value.</i><BR>
1896                 _scenarioService.assignStudyContext(studyId1, "new context type",
1897                                 "new context value");
1898
1899                 ht.flush();
1900                 ht.clear();
1901
1902                 // Check the assigned simulation context
1903                 checkCtx(studyId1, "new context type", "new context value");
1904
1905                 // 4. call the method for existing context type and not existing context value.</i><BR>
1906                 _scenarioService.assignStudyContext(studyId1, "new context type",
1907                                 "new context value1");
1908
1909                 ht.flush();
1910                 ht.clear();
1911
1912                 // Check the assigned simulation context
1913                 checkCtx(studyId1, "new context type", "new context value1");
1914
1915                 // 5. call the method for empty context type.</i><BR>
1916                 try {
1917                         _scenarioService.assignStudyContext(studyId1, "",
1918                                         "new context value");
1919                         Assert.fail("Empty context type name must be forbidden.");
1920                 } catch (InvalidPropertyException ipe) {
1921                         LOG.debug("Expected exception: " + ipe.getMessage());
1922                 }
1923                 // 6. call the method for empty context value.</i><BR>
1924                 try {
1925                         _scenarioService.assignStudyContext(studyId1, "new context type",
1926                                         "");
1927                         Assert.fail("Empty context value must be forbidden.");
1928                 } catch (InvalidPropertyException ipe) {
1929                         LOG.debug("Expected exception: " + ipe.getMessage());
1930                 }
1931
1932                 rollbackNestedTransaction();
1933                 LOG.debug(">>>>> END testAssignStudyContextFromPython()");
1934         }
1935
1936         /**
1937          * Test getting a study scenarios DTO list.<BR>
1938          * <B>Description :</B> <BR>
1939          * <i>Create a study and get its scenarios DTO list.</i><BR>
1940          * <B>Action : </B><BR>
1941          * <i>1. call the method for not existing study id.</i><BR>
1942          * <i>2. call the method for a study with one scenario.</i><BR>
1943          * <i>3. call the method for a study with several scenarios.</i><BR>
1944          * <B>Test data : </B><BR>
1945          * <i>no input parameters</i><BR>
1946          * 
1947          * <B>Outcome results:</B><BR>
1948          * <i>
1949          * <ul>
1950          * <li>1: The returned list of DTO must be empty.</li>
1951          * <li>2: The returned list of DTO must contain one scenario DTO.</li>
1952          * <li>3: The returned list of DTO must contain several scenario DTOs.</li>
1953          * </ul>
1954          * </i>
1955          * 
1956          * @throws IOException
1957          *             if application configuration loading is failed
1958          * @throws SQLException
1959          *             if application configuration loading is failed
1960          * @throws BusinessException
1961          *             if test data creation is failed
1962          */
1963         @Test(groups = { "study", "sevice", "functional", "business" })
1964         public void testGetStudyScenarios() throws IOException, SQLException,
1965                         BusinessException {
1966                 LOG.debug(">>>>> BEGIN testGetStudyScenarios()");
1967                 startNestedTransaction();
1968
1969                 HibernateTemplate ht = getHibernateTemplate();
1970
1971                 Database.getInstance().reset();
1972                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1973                 _projectSettings.configure("classpath:test/som.xml");
1974
1975                 // Create a test user
1976                 User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
1977                 _userDAO.create(goodUser);
1978                 Study study = TestEntitiesGenerator.getTestStudy(goodUser);
1979                 long studyId1 = _studyDAO.create(study);
1980                 ht.flush();
1981                 Scenario scen = TestEntitiesGenerator.getTestScenario(study,
1982                                 "test scen11");
1983                 long id11 = _scenarioDAO.create(scen);
1984                 ht.flush();
1985                 study = TestEntitiesGenerator.getTestStudy(goodUser);
1986                 long studyId2 = _studyDAO.create(study);
1987                 ht.flush();
1988                 scen = TestEntitiesGenerator.getTestScenario(study, "test scen21");
1989                 long id21 = _scenarioDAO.create(scen);
1990                 ht.flush();
1991                 scen = TestEntitiesGenerator.getTestScenario(study, "test scen22");
1992                 long id22 = _scenarioDAO.create(scen);
1993                 ht.flush();
1994                 scen = TestEntitiesGenerator.getTestScenario(study, "test scen23");
1995                 long id23 = _scenarioDAO.create(scen);
1996                 ht.flush();
1997                 ht.clear();
1998
1999                 // //////// START OF TESTS
2000                 // 1. call the method for not existing study id.
2001                 List<ScenarioDTO> scens = _scenarioService.getStudyScenarios(-1L);
2002
2003                 Assert.assertNotNull(scens);
2004                 Assert.assertTrue(scens.isEmpty());
2005
2006                 // 2. call the method for a study with one scenario.
2007                 scens = _scenarioService.getStudyScenarios(studyId1);
2008
2009                 ht.flush();
2010                 ht.clear();
2011                 Assert.assertNotNull(scens);
2012                 Assert.assertEquals(scens.size(), 1);
2013                 Assert.assertEquals(scens.get(0).getIndex().longValue(), id11);
2014                 Assert.assertEquals(scens.get(0).getTitle(), "test scen11");
2015
2016                 // 3. call the method for a study with several scenarios.
2017                 scens = _scenarioService.getStudyScenarios(studyId2);
2018                 Assert.assertEquals(scens.size(), 3);
2019                 Assert.assertEquals(scens.get(0).getIndex().longValue(), id21);
2020                 Assert.assertEquals(scens.get(0).getTitle(), "test scen21");
2021                 Assert.assertEquals(scens.get(1).getIndex().longValue(), id22);
2022                 Assert.assertEquals(scens.get(1).getTitle(), "test scen22");
2023                 Assert.assertEquals(scens.get(2).getIndex().longValue(), id23);
2024                 Assert.assertEquals(scens.get(2).getTitle(), "test scen23");
2025
2026                 ht.flush();
2027                 ht.clear();
2028
2029                 rollbackNestedTransaction();
2030                 LOG.debug(">>>>> END testGetStudyScenarios()");
2031         }
2032
2033         /**
2034          * Check if the context is assigned to the study.
2035          * 
2036          * @param studyId1
2037          *            the study id
2038          * @param ctxType
2039          *            the context type name
2040          * @param ctxValue
2041          *            the context value
2042          */
2043         private void checkCtx(final long studyId1, final String ctxType,
2044                         final String ctxValue) {
2045                 // Check the assigned simulation context
2046                 Study study1 = _studyService.selectStudy(studyId1);
2047                 Iterator<SimulationContext> it = study1.SimulationContextIterator();
2048                 SimulationContext ctx;
2049                 boolean isFound = false;
2050                 while ((!isFound) && it.hasNext()) {
2051                         ctx = it.next();
2052                         isFound = ctx.getType().getName().equals(ctxType)
2053                                         && ctx.getValue().equals(ctxValue);
2054                 }
2055                 Assert.assertTrue(isFound, "Context must be assigned to the study.");
2056         }
2057 }