test.erp5.testERP5Administration.py 8.01 KB
Newer Older
1 2
##############################################################################
#
3
# Copyright (c) 2004, 2005, 2006 Nexedi SARL and Contributors.
4 5 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
# All Rights Reserved.
#          Sebastien Robin <seb@nexedi.com>
#
# 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.
#
##############################################################################

import unittest
31
import time
32 33 34 35 36 37 38 39
from Products.ERP5.tests.testInventoryAPI import InventoryAPITestCase

class TestERP5Administration(InventoryAPITestCase):
  """Test for erp5_administration business template.
  """
  def getTitle(self):
    return "ERP5Administration"

40 41 42 43 44
  def beforeTearDown(self):
    # InventoryAPITestCase.beforeTearDown clears everything.
    # We do not want this on a ZODB test.
    pass

45
  def getBusinessTemplateList(self):
46
    """
47 48
        Same list as for Inventory API and add erp5_administration
    """
49
    return InventoryAPITestCase.getBusinessTemplateList(self) + ('erp5_full_text_mroonga_catalog', 'erp5_administration')
50 51 52 53 54 55 56

  def test_01_RunCheckStockTableAlarm(self):
    """
    Create a new alarm and check that it is able to detect any divergence
    between the predicate table and zodb objects
    """
    portal = self.getPortal()
57
    sql_test = portal.erp5_sql_connection.manage_test
58
    alarm = portal.portal_alarms.check_stock
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74

    def checkActiveProcess(failed):
      self.tic()
      self.assertEqual(alarm.getLastActiveProcess().ActiveProcess_sense(),
                       failed)
    def checkStock(row_count):
      alarm.activeSense()
      checkActiveProcess(1)
      alarm.solve()
      checkActiveProcess(1)
      alarm.activeSense()
      checkActiveProcess(0)
      self.assertEqual(row_count, sql_test("select count(*) from stock")[0][0])

    alarm.setAlarmNotificationMode('never')
    mvt = self._makeMovement(quantity=1.23)
75 76
    self.tic()
    alarm.activeSense()
77 78 79 80 81 82 83
    checkActiveProcess(0)

    row_count = sql_test("select count(*) from stock")[0][0]
    sql_test("update stock set quantity=5")
    checkStock(row_count)   # alarm.solve will reindex 'mvt'
    mvt.getParentValue()._delOb(mvt.getId())
    checkStock(row_count-2) # alarm.solve will unindex 'mvt'
84

Jérome Perrin's avatar
Jérome Perrin committed
85 86
  def test_check_consistency_alarm(self):
    alarm = self.portal.portal_alarms.check_consistency
87 88
    inconsistent_document = self.portal.organisation_module.newContent(
        portal_type='Organisation')
Jérome Perrin's avatar
Jérome Perrin committed
89
    # this document will be non consistent, for PropertyTypeValidity
90
    inconsistent_document.title = 3
91 92
    # tic right now to make sure the person is indexed, indeed the alarm
    # could use catalog to retrieve objects to check
93
    self.tic()
94

Jérome Perrin's avatar
Jérome Perrin committed
95
    alarm.activeSense()
96
    self.tic()
97

Jérome Perrin's avatar
Jérome Perrin committed
98 99
    # some errors were detected
    self.assertTrue(alarm.sense())
100

Jérome Perrin's avatar
Jérome Perrin committed
101 102 103 104 105 106
    # this alarm has a custom report
    alarm.Alarm_viewConsistencyCheckReport()
    # which has a listbox showing all problem reported by constraints and
    # errors reported by property type validity constraint
    line_list = alarm.Alarm_viewConsistencyCheckReport.listbox.get_value(
                        'default', render_format='list')
