]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/Siman-Common/src/test/splat/service/TestStudyService.java
Salome HOME
Added checking of a document state when replacing a source file. Exception is thrown...
[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 setting 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 testSetDescription() throws BusinessException {
545                 LOG.debug(">>>>> BEGIN testSetDescription()");
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                 Long studyId = Long.valueOf(study.getIndex());
554
555                 // Setting description for study without any
556                 _studyService.setDescription(studyId, "description");
557
558                 // Resetting description
559                 _studyService.setDescription(studyId, "replaced description");
560
561                 // null id
562                 try {
563                         _studyService.setDescription(null, "description");
564                         Assert.fail("setting with null study id must fail");
565                 } catch (InvalidParameterException e) {
566                         LOG.debug("Expected exception is thrown: "
567                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
568                 }
569
570                 // Non-existing id
571                 Study tmpStudy = TestEntitiesGenerator.getTestStudy(user);
572                 _studyDAO.create(tmpStudy);
573                 Long nonExistingId = tmpStudy.getIndex();
574                 _studyDAO.delete(tmpStudy);
575
576                 try {
577                         _studyService.setDescription(nonExistingId, "description");
578                         Assert.fail("retrieval with non-existing study id must fail");
579                 } catch (InvalidParameterException e) {
580                         LOG.debug("Expected exception is thrown: "
581                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
582                 }
583
584                 rollbackNestedTransaction();
585                 LOG.debug(">>>>> END testSetDescription()");
586         }
587
588         /**
589          * Test of removal of a study description.
590          * 
591          * @throws BusinessException
592          *             if there is something wrong likely unrelated to the tested method
593          */
594         @Test
595         public void testRemoveDescription() throws BusinessException {
596                 LOG.debug(">>>>> BEGIN testRemoveDescription()");
597                 startNestedTransaction();
598
599                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
600                 _userDAO.create(user);
601                 Study study = TestEntitiesGenerator.getTestStudy(user);
602                 _studyDAO.create(study);
603                 _studyDAO.flush();
604                 Long studyId = Long.valueOf(study.getIndex());
605
606                 // Empty description:
607                 Assert.assertFalse(_studyService.removeDescription(studyId),
608                                 "returned value for study without description must be null");
609
610                 // Not empty description:
611                 study.setAttribute(new DescriptionAttribute(study, "description"));
612                 _studyDAO.update(study);
613                 _studyDAO.flush();
614                 Assert.assertTrue(_studyService.removeDescription(studyId),
615                                 "existing description removal must return true");
616
617                 Assert.assertNull(_studyService.getDescription(studyId),
618                                 "description hasn't been successfully removed");
619
620                 // null id
621                 try {
622                         _studyService.removeDescription(null);
623                         Assert.fail("removal with null study id must fail");
624                 } catch (InvalidParameterException e) {
625                         LOG.debug("Expected exception is thrown: "
626                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
627                 }
628
629                 // Non-existing id
630                 Study tmpStudy = TestEntitiesGenerator.getTestStudy(user);
631                 _studyDAO.create(tmpStudy);
632                 Long nonExistingId = tmpStudy.getIndex();
633                 _studyDAO.delete(tmpStudy);
634                 try {
635                         _studyService.removeDescription(nonExistingId);
636                         Assert.fail("removal with non-existing study id must fail");
637                 } catch (InvalidParameterException e) {
638                         LOG.debug("Expected exception is thrown: "
639                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
640                 }
641
642                 rollbackNestedTransaction();
643                 LOG.debug(">>>>> END testGetDescription()");
644         }
645
646         /**
647          * Test study removal.<BR>
648          * <B>Description :</B> <BR>
649          * <i>Delete a study.</i><BR>
650          * <B>Action : </B><BR>
651          * <i>1. call the method for a not existing study id expecting an exception.</i><BR>
652          * <i>2. call the method for an existing study id.</i><BR>
653          * <B>Test data : </B><BR>
654          * <i>no input parameters</i><BR>
655          * 
656          * <B>Outcome results:</B><BR>
657          * <i>
658          * <ul>
659          * <li>1: Exception must be thrown.</li>
660          * <li>2: The study and all its objects must be removed.</li>
661          * </ul>
662          * </i>
663          * 
664          * @throws BusinessException
665          *             if test data creation is failed
666          * @throws IOException
667          *             if document creation is failed
668          */
669         @Test
670         public void testRemoveStudy() throws BusinessException, IOException {
671                 LOG.debug(">>>>> BEGIN testRemoveStudy()");
672                 startNestedTransaction();
673
674                 HibernateTemplate ht = getHibernateTemplate();
675
676                 Database.getInstance().reset();
677                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
678                 // Load workflow customization
679                 try {
680                         _projectSettings.configure("classpath:test/som.xml");
681                 } catch (Exception e) {
682                         Assert.fail("Can't load som.xml: ", e);
683                 }
684
685                 User goodUser = TestEntitiesGenerator.getTestUser("GoodUser");
686                 _userDAO.create(goodUser);
687                 User otherUser = TestEntitiesGenerator.getTestUser("otherUser");
688                 _userDAO.create(otherUser);
689                 User thirdUser = TestEntitiesGenerator.getTestUser("thirdUser");
690                 _userDAO.create(thirdUser);
691                 KnowledgeElementType ktype1 = new KnowledgeElementType("testKType1");
692                 KnowledgeElementType ktype2 = new KnowledgeElementType("testKType2");
693                 ktype2.setState(ProgressState.inWORK);
694                 _knowledgeElementTypeDAO.create(ktype1);
695                 _knowledgeElementTypeDAO.create(ktype2);
696
697                 // Create private study
698                 Study aStudy = TestEntitiesGenerator.getTestStudy(goodUser);
699                 aStudy.setTitle("0.This is private study");
700                 Long studyId = _studyDAO.create(aStudy);
701
702                 // Add simulation context to the study
703                 SimulationContext.Properties cprop = new SimulationContext.Properties();
704                 cprop.setType(_simulationContextService.selectType("product"))
705                                 .setValue("Test Simulation Context: Product");
706                 _studyService.addProjectContext(aStudy, cprop);
707                 ht.flush();
708
709                 // Add a scenario to the study
710                 Scenario scen = TestEntitiesGenerator.getTestScenario(aStudy);
711                 _scenarioDAO.create(scen);
712                 ht.flush();
713
714                 // Add knowledge elements to the scenario
715                 KnowledgeElement kelm01 = TestEntitiesGenerator
716                                 .getTestKnowledgeElement(scen, ktype1, "TestKelm01 title");
717                 KnowledgeElement kelm02 = TestEntitiesGenerator
718                                 .getTestKnowledgeElement(scen, ktype2, "TestKelm02 title");
719                 _knowledgeElementDAO.create(kelm01);
720                 _knowledgeElementDAO.create(kelm02);
721                 ht.flush();
722
723                 // Add contributor relation
724                 aStudy.addRelation(new ContributorRelation(aStudy, otherUser));
725                 ht.flush();
726
727                 // Add a validation cycle with otherUser as a reviewer
728                 ValidationCycle.Properties vprop = new ValidationCycle.Properties();
729                 DocumentType dtype = _documentTypeService.selectType("minutes");
730                 vprop.setDocumentType(dtype);
731                 vprop.setActor(ValidationStep.REVIEW, otherUser);
732                 ValidationCycle cycle = new ValidationCycle(aStudy, vprop);
733                 _validationCycleDAO.create(cycle);
734                 ValidationCycleRelation link = cycle.getContext();
735                 aStudy.addRelation(link);
736                 ht.flush();
737
738                 // Add documents to the first study activity
739                 // Add a converts relations
740                 Publication pub1 = addDoc(aStudy, "document1", dtype);
741                 Publication pub2 = addDoc(aStudy, "document2", dtype);
742                 Publication pub3 = addDoc(aStudy, "document3", dtype);
743                 ht.flush();
744
745                 LOG.debug("pub1 version doc: " + pub1.value().getTitle() + " ["
746                                 + pub1.value().getReference() + "]" + " ["
747                                 + pub1.value().getRid() + "]");
748                 LOG.debug("pub2 version doc: " + pub2.value().getTitle() + " ["
749                                 + pub2.value().getReference() + "]" + " ["
750                                 + pub2.value().getRid() + "]");
751                 LOG.debug("pub3 version doc: " + pub3.value().getTitle() + " ["
752                                 + pub3.value().getReference() + "]" + " ["
753                                 + pub3.value().getRid() + "]");
754
755                 ht.update(aStudy);
756
757                 ht.flush();
758                 LOG.debug("Before versioning:");
759                 for (Publication doc : _projectElementService.getFirstStep(aStudy)
760                                 .getAllDocuments()) {
761                         LOG.debug("Study doc: " + doc.value().getTitle() + " ["
762                                         + doc.value().getReference() + "]" + " ["
763                                         + doc.value().getRid() + "]");
764                 }
765                 // Add a version relations
766                 Publication pub31 = version(pub3);
767
768                 // _publicationService.versionDocument(_projectElementService
769                 // .getFirstStep(aStudy), goodUser, pub3
770                 // .getSourceFile().getName(), pub3.value().getIndex(), "",
771                 // "The new version", pub3.getProgressState(), new Date(), null,
772                 // null);
773
774                 // Publication pub31 = null;
775                 // for (Publication pub : aStudy.getDocums()) {
776                 // if (pub.value().getPreviousVersion() != null) {
777                 // pub31 = pub;
778                 // }
779                 // }
780
781                 LOG.debug("pub31 version doc: " + pub31.value().getTitle() + " ["
782                                 + pub31.value().getReference() + "]" + " ["
783                                 + pub31.value().getRid() + "]");
784                 ht.saveOrUpdate(aStudy);
785
786                 LOG.debug("After versioning:");
787                 for (Publication doc : aStudy.getDocums()) {
788                         LOG.debug("Study doc: " + doc.value().getTitle() + " ["
789                                         + doc.value().getReference() + "]" + " ["
790                                         + doc.value().getRid() + "]");
791                 }
792
793                 // Add documents to the first scenario activity
794                 Publication spub1 = addDoc(scen, "sdocument1", dtype);
795                 Publication spub2 = addDoc(scen, "sdocument2", dtype);
796                 Publication spub3 = addDoc(scen, "sdocument3", dtype);
797                 LOG.debug("spub1 version doc: " + spub1.value().getTitle() + " ["
798                                 + spub1.value().getReference() + "]" + " ["
799                                 + spub1.value().getRid() + "]");
800                 LOG.debug("spub2 version doc: " + spub2.value().getTitle() + " ["
801                                 + spub2.value().getReference() + "]" + " ["
802                                 + spub2.value().getRid() + "]");
803                 LOG.debug("spub3 version doc: " + spub3.value().getTitle() + " ["
804                                 + spub3.value().getReference() + "]" + " ["
805                                 + spub3.value().getRid() + "]");
806                 ht.flush();
807
808                 // Create a scenario document version
809                 Publication spub31 = version(spub3);
810                 LOG.debug("spub31 version doc: " + spub31.value().getTitle() + " ["
811                                 + spub31.value().getReference() + "]" + " ["
812                                 + spub31.value().getRid() + "]");
813
814                 // Add uses relations
815                 pub2.addDependency(pub1);
816                 ht.saveOrUpdate(pub2.value());
817                 pub3.addDependency(pub2);
818                 ht.saveOrUpdate(pub3.value());
819
820                 spub2.addDependency(pub1);
821                 spub2.addDependency(spub1);
822                 spub2.addDependency(pub2);
823                 spub2.addDependency(pub3);
824                 ht.saveOrUpdate(spub2.value());
825                 spub3.addDependency(spub2);
826                 ht.saveOrUpdate(spub3.value());
827                 spub31.addDependency(spub31);
828                 ht.saveOrUpdate(spub31.value());
829                 ht.flush();
830
831                 // /////////////////////////////////////////////////////////
832                 ht.clear();
833                 // Check removal of contributors relation
834                 List found1 = ht.find("from ContributorRelation where owner=" + studyId);
835                 Assert.assertEquals(found1.size(), 1,
836                                 "ContributorRelation is not created");
837                 ht.clear();
838                 
839                 _studyService.removeStudy(studyId);
840                 ht.flush();
841
842                 // Check removal of the study
843                 Study foundStudy = ht.get(Study.class, studyId);
844                 Assert.assertNull(foundStudy);
845                 // Check removal of relations to validation cycle
846                 List found = ht.find("from ValidationCycleRelation where owner="
847                                 + studyId);
848                 Assert.assertEquals(found.size(), 0,
849                                 "ValidationCycleRelation is not removed");
850                 // Check removal of validation cycles
851                 found = ht.find("from ValidationCycle where rid=" + cycle.getIndex());
852                 Assert.assertEquals(found.size(), 0, "ValidationCycle is not removed");
853                 // Check removal of contributors relation
854                 found = ht.find("from ContributorRelation where owner=" + studyId);
855                 Assert.assertEquals(found.size(), 0,
856                                 "ContributorRelation is not removed");
857                 // Check that contributors are not removed
858                 User foundUser = ht.get(User.class, otherUser.getIndex());
859                 Assert.assertNotNull(foundUser);
860                 // Check removal of the scenario
861                 found = ht.find("from Scenario where owner=" + studyId);
862                 Assert.assertEquals(found.size(), 0, "Scenario is not removed");
863                 // Check removal of publications
864                 found = ht
865                                 .find("from Publication pub left join pub.owner as own where own.rid="
866                                                 + studyId + " or own.rid=" + scen.getIndex());
867                 Assert.assertEquals(found.size(), 0, "Publication is not removed");
868                 found = ht.find("from Publication");
869                 Assert.assertEquals(found.size(), 0, "Publication is not removed");
870                 // Check removal of documents
871                 found = ht.find("from Document");
872                 Assert.assertEquals(found.size(), 0, "Document is not removed");
873                 // Check removal of version relations
874                 found = ht.find("from VersionsRelation");
875                 Assert.assertEquals(found.size(), 0, "VersionsRelation is not removed");
876                 // Check removal of converts relations
877                 found = ht.find("from ConvertsRelation");
878                 Assert.assertEquals(found.size(), 0, "ConvertsRelation is not removed");
879                 // Check removal of files
880                 found = ht.find("from File");
881                 Assert.assertEquals(found.size(), 0, "File is not removed");
882                 // Check removal of uses relations
883                 found = ht.find("from UsesRelation");
884                 Assert.assertEquals(found.size(), 0, "UsesRelation is not removed");
885                 // Check removal of usedBy relations
886                 found = ht.find("from UsedByRelation");
887                 Assert.assertEquals(found.size(), 0, "UsedByRelation is not removed");
888
889                 rollbackNestedTransaction();
890                 LOG.debug(">>>>> END testRemoveStudy()");
891         }
892
893         /**
894          * Create a document and publish it in the project element.
895          * 
896          * @param aProjElem
897          *            the project element
898          * @param stStep
899          * @param docname
900          *            document name
901          * @param dtype
902          *            document type
903          * @return publication of the created document
904          * @throws BusinessException
905          *             if document creation is failed
906          * @throws IOException
907          *             if file creation is failed
908          */
909         private Publication addDoc(final ProjectElement aProjElem,
910                         final String docname, final DocumentType dtype)
911                         throws BusinessException, IOException {
912                 HibernateTemplate ht = getHibernateTemplate();
913                 // Add documents to the first study activity
914                 org.splat.som.Step aStep = _projectElementService.getFirstStep(aProjElem);
915                 Document.Properties dprop = new Document.Properties().setAuthor(
916                                 aProjElem.getAuthor()).setDate(new Date()).setName(docname)
917                                 .setType(dtype).setFormat("py");
918                 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
919                 dprop.setStep(aStep.getStep());
920                 Publication pub = _stepService.createDocument(aStep, dprop);
921                 pub.setStep(aStep);
922                 aProjElem.add(pub);
923                 aStep.getDocuments().add(pub);
924                 ht.saveOrUpdate(pub);
925                 ht.save(pub.value());
926                 // Add a converts relation
927                 // Attach a med file
928                 ht.saveOrUpdate(_publicationService.attach(pub, "med"));
929                 createDownloadedFile(aProjElem.getAuthor().getIndex(), dprop
930                                 .getLocalPath());
931                 createDownloadedFile(aProjElem.getAuthor().getIndex(), dprop
932                                 .getLocalPath().substring(0,
933                                                 dprop.getLocalPath().lastIndexOf(".") - 1), "med");
934                 return pub;
935         }
936
937         /**
938          * Create a file in the user's repository downloads directory.
939          * 
940          * @param userId
941          *            user id
942          * @param name
943          *            file name
944          * @param format
945          *            file extension
946          * @return created file DTO
947          * @throws IOException
948          *             if file creation failed
949          */
950         private FileDTO createDownloadedFile(final long userId, final String name,
951                         final String format) throws IOException {
952                 // Create a file in the download directory
953                 return createDownloadedFile(userId, name + "." + format);
954         }
955
956         /**
957          * Create a file in the user's repository downloads directory.
958          * 
959          * @param userId
960          *            user id
961          * @param fname
962          *            file name
963          * @return created file DTO
964          * @throws IOException
965          *             if file creation failed
966          */
967         private FileDTO createDownloadedFile(final long userId, final String fname)
968                         throws IOException {
969                 // Create a file in the download directory
970                 String filePath = getDownloadPath(userId) + fname;
971                 FileWriter fw = new FileWriter(filePath);
972                 fw.write("Simulation of " + fname + " file for checkin at "
973                                 + new Date());
974                 fw.close();
975                 return new FileDTO(filePath);
976         }
977
978         @Test
979         public void testReaders() throws InvalidPropertyException, BusinessException {
980                 LOG.debug(">>>>> BEGIN testReaders()");
981                 startNestedTransaction();
982
983                 HibernateTemplate ht = getHibernateTemplate();
984
985                 User user = TestEntitiesGenerator.getTestUser("GoodUser");
986                 _userDAO.create(user);
987                 Study study = TestEntitiesGenerator.getTestStudy(user);
988                 _studyDAO.create(study);
989                 _studyDAO.flush();
990                 ht.clear();
991                 long studyId = study.getIndex();
992                 long userId = user.getIndex();
993                 
994                 //get a non-existing user id
995                 User nonExistingUser = TestEntitiesGenerator.getTestUser("nonExistingUser");
996                 _userDAO.create(nonExistingUser);
997                 long nonExistingUserId = nonExistingUser.getIndex();
998                 _userDAO.delete(nonExistingUser);
999                 _userDAO.flush();
1000                 ht.clear();
1001
1002                 //get a non-existing study id
1003                 Study nonExistingStudy = TestEntitiesGenerator.getTestStudy(user);
1004                 _studyDAO.create(nonExistingStudy);
1005                 long nonExistingStudyId = nonExistingStudy.getIndex();
1006                 _studyDAO.delete(nonExistingStudy);
1007                 _userDAO.flush();
1008                 ht.clear();
1009
1010
1011         //  ==============================================================================================================================
1012         //  1.Non-existing user and study ids
1013         //  ==============================================================================================================================
1014
1015                 //Test getReaders method with a non-existing study id
1016                 try {
1017                         _studyService.getReaders(nonExistingStudyId);
1018                         Assert.fail("retrieval of readers with non-existing study id " +
1019                                         "must throw InvalidParameterException");
1020                 } catch(InvalidParameterException e) {
1021                         LOG.debug("Expected exception is thrown: "
1022                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
1023                 }
1024                 
1025                 //Test removeReader method with a non-existing study id
1026                 try {
1027                         _studyService.removeReader(nonExistingStudyId, userId);
1028                         Assert.fail("attempt to remove from readers with non-existing study id " +
1029                                         "must throw InvalidParameterException");
1030                 } catch(InvalidParameterException e) {
1031                         LOG.debug("Expected exception is thrown: "
1032                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
1033                 }
1034                 
1035                 //Test removeReader method with an non-existing user id
1036                 try {
1037                         _studyService.removeReader(studyId, nonExistingUserId);
1038                         Assert.fail("attempt to remove from readers with non-existing user id " +
1039                                         "must throw InvalidParameterException");                
1040                 } catch(InvalidParameterException e) {
1041                         LOG.debug("Expected exception is thrown: "
1042                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
1043                 }
1044
1045                 //Test addReader method with a non-existing study id
1046                 try {
1047                         _studyService.addReader(nonExistingStudyId, userId);
1048                         Assert.fail("attempt to add a user to readers of a study 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 addReader method with a non-existing user id
1056                 try {
1057                         _studyService.addReader(studyId, nonExistingUserId);
1058                         Assert.fail("attempt to add to readers a user with non-existing id " +
1059                                         "must throw InvalidParameterException");
1060                 } catch(InvalidParameterException e) {
1061                         LOG.debug("Expected exception is thrown: "
1062                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
1063                 }
1064
1065                 //  ==============================================================================================================================
1066                 //  2.Existing user who is not yet reader
1067                 //  ==============================================================================================================================
1068
1069                 //Test getReaders method with no readers
1070                 Assert.assertTrue(_studyService.getReaders(studyId).isEmpty(),
1071                                 "returned list for a study without readers must be empty");
1072                 
1073                 //Test removeReader method with an existing user who is not reader
1074                 Assert.assertFalse(_studyService.removeReader(studyId, userId),
1075                                 "attempt to remove from readers of a non-reader user must return false");
1076                 
1077                 //ADD A READER:
1078                 //Test addReader method with an existing user who is not yet reader
1079                 Assert.assertTrue(_studyService.addReader(studyId, userId),
1080                                 "addition of a user who is not yet reader must return true");
1081                 
1082                 _studyDAO.flush();
1083                 ht.clear();
1084                 study = _studyDAO.get(studyId);
1085                 
1086                 List<Relation> readerRelations = study.getRelations(ReaderRelation.class);
1087                 Assert.assertTrue(readerRelations.size() == 1, "The retrieved relations list has wrong size");
1088                 Assert.assertEquals(readerRelations.get(0).getFrom(), study,
1089                                 "the retrieved relation does not equal the one that has been added.");
1090                 Assert.assertEquals(readerRelations.get(0).getTo(), user,
1091                                 "the retrieved relation does not equal the one that has been added.");
1092
1093
1094                 //  ==============================================================================================================================
1095                 //  3.Existing reader
1096                 //  ==============================================================================================================================
1097
1098                 //Test getReaders method with an existing reader
1099                 List<UserDTO> readers = _studyService.getReaders(studyId);
1100                 Assert.assertTrue(readers.size() == 1, "The retrieved reader list has wrong size");
1101                 Assert.assertEquals(readers.get(0), BeanHelper.copyBean(user, UserDTO.class),
1102                                 "the retrieved user does not equal the one that has been added.");
1103
1104                 //Test addReader method with a user who is already reader
1105                 Assert.assertFalse(_studyService.addReader(studyId, userId),
1106                                 "addition of a user who is already reader must return false");
1107                 
1108                 //Test removeReader method with a user user who is already reader
1109                 Assert.assertTrue(_studyService.removeReader(studyId, userId),
1110                                 "removal from readers of a user who is study reader must return true");
1111                 Assert.assertTrue(study.getRelations(ReaderRelation.class).isEmpty(),
1112                                 "a relation has not been properly removed");
1113
1114                 rollbackNestedTransaction();
1115                 LOG.debug(">>>>> END testReaders()");
1116         }
1117 }