'Test record approval including components'

def testRecordApprovalWithComponents(self):

    db = current.db
    auth = current.auth
    s3db = current.s3db
    settings = current.deployment_settings
    settings.auth.record_approval = True
    self.approved_org = None
    def org_onapprove_test(record):
        self.approved_org = record.id
    org_onapprove = s3db.get_config('org_organisation', 'onapprove')
    otable_requires_approval = s3db.get_config('org_organisation', 'requires_approval', False)
    s3db.configure('org_organisation', onapprove=org_onapprove_test, requires_approval=True)
    self.approved_office = None
    def office_onapprove_test(record):
        self.approved_office = record.id
    office_onapprove = s3db.get_config('org_office', 'onapprove')
    ftable_requires_approval = s3db.get_config('org_office', 'requires_approval', False)
    s3db.configure('org_office', onapprove=office_onapprove_test, requires_approval=True)
    assertEqual = self.assertEqual
    assertNotEqual = self.assertNotEqual
    assertTrue = self.assertTrue
    assertFalse = self.assertFalse
    try:
        auth.s3_impersonate('admin@example.com')
        otable = s3db.org_organisation
        otable.approved_by.default = None
        org = Storage(name='Test    Approval    Organisation')
        org_id = otable.insert(**org)
        assertTrue((org_id > 0))
        org.update(id=org_id)
        s3db.update_super(otable, org)
        ftable = s3db.org_office
        ftable.approved_by.default = None
        office = Storage(name='Test    Approval    Office', organisation_id=org_id)
        office_id = ftable.insert(**office)
        assertTrue((office_id > 0))
        office.update(id=office_id)
        s3db.update_super(ftable, office)
        row = db((otable.id == org_id)).select(limitby=(0, 1)).first()
        assertNotEqual(row, None)
        assertEqual(row.approved_by, None)
        row = db((ftable.id == office_id)).select(limitby=(0, 1)).first()
        assertNotEqual(row, None)
        assertEqual(row.approved_by, None)
        approved = auth.permission.approved
        unapproved = auth.permission.unapproved
        assertFalse(approved(otable, org_id))
        assertTrue(unapproved(otable, org_id))
        assertFalse(approved(ftable, office_id))
        assertTrue(unapproved(ftable, office_id))
        resource = s3db.resource('org_organisation', id=org_id, unapproved=True)
        assertTrue(resource.approve(components=['office']))
        row = db((otable.id == org_id)).select(limitby=(0, 1)).first()
        assertNotEqual(row, None)
        assertEqual(row.approved_by, auth.user.id)
        row = db((ftable.id == office_id)).select(limitby=(0, 1)).first()
        assertNotEqual(row, None)
        assertEqual(row.approved_by, auth.user.id)
        assertTrue(approved(otable, org_id))
        assertFalse(unapproved(otable, org_id))
        assertTrue(approved(ftable, office_id))
        assertFalse(unapproved(ftable, office_id))
        assertEqual(self.approved_org, org_id)
        assertEqual(self.approved_office, office_id)
    finally:
        current.db.rollback()
        settings.auth.record_approval = False
        auth.s3_impersonate(None)
        s3db.configure('org_organisation', onapprove=org_onapprove, requires_approval=otable_requires_approval)
        s3db.configure('org_office', onapprove=office_onapprove, requires_approval=ftable_requires_approval)