107 108
    self.assertEqual(1, len([line for line in line_list if line.isDataLine()]))
    self.assertEqual(str(line_list[-1].getColumnProperty('getTranslatedMessage')),
Jérome Perrin's avatar
Jérome Perrin committed
109 110 111 112 113 114
      "Attribute title should be of type string but is of type <type 'int'>")

    # this alarm can solve, as long as the constraints can solve, this is the
    # case of PropertyTypeValidity
    alarm.solve()
    self.tic()
115
    self.assertEqual('3', inconsistent_document.title)
Jérome Perrin's avatar
Jérome Perrin committed
116

117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
  def test_check_consistency_incremental(self):
    alarm = self.portal.portal_alarms.check_consistency.Base_createCloneDocument(
        batch_mode=True)
    alarm.edit(incremental_check=True)
    alarm.activeSense()
    self.tic()
    # create an inconsistent document
    inconsistent_document = self.portal.organisation_module.newContent(
        portal_type='Organisation')
    inconsistent_document.title = 0
    self.tic()

    # alarm report this document as not consistent
    time.sleep(2) # catalog date columns have a one second precision
    alarm.activeSense()
    self.tic()
    self.assertTrue(alarm.sense())
    result, = alarm.getLastActiveProcess().getResultList()
    constraint_message, = result.getProperty('constraint_message_list')
    self.assertEqual(inconsistent_document.getRelativeUrl(), constraint_message.object_relative_url)

    # next time the alarm run, document is not reported anymore
    alarm.activeSense()
    self.tic()
    self.assertFalse(alarm.sense())
    self.assertEqual([], alarm.getLastActiveProcess().getResultList())

    # cleanup
    self.portal.organisation_module.manage_delObjects(
        ids=[inconsistent_document.getId()])
    self.tic()

149 150 151 152 153 154 155 156 157 158
  def test_missing_category_document_constraint(self):
    person = self.portal.person_module.newContent(portal_type='Person')
    # This category does not exist
    person.setGroup('not/exist')

    # constraint reports one error
    consistency_error, = self.portal.portal_trash.newContent(
      portal_type='Missing Category Document Constraint',
      temp_object=True,
    ).checkConsistency(person)
159
    self.assertEqual(
160 161 162
      'Category group/not/exist on object %s is missing.' % person.getRelativeUrl(),
      str(consistency_error.getTranslatedMessage()))

163 164 165 166 167 168 169 170 171 172 173 174 175 176
  def test_missing_category_document_constraint_acquisition(self):
    person = self.portal.person_module.newContent(portal_type='Person')
    # This constraint is not confused by acquisition. group/level1/test_group can
    # be traversed, but category API does not use simple traversal.
    person.setCategoryList(['group/level1/test_group'])

    consistency_error, = self.portal.portal_trash.newContent(
      portal_type='Missing Category Document Constraint',
      temp_object=True,
    ).checkConsistency(person)
    self.assertEqual(
      'Category group/level1/test_group on object %s is missing.' % person.getRelativeUrl(),
      str(consistency_error.getTranslatedMessage()))

177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
  def test_Base_viewDict(self):
    # modules and documents
    self.assertTrue(self.portal.person_module.Base_viewDict())
    self.assertTrue(self.portal.person_module.newContent().Base_viewDict())
    # base categories and categories
    base_category = self.portal.portal_categories.contentValues()[0]
    self.assertTrue(base_category.Base_viewDict())
    self.assertTrue(base_category.newContent().Base_viewDict())
    self.assertTrue(base_category.Base_viewDict()) # base category with content
    # workflows
    workflow = self.portal.portal_workflow.newContent(portal_type='Workflow')
    state = workflow.newContent(portal_type='Workflow State', title='Some State')
    self.assertTrue(state.Base_viewDict())
    transition = workflow.newContent(portal_type='Workflow Transition',
                                     title='Some Transition')
    transition.setReference('change_something')
    transition.setGuardRoleList(['Assignee', 'Assignor'])
    transition.setCategoryList('destination/' + transition.getPath())
    self.assertTrue(transition.Base_viewDict())

197

198 199 200 201
def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestERP5Administration))
  return suite