testBug.py 19 KB
Newer Older
1 2
##############################################################################
#
3 4 5
# Copyright (c) 2007-2008 Nexedi SA and Contributors. All Rights Reserved.
#                       Kevin Deldycke <kevin_AT_nexedi_DOT_com>
#                       Rafael Monnerat <rafael@nexedi.com>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################


31
import unittest
32
import transaction
33 34 35
from DateTime import DateTime
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.Sequence import SequenceList
36
from Products.ERP5Type.tests.utils import DummyMailHost
37 38


39
class TestBug(ERP5TypeTestCase):
40
  """
41
    ERP5 unit tests for Bug module (part of erp5_forge business template).
42 43 44 45
  """
  # pseudo constants
  RUN_ALL_TEST = 1
  QUIET = 1
46
  person_portal_type = "Person" 
47
  assignment_portal_type = "Assignment"
48
  project_portal_type = "Project"
49
  bug_portal_type = "Bug"
50
  organisation_portal_type  = "Organisation"
51 52 53 54 55

  def getTitle(self):
    """
      Return the title of the current test set.
    """
56
    return "Bug"
57 58 59 60 61

  def getBusinessTemplateList(self):
    """
      Return the list of required business templates.
    """
62 63
    return ( 'erp5_base'
           , 'erp5_forge'
64 65 66 67
           , 'erp5_base'
           , 'erp5_pdm'
           , 'erp5_trade'
           , 'erp5_project'
68
           )
69 70 71 72 73 74

  def afterSetUp(self, quiet=QUIET, run=RUN_ALL_TEST):
    """
      Initialize the ERP5 site.
    """
    self.login()
75 76
    self.datetime = DateTime() 
    self.portal = self.getPortal()
Kevin Deldycke's avatar
Kevin Deldycke committed
77
    self.workflow_tool = self.portal.portal_workflow
78 79 80 81 82
    # Use a dummy mailhost to not send mail notification to the guy how run unit test
    if 'MailHost' in self.portal.objectIds():
      self.portal.manage_delObjects(['MailHost'])
      self.portal._setObject('MailHost', DummyMailHost('MailHost'))

83 84 85
  ##################################
  ##  Usefull methods
  ##################################
86 87 88 89 90 91 92 93 94 95
#  def login(self, quiet=QUIET, run=RUN_ALL_TEST):
#    """
#      Create a new manager user and login.
#    """
#    user_name = 'kevin'
#    user_folder = self.getPortal().acl_users
#    user_folder._doAddUser(user_name, '', ['Manager', 'Owner', 'Assignor'], [])
#    user = user_folder.getUserById(user_name).__of__(user_folder)
#    newSecurityManager(None, user)
#
96 97 98
  ##################################
  ##  Basic steps
  ##################################
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
  def stepLoginUsualUser(self, **kw):
    portal = self.getPortal()
    uf = portal.acl_users
    if not uf.getUser('dummy'):
      uf._doAddUser('manager', '', ['Manager'], [])
      self.login('manager')
      person_module = portal.getDefaultModule(self.person_portal_type)
      person = person_module.newContent(id='dummy', title='dummy',
                                        reference='dummy')
      portal.portal_categories.group.newContent(id='dummy',
                                                codification='DUMMY')
      
      person.setEmailText('loggedperson@localhost')
      assignment = person.newContent(title='dummy', group='dummy',
                                     portal_type='Assignment',
                                     start_date='1980-01-01',
                                     stop_date='2099-12-31')
      assignment.open()
117
      transaction.commit()
118 119 120
      self.tic()
      portal_type_list = []
      for portal_type in (self.project_portal_type,
121 122 123
                          self.bug_portal_type,
                          self.person_portal_type,
                          self.assignment_portal_type,
124 125
                          self.organisation_portal_type,):
        portal_type_list.append(portal_type)
126 127 128
        module = portal.getDefaultModule(portal_type, None)
        if module is not None:
          portal_type_list.append(module.getPortalType())
129 130 131

      for portal_type in portal_type_list:
        ti = portal.portal_types[portal_type]
