]> SALOME platform Git repositories - tools/siman.git/blob - Workspace/Siman-Common/src/test/splat/service/TestStepService.java
Salome HOME
ProjectSettings are now configured when the bean is created (without call to a struts...
[tools/siman.git] / Workspace / Siman-Common / src / test / splat / service / TestStepService.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.IOException;
13 import java.sql.SQLException;
14 import java.util.ArrayList;
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.User;
21 import org.splat.dal.bo.som.ConvertsRelation;
22 import org.splat.dal.bo.som.Document;
23 import org.splat.dal.bo.som.DocumentType;
24 import org.splat.dal.bo.som.File;
25 import org.splat.dal.bo.som.ProjectElement;
26 import org.splat.dal.bo.som.Publication;
27 import org.splat.dal.bo.som.Scenario;
28 import org.splat.dal.bo.som.StepCommentAttribute;
29 import org.splat.dal.bo.som.Study;
30 import org.splat.dal.bo.som.UsedByRelation;
31 import org.splat.dal.bo.som.UsesRelation;
32 import org.splat.dal.bo.som.Document.Properties;
33 import org.splat.dal.dao.kernel.UserDAO;
34 import org.splat.dal.dao.som.Database;
35 import org.splat.dal.dao.som.FileDAO;
36 import org.splat.dal.dao.som.ScenarioDAO;
37 import org.splat.dal.dao.som.StepCommentAttributeDAO;
38 import org.splat.dal.dao.som.StudyDAO;
39 import org.splat.exception.BusinessException;
40 import org.splat.exception.DocumentIsUsedException;
41 import org.splat.exception.InvalidParameterException;
42 import org.splat.kernel.InvalidPropertyException;
43 import org.splat.kernel.MissedPropertyException;
44 import org.splat.kernel.MultiplyDefinedException;
45 import org.splat.log.AppLogger;
46 import org.splat.service.DocumentTypeService;
47 import org.splat.service.PublicationService;
48 import org.splat.service.StepService;
49 import org.splat.service.StudyService;
50 import org.splat.service.dto.StepCommentDTO;
51 import org.splat.service.technical.ProjectSettingsService;
52 import org.splat.service.technical.ProjectSettingsService.Step;
53 import org.springframework.beans.factory.annotation.Autowired;
54 import org.springframework.beans.factory.annotation.Qualifier;
55 import org.springframework.orm.hibernate3.HibernateTemplate;
56 import org.testng.Assert;
57 import org.testng.annotations.Test;
58
59 import test.splat.common.BaseTest;
60 import test.splat.util.TestEntitiesGenerator;
61
62 /**
63  * Test class for StepService.
64  * 
65  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
66  * 
67  */
68 public class TestStepService extends BaseTest {
69
70         /**
71          * Logger for the class.
72          */
73         private static final AppLogger LOG = AppLogger
74                         .getLogger(TestStepService.class);
75
76         /**
77          * The StudyService. Later injected by Spring.
78          */
79         @Autowired
80         @Qualifier("studyService")
81         private transient StudyService _studyService;
82
83         /**
84          * The Scenario DAO. Later injected by Spring.
85          */
86         @Autowired
87         @Qualifier("scenarioDAO")
88         private transient ScenarioDAO _scenarioDAO;
89
90         /**
91          * The File DAO. Later injected by Spring.
92          */
93         @Autowired
94         @Qualifier("fileDAO")
95         private transient FileDAO _fileDAO;
96
97         /**
98          * The PublicationService. Later injected by Spring.
99          */
100         @Autowired
101         @Qualifier("publicationService")
102         private transient PublicationService _publicationService;
103
104         /**
105          * The StepService. Later injected by Spring.
106          */
107         @Autowired
108         @Qualifier("stepService")
109         private transient StepService _stepService;
110
111         /**
112          * The ProjectSettingsService. Later injected by Spring.
113          */
114         @Autowired
115         @Qualifier("projectSettings")
116         private transient ProjectSettingsService _projectSettings;
117         
118         /**
119          * The injected by Spring StepCommentAttributeDAO.
120          */
121         @Autowired
122         @Qualifier("stepCommentAttributeDAO")
123         private transient StepCommentAttributeDAO _stepCommentAttributeDAO;
124
125         /**
126          * The injected by Spring UserDAO.
127          */
128         @Autowired
129         @Qualifier("userDAO")
130         private transient UserDAO _userDAO;
131
132
133         /**
134          * The injected by Spring StudyDAO.
135          */
136         @Autowired
137         @Qualifier("studyDAO")
138         private transient StudyDAO _studyDAO;
139
140         /**
141          * The DocumentTypeService. Later injected by Spring.
142          */
143         @Autowired
144         @Qualifier("documentTypeService")
145         private transient DocumentTypeService _documentTypeService;
146
147         /**
148          * Test removeDocument method.<BR>
149          * <B>Description :</B> <BR>
150          * <i>Create a scenario and try to remove documents from it.<BR>
151          * </i><BR>
152          * <B>Action : </B><BR>
153          * <i>1. call the method for all documents used by other document(s).</i><BR>
154          * <i>2. call the method for all documents starting from the last activity.</i><BR>
155          * <B>Test data : </B><BR>
156          * <i>no input parameters</i><BR>
157          * <i>no input parameters</i><BR>
158          * 
159          * <B>Outcome results:</B><BR>
160          * <i>
161          * <ul>
162          * <li>Exception DocumentIsUsedException is expected<BR>
163          * </li>
164          * <li>All documents and their files and relations must be removed<BR>
165          * </li>
166          * </ul>
167          * </i>
168          * 
169          * @throws BusinessException
170          *             if scenario creation or checkin is failed
171          * @throws IOException
172          *             if scenario creation is failed
173          * @throws SQLException
174          *             if scenario creation is failed
175          */
176         @Test
177         public void testRemoveDocument() throws BusinessException, IOException,
178                         SQLException {
179                 LOG.debug(">>>>> BEGIN testRemoveDocument()");
180                 startNestedTransaction();
181
182                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
183                 _projectSettings.configure("classpath:test/som.xml");
184                 HibernateTemplate ht = getHibernateTemplate();
185                 ht.flush();
186                 long scenarioId = createScenario();
187                 ht.flush();
188                 _scenarioDAO.flush();
189                 Scenario aScen = _scenarioDAO.get(scenarioId);
190
191                 ht.evict(aScen);
192                 ht.evict(aScen.getOwnerStudy());
193
194                 Assert.assertTrue(ht.find("from UsesRelation").size() > 0,
195                                 "Uses relations were not created in the database.");
196
197                 Assert.assertTrue(ht.find("from UsedByRelation").size() > 0,
198                                 "UsedBy relations were not created in the database.");
199
200                 ProjectElement projElem;
201                 boolean ok = false;
202                 long docId;
203                 Step step;
204                 int nbDoc = ht.find("from Document").size();
205                 int nbRemovedDoc = 0;
206                 List<Long> removedDocs = new ArrayList<Long>();
207
208                 // ////////////////////////////////////////////////////////
209                 // Call removeDocument method for each document
210                 // used by other document(s).
211                 // Exception DocumentIsUsedException is expected
212                 for (int i = 1; i <= _projectSettings.getAllSteps().size(); i++) {
213                         LOG.debug("Remove used documents from the step " + i);
214                         step = _projectSettings.getStep(i);
215                         if (step.appliesTo(Study.class)) {
216                                 projElem = _studyService.selectStudy(aScen.getOwnerStudy()
217                                                 .getIndex());
218                         } else {
219                                 projElem = aScen;
220                         }
221
222                         org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
223
224                         if (aScStep.getDocuments().size() > 0) {
225                                 docId = aScStep.getDocuments().get(0).value().getIndex();
226                                 ht.flush();
227
228                                 List<UsesRelation> uses = ht
229                                                 .find("from UsesRelation where owner=" + docId);
230                                 List<UsedByRelation> usedBy = ht
231                                                 .find("from UsedByRelation where owner=" + docId);
232                                 if (!usedBy.isEmpty()) {
233                                         int usesRefer = ht.find(
234                                                         "from UsesRelation where refer=" + docId).size();
235                                         int usedByRefer = ht.find(
236                                                         "from UsedByRelation where refer=" + docId).size();
237                                         int convertsNb = ht.find(
238                                                         "from ConvertsRelation where owner=" + docId)
239                                                         .size();
240                                         LOG.debug("Remove used document "
241                                                         + aScStep.getDocument(docId).value().getTitle());
242                                         LOG.debug("From db: It uses following " + uses.size()
243                                                         + " documents: ");
244                                         for (UsesRelation rel : uses) {
245                                                 LOG.debug(rel.getTo().getTitle());
246                                         }
247                                         LOG
248                                                         .debug("From step: It uses following "
249                                                                         + aScStep.getDocument(docId).value()
250                                                                                         .getRelations(UsesRelation.class)
251                                                                                         .size() + " documents: ");
252                                         for (Publication rel : aScStep.getDocument(docId)
253                                                         .getRelations(UsesRelation.class)) {
254                                                 LOG.debug(rel.value().getTitle());
255                                         }
256                                         LOG.debug("From db: It is used by following "
257                                                         + usedBy.size() + " documents: ");
258                                         for (UsedByRelation rel : usedBy) {
259                                                 LOG.debug(rel.getTo().getTitle());
260                                         }
261                                         LOG.debug("From step: It is used by following "
262                                                         + aScStep.getDocument(docId).value().getRelations(
263                                                                         UsedByRelation.class).size()
264                                                         + " documents: ");
265                                         for (Publication rel : aScStep.getDocument(docId)
266                                                         .getRelations(UsedByRelation.class)) {
267                                                 LOG.debug(rel.value().getTitle());
268                                         }
269                                         try {
270                                                 ok = _stepService.removeDocument(aScStep, docId);
271                                                 Assert.fail("DocumentIsUsedException must be thrown.");
272                                         } catch (DocumentIsUsedException e) {
273                                                 LOG.debug("Expected exception is thrown: "
274                                                                 + e.getLocalizedMessage());
275                                         }
276                                         _scenarioDAO.flush();
277                                         ht.flush();
278                                         Assert
279                                                         .assertEquals(ht.find(
280                                                                         "from UsesRelation where owner=" + docId)
281                                                                         .size(), uses.size(),
282                                                                         "UsesRelation(s) must not be changed.");
283                                         Assert.assertEquals(ht.find(
284                                                         "from UsedByRelation where owner=" + docId).size(),
285                                                         usedBy.size(),
286                                                         "UsedByRelation(s) must not be changed.");
287                                         Assert.assertEquals(ht.find(
288                                                         "from UsesRelation where refer=" + docId).size(),
289                                                         usesRefer,
290                                                         "Referencing UsesRelation(s) must not be changed.");
291                                         Assert
292                                                         .assertEquals(ht.find(
293                                                                         "from UsedByRelation where refer=" + docId)
294                                                                         .size(), usedByRefer,
295                                                                         "Referencing UsedByRelation(s) must not be changed.");
296                                         Assert.assertEquals(ht.find(
297                                                         "from ConvertsRelation where owner=" + docId)
298                                                         .size(), convertsNb,
299                                                         "ConvertsRelation(s) must not be changed.");
300                                 }
301                         }
302                 }
303
304                 // ////////////////////////////////////////////////////////
305                 // Call removeDocument method for each document
306                 // starting from the last activity.
307                 for (int i = _projectSettings.getAllSteps().size(); i > 0; i--) {
308                         LOG.debug("Remove documents from the step " + i);
309                         step = _projectSettings.getStep(i);
310                         if (step.appliesTo(Study.class)) {
311                                 projElem = _studyService.selectStudy(aScen.getOwnerStudy()
312                                                 .getIndex());
313                         } else {
314                                 projElem = aScen;
315                         }
316
317                         org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
318
319                         if (aScStep.getDocuments().size() > 0) {
320                                 docId = aScStep.getDocuments().get(0).value().getIndex();
321                                 LOG.debug("Remove document#" + docId + " "
322                                                 + aScStep.getDocument(docId).value().getTitle());
323                                 ht.flush();
324                                 List<UsesRelation> uses = ht
325                                                 .find("from UsesRelation where owner=" + docId);
326                                 List<UsedByRelation> usedBy = ht
327                                                 .find("from UsedByRelation where owner=" + docId);
328                                 LOG.debug("From db: It uses following " + uses.size()
329                                                 + " documents: ");
330                                 for (UsesRelation rel : uses) {
331                                         LOG.debug(rel.getTo().getTitle());
332                                 }
333                                 LOG.debug("From step: It uses following "
334                                                 + aScStep.getDocument(docId).getRelations(
335                                                                 UsesRelation.class).size() + " documents: ");
336                                 for (Publication rel : aScStep.getDocument(docId).getRelations(
337                                                 UsesRelation.class)) {
338                                         LOG.debug(rel.value().getTitle());
339                                 }
340                                 LOG.debug("From db: It is used by following " + usedBy.size()
341                                                 + " documents: ");
342                                 for (UsedByRelation rel : usedBy) {
343                                         LOG.debug(rel.getTo().getTitle());
344                                 }
345                                 LOG.debug("From step: It is used by following "
346                                                 + aScStep.getDocument(docId).getRelations(
347                                                                 UsedByRelation.class).size() + " documents: ");
348                                 for (Publication rel : aScStep.getDocument(docId).getRelations(
349                                                 UsedByRelation.class)) {
350                                         LOG.debug(rel.value().getTitle());
351                                 }
352                                 Assert.assertEquals(ht.find("from Document where rid=" + docId)
353                                                 .size(), 1, "Nothing to delete.");
354
355                                 
356                                 ht.evict(aScStep.getDocuments().get(0).value()
357                                                 .getFile());
358                                 LOG.debug("Load file#" + aScStep.getDocuments().get(0).value()
359                                                 .getRelations(ConvertsRelation.class).get(0).getTo().getIndex());
360
361                                 ht.clear();
362                                 File f = _fileDAO.get(aScStep.getDocuments().get(0).value()
363                                                 .getRelations(ConvertsRelation.class).get(0).getTo().getIndex());
364                                 ht.evict(aScStep.getDocuments().get(0).value());
365                                 
366                                 ok = _stepService.removeDocument(aScStep, docId);
367
368                                 nbRemovedDoc++;
369                                 removedDocs.add(docId);
370
371                                 Assert.assertTrue(ok, "Removing was failed.");
372                                 _scenarioDAO.flush();
373                                 ht.flush();
374
375                                 for (Long id : removedDocs) {
376                                         String title = "";
377                                         if (ht.get(Document.class, id) != null) {
378                                                 title = ht.get(Document.class, id).getTitle();
379                                         }
380                                         Assert.assertEquals(ht
381                                                         .find("from Document where rid=" + id).size(), 0,
382                                                         "Document#" + id + "(" + title
383                                                                         + ") was not removed from the database.");
384                                 }
385
386                                 Assert.assertEquals(ht.find("from Document").size(), nbDoc
387                                                 - nbRemovedDoc,
388                                                 "Documents were not removed from the database.");
389                                 Assert.assertEquals(ht.find(
390                                                 "from UsesRelation where owner=" + docId).size(), 0,
391                                                 "UsesRelation(s) were not removed from the database.");
392                                 Assert
393                                                 .assertEquals(ht.find(
394                                                                 "from UsedByRelation where owner=" + docId)
395                                                                 .size(), 0,
396                                                                 "UsedByRelation(s) were not removed from the database.");
397                                 Assert
398                                                 .assertEquals(ht.find(
399                                                                 "from UsesRelation where refer=" + docId)
400                                                                 .size(), 0,
401                                                                 "Referencing UsesRelation(s) were not removed from the database.");
402                                 Assert
403                                                 .assertEquals(ht.find(
404                                                                 "from UsedByRelation where refer=" + docId)
405                                                                 .size(), 0,
406                                                                 "Referencing UsedByRelation(s) were not removed from the database.");
407                                 Assert
408                                                 .assertEquals(ht.find(
409                                                                 "from ConvertsRelation where owner=" + docId)
410                                                                 .size(), 0,
411                                                                 "ConvertsRelation(s) were not removed from the database.");
412                         }
413                 }
414
415                 Assert
416                                 .assertEquals(ht.find("from Document").size(), nbDoc
417                                                 - nbRemovedDoc,
418                                                 "Documents were not removed from the database.");
419
420                 Assert.assertEquals(ht.find("from File").size(), 0,
421                                 "Files were not removed from the database.");
422
423                 Assert.assertEquals(ht.find(
424                                 "from Publication where owner=" + aScen.getIndex()).size(), 0,
425                                 "Publications were not removed from the database.");
426
427                 Assert.assertEquals(ht.find("from UsesRelation").size(), 0,
428                                 "Uses relations were not removed from the database.");
429
430                 Assert.assertEquals(ht.find("from UsedByRelation").size(), 0,
431                                 "UsedBy relations were not removed from the database.");
432
433                 rollbackNestedTransaction();
434                 LOG.debug(">>>>> END testRemoveDocument()");
435         }
436
437         /**
438          * Create a persistent scenario for tests.
439          * 
440          * @return a persistent scenario
441          * @throws InvalidPropertyException
442          *             if an invalid property is used when creating objects
443          * @throws MultiplyDefinedException
444          *             when trying to create an object with already existing id
445          * @throws MissedPropertyException
446          *             if a mandatory property is not defined for an object to be created
447          * @throws IOException
448          *             if document creation is failed
449          * @throws SQLException
450          *             if project settings loading is failed
451          */
452         private long createScenario() throws InvalidPropertyException,
453                         MissedPropertyException, MultiplyDefinedException, IOException,
454                         SQLException {
455                 // Create a scenario for tests
456                 HibernateTemplate ht = getHibernateTemplate();
457
458                 Database.getInstance().reset();
459                 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
460                 // Load workflow customization
461                 try {
462                         _projectSettings.configure("classpath:test/som.xml");
463                 } catch (FileNotFoundException e) {
464                         Assert.fail("Can't find som.xml: ", e);
465                 }
466                 List<Step> steps = _projectSettings.getAllSteps();
467                 Assert.assertTrue(steps.size() > 0, "No steps are created.");
468
469                 // Create a test user
470                 User.Properties uprop = new User.Properties();
471                 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
472                                 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
473                                 .addRole("TST_user").setMailAddress(
474                                                 "noreply@salome-platform.org");
475                 uprop.disableCheck();
476                 User anAuthor = new User(uprop);
477                 ht.saveOrUpdate(anAuthor);
478
479                 // Create a test study
480                 Study.Properties stprops = new Study.Properties().setReference(
481                                 "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
482                 Study aStudy = new Study(stprops);
483                 ht.saveOrUpdate(aStudy);
484
485                 // Create a test scenario
486                 Scenario.Properties sprops = new Scenario.Properties().setTitle(
487                                 "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
488                 Scenario aScenario = new Scenario(sprops);
489                 aStudy.getScenariiList().add(aScenario);
490                 ht.saveOrUpdate(anAuthor);
491                 ht.saveOrUpdate(aStudy);
492                 ht.saveOrUpdate(aScenario);
493
494                 // Create documents for each scenario step
495                 Document.Properties dprop = new Document.Properties().setAuthor(
496                                 anAuthor).setDate(new Date());
497                 int i = 0;
498                 Publication usedPub = null;
499                 Map<Long, Long> usedMap = new HashMap<Long, Long>();
500                 for (int stepNum = 1; stepNum <= steps.size(); stepNum++) {
501                         Step step = _projectSettings.getStep(stepNum);
502                         LOG.debug("Create scenario step: " + stepNum);
503                         ProjectElement projElem;
504
505                         if (step.appliesTo(Study.class)) {
506                                 projElem = aStudy;
507                         } else {
508                                 projElem = aScenario;
509                         }
510                         org.splat.som.Step aScStep = new org.splat.som.Step(step, projElem);
511                         List<DocumentType> dtypes = _documentTypeService
512                                         .selectTypesOf(step);
513                         if (dtypes.size() > 0) {
514                                 DocumentType dtype = dtypes.get(0);
515                                 // Create a document published in the scenario
516                                 // document<i>: document type[0] - first type used on the step
517                                 // <source-file>.brep
518                                 // <attached-file>.med
519                                 i++;
520                                 dprop.setName("document" + stepNum).setType(dtype);
521                                 if (step.getNumber() > 3) {
522                                         dprop.setFormat("med");
523                                 } else {
524                                         dprop.setFormat("py");
525                                 }
526                                 Publication pub = createDoc(projElem, aScStep, dprop, "med",
527                                                 false);
528                                 if (usedPub != null) {
529                                         pub.addDependency(usedPub);
530                                         LOG.debug("Add dependency: " + pub.value().getTitle()
531                                                         + " from " + usedPub.value().getTitle());
532                                         ht.saveOrUpdate(pub.value());
533                                         ht.flush();
534
535                                         usedMap.put(pub.getIndex(), usedPub.getIndex());
536                                 }
537                                 usedPub = pub;
538                         }
539                         if (dtypes.size() <= 0) {
540                                 LOG.debug("No document types are found for scenario step " + i);
541                         }
542                 }
543
544                 // Check that the scenario and its documents have been created correctly.
545
546                 Assert.assertNotNull(ht.find("from Document"),
547                                 "No documents in the database.");
548                 Assert.assertTrue(ht.find("from Document").size() > 0,
549                                 "No documents in the database.");
550
551                 Assert.assertNotNull(ht.find("from Publication where owner="
552                                 + aScenario.getIndex()), "No publications in the database.");
553                 Assert.assertTrue(
554                                 ht.find("from Publication where owner=" + aScenario.getIndex())
555                                                 .size() > 0, "No publications in the database.");
556
557                 for (Publication p : (List<Publication>) ht
558                                 .find("from Publication where owner=" + aScenario.getIndex())) {
559                         LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
560                                         + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
561                                         + "]");
562                         Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
563                                         "The publication was not attached to the scenario.");
564                 }
565
566                 // Remove the scenario from the current hibernate session.
567                 ht.evict(aScenario);
568                 // Check that the scenario is created in the database.
569                 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
570                 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
571                 Assert.assertTrue(aScen.getDocums().size() > 0,
572                                 "No publications in the scenario.");
573
574                 Assert.assertTrue(i > 0,
575                                 "More then one document must be in the database");
576
577                 // Check created uses relations
578                 Assert
579                                 .assertTrue(usedMap.size() > 0,
580                                                 "Uses relations must be created.");
581                 boolean foundAny = false;
582                 for (Long usingId : usedMap.keySet()) {
583                         for (Publication pub : aScen.getDocums()) {
584                                 if (pub.getIndex() == usingId) {
585                                         boolean found = false;
586                                         for (Publication used : aScen.getDocums()) {
587                                                 found = (used.getIndex() == usedMap.get(usingId));
588                                                 if (found) {
589                                                         break;
590                                                 }
591                                         }
592                                         if (!found) {
593                                                 for (Publication used : aStudy.getDocums()) {
594                                                         found = (used.getIndex() == usedMap.get(usingId));
595                                                         if (found) {
596                                                                 break;
597                                                         }
598                                                 }
599                                         }
600                                         Assert.assertTrue(found,
601                                                         "Uses relation was not created in the database.");
602                                         foundAny = foundAny || found;
603                                 }
604                         }
605                 }
606                 Assert.assertTrue(foundAny,
607                                 "No Uses relation was created in the database.");
608
609                 return aScenario.getIndex();
610         }
611
612         /**
613          * Create a document published in the scenario. <BR>
614          * document:<BR>
615          * document type - type used on the step <BR>
616          * &lt;source-file&gt;.brep <BR>
617          * &lt;attached-file&gt;.med
618          * 
619          * @param aScenario
620          *            the scenario to add the document to
621          * @param aScStep
622          *            scenario step where the document to be published
623          * @param dprop
624          *            document properties
625          * @param attachedFileExt
626          *            extension of the secon attached (exported) file
627          * @param isOutdated
628          *            outdated document flag
629          * @return the publication of the created document
630          * @throws IOException
631          * @throws MultiplyDefinedException
632          * @throws InvalidPropertyException
633          * @throws MissedPropertyException
634          */
635         private Publication createDoc(final ProjectElement aScenario,
636                         final org.splat.som.Step aScStep, final Properties dprop,
637                         final String attachedFileExt, final boolean isOutdated)
638                         throws MissedPropertyException, InvalidPropertyException,
639                         MultiplyDefinedException, IOException {
640                 // Create a document published in the scenario
641                 // document<i>: document type - type used on the step
642                 // <source-file>.brep
643                 // <attached-file>.med
644                 Publication pub = _stepService.createDocument(aScStep, dprop);
645                 Assert.assertNotNull(pub.getOwner(),
646                                 "The publication must be attached to the scenario.");
647                 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
648                                 "The publication was not attached to the scenario.");
649
650                 if (isOutdated) {
651                         pub.setIsnew('O');
652                 }
653                 aScenario.add(pub);
654                 HibernateTemplate ht = getHibernateTemplate();
655                 ht.saveOrUpdate(pub);
656
657                 // Attach a file
658                 ht.save(pub.value());
659                 ht.flush();
660                 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
661
662                 return pub;
663         }
664         
665         /**
666          * Test of addition of a new step comment.
667          *
668          * @throws BusinessException if there is something wrong likely unrelated to the tested method
669          */
670         @Test
671         public void testAddStepComment() throws BusinessException{
672
673                 User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
674                 _userDAO.create(goodUser);
675                 Study goodStudy = TestEntitiesGenerator.getTestStudy(goodUser);
676                 _studyDAO.create(goodStudy);
677                 getHibernateTemplate().flush();
678                 StepCommentDTO goodStepCommentDTO = createStepCommentDTO(goodUser, goodStudy);
679
680                 //valid DTO, existing params
681                 _stepService.addStepComment(goodStepCommentDTO);
682                 Long id = goodStepCommentDTO.getId();
683                 Assert.assertNotNull(id, "Add method returns null instead of a new id.");
684                 Assert.assertTrue(id > 0, "The new id is not a positive number.");
685                 StepCommentDTO retrievedComment = getDTOfromStepCommentAttribute(
686                                 _stepCommentAttributeDAO.get(id));
687                 Assert.assertTrue(compareStepCommentDTO(goodStepCommentDTO, retrievedComment),
688                                 "The comment created in database has wrong data");
689
690                 //valid DTO, non-existing user
691                 {
692                         //get a non-existing id
693                         User badUser = TestEntitiesGenerator.getTestUser("badUser");
694                         _userDAO.create(badUser);
695                         getHibernateTemplate().evict(badUser);//so createStepCommentDTO will invoke an
696                                         //actual query to the base, not cache, in order to check if the user already exists
697                         StepCommentDTO aBadDTO = createStepCommentDTO(badUser, goodStudy);
698
699                         try{
700                                 _stepService.addStepComment(aBadDTO);
701                                 getHibernateTemplate().flush();
702                                 Assert.fail("Creation with non-existing user must be failed.");
703                         }
704                         catch(InvalidParameterException e){
705                                 LOG.debug("Expected exception is thrown: "
706                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
707                         }
708                 }
709
710                 //valid DTO, non-existing project element
711                 {
712                         Study badStudy = TestEntitiesGenerator.getTestStudy(goodUser);
713                         _studyDAO.create(badStudy);
714                         getHibernateTemplate().evict(badStudy);//so createStepCommentDTO will invoke an
715                         //actual query to the base, not cache in order to check if the study already exists
716                         StepCommentDTO aBadDTO = createStepCommentDTO(goodUser, badStudy);
717
718                         try{
719                                 _stepService.addStepComment(aBadDTO);
720                                 Assert.fail("Creation with non-existing user must be failed.");
721                         }
722                         catch(InvalidParameterException e){
723                                 LOG.debug("Expected exception is thrown: "
724                                         + e.getClass().getSimpleName() + ": " + e.getMessage());
725                         }
726                 }
727
728                 //not valid DTO (id filled in)
729                 {
730                         StepCommentDTO aBadDTO = createStepCommentDTO(goodUser, goodStudy);
731                         aBadDTO.setId(goodStepCommentDTO.getId());
732
733                         try {
734                                 _stepService.addStepComment(aBadDTO);
735                                 Assert.fail("Creation with filled in id must be failed.");
736                         } catch (InvalidParameterException e) {
737                                 LOG.debug("Expected exception is thrown: "
738                                                 + e.getClass().getSimpleName() + ": " + e.getMessage());
739                         }
740                 }
741         }
742
743         /**
744          * Test of retrieval of all comments corresponding to a step.
745          *
746          * @throws BusinessException if there is something wrong likely unrelated to the tested method
747          */
748         @Test
749         public void testGetStepComments() throws BusinessException {
750
751                 User user = TestEntitiesGenerator.getTestUser("goodUser");
752                 _userDAO.create(user);
753                 Study study = TestEntitiesGenerator.getTestStudy(user);
754                 
755                 //Before we create the study in the database:
756                 org.splat.som.Step step = new org.splat.som.Step(_projectSettings.getStep(1), study);
757                 try{
758                         _stepService.getStepComments(step);
759                         Assert.fail("Retrieval by step with non-existing owner project element must be failed.");
760                 }
761                 catch(InvalidParameterException e){
762                         LOG.debug("Expected exception is thrown: "
763                                 + e.getClass().getSimpleName() + ": " + e.getMessage());
764                 }
765                 
766                 _studyDAO.create(study);
767                 
768                 StepCommentAttribute matchingStepComment = new StepCommentAttribute(
769                                 study, "matching test comment", new Date(), step.getNumber(), user, "matching test comment title");
770                 StepCommentAttribute notMatchingStepComment = new StepCommentAttribute(
771                                 study, "not matching test comment", new Date(), 2, user, "not matching test comment title");
772                 _stepCommentAttributeDAO.create(matchingStepComment);
773                 _stepCommentAttributeDAO.create(notMatchingStepComment);
774                 getHibernateTemplate().flush();
775                 
776                 List<StepCommentDTO> stepComments = _stepService.getStepComments(step);
777                 Assert.assertTrue(stepComments.size() == 1, "Wrong number of retrieved comments");
778                 StepCommentDTO stepCommentDTO = stepComments.get(0);
779                 Assert.assertTrue(stepCommentDTO.getId().equals(matchingStepComment.getRid())
780                                 && stepCommentDTO.getDate().equals(matchingStepComment.getDate())
781                                 && stepCommentDTO.getText().equals(matchingStepComment.getValue())              
782                                 && stepCommentDTO.getUser().getIndex() == matchingStepComment.getUser().getRid()
783                                 && stepCommentDTO.getTitle().equals(matchingStepComment.getTitle()),
784                                 "some of the needed fields of the retrieved comment doesn't match with original.");
785         }
786         
787         /**
788          * Test of retrieval of all comments corresponding to a step.
789          *
790          * @throws BusinessException if there is something wrong likely unrelated to the tested method
791          */
792         @Test
793         public void testEditStepComments() throws BusinessException {
794                 LOG.debug(">>>>> BEGIN testEditStepComments()");
795                 startNestedTransaction();
796                 
797                 User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
798                 _userDAO.create(goodUser);
799                 Study goodStudy = TestEntitiesGenerator.getTestStudy(goodUser);
800                 _studyDAO.create(goodStudy);
801                 getHibernateTemplate().flush();
802
803                 org.splat.som.Step step = new org.splat.som.Step(_projectSettings.getStep(1), goodStudy);
804                 
805                 StepCommentAttribute comment = new StepCommentAttribute(goodStudy, "commentValue",
806                                 new Date(), Integer.valueOf(step.getNumber()), goodUser, "commentTitle");
807                 _stepCommentAttributeDAO.saveOrUpdate(comment);
808
809                 getHibernateTemplate().flush();
810                 
811                 //non-existing id
812                 StepCommentAttribute tmpComment = new StepCommentAttribute(goodStudy,"tmpCommentValue",
813                                 new Date(), Integer.valueOf(step.getNumber()), goodUser, "tmpCommentTitle");
814                 _stepCommentAttributeDAO.create(tmpComment);
815                 long nonExistingId = tmpComment.getIndex();
816                 _stepCommentAttributeDAO.delete(tmpComment);
817                 //getHibernateTemplate().evict(goodUser);
818                 
819
820                 try{
821                         _stepService.editStepComment(nonExistingId, "newValue", "newTitle");
822                         getHibernateTemplate().flush();
823                         Assert.fail("Creation with non-existing user must be failed.");
824                 }
825                 catch(InvalidParameterException e){
826                         LOG.debug("Expected exception is thrown: "
827                                 + e.getClass().getSimpleName() + ": " + e.getMessage());
828                 }
829
830                 //different configurations with valid comment id
831                 testEdit(comment, "newValue", null);
832                 testEdit(comment, null, "newTitle");
833                 testEdit(comment, "veryNewValue", "veryNewTitle");
834
835                 rollbackNestedTransaction();
836                 LOG.debug(">>>>> END testEditStepComments()");
837         }
838         
839         /**
840          * Test of comment editing.
841          * @param comment the comment
842          * @param value the value
843          * @param title the title
844          * @throws InvalidParameterException if there is something wrong likely unrelated to the tested method
845          */
846         private void testEdit(final StepCommentAttribute comment, final String value, final String title)
847                         throws InvalidParameterException {
848                 String oldValue = comment.getValue();
849                 String oldTitle = comment.getTitle();
850                 
851                 _stepService.editStepComment(comment.getIndex(), value, title);
852                 _stepCommentAttributeDAO.flush();
853                 getHibernateTemplate().evict(comment);
854                 _stepCommentAttributeDAO.refresh(comment);
855                 if(value == null) {
856                         Assert.assertEquals(comment.getValue(), oldValue);
857                 } else {
858                         Assert.assertEquals(comment.getValue(), value);
859                 }
860                 if(title == null) {
861                         Assert.assertEquals(comment.getTitle(), oldTitle);
862                 } else {
863                         Assert.assertEquals(comment.getTitle(), title);
864                 }
865         }
866         
867         
868         /**
869          * Create a transient StepCommentDTO.
870          *
871          * @param study must be already persisted into the database
872          * @param user must be already persisted into the database
873          * @return a transient StepCommentDTO
874          * @throws BusinessException if something's wrong
875          */
876         private StepCommentDTO createStepCommentDTO(final User user, final Study study) throws BusinessException {
877
878                 return new StepCommentDTO(null, "A good comment", study.getRid(),
879                                 new Integer(0), new Date(), user.getRid(), user.getName(), "Good comment title");
880         }
881
882         /**
883          * Create StepCommentDTO with all the fields filled in from StepCommentAttribute.
884          * @param comment the comment
885          * @return Step Comment DTO
886          */
887         private StepCommentDTO getDTOfromStepCommentAttribute(final StepCommentAttribute comment) {
888
889                 StepCommentDTO stepCommentDTO = new StepCommentDTO(
890                                 comment.getRid(),
891                                 comment.getValue(),
892                                 comment.getFrom().getRid(),
893                                 comment.getStep(),
894                                 comment.getDate(),
895                                 comment.getUser().getRid(),
896                                 comment.getUser().getName(),
897                                 comment.getTitle()
898                         );
899                 return stepCommentDTO;
900         }
901
902         /**
903          * Compare StepCommentDTO.
904          * @param a the first DTO to compare
905          * @param b the second DTO to compare
906          * @return true if comments are equal
907          */
908         private Boolean compareStepCommentDTO(final StepCommentDTO a, final StepCommentDTO b){
909                 return a.getId().equals(b.getId())
910                                 && a.getId().equals(b.getId())
911                                 && a.getDate().equals(b.getDate())
912                                 && a.getStep().equals(b.getStep())
913                                 && a.getText().equals(b.getText())
914                                 && a.getUserId().equals(b.getUserId())
915                                 && a.getProjectElementId().equals(b.getProjectElementId()) 
916                                 && a.getTitle().equals(b.getTitle());
917         }
918 }