]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/Siman-Common/src/test/splat/service/TestStudyService.java
Salome HOME
Unit test for getStudyResultType is added.
[tools/siman.git] / Workspace / Siman-Common / src / test / splat / service / TestStudyService.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.FileNotFoundException;
12 import java.io.FileWriter;
13 import java.io.IOException;
14 import java.sql.SQLException;
15 import java.util.Date;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20 import org.splat.dal.bo.kernel.Relation;
21 import org.splat.dal.bo.kernel.User;
22 import org.splat.dal.bo.som.ContributorRelation;
23 import org.splat.dal.bo.som.DescriptionAttribute;
24 import org.splat.dal.bo.som.Document;
25 import org.splat.dal.bo.som.DocumentType;
26 import org.splat.dal.bo.som.KnowledgeElement;
27 import org.splat.dal.bo.som.KnowledgeElementType;
28 import org.splat.dal.bo.som.ProgressState;
29 import org.splat.dal.bo.som.ProjectElement;
30 import org.splat.dal.bo.som.Publication;
31 import org.splat.dal.bo.som.ReaderRelation;
32 import org.splat.dal.bo.som.Scenario;
33 import org.splat.dal.bo.som.SimulationContext;
34 import org.splat.dal.bo.som.Study;
35 import org.splat.dal.bo.som.ValidationCycle;
36 import org.splat.dal.bo.som.ValidationCycleRelation;
37 import org.splat.dal.bo.som.ValidationStep;
38 import org.splat.dal.bo.som.Document.Properties;
39 import org.splat.dal.dao.kernel.UserDAO;
40 import org.splat.dal.dao.som.Database;
41 import org.splat.dal.dao.som.KnowledgeElementDAO;
42 import org.splat.dal.dao.som.KnowledgeElementTypeDAO;
43 import org.splat.dal.dao.som.ScenarioDAO;
44 import org.splat.dal.dao.som.StudyDAO;
45 import org.splat.dal.dao.som.ValidationCycleDAO;
46 import org.splat.exception.BusinessException;
47 import org.splat.exception.InvalidParameterException;
48 import org.splat.kernel.InvalidPropertyException;
49 import org.splat.kernel.MissedPropertyException;
50 import org.splat.kernel.MultiplyDefinedException;
51 import org.splat.log.AppLogger;
52 import org.splat.service.DocumentTypeService;
53 import org.splat.service.ProjectElementService;
54 import org.splat.service.PublicationService;
55 import org.splat.service.SimulationContextService;
56 import org.splat.service.StepService;
57 import org.splat.service.StudyService;
58 import org.splat.service.dto.FileDTO;
59 import org.splat.service.dto.UserDTO;
60 import org.splat.service.technical.ProjectSettingsService;
61 import org.splat.service.technical.RepositoryService;
62 import org.splat.service.technical.ProjectSettingsService.Step;
63 import org.splat.util.BeanHelper;
64 import org.springframework.beans.factory.annotation.Autowired;
65 import org.springframework.beans.factory.annotation.Qualifier;
66 import org.springframework.orm.hibernate3.HibernateTemplate;
67 import org.testng.Assert;
68 import org.testng.annotations.Test;
69
70 import test.splat.common.BaseTest;
71 import test.splat.util.TestEntitiesGenerator;
72
73 /**
74  * Test class for StudyService.
75  * 
76  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
77  * 
78  */
79 public class TestStudyService extends BaseTest {
80
81         /**
82          * Logger for the class.
83          */
84         private static final AppLogger LOG = AppLogger
85                         .getLogger(TestStudyService.class);
86
87         /**
88          * The StudyDAO. Later injected by Spring.
89          */
90         @Autowired
91         @Qualifier("studyDAO")
92         private transient StudyDAO _studyDAO;
93
94         /**
95          * The PublicationService. Later injected by Spring.
96          */
97         @Autowired
98         @Qualifier("publicationService")
99         private transient PublicationService _publicationService;
100
101         /**
102          * The ProjectElementService. Later injected by Spring.
103          */
104         @Autowired
105         @Qualifier("projectElementService")
106         private transient ProjectElementService _projectElementService;
107
108         /**
109          * The StepService. Later injected by Spring.
110          */
111         @Autowired
112         @Qualifier("stepService")
113         private transient StepService _stepService;
114
115         /**
116          * The ProjectSettingsService. Later injected by Spring.
117          */
118         @Autowired
119         @Qualifier("projectSettings")
120         private transient ProjectSettingsService _projectSettings;
121
122         /**
123          * The DocumentTypeService. Later injected by Spring.
124          */
125         @Autowired
126         @Qualifier("documentTypeService")
127         private transient DocumentTypeService _documentTypeService;
128
129         /**
130          * The StudyService. Later injected by Spring.
131          */
132         @Autowired
133         @Qualifier("studyService")
134         private transient StudyService _studyService;
135
136         /**
137          * The UserDAO. Later injected by Spring.
138          */
139         @Autowired
140         @Qualifier("userDAO")
141         private transient UserDAO _userDAO;
142
143         /**
144          * The KnowledgeElementDAO. Later injected by Spring.
145          */
146         @Autowired
147         @Qualifier("knowledgeElementDAO")
148         private transient KnowledgeElementDAO _knowledgeElementDAO;
149
150         /**
151          * The KnowledgeElementTypeDAO. Later injected by Spring.
152          */
153         @Autowired
154         @Qualifier("knowledgeElementTypeDAO")
155         private transient KnowledgeElementTypeDAO _knowledgeElementTypeDAO;
156
157         /**
158          * The ScenarioDAO. Later injected by Spring.
159          */
160         @Autowired
161         @Qualifier("scenarioDAO")
162         private transient ScenarioDAO _scenarioDAO;
163
164         /**
165          * The SimulationContextService. Later injected by Spring.
166          */
167         @Autowired
168         @Qualifier("simulationContextService")
169         private transient SimulationContextService _simulationContextService;
170
171         /**
172          * The ValidationCycleDAO. Later injected by Spring.
173          */
174         @Autowired
175         @Qualifier("validationCycleDAO")
176         private transient ValidationCycleDAO _validationCycleDAO;
177
178         /**
179          * The RepositoryService. Later injected by Spring.
180          */
181         @Autowired
182         @Qualifier("repositoryService")
183         private transient RepositoryService _repositoryService;
184
185         /**
186          * Create a persistent scenario for tests.
187          * 
188          * @return a persistent scenario
189          * @throws InvalidPropertyException
190          *             if an invalid property is used when creating objects
191          * @throws MultiplyDefinedException
192          *             when trying to create an object with already existing id
193          * @throws MissedPropertyException
194          *             if a mandatory property is not defined for an object to be created
195          * @throws IOException
196          *             if document creation is failed
197          * @throws SQLException
198          *             if project settings loading is failed
199          */
200         private Study createStudy() throws InvalidPropertyException,
201                         MissedPropertyException, MultiplyDefinedException, IOException,
202                         SQLException {
203                 // Create a scenario for tests
204                 HibernateTemplate ht = getHibernateTemplate();
205
206                 Database.getInstance().reset();
207                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
208                 // Load workflow customization
209                 try {
210                         _projectSettings.configure("classpath:test/som.xml");
211                 } catch (FileNotFoundException e) {
212                         Assert.fail("Can't find som.xml: ", e);
213                 }
214                 List<Step> steps = _projectSettings.getAllSteps();
215                 Assert.assertTrue(steps.size() > 0, "No steps are created.");
216
217                 // Create a test user
218                 User.Properties uprop = new User.Properties();
219                 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
220                                 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
221                                 .addRole("TST_user").setMailAddress(
222                                                 "noreply@salome-platform.org");
223                 uprop.disableCheck();
224                 User anAuthor = new User(uprop);
225                 ht.saveOrUpdate(anAuthor);
226
227                 // Create a test study
228                 Study.Properties stprops = new Study.Properties().setReference(
229                                 "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
230                 Study aStudy = new Study(stprops);
231                 ht.saveOrUpdate(aStudy);
232
233                 // Create a test scenario
234                 Scenario.Properties sprops = new Scenario.Properties().setTitle(
235                                 "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
236                 Scenario aScenario = new Scenario(sprops);
237                 aStudy.getScenariiList().add(aScenario);
238                 ht.saveOrUpdate(anAuthor);
239                 ht.saveOrUpdate(aStudy);
240                 ht.saveOrUpdate(aScenario);
241
242                 // Create documents for each scenario step
243                 Document.Properties dprop = new Document.Properties().setAuthor(
244                                 anAuthor).setDate(new Date());
245                 int i = 0;
246                 Publication usedPub = null;
247                 Map<Long, Long> usedMap = new HashMap<Long, Long>();
248                 for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
249                         Step step = _projectSettings.getStep(stepNum);
250                         LOG.debug("Create scenario step: " + stepNum);
251                         ProjectElement projElem;
252
253                         if (step.appliesTo(Study.class)) {
254                                 projElem = aStudy;
255                         } else {
256                                 projElem = aScenario;
257                         }
258                         org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
259                         List<DocumentType> dtypes = _documentTypeService
260                                         .selectTypesOf(step);
261                         if (dtypes.size() > 0) {
262                                 DocumentType dtype = dtypes.get(0);
263                                 // Create a document published in the scenario
264                                 // document<i>: document type[0] - first type used on the step
265                                 // <source-file>.brep
266                                 // <attached-file>.med
267                                 i++;
268                                 dprop.setName("document" + stepNum).setType(dtype);
269                                 if (step.getNumber() > 3) {
270                                         dprop.setFormat("med");
271                                 } else {
272                                         dprop.setFormat("py");
273                                 }
274                                 Publication pub = createDoc(projElem, aScStep, dprop, "med",
275                                                 false);
276                                 if (usedPub != null) {
277                                         pub.addDependency(usedPub);
278                                         LOG.debug("Add dependency: " + pub.value().getTitle()
279                                                         + " from " + usedPub.value().getTitle());
280                                         ht.saveOrUpdate(pub.value());
281                                         ht.flush();
282
283                                         usedMap.put(pub.getIndex(), usedPub.getIndex());
284                                 }
285                                 usedPub = pub;
286                         }
287                         if (dtypes.size() <= 0) {
288                                 LOG.debug("No document types are found for scenario step " + i);
289                         }
290                 }
291
292                 // Check that the scenario and its documents have been created correctly.
293
294                 Assert.assertNotNull(ht.find("from Document"),
295                                 "No documents in the database.");
296                 Assert.assertTrue(ht.find("from Document").size() > 0,
297                                 "No documents in the database.");
298
299                 Assert.assertNotNull(ht.find("from Publication where owner="
300                                 + aScenario.getIndex()), "No publications in the database.");
301                 Assert.assertTrue(
302                                 ht.find("from Publication where owner=" + aScenario.getIndex())
303                                                 .size() > 0, "No publications in the database.");
304
305                 for (Publication p : (List<Publication>) ht
306                                 .find("from Publication where owner=" + aScenario.getIndex())) {
307                         LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
308                                         + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
309                                         + "]");
310                         Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
311                                         "The publication was not attached to the scenario.");
312                 }
313
314                 // Remove the scenario from the current hibernate session.
315                 ht.evict(aScenario);
316                 // Check that the scenario is created in the database.
317                 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
318                 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
319                 Assert.assertTrue(aScen.getDocums().size() > 0,
320                                 "No publications in the scenario.");
321
322                 Assert.assertTrue(i > 0,
323                                 "More then one document must be in the database");
324
325                 // Check created uses relations
326                 Assert
327                                 .assertTrue(usedMap.size() > 0,
328                                                 "Uses relations must be created.");
329                 boolean foundAny = false;
330                 for (Long usingId : usedMap.keySet()) {
331                         for (Publication pub : aScen.getDocums()) {
332                                 if (pub.getIndex() == usingId) {
333                                         boolean found = false;
334                                         for (Publication used : aScen.getDocums()) {
335                                                 found = (used.getIndex() == usedMap.get(usingId));
336                                                 if (found) {
337                                                         break;
338                                                 }
339                                         }
340                                         if (!found) {
341                                                 for (Publication used : aStudy.getDocums()) {
342                                                         found = (used.getIndex() == usedMap.get(usingId));
343                                                         if (found) {
344                                                                 break;
345                                                         }
346                                                 }
347                                         }
348                                         Assert.assertTrue(found,
349                                                         "Uses relation was not created in the database.");
350                                         foundAny = foundAny || found;
351                                 }
352                         }
353                 }
354                 Assert.assertTrue(foundAny,
355                                 "No Uses relation was created in the database.");
356
357                 return aScenario.getOwnerStudy();
358         }
359
360         /**
361          * Create a document published in the scenario. <BR>
362          * document:<BR>
363          * document type - type used on the step <BR>
364          * &lt;source-file&gt;.brep <BR>
365          * &lt;attached-file&gt;.med
366          * 
367          * @param aScenario
368          *            the scenario to add the document to
369          * @param aScStep
370          *            scenario step where the document to be published
371          * @param dprop
372          *            document properties
373          * @param attachedFileExt
374          *            extension of the secon attached (exported) file
375          * @param isOutdated
376          *            outdated document flag
377          * @return the publication of the created document
378          * @throws IOException
379          * @throws MultiplyDefinedException
380          * @throws InvalidPropertyException
381          * @throws MissedPropertyException
382          */
383         private Publication createDoc(final ProjectElement aScenario,
384                         final org.splat.som.Step aScStep, final Properties dprop,
385                         final String attachedFileExt, final boolean isOutdated)
386                         throws MissedPropertyException, InvalidPropertyException,
387                         MultiplyDefinedException, IOException {
388                 // Create a document published in the scenario
389                 // document<i>: document type - type used on the step
390                 // <source-file>.brep
391                 // <attached-file>.med
392                 Publication pub = _stepService.createDocument(aScStep, dprop);
393                 Assert.assertNotNull(pub.getOwner(),
394                                 "The publication must be attached to the scenario.");
395                 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
396                                 "The publication was not attached to the scenario.");
397
398                 if (isOutdated) {
399                         pub.setIsnew('O');
400                 }
401                 aScenario.add(pub);
402                 HibernateTemplate ht = getHibernateTemplate();
403                 ht.saveOrUpdate(pub);
404
405                 // Attach a file
406                 ht.save(pub.value());
407                 ht.flush();
408                 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
409
410                 return pub;
411         }
412
413         /**
414          * Test of generating a study document index.<BR>
415          * <B>Description :</B> <BR>
416          * <i>Create a study and try to generate the next document index.</i><BR>
417          * <B>Action : </B><BR>
418          * <i>1. call DAO's read method for an existing id.</i><BR>
419          * <B>Test data : </B><BR>
420          * <i>no input parameters</i><BR>
421          * 
422          * <B>Outcome results:</B><BR>
423          * <i>
424          * <ul>
425          * <li>The new index must be equal to the incremented old one and saved into the database<BR>
426          * </li>
427          * </ul>
428          * </i>
429          * 
430          * @throws InvalidPropertyException
431          *             if an invalid property is used when creating objects
432          * @throws MultiplyDefinedException
433          *             when trying to create an object with already existing id
434          * @throws MissedPropertyException
435          *             if a mandatory property is not defined for an object to be created
436          * @throws SQLException
437          *             if test study creation is failed
438          * @throws IOException
439          *             if test study creation is failed
440          * 
441          */
442         @Test
443         public void testGenerateLocalIndex() throws InvalidPropertyException,
444                         MissedPropertyException, MultiplyDefinedException, IOException,
445                         SQLException {
446                 LOG.debug(">>>>> BEGIN testGenerateLocalIndex()");
447                 startNestedTransaction();
448
449                 HibernateTemplate ht = getHibernateTemplate();
450                 Study aStudy = createStudy();
451                 // Call DAO's create method for a good transient study.
452                 Long id = aStudy.getIndex();
453                 Assert.assertNotNull(id,
454                                 "Create method returns null instead of a new id.");
455                 Assert.assertTrue(id > 0, "The new id is not a positive number.");
456
457                 // Call DAO's get method for an existing id.
458                 _studyDAO.flush();
459                 getHibernateTemplate().evict(aStudy);
460                 getHibernateTemplate().clear();
461                 Study aStudyFound = _studyDAO.get(id);
462
463                 int oldInd = aStudyFound.getLastLocalIndex();
464                 int ind = _studyService.generateLocalIndex(aStudyFound);
465
466                 _studyDAO.flush();
467                 Assert.assertEquals(ind, oldInd + 1, "Index must be incremented.");
468                 Assert.assertEquals(ind, aStudyFound.getLastLocalIndex(),
469                                 "Index must be incremented.");
470                 Assert.assertEquals(ind, ht.get(Study.class, aStudyFound.getIndex())
471                                 .getLastLocalIndex(),
472                                 "Incremented index must be saved in the database.");
473                 aStudy = (Study) ht.find(
474                                 "from Study where rid = " + aStudyFound.getIndex()).get(0);
475                 Assert.assertEquals(ind, aStudy.getLastLocalIndex(),
476                                 "Incremented index must be saved in the database.");
477
478                 rollbackNestedTransaction();
479                 LOG.debug(">>>>> END testGenerateLocalIndex()");
480         }
481
482         /**
483          * Test of retrieval of a study description.
484          * 
485          * @throws BusinessException
486          *             if there is something wrong likely unrelated to the tested method
487          */
488         @Test
489         public void testGetDescription() throws BusinessException {
490                 LOG.debug(">>>>> BEGIN testGetDescription()");
491                 startNestedTransaction();
492
493                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
494                 _userDAO.create(user);
495                 Study study = TestEntitiesGenerator.getTestStudy(user);
496                 _studyDAO.create(study);
497                 _studyDAO.flush();
498                 Long studyId = Long.valueOf(study.getIndex());
499
500                 // Empty description:
501                 Assert.assertNull(_studyService.getDescription(studyId),
502                                 "returned value for study without description must be null");
503
504                 // Not empty description:
505                 study.setAttribute(new DescriptionAttribute(study, "description"));
506                 _studyDAO.update(study);
507                 _studyDAO.flush();
508                 Assert.assertEquals("description", _studyService
509                                 .getDescription(studyId));
510
511                 // null id
512                 try {
513                         _studyService.getDescription(null);
514                         Assert.fail("retrieval with null study id must fail");
515                 } catch (InvalidParameterException e) {
516                         LOG.debug("Expected exception is thrown: "
517                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
518                 }
519
520                 // Non-existing id
521                 Study tmpStudy = TestEntitiesGenerator.getTestStudy(user);
522                 _studyDAO.create(tmpStudy);
523                 Long nonExistingId = tmpStudy.getIndex();
524                 _studyDAO.delete(tmpStudy);
525                 try {
526                         _studyService.getDescription(nonExistingId);
527                         Assert.fail("retrieval with non-existing study id must fail");
528                 } catch (InvalidParameterException e) {
529                         LOG.debug("Expected exception is thrown: "
530                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
531                 }
532
533                 rollbackNestedTransaction();
534                 LOG.debug(">>>>> END testGetDescription()");
535         }
536
537         /**
538          * Test of retrieval of a study description.
539          * 
540          * @throws BusinessException
541          *             if there is something wrong likely unrelated to the tested method
542          */
543         @Test
544         public void testGetStudyResultType() throws BusinessException {
545                 LOG.debug(">>>>> BEGIN testGetStudyResultType()");
546                 startNestedTransaction();
547
548                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
549                 _userDAO.create(user);
550                 Study study = TestEntitiesGenerator.getTestStudy(user);
551                 _studyDAO.create(study);
552                 _studyDAO.flush();
553
554                 // Empty description:
555                 DocumentType dtype = _studyService.getStudyResultType(study);
556                 Assert.assertNotNull(dtype,
557                                 "returned study result type must not be null");
558                 Assert.assertEquals(dtype.getName(), "report");
559
560                 rollbackNestedTransaction();
561                 LOG.debug(">>>>> END testGetStudyResultType()");
562         }
563
564         /**
565          * Test of setting of a study description.
566          * 
567          * @throws BusinessException
568          *             if there is something wrong likely unrelated to the tested method
569          */
570         @Test
571         public void testSetDescription() throws BusinessException {
572                 LOG.debug(">>>>> BEGIN testSetDescription()");
573                 startNestedTransaction();
574
575                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
576                 _userDAO.create(user);
577                 Study study = TestEntitiesGenerator.getTestStudy(user);
578                 _studyDAO.create(study);
579                 _studyDAO.flush();
580                 Long studyId = Long.valueOf(study.getIndex());
581
582                 // Setting description for study without any
583                 _studyService.setDescription(studyId, "description");
584
585                 // Resetting description
586                 _studyService.setDescription(studyId, "replaced description");
587
588                 // null id
589                 try {
590                         _studyService.setDescription(null, "description");
591                         Assert.fail("setting with null study id must fail");
592                 } catch (InvalidParameterException e) {
593                         LOG.debug("Expected exception is thrown: "
594                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
595                 }
596
597                 // Non-existing id
598                 Study tmpStudy = TestEntitiesGenerator.getTestStudy(user);
599                 _studyDAO.create(tmpStudy);
600                 Long nonExistingId = tmpStudy.getIndex();
601                 _studyDAO.delete(tmpStudy);
602
603                 try {
604                         _studyService.setDescription(nonExistingId, "description");
605                         Assert.fail("retrieval with non-existing study id must fail");
606                 } catch (InvalidParameterException e) {
607                         LOG.debug("Expected exception is thrown: "
608                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
609                 }
610
611                 rollbackNestedTransaction();
612                 LOG.debug(">>>>> END testSetDescription()");
613         }
614
615         /**
616          * Test of removal of a study description.
617          * 
618          * @throws BusinessException
619          *             if there is something wrong likely unrelated to the tested method
620          */
621         @Test
622         public void testRemoveDescription() throws BusinessException {
623                 LOG.debug(">>>>> BEGIN testRemoveDescription()");
624                 startNestedTransaction();
625
626                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
627                 _userDAO.create(user);
628                 Study study = TestEntitiesGenerator.getTestStudy(user);
629                 _studyDAO.create(study);
630                 _studyDAO.flush();
631                 Long studyId = Long.valueOf(study.getIndex());
632
633                 // Empty description:
634                 Assert.assertFalse(_studyService.removeDescription(studyId),
635                                 "returned value for study without description must be null");
636
637                 // Not empty description:
638                 study.setAttribute(new DescriptionAttribute(study, "description"));
639                 _studyDAO.update(study);
640                 _studyDAO.flush();
641                 Assert.assertTrue(_studyService.removeDescription(studyId),
642                                 "existing description removal must return true");
643
644                 Assert.assertNull(_studyService.getDescription(studyId),
645                                 "description hasn't been successfully removed");
646
647                 // null id
648                 try {
649                         _studyService.removeDescription(null);
650                         Assert.fail("removal with null study id must fail");
651                 } catch (InvalidParameterException e) {
652                         LOG.debug("Expected exception is thrown: "
653                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
654                 }
655
656                 // Non-existing id
657                 Study tmpStudy = TestEntitiesGenerator.getTestStudy(user);
658                 _studyDAO.create(tmpStudy);
659                 Long nonExistingId = tmpStudy.getIndex();
660                 _studyDAO.delete(tmpStudy);
661                 try {
662                         _studyService.removeDescription(nonExistingId);
663                         Assert.fail("removal with non-existing study id must fail");
664                 } catch (InvalidParameterException e) {
665                         LOG.debug("Expected exception is thrown: "
666                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
667                 }
668
669                 rollbackNestedTransaction();
670                 LOG.debug(">>>>> END testGetDescription()");
671         }
672
673         /**
674          * Test study removal.<BR>
675          * <B>Description :</B> <BR>
676          * <i>Delete a study.</i><BR>
677          * <B>Action : </B><BR>
678          * <i>1. call the method for a not existing study id expecting an exception.</i><BR>
679          * <i>2. call the method for an existing study id.</i><BR>
680          * <B>Test data : </B><BR>
681          * <i>no input parameters</i><BR>
682          * 
683          * <B>Outcome results:</B><BR>
684          * <i>
685          * <ul>
686          * <li>1: Exception must be thrown.</li>
687          * <li>2: The study and all its objects must be removed.</li>
688          * </ul>
689          * </i>
690          * 
691          * @throws BusinessException
692          *             if test data creation is failed
693          * @throws IOException
694          *             if document creation is failed
695          */
696         @Test
697         public void testRemoveStudy() throws BusinessException, IOException {
698                 LOG.debug(">>>>> BEGIN testRemoveStudy()");
699                 startNestedTransaction();
700
701                 HibernateTemplate ht = getHibernateTemplate();
702
703                 Database.getInstance().reset();
704                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
705                 // Load workflow customization
706                 try {
707                         _projectSettings.configure("classpath:test/som.xml");
708                 } catch (Exception e) {
709                         Assert.fail("Can't load som.xml: ", e);
710                 }
711
712                 User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
713                 _userDAO.create(goodUser);
714                 User otherUser = TestEntitiesGenerator.getTestUser("otherUser");
715                 _userDAO.create(otherUser);
716                 User thirdUser = TestEntitiesGenerator.getTestUser("thirdUser");
717                 _userDAO.create(thirdUser);
718                 KnowledgeElementType ktype1 = new KnowledgeElementType("testKType1");
719                 KnowledgeElementType ktype2 = new KnowledgeElementType("testKType2");
720                 ktype2.setState(ProgressState.inWORK);
721                 _knowledgeElementTypeDAO.create(ktype1);
722                 _knowledgeElementTypeDAO.create(ktype2);
723
724                 // Create private study
725                 Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
726                 aStudy.setTitle("0.This is private study");
727                 Long studyId = _studyDAO.create(aStudy);
728
729                 // Add simulation context to the study
730                 SimulationContext.Properties cprop = new SimulationContext.Properties();
731                 cprop.setType(_simulationContextService.selectType("product"))
732                                 .setValue("Test Simulation Context: Product");
733                 _studyService.addProjectContext(aStudy, cprop);
734                 ht.flush();
735
736                 // Add a scenario to the study
737                 Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
738                 _scenarioDAO.create(scen);
739                 ht.flush();
740
741                 // Add knowledge elements to the scenario
742                 KnowledgeElement kelm01 = TestEntitiesGenerator
743                                 .getTestKnowledgeElement(scen, ktype1, "TestKelm01 title");
744                 KnowledgeElement kelm02 = TestEntitiesGenerator
745                                 .getTestKnowledgeElement(scen, ktype2, "TestKelm02 title");
746                 _knowledgeElementDAO.create(kelm01);
747                 _knowledgeElementDAO.create(kelm02);
748                 ht.flush();
749
750                 // Add contributor relation
751                 aStudy.addRelation(new ContributorRelation(aStudy, otherUser));
752                 ht.flush();
753
754                 // Add a validation cycle with otherUser as a reviewer
755                 ValidationCycle.Properties vprop = new ValidationCycle.Properties();
756                 DocumentType dtype = _documentTypeService.selectType("minutes");
757                 vprop.setDocumentType(dtype);
758                 vprop.setActor(ValidationStep.REVIEW, otherUser);
759                 ValidationCycle cycle = new ValidationCycle(aStudy, vprop);
760                 _validationCycleDAO.create(cycle);
761                 ValidationCycleRelation link = cycle.getContext();
762                 aStudy.addRelation(link);
763                 ht.flush();
764
765                 // Add documents to the first study activity
766                 // Add a converts relations
767                 Publication pub1 = addDoc(aStudy, "document1", dtype);
768                 Publication pub2 = addDoc(aStudy, "document2", dtype);
769                 Publication pub3 = addDoc(aStudy, "document3", dtype);
770                 ht.flush();
771
772                 LOG.debug("pub1 version doc: " + pub1.value().getTitle() + " ["
773                                 + pub1.value().getReference() + "]" + " ["
774                                 + pub1.value().getRid() + "]");
775                 LOG.debug("pub2 version doc: " + pub2.value().getTitle() + " ["
776                                 + pub2.value().getReference() + "]" + " ["
777                                 + pub2.value().getRid() + "]");
778                 LOG.debug("pub3 version doc: " + pub3.value().getTitle() + " ["
779                                 + pub3.value().getReference() + "]" + " ["
780                                 + pub3.value().getRid() + "]");
781
782                 ht.update(aStudy);
783
784                 ht.flush();
785                 LOG.debug("Before versioning:");
786                 for (Publication doc : _projectElementService.getFirstStep(aStudy)
787                                 .getAllDocuments()) {
788                         LOG.debug("Study doc: " + doc.value().getTitle() + " ["
789                                         + doc.value().getReference() + "]" + " ["
790                                         + doc.value().getRid() + "]");
791                 }
792                 // Add a version relations
793                 Publication pub31 = version(pub3);
794
795                 // _publicationService.versionDocument(_projectElementService
796                 // .getFirstStep(aStudy), goodUser, pub3
797                 // .getSourceFile().getName(), pub3.value().getIndex(), "",
798                 // "The new version", pub3.getProgressState(), new Date(), null,
799                 // null);
800
801                 // Publication pub31 = null;
802                 // for (Publication pub : aStudy.getDocums()) {
803                 // if (pub.value().getPreviousVersion() != null) {
804                 // pub31 = pub;
805                 // }
806                 // }
807
808                 LOG.debug("pub31 version doc: " + pub31.value().getTitle() + " ["
809                                 + pub31.value().getReference() + "]" + " ["
810                                 + pub31.value().getRid() + "]");
811                 ht.saveOrUpdate(aStudy);
812
813                 LOG.debug("After versioning:");
814                 for (Publication doc : aStudy.getDocums()) {
815                         LOG.debug("Study doc: " + doc.value().getTitle() + " ["
816                                         + doc.value().getReference() + "]" + " ["
817                                         + doc.value().getRid() + "]");
818                 }
819
820                 // Add documents to the first scenario activity
821                 Publication spub1 = addDoc(scen, "sdocument1", dtype);
822                 Publication spub2 = addDoc(scen, "sdocument2", dtype);
823                 Publication spub3 = addDoc(scen, "sdocument3", dtype);
824                 LOG.debug("spub1 version doc: " + spub1.value().getTitle() + " ["
825                                 + spub1.value().getReference() + "]" + " ["
826                                 + spub1.value().getRid() + "]");
827                 LOG.debug("spub2 version doc: " + spub2.value().getTitle() + " ["
828                                 + spub2.value().getReference() + "]" + " ["
829                                 + spub2.value().getRid() + "]");
830                 LOG.debug("spub3 version doc: " + spub3.value().getTitle() + " ["
831                                 + spub3.value().getReference() + "]" + " ["
832                                 + spub3.value().getRid() + "]");
833                 ht.flush();
834
835                 // Create a scenario document version
836                 Publication spub31 = version(spub3);
837                 LOG.debug("spub31 version doc: " + spub31.value().getTitle() + " ["
838                                 + spub31.value().getReference() + "]" + " ["
839                                 + spub31.value().getRid() + "]");
840
841                 // Add uses relations
842                 pub2.addDependency(pub1);
843                 ht.saveOrUpdate(pub2.value());
844                 pub3.addDependency(pub2);
845                 ht.saveOrUpdate(pub3.value());
846
847                 spub2.addDependency(pub1);
848                 spub2.addDependency(spub1);
849                 spub2.addDependency(pub2);
850                 spub2.addDependency(pub3);
851                 ht.saveOrUpdate(spub2.value());
852                 spub3.addDependency(spub2);
853                 ht.saveOrUpdate(spub3.value());
854                 spub31.addDependency(spub31);
855                 ht.saveOrUpdate(spub31.value());
856                 ht.flush();
857
858                 // /////////////////////////////////////////////////////////
859                 ht.clear();
860                 // Check removal of contributors relation
861                 List found1 = ht
862                                 .find("from ContributorRelation where owner=" + studyId);
863                 Assert.assertEquals(found1.size(), 1,
864                                 "ContributorRelation is not created");
865                 ht.clear();
866
867                 _studyService.removeStudy(studyId);
868                 ht.flush();
869
870                 // Check removal of the study
871                 Study foundStudy = ht.get(Study.class, studyId);
872                 Assert.assertNull(foundStudy);
873                 // Check removal of relations to validation cycle
874                 List found = ht.find("from ValidationCycleRelation where owner="
875                                 + studyId);
876                 Assert.assertEquals(found.size(), 0,
877                                 "ValidationCycleRelation is not removed");
878                 // Check removal of validation cycles
879                 found = ht.find("from ValidationCycle where rid=" + cycle.getIndex());
880                 Assert.assertEquals(found.size(), 0, "ValidationCycle is not removed");
881                 // Check removal of contributors relation
882                 found = ht.find("from ContributorRelation where owner=" + studyId);
883                 Assert.assertEquals(found.size(), 0,
884                                 "ContributorRelation is not removed");
885                 // Check that contributors are not removed
886                 User foundUser = ht.get(User.class, otherUser.getIndex());
887                 Assert.assertNotNull(foundUser);
888                 // Check removal of the scenario
889                 found = ht.find("from Scenario where owner=" + studyId);
890                 Assert.assertEquals(found.size(), 0, "Scenario is not removed");
891                 // Check removal of publications
892                 found = ht
893                                 .find("from Publication pub left join pub.owner as own where own.rid="
894                                                 + studyId + " or own.rid=" + scen.getIndex());
895                 Assert.assertEquals(found.size(), 0, "Publication is not removed");
896                 found = ht.find("from Publication");
897                 Assert.assertEquals(found.size(), 0, "Publication is not removed");
898                 // Check removal of documents
899                 found = ht.find("from Document");
900                 Assert.assertEquals(found.size(), 0, "Document is not removed");
901                 // Check removal of version relations
902                 found = ht.find("from VersionsRelation");
903                 Assert.assertEquals(found.size(), 0, "VersionsRelation is not removed");
904                 // Check removal of converts relations
905                 found = ht.find("from ConvertsRelation");
906                 Assert.assertEquals(found.size(), 0, "ConvertsRelation is not removed");
907                 // Check removal of files
908                 found = ht.find("from File");
909                 Assert.assertEquals(found.size(), 0, "File is not removed");
910                 // Check removal of uses relations
911                 found = ht.find("from UsesRelation");
912                 Assert.assertEquals(found.size(), 0, "UsesRelation is not removed");
913                 // Check removal of usedBy relations
914                 found = ht.find("from UsedByRelation");
915                 Assert.assertEquals(found.size(), 0, "UsedByRelation is not removed");
916
917                 rollbackNestedTransaction();
918                 LOG.debug(">>>>> END testRemoveStudy()");
919         }
920
921         /**
922          * Create a document and publish it in the project element.
923          * 
924          * @param aProjElem
925          *            the project element
926          * @param stStep
927          * @param docname
928          *            document name
929          * @param dtype
930          *            document type
931          * @return publication of the created document
932          * @throws BusinessException
933          *             if document creation is failed
934          * @throws IOException
935          *             if file creation is failed
936          */
937         private Publication addDoc(final ProjectElement aProjElem,
938                         final String docname, final DocumentType dtype)
939                         throws BusinessException, IOException {
940                 HibernateTemplate ht = getHibernateTemplate();
941                 // Add documents to the first study activity
942                 org.splat.som.Step aStep = _projectElementService
943                                 .getFirstStep(aProjElem);
944                 Document.Properties dprop = new Document.Properties().setAuthor(
945                                 aProjElem.getAuthor()).setDate(new Date()).setName(docname)
946                                 .setType(dtype).setFormat("py");
947                 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
948                 dprop.setStep(aStep.getStep());
949                 Publication pub = _stepService.createDocument(aStep, dprop);
950                 pub.setStep(aStep);
951                 aProjElem.add(pub);
952                 aStep.getDocuments().add(pub);
953                 ht.saveOrUpdate(pub);
954                 ht.save(pub.value());
955                 // Add a converts relation
956                 // Attach a med file
957                 ht.saveOrUpdate(_publicationService.attach(pub, "med"));
958                 createDownloadedFile(aProjElem.getAuthor().getIndex(), dprop
959                                 .getLocalPath());
960                 createDownloadedFile(aProjElem.getAuthor().getIndex(), dprop
961                                 .getLocalPath().substring(0,
962                                                 dprop.getLocalPath().lastIndexOf(".") - 1), "med");
963                 return pub;
964         }
965
966         /**
967          * Create a file in the user's repository downloads directory.
968          * 
969          * @param userId
970          *            user id
971          * @param name
972          *            file name
973          * @param format
974          *            file extension
975          * @return created file DTO
976          * @throws IOException
977          *             if file creation failed
978          */
979         private FileDTO createDownloadedFile(final long userId, final String name,
980                         final String format) throws IOException {
981                 // Create a file in the download directory
982                 return createDownloadedFile(userId, name + "." + format);
983         }
984
985         /**
986          * Create a file in the user's repository downloads directory.
987          * 
988          * @param userId
989          *            user id
990          * @param fname
991          *            file name
992          * @return created file DTO
993          * @throws IOException
994          *             if file creation failed
995          */
996         private FileDTO createDownloadedFile(final long userId, final String fname)
997                         throws IOException {
998                 // Create a file in the download directory
999                 String filePath = getDownloadPath(userId) + fname;
1000                 FileWriter fw = new FileWriter(filePath);
1001                 fw.write("Simulation of " + fname + " file for checkin at "
1002                                 + new Date());
1003                 fw.close();
1004                 return new FileDTO(filePath);
1005         }
1006
1007         @Test
1008         public void testReaders() throws InvalidPropertyException,
1009                         BusinessException {
1010                 LOG.debug(">>>>> BEGIN testReaders()");
1011                 startNestedTransaction();
1012
1013                 HibernateTemplate ht = getHibernateTemplate();
1014
1015                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
1016                 _userDAO.create(user);
1017                 Study study = TestEntitiesGenerator.getTestStudy(user);
1018                 _studyDAO.create(study);
1019                 _studyDAO.flush();
1020                 ht.clear();
1021                 long studyId = study.getIndex();
1022                 long userId = user.getIndex();
1023
1024                 // get a non-existing user id
1025                 User nonExistingUser = TestEntitiesGenerator
1026                                 .getTestUser("nonExistingUser");
1027                 _userDAO.create(nonExistingUser);
1028                 long nonExistingUserId = nonExistingUser.getIndex();
1029                 _userDAO.delete(nonExistingUser);
1030                 _userDAO.flush();
1031                 ht.clear();
1032
1033                 // get a non-existing study id
1034                 Study nonExistingStudy = TestEntitiesGenerator.getTestStudy(user);
1035                 _studyDAO.create(nonExistingStudy);
1036                 long nonExistingStudyId = nonExistingStudy.getIndex();
1037                 _studyDAO.delete(nonExistingStudy);
1038                 _userDAO.flush();
1039                 ht.clear();
1040
1041                 // ==============================================================================================================================
1042                 // 1.Non-existing user and study ids
1043                 // ==============================================================================================================================
1044
1045                 // Test getReaders method with a non-existing study id
1046                 try {
1047                         _studyService.getReaders(nonExistingStudyId);
1048                         Assert.fail("retrieval of readers with non-existing study id "
1049                                         + "must throw InvalidParameterException");
1050                 } catch (InvalidParameterException e) {
1051                         LOG.debug("Expected exception is thrown: "
1052                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
1053                 }
1054
1055                 // Test removeReader method with a non-existing study id
1056                 try {
1057                         _studyService.removeReader(nonExistingStudyId, userId);
1058                         Assert
1059                                         .fail("attempt to remove from readers with non-existing study id "
1060                                                         + "must throw InvalidParameterException");
1061                 } catch (InvalidParameterException e) {
1062                         LOG.debug("Expected exception is thrown: "
1063                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
1064                 }
1065
1066                 // Test removeReader method with an non-existing user id
1067                 try {
1068                         _studyService.removeReader(studyId, nonExistingUserId);
1069                         Assert
1070                                         .fail("attempt to remove from readers with non-existing user id "
1071                                                         + "must throw InvalidParameterException");
1072                 } catch (InvalidParameterException e) {
1073                         LOG.debug("Expected exception is thrown: "
1074                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
1075                 }
1076
1077                 // Test addReader method with a non-existing study id
1078                 try {
1079                         _studyService.addReader(nonExistingStudyId, userId);
1080                         Assert
1081                                         .fail("attempt to add a user to readers of a study with non-existing study id "
1082                                                         + "must throw InvalidParameterException");
1083                 } catch (InvalidParameterException e) {
1084                         LOG.debug("Expected exception is thrown: "
1085                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
1086                 }
1087
1088                 // Test addReader method with a non-existing user id
1089                 try {
1090                         _studyService.addReader(studyId, nonExistingUserId);
1091                         Assert
1092                                         .fail("attempt to add to readers a user with non-existing id "
1093                                                         + "must throw InvalidParameterException");
1094                 } catch (InvalidParameterException e) {
1095                         LOG.debug("Expected exception is thrown: "
1096                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
1097                 }
1098
1099                 // ==============================================================================================================================
1100                 // 2.Existing user who is not yet reader
1101                 // ==============================================================================================================================
1102
1103                 // Test getReaders method with no readers
1104                 Assert.assertTrue(_studyService.getReaders(studyId).isEmpty(),
1105                                 "returned list for a study without readers must be empty");
1106
1107                 // Test removeReader method with an existing user who is not reader
1108                 Assert
1109                                 .assertFalse(_studyService.removeReader(studyId, userId),
1110                                                 "attempt to remove from readers of a non-reader user must return false");
1111
1112                 // ADD A READER:
1113                 // Test addReader method with an existing user who is not yet reader
1114                 Assert.assertTrue(_studyService.addReader(studyId, userId),
1115                                 "addition of a user who is not yet reader must return true");
1116
1117                 _studyDAO.flush();
1118                 ht.clear();
1119                 study = _studyDAO.get(studyId);
1120
1121                 List<Relation> readerRelations = study
1122                                 .getRelations(ReaderRelation.class);
1123                 Assert.assertTrue(readerRelations.size() == 1,
1124                                 "The retrieved relations list has wrong size");
1125                 Assert
1126                                 .assertEquals(readerRelations.get(0).getFrom(), study,
1127                                                 "the retrieved relation does not equal the one that has been added.");
1128                 Assert
1129                                 .assertEquals(readerRelations.get(0).getTo(), user,
1130                                                 "the retrieved relation does not equal the one that has been added.");
1131
1132                 // ==============================================================================================================================
1133                 // 3.Existing reader
1134                 // ==============================================================================================================================
1135
1136                 // Test getReaders method with an existing reader
1137                 List<UserDTO> readers = _studyService.getReaders(studyId);
1138                 Assert.assertTrue(readers.size() == 1,
1139                                 "The retrieved reader list has wrong size");
1140                 Assert
1141                                 .assertEquals(readers.get(0), BeanHelper.copyBean(user,
1142                                                 UserDTO.class),
1143                                                 "the retrieved user does not equal the one that has been added.");
1144
1145                 // Test addReader method with a user who is already reader
1146                 Assert.assertFalse(_studyService.addReader(studyId, userId),
1147                                 "addition of a user who is already reader must return false");
1148
1149                 // Test removeReader method with a user user who is already reader
1150                 Assert
1151                                 .assertTrue(_studyService.removeReader(studyId, userId),
1152                                                 "removal from readers of a user who is study reader must return true");
1153                 Assert.assertTrue(study.getRelations(ReaderRelation.class).isEmpty(),
1154                                 "a relation has not been properly removed");
1155
1156                 rollbackNestedTransaction();
1157                 LOG.debug(">>>>> END testReaders()");
1158         }
1159 }