]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/Siman-Common/src/test/splat/service/TestScenarioService.java
Salome HOME
Added test of checkin with empty list of steps.
[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.List;
20 import java.util.Map;
21 import java.util.Set;
22
23 import org.splat.dal.bo.kernel.Relation;
24 import org.splat.dal.bo.kernel.User;
25 import org.splat.dal.bo.som.Document;
26 import org.splat.dal.bo.som.DocumentType;
27 import org.splat.dal.bo.som.KnowledgeElementType;
28 import org.splat.dal.bo.som.Publication;
29 import org.splat.dal.bo.som.Scenario;
30 import org.splat.dal.bo.som.SimulationContext;
31 import org.splat.dal.bo.som.SimulationContextType;
32 import org.splat.dal.bo.som.Study;
33 import org.splat.dal.bo.som.UsedByRelation;
34 import org.splat.dal.bo.som.UsesRelation;
35 import org.splat.dal.bo.som.Document.Properties;
36 import org.splat.dal.dao.som.Database;
37 import org.splat.dal.dao.som.ScenarioDAO;
38 import org.splat.kernel.InvalidPropertyException;
39 import org.splat.kernel.MismatchException;
40 import org.splat.kernel.MissedPropertyException;
41 import org.splat.kernel.MultiplyDefinedException;
42 import org.splat.kernel.NotApplicableException;
43 import org.splat.log.AppLogger;
44 import org.splat.service.DocumentTypeService;
45 import org.splat.service.KnowledgeElementTypeService;
46 import org.splat.service.PublicationService;
47 import org.splat.service.ScenarioService;
48 import org.splat.service.SimulationContextService;
49 import org.splat.service.StepService;
50 import org.splat.service.dto.DocumentDTO;
51 import org.splat.service.dto.FileDTO;
52 import org.splat.service.dto.StepDTO;
53 import org.splat.service.technical.ProjectSettingsService;
54 import org.splat.service.technical.RepositoryService;
55 import org.splat.service.technical.ProjectSettingsService.Step;
56 import org.springframework.beans.factory.annotation.Autowired;
57 import org.springframework.beans.factory.annotation.Qualifier;
58 import org.springframework.orm.hibernate3.HibernateTemplate;
59 import org.testng.Assert;
60 import org.testng.annotations.Test;
61 import org.testng.reporters.Files;
62
63 import test.splat.common.BaseTest;
64
65 /**
66  * Test class for KnowledgeElementDAO.
67  * 
68  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
69  * 
70  */
71 public class TestScenarioService extends BaseTest {
72
73         /**
74          * Logger for the class.
75          */
76         private static final AppLogger LOG = AppLogger
77                         .getLogger(TestScenarioService.class);
78
79         /**
80          * The tested ScenarioService. Later injected by Spring.
81          */
82         @Autowired
83         @Qualifier("scenarioService")
84         private transient ScenarioService _scenarioService;
85
86         /**
87          * The RepositoryService. Later injected by Spring.
88          */
89         @Autowired
90         @Qualifier("repositoryService")
91         private transient RepositoryService _repositoryService;
92
93         /**
94          * The Scenario DAO. Later injected by Spring.
95          */
96         @Autowired
97         @Qualifier("scenarioDAO")
98         private transient ScenarioDAO _scenarioDAO;
99
100         /**
101          * The PublicationService. Later injected by Spring.
102          */
103         @Autowired
104         @Qualifier("publicationService")
105         private transient PublicationService _publicationService;
106
107         /**
108          * The StepService. Later injected by Spring.
109          */
110         @Autowired
111         @Qualifier("stepService")
112         private transient StepService _stepService;
113
114         /**
115          * The SimulationContextService. Later injected by Spring.
116          */
117         @Autowired
118         @Qualifier("simulationContextService")
119         private transient SimulationContextService _simulationContextService;
120
121         /**
122          * The ProjectSettingsService. Later injected by Spring.
123          */
124         @Autowired
125         @Qualifier("projectSettings")
126         private transient ProjectSettingsService _projectSettings;
127
128         /**
129          * The DocumentTypeService. Later injected by Spring.
130          */
131         @Autowired
132         @Qualifier("documentTypeService")
133         private transient DocumentTypeService _documentTypeService;
134
135         /**
136          * The KnowledgeElementTypeService. Later injected by Spring.
137          */
138         @Autowired
139         @Qualifier("knowledgeElementTypeService")
140         private transient KnowledgeElementTypeService _knowledgeElementTypeService;
141
142         /**
143          * Test of getting a scenario content for building siman-salome.conf.<BR>
144          * <B>Description :</B> <BR>
145          * <i>Create a scenario and try to get an info for it.</i><BR>
146          * <B>Action : </B><BR>
147          * <i>1. call the method for an existing scenario id.</i><BR>
148          * <i>2. call the method for a not existing scenario id.</i><BR>
149          * <B>Test data : </B><BR>
150          * <i>no input parameters</i><BR>
151          * <i>no input parameters</i><BR>
152          * 
153          * <B>Outcome results:</B><BR>
154          * <i>
155          * <ul>
156          * <li>result DTO must contain list of all documents and files<BR>
157          * </li>
158          * <li>Exception is thrown<BR>
159          * </li>
160          * </ul>
161          * </i>
162          * 
163          * @throws InvalidPropertyException
164          *             if an invalid property is used when creating objects
165          * @throws MultiplyDefinedException
166          *             when trying to create an object with already existing id
167          * @throws MissedPropertyException
168          *             if a mandatory property is not defined for an object to be created
169          * @throws IOException
170          *             if scenario creation is failed
171          * @throws SQLException
172          *             if scenario creation is failed
173          */
174         @Test(groups = { "checkout", "sevice", "functional", "business" })
175         public void testGetScenarioInfo() throws InvalidPropertyException,
176                         MissedPropertyException, MultiplyDefinedException, IOException,
177                         SQLException {
178                 LOG.debug(">>>>> BEGIN testGetScenarioInfo()");
179                 startNestedTransaction();
180
181                 long scenarioId = createScenario();
182                 // Call DAO's create method for a good transient knowledge element.
183                 List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
184                 Assert.assertNotNull(steps, "List of steps must not be null.");
185                 Assert.assertTrue(steps.size() > 0, "No steps are read.");
186
187                 List<Step> projSteps = _projectSettings.getStepsOf(Scenario.class);
188                 Assert.assertEquals(steps.size(), projSteps.size(),
189                                 "Not all steps are listed.");
190                 int docIndex = 0;
191                 for (StepDTO step : steps) {
192                         LOG.debug("check the step " + step.getNumber() + ":\n" + step);
193                         Assert.assertNotNull(step, "Step DTO must not be null.");
194                         Assert.assertNotNull(step.getKey(), "Step name must not be null.");
195                         Assert.assertFalse(step.getKey().isEmpty(),
196                                         "Step name must not empty.");
197                         Assert.assertTrue(step.getNumber() > 0,
198                                         "Step number must be positive integer.");
199                         Assert.assertNotNull(step.getDocs(),
200                                         "Step documents list must not be null.");
201
202                         Step aProjStep = null;
203                         for (Step projStep : projSteps) {
204                                 if (projStep.getNumber() == step.getNumber()) {
205                                         aProjStep = projStep;
206                                         break;
207                                 }
208                         }
209
210                         List<DocumentType> dtypes = _documentTypeService
211                                         .selectTypesOf(aProjStep);
212                         for (DocumentType dtype : dtypes) {
213                                 Assert.assertTrue(step.getDocs().size() > 0,
214                                                 "Step documents list must not be empty.");
215                                 String docName = "document" + docIndex;
216                                 for (DocumentDTO doc : step.getDocs()) {
217                                         if (docName.equals(doc.getTitle())) {
218                                                 Assert.assertTrue(doc.getId() > 0,
219                                                                 "Document id must be positive integer.");
220                                                 Assert.assertEquals(doc.getTitle(), docName);
221                                                 Assert.assertNotNull(doc.getFiles(),
222                                                                 "Document files list must not be null.");
223                                                 Assert.assertTrue(doc.getFiles().size() > 1,
224                                                                 "Document must have more then 1 attached file.");
225
226                                                 for (FileDTO file : doc.getFiles()) {
227                                                         Assert.assertNotNull(file.getPath(),
228                                                                         "File path must not be null.");
229                                                         Assert.assertFalse(file.getPath().isEmpty(),
230                                                                         "File path must not be empty.");
231                                                         /*
232                                                          * <mappings> <document type="geometry"> <import format="brep"/> <!-- Result Shape --> </document> <document
233                                                          * type="model"> <import format="med"/> <!-- Result mesh without input parameters --> </document> <document
234                                                          * type="loads"> <import format="c3m"/> <!-- Input data created interactively --> </document> <document
235                                                          * type="results"> <import format="med"/> <!-- Calculation results source file --> </document> </mappings>
236                                                          */
237                                                         // Check state and processing instruction
238                                                         String fileFormat = file.getPath().substring(
239                                                                         file.getPath().lastIndexOf('.') + 1);
240                                                         /*
241                                                          * if (_projectSettings.doImport(dtype.getName(), fileFormat)) { Assert.assertTrue(file.isResult(), "The file
242                                                          * must be a result file."); } else { Assert.assertFalse(file.isResult(), "The file must be a source file."); }
243                                                          */if ((docIndex % 2) == 0) { // New
244                                                                 Assert.assertEquals(file.getState(), 'Y',
245                                                                                 "File state must be actual ('Y').");
246                                                                 if (_projectSettings.doImport(dtype.getName(),
247                                                                                 fileFormat)) {
248                                                                         Assert.assertEquals(file.getProcessing(),
249                                                                                         "file-import",
250                                                                                         "File must be imported.");
251                                                                 } else {
252                                                                         Assert.assertEquals(file.getProcessing(),
253                                                                                         "file-download",
254                                                                                         "File must be downloaded.");
255                                                                 }
256                                                         } else { // Outdated
257                                                                 Assert.assertEquals(file.getState(), 'O',
258                                                                                 "File state must be outdated ('O').");
259                                                                 Assert.assertEquals(file.getProcessing(),
260                                                                                 "file-download",
261                                                                                 "Outdated document should not be imported but downloaded.");
262                                                         }
263                                                 }
264                                         }
265                                 }
266                                 docIndex++;
267                         }
268                 }
269
270                 // Call DAO's get method for a not existing id.
271                 try {
272                         steps = _scenarioService.getScenarioInfo(-1L);
273                         // getHibernateTemplate().flush();
274                         Assert.fail("Getting an object with not existing id must be failed.");
275                 } catch (Exception e) {
276                         LOG.debug("Expected exception is thrown: "
277                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
278                 }
279                 rollbackNestedTransaction();
280                 LOG.debug(">>>>> END testGetScenarioInfo()");
281         }
282
283         /**
284          * Test check-in scenario operation to be performed after SALOME session.<BR>
285          * <B>Description :</B> <BR>
286          * <i>Create a scenario and try to check-in it with some simulated SALOME results data.<BR>
287          * After check-in verify following points:
288          * <ul>
289          * <li>scenario is no more marked as checked out</li>
290          * <li>new document versions are created for checked in documents</li>
291          * <li>presentation of the previous version is removed</li>
292          * <li>uses relations are copied correctly</li>
293          * <li>files are moved correctly</li>
294          * <li>new documents are created for new data</li>
295          * <li>new documents have correctly generated names</li>
296          * <li>uses relations are created correctly</li>
297          * <li>files are moved correctly</li>
298          * </ul>
299          * </i><BR>
300          * <B>Action : </B><BR>
301          * <i>1. call the method for an existing scenario id.</i><BR>
302          * <i>2. call the method for a not existing scenario id.</i><BR>
303          * <B>Test data : </B><BR>
304          * <i>no input parameters</i><BR>
305          * <i>no input parameters</i><BR>
306          * 
307          * <B>Outcome results:</B><BR>
308          * <i>
309          * <ul>
310          * <li>New version of existing documents must be created and new documents must be imported for documents with zero id. Correct
311          * relations must be created.<BR>
312          * </li>
313          * <li>Exception is thrown<BR>
314          * </li>
315          * </ul>
316          * </i>
317          * 
318          * @throws InvalidPropertyException
319          *             if an invalid property is used when creating objects
320          * @throws MultiplyDefinedException
321          *             when trying to create an object with already existing id
322          * @throws MissedPropertyException
323          *             if a mandatory property is not defined for an object to be created
324          * @throws IOException
325          *             if scenario creation is failed
326          * @throws SQLException
327          *             if scenario creation is failed
328          * @throws NotApplicableException
329          *             if checkin failed
330          * @throws MismatchException
331          *             if checkin failed
332          */
333         @Test(groups = { "checkin", "sevice", "functional", "business" })
334         public void testCheckin() throws InvalidPropertyException,
335                         MissedPropertyException, MultiplyDefinedException, IOException,
336                         SQLException, MismatchException, NotApplicableException {
337                 LOG.debug(">>>>> BEGIN testCheckin()");
338                 startNestedTransaction();
339
340                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
341                 _projectSettings.configure(ClassLoader
342                                 .getSystemResource("test/som.xml").getPath());
343                 getHibernateTemplate().flush();
344                 long scenarioId = createScenario();
345                 Scenario aScen = _scenarioDAO.get(scenarioId);
346                 User user = aScen.getAuthor();
347                 long userId = user.getIndex();
348
349                 // ////////////////////////////////////////////////////////
350                 // Call checkin method for good prepared transient data.
351
352                 // Simulate checkout
353                 List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
354                 _scenarioService.checkout(aScen, user);
355
356                 // Prepare test data for checkin
357                 // Checkin only two first steps (geom and mesh)
358                 List<StepDTO> stepsToCheckin = new ArrayList<StepDTO>();
359                 for (StepDTO step : steps) {
360                         // Prepare GEOM: checkin actual brep
361                         StepDTO stepToCheckin = createDocDTOForModule(null, "GEOM", "brep",
362                                         userId, step, stepsToCheckin);
363                         createDocDTOForModule(stepToCheckin, "SMESH", "med", userId, step,
364                                         stepsToCheckin);
365                 }
366                 // Do test checkin
367                 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
368
369                 // Check that scenario is no more marked as checked out
370                 aScen = _scenarioDAO.get(scenarioId);
371                 Assert.assertFalse(aScen.isCheckedout(),
372                                 "Scenario is still marked as checked out after checkin.");
373                 // Check that new document versions are created for checked in documents
374                 boolean caseFound = false;
375                 for (StepDTO step : stepsToCheckin) {
376                         for (DocumentDTO docDTO : step.getDocs()) {
377                                 if ((docDTO.getId() != 0) && (docDTO.getId() != null)) {
378                                         boolean found = false;
379                                         Document prevDoc = null;
380                                         Publication newPub = null;
381                                         for (Publication pub : aScen.getDocums()) {
382                                                 prevDoc = pub.value().getPreviousVersion();
383                                                 if (prevDoc != null) {
384                                                         found = (prevDoc.getIndex() == docDTO.getId());
385                                                         if (found) { // Found next published version of the checked in document
386                                                                 newPub = pub;
387                                                                 break;
388                                                         }
389                                                 }
390                                         }
391                                         Assert.assertTrue(
392                                                         found,
393                                                         "New version of the existing checked in document \""
394                                                                         + docDTO.getTitle() + "\" (id="
395                                                                         + docDTO.getId()
396                                                                         + ") is not found in the scenario.");
397                                         // Check that presentation of the previous version is removed
398                                         Assert.assertFalse(aScen.publishes(prevDoc));
399                                         checkFiles(docDTO, newPub);
400                                         // Check that uses relations are copied correctly
401
402                                         // 1. Get all uses relations of the previous document version
403                                         for (Relation rel : prevDoc
404                                                         .getRelations(UsesRelation.class)) {
405                                                 Document used = ((UsesRelation) rel).getTo();
406                                                 // 2.1. Get the latest version of the document published in this scenario
407                                                 Publication toBeUsed = aScen.getPublication(used);
408                                                 if (toBeUsed == null) {
409                                                         // Find the latest published version
410                                                         for (Publication lastPub : aScen.getDocums()) {
411                                                                 if ((lastPub.value().getPreviousVersion() != null)
412                                                                                 && (lastPub.value()
413                                                                                                 .getPreviousVersion()
414                                                                                                 .getIndex() == used.getIndex())) {
415                                                                         toBeUsed = lastPub;
416                                                                         break;
417                                                                 }
418                                                         }
419                                                 }
420                                                 if ((toBeUsed != null) && (!toBeUsed.isOutdated())) {
421                                                         // 2.2. For each used document check that its latest not outdated version
422                                                         // is used by the new checked in document version.
423                                                         checkUsesRelation(newPub, toBeUsed);
424                                                 }
425                                         }
426                                         // 1. Get all usedBy relations of the previous document version
427                                         for (Relation rel : prevDoc
428                                                         .getRelations(UsedByRelation.class)) {
429                                                 Document using = ((UsedByRelation) rel).getTo();
430                                                 // Check that not checked in dependent documents became outdated
431                                                 Publication usingPub = aScen.getPublication(using);
432                                                 if (usingPub != null) { // if the document using the old version is still published
433                                                         Assert.assertTrue(usingPub.isOutdated(),
434                                                                         "Not checked in dependent document "
435                                                                                         + using.getTitle() + " ("
436                                                                                         + using.getType().getName()
437                                                                                         + ") must become outdated.");
438                                                         caseFound = true;
439                                                 }
440                                         }
441
442                                 } else {
443                                         // Check that new documents are created for new data
444                                         boolean found = false;
445                                         Publication newPub = null;
446                                         for (Publication pub : aScen.getDocums()) {
447                                                 if (pub.value().getPreviousVersion() == null) {
448                                                         found = (pub.value().getTitle().startsWith(pub
449                                                                         .value().getType().getName()));
450                                                         if (found) { // Found next published version of the checked in document
451                                                                 String fcontent = Files.readFile(pub
452                                                                                 .getSourceFile().asFile());
453                                                                 found = fcontent.contains(docDTO.getTitle());
454                                                                 if (found) {
455                                                                         LOG.debug("Found new document with generated title: "
456                                                                                         + pub.value().getTitle());
457                                                                         newPub = pub;
458                                                                         break;
459                                                                 }
460                                                         }
461                                                 }
462                                         }
463                                         Assert.assertTrue(found,
464                                                         "New document is not created for checked in document \""
465                                                                         + docDTO.getTitle() + "\".");
466                                         // Check that uses relations are created correctly
467                                         Assert.assertTrue(
468                                                         newPub.value()
469                                                                         .getTitle()
470                                                                         .startsWith(
471                                                                                         newPub.value().getType().getName()
472                                                                                                         + "_"),
473                                                         "Document title newPub.value().getTitle() must start with "
474                                                                         + newPub.value().getType().getName() + "_");
475
476                                         // 1. Find the document type used by this document type
477                                         Set<DocumentType> usedTypes = newPub.value().getType()
478                                                         .getDefaultUses();
479                                         // 2. Find documents of used types in the current study step and previous study steps
480                                         for (Publication pub : aScen.getDocums()) {
481                                                 if ((pub.getStep().getNumber() <= step.getNumber())
482                                                                 && (!pub.isOutdated())
483                                                                 && usedTypes.contains(pub.value().getType())) {
484                                                         // 3. Check that there is uses relation to the found document
485                                                         // if it is not outdated.
486                                                         checkUsesRelation(newPub, pub);
487                                                 }
488                                         }
489
490                                         // Check that files are moved correctly
491                                         checkFiles(docDTO, newPub);
492                                 }
493                         }
494                 }
495                 Assert.assertTrue(caseFound,
496                                 "Not checked in dependent documents must become outdated.");
497
498                 // ///////////////////////////////////////////////////////////
499                 // Call checkin method for a not existing id.
500                 try {
501                         _scenarioService.checkin(-1, userId, stepsToCheckin);
502                         Assert.fail("Check in for scenario with not existing id must be failed.");
503                 } catch (Exception e) {
504                         LOG.debug("Expected exception is thrown: "
505                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
506                 }
507
508                 // Test checkin with empty list of steps
509                 stepsToCheckin.clear();
510                 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
511
512                 rollbackNestedTransaction();
513                 LOG.debug(">>>>> END testCheckin()");
514         }
515
516         /**
517          * Check if there is uses relation from the newPub to pub.
518          * 
519          * @param newPub
520          *            the new publication
521          * @param pub
522          *            the publication to be used
523          */
524         private void checkUsesRelation(final Publication newPub,
525                         final Publication pub) {
526                 boolean uses = false;
527                 boolean usesExist = false;
528                 for (Publication usesPub : newPub.getRelations(UsesRelation.class)) {
529                         usesExist = true;
530                         uses = (usesPub.equals(pub));
531                         if (uses) {
532                                 break;
533                         }
534                 }
535                 Assert.assertTrue(usesExist && uses, "The created document "
536                                 + newPub.value().getTitle() + "("
537                                 + newPub.value().getType().getName() + ")"
538                                 + " has no uses relation to the document "
539                                 + pub.value().getTitle() + "("
540                                 + pub.value().getType().getName() + ")");
541         }
542
543         /**
544          * Check that files are moved correctly.
545          * 
546          * @param docDTO
547          *            checked in document DTO
548          * @param newPub
549          *            the created document publication
550          */
551         private void checkFiles(final DocumentDTO docDTO, final Publication newPub) {
552                 // Check that original files are deleted
553                 for (int j = 0; j < docDTO.getFiles().size(); j++) {
554                         FileDTO fileDTO = docDTO.getFiles().get(j);
555                         Assert.assertFalse(new File(fileDTO.getPath()).exists(), "File"
556                                         + fileDTO.getPath()
557                                         + " was not removed from downloads directory.");
558                         String format = fileDTO.getPath().substring(
559                                         fileDTO.getPath().lastIndexOf('.') + 1);
560                 }
561                 // TODO:Check file by its internal content
562                 Assert.assertTrue(newPub.getSourceFile().exists(), "File "
563                                 + newPub.getSourceFile().asFile().getAbsolutePath()
564                                 + " for the document " + docDTO.getTitle()
565                                 + " was not created.");
566         }
567
568         /**
569          * Prepare a document with a file for check-in.
570          * 
571          * @param stepTo
572          *            step DTO with data for check-in
573          * @param module
574          *            SALOME module name
575          * @param format
576          *            file extension
577          * @param userId
578          *            download directory
579          * @param stepFrom
580          *            checked out stepDTO
581          * @param stepsToCheckin
582          *            DTO for check-in
583          * @throws IOException
584          *             if file creation failed
585          * @return step DTO with data prepared for check-in (stepTo or new if stepTo is null)
586          */
587         private StepDTO createDocDTOForModule(final StepDTO stepTo,
588                         final String module, final String format, final long userId,
589                         final StepDTO stepFrom, final List<StepDTO> stepsToCheckin)
590                         throws IOException {
591                 StepDTO stepToCheckin = stepTo;
592                 if (stepToCheckin == null) {
593                         stepToCheckin = new StepDTO();
594                 }
595                 if (module.equals(stepFrom.getModule())) {
596                         stepsToCheckin.add(stepToCheckin);
597                         stepToCheckin.setNumber(stepFrom.getNumber());
598                         for (DocumentDTO doc : stepFrom.getDocs()) {
599                                 if (doc.getFiles().get(0).getState() != 'O') {
600                                         DocumentDTO docToCheckin = stepToCheckin.addDoc(
601                                                         doc.getId(), doc.getTitle());
602                                         for (FileDTO file : doc.getFiles()) {
603                                                 if (file.getPath().endsWith(format)) {
604                                                         // Create a file in the download directory
605                                                         docToCheckin.addFile(createDownloadedFile(userId,
606                                                                         doc.getTitle() + "_result", format));
607                                                 }
608                                         }
609                                 }
610                         }
611                         // Prepare new data
612                         stepToCheckin.addDoc(0, "newdoc" + stepFrom.getNumber()).addFile(
613                                         createDownloadedFile(userId,
614                                                         "newdoc" + stepFrom.getNumber(), "brep"));
615                 }
616                 return stepToCheckin;
617         }
618
619         /**
620          * Create a file in the user's repository downloads directory.
621          * 
622          * @param userId
623          *            user id
624          * @param name
625          *            file name
626          * @param format
627          *            file extension
628          * @return created file DTO
629          * @throws IOException
630          *             if file creation failed
631          */
632         private FileDTO createDownloadedFile(final long userId, final String name,
633                         final String format) throws IOException {
634                 // Create a file in the download directory
635                 String filePath = getDownloadPath(userId) + name + "." + format;
636                 FileWriter fw = new FileWriter(filePath);
637                 fw.write("Simulation of " + name + "." + format
638                                 + " file for checkin at " + new Date());
639                 fw.close();
640                 return new FileDTO(filePath);
641         }
642
643         /**
644          * Get path to the user's downloads directory. The directory is created if it is not exist yet.
645          * 
646          * @param userId
647          *            user id
648          * @return absolute path to downloads directory followed by slash
649          */
650         private String getDownloadPath(final long userId) {
651                 // Prepare download directory
652                 File tmpDir = _repositoryService.getDownloadDirectory(userId);
653                 if (!tmpDir.exists()) {
654                         Assert.assertTrue(
655                                         tmpDir.mkdir(),
656                                         "Can't create temporary directory: "
657                                                         + tmpDir.getAbsolutePath());
658                 }
659
660                 return tmpDir.getAbsolutePath() + "/";
661         }
662
663         /**
664          * Create a persistent scenario for tests.
665          * 
666          * @return a persistent scenario
667          * @throws InvalidPropertyException
668          *             if an invalid property is used when creating objects
669          * @throws MultiplyDefinedException
670          *             when trying to create an object with already existing id
671          * @throws MissedPropertyException
672          *             if a mandatory property is not defined for an object to be created
673          * @throws IOException
674          *             if document creation is failed
675          * @throws SQLException
676          *             if project settings loading is failed
677          */
678         private long createScenario() throws InvalidPropertyException,
679                         MissedPropertyException, MultiplyDefinedException, IOException,
680                         SQLException {
681                 // Create a scenario for tests
682                 HibernateTemplate ht = getHibernateTemplate();
683
684                 Database.getInstance().reset();
685                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
686                 // Load workflow customization
687                 try {
688                         _projectSettings.configure(ClassLoader.getSystemResource(
689                                         "test/som.xml").getPath());
690                 } catch (FileNotFoundException e) {
691                         Assert.fail("Can't find som.xml: ", e);
692                 }
693                 List<Step> steps = _projectSettings.getStepsOf(Scenario.class);
694                 Assert.assertTrue(steps.size() > 0, "No steps are created.");
695
696                 // Create a test user
697                 User.Properties uprop = new User.Properties();
698                 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
699                                 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
700                                 .addRole("TST_user")
701                                 .setMailAddress("noreply@salome-platform.org");
702                 uprop.disableCheck();
703                 User anAuthor = new User(uprop);
704                 ht.saveOrUpdate(anAuthor);
705
706                 // Create a test study
707                 Study.Properties stprops = new Study.Properties()
708                                 .setReference("TST_SID_01").setTitle("TST_Study")
709                                 .setManager(anAuthor);
710                 Study aStudy = new Study(stprops);
711                 ht.saveOrUpdate(aStudy);
712
713                 // Create a test scenario
714                 Scenario.Properties sprops = new Scenario.Properties()
715                                 .setTitle("TST_Scenario").setManager(anAuthor)
716                                 .setOwnerStudy(aStudy);
717                 Scenario aScenario = new Scenario(sprops);
718                 aStudy.getScenariiList().add(aScenario);
719                 ht.saveOrUpdate(anAuthor);
720                 ht.saveOrUpdate(aStudy);
721                 ht.saveOrUpdate(aScenario);
722
723                 // Create documents for each scenario step
724                 Document.Properties dprop = new Document.Properties().setAuthor(
725                                 anAuthor).setDate(new Date());
726                 int i = 0;
727                 Publication usedPub = null;
728                 Map<Long, Long> usedMap = new HashMap<Long, Long>();
729                 for (Step step : steps) {
730                         LOG.debug("Create scenario step: " + i);
731
732                         org.splat.som.Step aScStep = new org.splat.som.Step(step, aScenario);
733                         List<DocumentType> dtypes = _documentTypeService
734                                         .selectTypesOf(step);
735                         for (DocumentType dtype : dtypes) {
736                                 // Create a document published in the scenario
737                                 // document<i>: document type[0] - first type used on the step
738                                 // <source-file>.brep
739                                 // <attached-file>.med
740                                 dprop.setName("document" + i++).setType(dtype);
741                                 if (step.getNumber() > 3) {
742                                         dprop.setFormat("med");
743                                 } else {
744                                         dprop.setFormat("brep");
745                                 }
746                                 Publication pub = createDoc(aScenario, aScStep, dprop, "med",
747                                                 false);
748                                 if (usedPub != null) {
749                                         pub.addDependency(usedPub);
750                                         ht.saveOrUpdate(pub.value());
751
752                                         usedMap.put(pub.getIndex(), usedPub.getIndex());
753                                 }
754                                 usedPub = pub;
755
756                                 // Create another document with outdated publication
757                                 dprop.setName("document" + i++).setType(dtype)
758                                                 .setFormat("brep");
759                                 createDoc(aScenario, aScStep, dprop, "med", true);
760
761                         }
762                         if (dtypes.size() <= 0) {
763                                 LOG.debug("No document types are found for scenario step " + i);
764                         }
765                 }
766
767                 // Check that the scenario and its documents have been created correctly.
768
769                 Assert.assertNotNull(ht.find("from Document"),
770                                 "No documents in the database.");
771                 Assert.assertTrue(ht.find("from Document").size() > 0,
772                                 "No documents in the database.");
773
774                 Assert.assertNotNull(
775                                 ht.find("from Publication where owner=" + aScenario.getIndex()),
776                                 "No publications in the database.");
777                 Assert.assertTrue(
778                                 ht.find("from Publication where owner=" + aScenario.getIndex())
779                                                 .size() > 0, "No publications in the database.");
780
781                 for (Publication p : (List<Publication>) ht
782                                 .find("from Publication where owner=" + aScenario.getIndex())) {
783                         LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
784                                         + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
785                                         + "]");
786                         Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
787                                         "The publication was not attached to the scenario.");
788                 }
789
790                 // Remove the scenario from the current hibernate session.
791                 ht.evict(aScenario);
792                 // Check that the scenario is created in the database.
793                 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
794                 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
795                 Assert.assertTrue(aScen.getDocums().size() > 0,
796                                 "No publications in the scenario.");
797
798                 Assert.assertTrue(i > 0,
799                                 "More then one document must be in the database");
800
801                 // Check created uses relations
802                 Assert.assertTrue(usedMap.size() > 0, "Uses relations must be created.");
803                 boolean foundAny = false;
804                 for (Long usingId : usedMap.keySet()) {
805                         for (Publication pub : aScen.getDocums()) {
806                                 if (pub.getIndex() == usingId) {
807                                         boolean found = false;
808                                         for (Publication used : aScen.getDocums()) {
809                                                 found = (used.getIndex() == usedMap.get(usingId));
810                                                 if (found) {
811                                                         break;
812                                                 }
813                                         }
814                                         Assert.assertTrue(found,
815                                                         "Uses relation was not created in the database.");
816                                         foundAny = foundAny || found;
817                                 }
818                         }
819                 }
820                 Assert.assertTrue(foundAny,
821                                 "No Uses relation was created in the database.");
822
823                 return aScenario.getIndex();
824         }
825
826         /**
827          * Create a document published in the scenario. <BR>
828          * document:<BR>
829          * document type[0] - first type used on the step <BR>
830          * &lt;source-file&gt;.brep <BR>
831          * &lt;attached-file&gt;.med
832          * 
833          * @param aScenario
834          *            the scenario to add the document to
835          * @param aScStep
836          *            scenario step where the document to be published
837          * @param dprop
838          *            document properties
839          * @param attachedFileExt
840          *            extension of the secon attached (exported) file
841          * @param isOutdated
842          *            outdated document flag
843          * @return the publication of the created document
844          * @throws IOException
845          * @throws MultiplyDefinedException
846          * @throws InvalidPropertyException
847          * @throws MissedPropertyException
848          */
849         private Publication createDoc(final Scenario aScenario,
850                         final org.splat.som.Step aScStep, final Properties dprop,
851                         final String attachedFileExt, final boolean isOutdated)
852                         throws MissedPropertyException, InvalidPropertyException,
853                         MultiplyDefinedException, IOException {
854                 // Create a document published in the scenario
855                 // document<i>: document type[0] - first type used on the step
856                 // <source-file>.brep
857                 // <attached-file>.med
858                 Publication pub = _stepService.createDocument(aScStep, dprop);
859                 Assert.assertNotNull(pub.getOwner(),
860                                 "The publication must be attached to the scenario.");
861                 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
862                                 "The publication was not attached to the scenario.");
863
864                 if (isOutdated) {
865                         pub.setIsnew('O');
866                 }
867                 aScenario.add(pub);
868                 HibernateTemplate ht = getHibernateTemplate();
869                 ht.saveOrUpdate(pub);
870
871                 // Attach a file
872                 ht.save(pub.value());
873                 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
874
875                 return pub;
876         }
877
878         /**
879          * Test check-in scenario operation to be performed after SALOME session.<BR>
880          * <B>Description :</B> <BR>
881          * <i>Create a scenario and try to check-in it with some simulated SALOME results data.<BR>
882          * After check-in verify following points:
883          * <ul>
884          * <li>scenario is no more marked as checked out</li>
885          * <li>new document versions are created for checked in documents</li>
886          * <li>presentation of the previous version is removed</li>
887          * <li>uses relations are copied correctly</li>
888          * <li>files are moved correctly</li>
889          * <li>new documents are created for new data</li>
890          * <li>uses relations are created correctly</li>
891          * <li>files are moved correctly</li>
892          * </ul>
893          * </i><BR>
894          * <B>Action : </B><BR>
895          * <i>1. call the method for an existing scenario id.</i><BR>
896          * <i>2. call the method for a not existing scenario id.</i><BR>
897          * <B>Test data : </B><BR>
898          * <i>no input parameters</i><BR>
899          * <i>no input parameters</i><BR>
900          * 
901          * <B>Outcome results:</B><BR>
902          * <i>
903          * <ul>
904          * <li>New version of existing documents must be created and new documents must be imported for documents with zero id. Correct
905          * relations must be created.<BR>
906          * </li>
907          * <li>Exception is thrown<BR>
908          * </li>
909          * </ul>
910          * </i>
911          * 
912          * @throws InvalidPropertyException
913          *             if an invalid property is used when creating objects
914          * @throws MultiplyDefinedException
915          *             when trying to create an object with already existing id
916          * @throws MissedPropertyException
917          *             if a mandatory property is not defined for an object to be created
918          * @throws IOException
919          *             if scenario creation is failed
920          * @throws SQLException
921          *             if scenario creation is failed
922          * @throws NotApplicableException
923          *             if checkin failed
924          * @throws MismatchException
925          *             if checkin failed
926          */
927         @Test(groups = { "study", "sevice", "functional", "business" })
928         public void testCreateStudy() throws InvalidPropertyException,
929                         MissedPropertyException, MultiplyDefinedException, IOException,
930                         SQLException, MismatchException, NotApplicableException {
931                 LOG.debug(">>>>> BEGIN testCreateStudy()");
932                 startNestedTransaction();
933
934                 Database.getInstance().reset();
935                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
936                 _projectSettings.configure(ClassLoader
937                                 .getSystemResource("test/som.xml").getPath());
938
939                 // Create a test user
940                 User.Properties uprop = new User.Properties();
941                 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
942                                 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
943                                 .addRole("TST_user")
944                                 .setMailAddress("noreply@salome-platform.org");
945                 uprop.disableCheck();
946                 User anAuthor = new User(uprop);
947
948                 getHibernateTemplate().saveOrUpdate(anAuthor);
949                 KnowledgeElementType ucase = _knowledgeElementTypeService
950                                 .selectType("usecase");
951                 Assert.assertNotNull(ucase,
952                                 "Knowledge type 'usecase' must be created in the database.");
953                 SimulationContextType prodtype = _simulationContextService
954                                 .selectType("product");
955                 Assert.assertNotNull(prodtype,
956                                 "Simulation context type 'product' must be created in the database.");
957
958                 // Create admin
959                 uprop.clear();
960                 uprop.setUsername("TST_Admin").setName("TST_SimanUnitTestsAdmin")
961                                 .setFirstName("TST_AdminFirstName")
962                                 .setDisplayName("TST_test.admin").addRole("TST_user,sysadmin")
963                                 .setMailAddress("noreply@salome-platform.org");
964                 uprop.disableCheck();
965
966                 getHibernateTemplate().saveOrUpdate(new User(uprop));
967                 getHibernateTemplate().flush();
968
969                 Study.Properties sprop = new Study.Properties();
970                 sprop.setTitle("Test study creation").setManager(anAuthor);
971                 Scenario.Properties oprop = new Scenario.Properties();
972                 oprop.setTitle("Test scenario for the created study");
973
974                 // Addition of the entered project context
975                 SimulationContext.Properties cprop = new SimulationContext.Properties();
976                 // Input of new project context
977                 cprop.setType(_simulationContextService.selectType("product"))
978                                 .setValue("Test Simulation Context: Product");
979                 Study study = _scenarioService.createStudy(sprop, oprop, cprop);
980
981                 rollbackNestedTransaction();
982                 LOG.debug(">>>>> END testCreateStudy()");
983         }
984 }