Julien Muchembled's avatar
Julien Muchembled committed
132
        ti.newContent(portal_type='Role Information',
133
          role_name_list=('Auditor','Author','Assignee','Assignor'),
Julien Muchembled's avatar
Julien Muchembled committed
134 135 136 137
          title='Dummy',
          role_base_category_script_id=
            'ERP5Type_getSecurityCategoryFromAssignment',
          role_category='group/dummy')
138 139
        ti.updateRoleMapping()

140
      transaction.commit()
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
      self.tic()
      portal.portal_caches.clearAllCache()

    self.login('dummy')

  def stepCreateProject(self,sequence=None, sequence_list=None, \
                        **kw):
    """
    Create a project
    """
    project_portal_type = "Project"
    portal = self.getPortal()
    module = portal.getDefaultModule(project_portal_type)
    project = module.newContent(
        portal_type=project_portal_type,
        title = 'Project')
    sequence.edit(project=project) 

  def createPerson(self):
    """
      Create a person.
    """
    portal_type = 'Person'
    person_module = self.portal.getDefaultModule(portal_type)
    person = person_module.newContent(portal_type = portal_type )
    return person

  def stepCreatePerson1(self, sequence=None, sequence_list=None, **kw):
    """
      Create one Person
    """
    person = self.createPerson()
    project = sequence.get("project")
    self.createPersonAssignment(person=person, project=project)
    person.setDefaultEmailText("person1@localhost")
    sequence.edit(person1 = person)

  def stepCreatePerson2(self, sequence=None, sequence_list=None, **kw):
    """
      Create Person 2
    """
    person = self.createPerson()
    project = sequence.get("project")
    person.setDefaultEmailText("person2@localhost")
    sequence.edit(person2 = person)

  def createPersonAssignment(self,person=None,project=None ):
    """
      Create a person Assigment and Assign to a Project.
    """
    # Create Assignment
    assignment = person.newContent(portal_type='Assignment')
    assignment.setDestinationProjectValue(project)
    assignment.setStartDate(DateTime()-365)
    assignment.setStopDate(DateTime()+365)
    self.portal.portal_workflow.doActionFor(assignment, 'open_action')

  def stepCheckBugNotification(self, sequence=None,
                                         sequence_list=None, **kw):
    """
    Check that notification works
    """
    bug = sequence.get('bug')
    last_message = self.portal.MailHost._last_message
    self.assertNotEquals((), last_message)
    mfrom, mto, messageText = last_message
207
    self.assertEquals('"dummy" <loggedperson@localhost>', mfrom)
208
    self.assertEquals(['person1@localhost'], mto)
209
    self.failUnless(bug.getTitle().replace(" ", "_") in messageText)
210 211 212 213 214 215

  def stepCheckBugMessageNotification(self, sequence=None,
                                         sequence_list=None, **kw):
    """
    Check that notification works
    """
216
    bug = sequence.get('bug')
217 218 219 220 221
    last_message = self.portal.MailHost._last_message
    self.assertNotEquals((), last_message)
    mfrom, mto, messageText = last_message
    self.assertEquals('person2@localhost', mfrom)
    self.assertEquals(['person1@localhost'], mto)
222
    self.failUnless(bug.getTitle().replace(" ", "_") in messageText)
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238

  def stepSetSourceProject(self, sequence=None, sequence_list=None, **kw):
    """
      Set Source Project to a Bug
    """
    bug = sequence.get('bug')
    project = sequence.get('project')
    bug.setSourceProjectValue(project)

  def stepSetRequester(self, sequence=None, sequence_list=None, **kw):
    """
      Set Source Project to a Bug
    """
    bug = sequence.get('bug')
    person2 = sequence.get('person2')
    bug.setDestinationValue(person2)
239

240
  def stepCreateBug(self, sequence=None, sequence_list=None, **kw):
241
    """
242
      Create a dummy bug
243
    """
244 245
    portal_type = 'Bug'
    bug_module = self.portal.getDefaultModule(portal_type)
246 247 248 249 250
    bug = bug_module.newContent( portal_type = portal_type
                               , title  = 'Bug Title'
                               , description = 'Bug Description'
                               , start_date = self.datetime
                               , stop_date = self.datetime
251 252 253
                               )
    sequence.edit(bug = bug)

254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
  def stepCreateBugMessage(self, sequence=None, sequence_list=None, **kw):
    """
      Create a dummy Bug Message
    """
    portal_type = 'Bug Line'
    bug = sequence.get('bug')
    person2 = sequence.get('person2')
    bug_message = bug.newContent( portal_type = portal_type
                                  , title  = 'Bug Message'
                                  , text_content = 'Bug Description'
                                )
    # usually the person who is creates the message is setted as source
    # by BugLine_init
    bug_message.setSourceValue(person2)
    sequence.edit(bug_message = bug_message)

  def stepPostBugMessage(self, sequence=None, sequence_list=None, **kw):
    """
      Post the bug message.
    """
    bug_message = sequence.get('bug_message')
    self.workflow_tool.doActionFor(bug_message, 'start_action')

Rafael Monnerat's avatar
Rafael Monnerat committed
277
  def stepCheckBugMessageIsDelivered(self, sequence=None, \
278 279
                                                     sequence_list=None, **kw):
    """
Rafael Monnerat's avatar
Rafael Monnerat committed
280
      check if the message is delivered the bug.
281 282
    """
    bug_message = sequence.get('bug_message')
Rafael Monnerat's avatar
Rafael Monnerat committed
283
    self.assertEquals(bug_message.getSimulationState(), 'delivered') 
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299

  def stepCheckBugMessage(self, sequence=None, sequence_list=None, **kw):
    """
      Check a dummy bug message
    """
    bug_message = sequence.get('bug_message')
    person = sequence.get('person1')
    self.assertEquals( [ person ] , bug_message.getDestinationValueList())
    self.failUnless( bug_message.getStartDate() is not None)
    #self.assertEquals(bug_message.getSourceValue().getTitle(), 'dummy')

  def stepCheckBugInit(self, sequence=None, sequence_list=None, **kw):
    """
      Create a dummy bug
    """
    bug = sequence.get('bug')
300
    self.assertEquals("#%s" % bug.getId(), bug.getReference())
301
    #self.assertEquals(bug_message.getSourceTradeValue().getTitle(), 'dummy')
302

303 304 305 306 307
  def stepCloneAndCheckBug(self, sequence=None, sequence_list=None, **kw):
    """
      Create a dummy bug
    """
    bug_to_clone = sequence.get('bug')
308
    self.assertNotEquals(len(bug_to_clone.contentValues()), 0)
309 310
    bug = bug_to_clone.Base_createCloneDocument(batch_mode=1)
    self.assertEquals("#%s" % bug.getId(), bug.getReference())
311
    self.assertEquals(len(bug.contentValues()), 0)
312

313
  def stepOpenBug(self, sequence=None, sequence_list=None, **kw):
314
    """
315
      Open the bug.
316
    """
317
    bug = sequence.get('bug')
Nicolas Delaby's avatar
Nicolas Delaby committed
318
    self.workflow_tool.doActionFor(bug, 'confirm_action', send_event=1)
319
    self.assertEquals(bug.getSimulationState(), 'confirmed')
320

321
  def stepAssignBug(self, sequence=None, sequence_list=None, **kw):
322
    """
323
      Close the bug.
324
    """
325
    bug = sequence.get('bug')
Nicolas Delaby's avatar
Nicolas Delaby committed
326
    self.workflow_tool.doActionFor(bug, 'set_ready_action', send_event=1)
327
    self.assertEquals(bug.getSimulationState(), 'ready')
328

329
  def stepResolveBug(self, sequence=None, sequence_list=None, **kw):
330
    """
331
      Close the bug.
332
    """
333
    bug = sequence.get('bug')
Nicolas Delaby's avatar
Nicolas Delaby committed
334
    self.workflow_tool.doActionFor(bug, 'stop_action', send_event=1)
335
    self.assertEquals(bug.getSimulationState(), 'stopped')
336

Nicolas Delaby's avatar
Nicolas Delaby committed
337 338
  def stepReAssignBug(self, sequence=None, sequence_list=None, **kw):
    """
Nicolas Delaby's avatar
Nicolas Delaby committed
339
      Re Assign the bug.
Nicolas Delaby's avatar
Nicolas Delaby committed
340 341 342 343
    """
    bug = sequence.get('bug')
    self.workflow_tool.doActionFor(bug, 're_assign_action', send_event=1)
    self.assertEquals(bug.getSimulationState(), 'ready')
344

345
  def stepCloseBug(self, sequence=None, sequence_list=None, **kw):
346
    """
347
      Close the bug.
348
    """
349
    bug = sequence.get('bug')
Nicolas Delaby's avatar
Nicolas Delaby committed
350
    self.workflow_tool.doActionFor(bug, 'deliver_action', send_event=1)
Rafael Monnerat's avatar
Rafael Monnerat committed
351
    self.assertEquals(bug.getSimulationState(), 'delivered')
352

353 354 355 356 357
  def stepCancelBug(self, sequence=None, sequence_list=None, **kw):
    """
      Cancel the bug.
    """
    bug = sequence.get('bug')
Nicolas Delaby's avatar
Nicolas Delaby committed
358
    self.workflow_tool.doActionFor(bug, 'cancel_action', send_event=1)
359
    self.assertEquals(bug.getSimulationState(), 'cancelled')
360 361

  def stepSetTestedBug(self, sequence=None, sequence_list=None, **kw):
362
    """
363
      Set the bug as unit tested.
364
    """
365 366 367
    bug = sequence.get('bug')
    bug.setTested(True)
    self.assertEquals(bug.getTested(), True)
368

369
  def stepSetOldClosedDate(self, sequence=None, sequence_list=None, **kw):
370
    """
371
      Change Closed Date to a funky old value.
372
    """
373 374
    bug = sequence.get('bug')
    bug.setStopDate(self.datetime - 10)
375
    self.assertEquals(bug.getStopDate().Date(), (self.datetime - 10).Date()) # Check that datetime is fixed
376

377
  def stepCheckClosedDate(self, sequence=None, sequence_list=None, **kw):
378
    """
379
      Check that the closed date is set as today.
380
    """
381
    bug = sequence.get('bug')
382
    self.assertEquals(bug.getStopDate().Date(), self.datetime.Date())
383

384 385 386 387
  ##################################
  ##  Tests
  ##################################
  def test_01_StopDateUpdatedOnClose(self, quiet=QUIET, run=RUN_ALL_TEST):
388
    """
389
      Test that a closed bug has its stop date property updated.
390 391 392
    """
    if not run: return
    sequence_list = SequenceList()
393
    step_list = [ 'stepCreateBug'
394
                , 'stepCheckBugInit'
395 396 397
                , 'stepOpenBug'
                , 'stepTic'
                , 'stepSetOldClosedDate'
398 399 400 401
                , 'stepAssignBug'
                , 'stepTic'
                , 'stepResolveBug'
                , 'stepTic'
Nicolas Delaby's avatar
Nicolas Delaby committed
402
                , 'stepReAssignBug'
403 404 405
                , 'stepTic'
                , 'stepResolveBug'
                , 'stepTic'
406 407 408
                , 'stepCloseBug'
                , 'stepTic'
                , 'stepCheckClosedDate'
409 410 411 412 413
                ]
    sequence_string = ' '.join(step_list)
    sequence_list.addSequenceString(sequence_string)
    sequence_list.play(self, quiet=quiet)

414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
  def test_02_setCheckBugNotification(self, quiet=QUIET, run=RUN_ALL_TEST):
    """
      Test that a closed bug has its stop date property updated.
    """
    if not run: return
    sequence_list = SequenceList()
    step_list = [ 'stepLoginUsualUser'
                , 'stepCreateBug'
                , 'stepCreateProject'
                , 'stepCreatePerson1'
                , 'stepCreatePerson2'
                , 'stepSetSourceProject'
                , 'stepSetRequester'
                , 'stepTic'
                , 'stepOpenBug'
                , 'stepTic'
                , 'stepCheckBugNotification'
                , 'stepAssignBug'
                , 'stepTic'
                , 'stepCheckBugNotification'
                , 'stepResolveBug'
                , 'stepTic'
                , 'stepCheckBugNotification'
Nicolas Delaby's avatar
Nicolas Delaby committed
437
                , 'stepReAssignBug'
438 439 440 441 442 443 444 445 446 447 448 449
                , 'stepTic'
                , 'stepCheckBugNotification'
                , 'stepResolveBug'
                , 'stepTic'
                , 'stepCheckBugNotification'
                , 'stepCloseBug'
                , 'stepTic'
                , 'stepCheckBugNotification'
                ]
    sequence_string = ' '.join(step_list)
    sequence_list.addSequenceString(sequence_string)
    sequence_list.play(self, quiet=quiet)
450

451
  def test_03_setCheckBugNotification(self, quiet=QUIET, run=RUN_ALL_TEST):
452
    """
453
      Test that a closed bug has its stop date property updated.
454 455 456
    """
    if not run: return
    sequence_list = SequenceList()
457 458
    step_list = [ 'stepLoginUsualUser'
                , 'stepCreateBug'
459 460 461 462 463 464
                , 'stepCreateProject'
                , 'stepCreatePerson1'
                , 'stepCreatePerson2'
                , 'stepSetSourceProject'
                , 'stepSetRequester'
                , 'stepTic'
465 466
                , 'stepOpenBug'
                , 'stepTic'
467 468 469
                , 'stepCheckBugNotification'
                , 'stepCreateBugMessage'
                , 'stepCheckBugMessage'
470
                , 'stepTic'
471 472
                , 'stepPostBugMessage'
                , 'stepTic'
Rafael Monnerat's avatar
Rafael Monnerat committed
473
                , 'stepCheckBugMessageIsDelivered'
474
                , 'stepCheckBugMessageNotification'
475 476 477 478 479
                ]
    sequence_string = ' '.join(step_list)
    sequence_list.addSequenceString(sequence_string)
    sequence_list.play(self, quiet=quiet)

480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
# This tests is not Appliable anymore. It will be kept for a while.
#  def test_04_StopDateUpdatedOnCancel(self, quiet=QUIET, run=RUN_ALL_TEST):
#    """
#      Same test as above but on cancel action (test bug #600).
#    """
#    if  not run: return
#    sequence_list = SequenceList()
#    step_list = [ 'stepCreateBug'
#                , 'stepOpenBug'
#                , 'stepTic'
#                , 'stepSetOldClosedDate'
#                , 'stepCancelBug'
#                , 'stepTic'
#                , 'stepCheckClosedDate'
#                ]
#    sequence_string = ' '.join(step_list)
#    sequence_list.addSequenceString(sequence_string)
#    sequence_list.play(self, quiet=quiet)
498

499 500 501 502 503 504 505 506
  def test_05_setCheckBugClone(self, quiet=QUIET, run=RUN_ALL_TEST):
    """
      Test that a closed bug has its stop date property updated.
    """
    if not run: return
    sequence_list = SequenceList()
    step_list = [ 'stepCreateBug',
                  'stepCheckBugInit',
507
                  'stepOpenBug',
508 509 510 511 512 513
                  'stepCloneAndCheckBug'
                ]
    sequence_string = ' '.join(step_list)
    sequence_list.addSequenceString(sequence_string)
    sequence_list.play(self, quiet=quiet)

514 515 516 517 518 519 520 521
  def test_06_BugLineClone(self):
    bug_portal_type = 'Bug'
    bug_line_portal_type = 'Bug Line'
    module = self.portal.getDefaultModule(portal_type=bug_portal_type)
    bug = module.newContent(portal_type=bug_portal_type)
    bug_line = bug.newContent(portal_type='Bug Line')
    cloned_bug_line = bug_line.Base_createCloneDocument(batch_mode=1)
    self.assertTrue(cloned_bug_line.getStartDate() > bug_line.getStartDate())
522

523 524 525 526 527 528 529 530 531
  def test_07_Bug_BugLineSendFastInput(self):
    bug_portal_type = 'Bug'
    bug_line_portal_type = 'Bug Line'
    module = self.portal.getDefaultModule(portal_type=bug_portal_type)
    bug = module.newContent(portal_type=bug_portal_type)

    text_content = 'text content'
    title = 'title'

532 533
    bug_line = bug.Bug_doBugLineSendFastInputAction(batch_mode=1, title=title,
        text_content=text_content)
534 535 536 537 538

    self.assertEqual(text_content, bug_line.getTextContent())
    self.assertEqual(title, bug_line.getTitle())
    self.assertEqual('delivered', bug_line.getSimulationState())

539 540 541 542
def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestBug))
  return suite