source: main/waeup.kofa/trunk/src/waeup/kofa/tests/test_reports.py @ 9506

Last change on this file since 9506 was 9344, checked in by uli, 12 years ago

Base components for reports (non-UI).

File size: 9.3 KB
Line 
1import datetime
2import grok
3import pytz
4import unittest
5from zc.async.interfaces import IJob
6from zope.component import getGlobalSiteManager
7from zope.interface.verify import verifyClass, verifyObject
8from waeup.kofa.interfaces import IJobManager
9from waeup.kofa.reports import (
10    IReport, IReportGenerator, IReportJob, IReportJobContainer,)
11from waeup.kofa.reports import (
12    Report, ReportGenerator, get_generators, report_job, AsyncReportJob,
13    ReportJobContainer,)
14from waeup.kofa.testing import FakeJob, FakeJobManager
15
16class FakeReportGenerator(ReportGenerator):
17    # fake report generator for tests.
18
19    def __init__(self, name=None, perm_create=None, perm_view=None):
20        self.name = name
21        self.perm_create = perm_create
22        self.perm_view = perm_view
23        return
24
25    def __eq__(self, obj):
26        return self.name == obj.name
27
28    def generate(self, site):
29        return Report()
30
31class ReportTests(unittest.TestCase):
32
33    def test_iface(self):
34        # make sure we fullfill the promised contracts
35        obj = Report()
36        verifyClass(IReport, Report)
37        verifyObject(IReport, obj)
38        return
39
40    def test_creation_dt(self):
41        # a report sets a datetime timestamp when created
42        report = Report()
43        self.assertTrue(hasattr(report, 'creation_dt'))
44        self.assertTrue(isinstance(report.creation_dt, datetime.datetime))
45        # the datetime is set with UTC timezone info
46        self.assertEqual(report.creation_dt.tzinfo, pytz.utc)
47        return
48
49class ReportGeneratorTest(unittest.TestCase):
50    def setUp(self):
51        grok.testing.grok('waeup.kofa.reports') # register utils
52
53    def test_iface(self):
54        # make sure we fullfill the promised contracts
55        obj = ReportGenerator()
56        verifyClass(IReportGenerator, ReportGenerator)
57        verifyObject(IReportGenerator, obj)
58        return
59
60
61class HelpersTests(unittest.TestCase):
62    # Tests for helper functions
63
64    def setUp(self):
65        grok.testing.grok('waeup.kofa.reports') # register utils
66        self.registered = [] # report utils registrations
67
68    def tearDown(self):
69        # unregister any previously registered report types
70        gsm = getGlobalSiteManager()
71        for report, name in self.registered:
72            gsm.unregisterUtility(report, IReportGenerator, name=name)
73        return
74
75    def register_generator(self, name, perm_create=None, perm_view=None):
76        # helper to register report generators as utils
77        gsm = getGlobalSiteManager()
78        generator = FakeReportGenerator(name)
79        gsm.registerUtility(generator, provided=IReportGenerator, name=name)
80        self.registered.append((generator, name),)
81        return generator
82
83    def test_get_generators_none(self):
84        # we get no generators if none was registered
85        result = list(get_generators())
86        self.assertEqual(result, [])
87        return
88
89    def test_get_generators_simple(self):
90        # we get a single generator if one is registered
91        self.register_generator('report1')
92        result = list(get_generators())
93        self.assertEqual(
94            result, [('report1', FakeReportGenerator('report1'))])
95        return
96
97    def test_get_generators_multiple(self):
98        # we also get multiple generators if available
99        self.register_generator('report1')
100        self.register_generator('report2')
101        result = list(get_generators())
102        self.assertEqual(
103            result,
104            [('report1', FakeReportGenerator('report1')),
105             ('report2', FakeReportGenerator('report2'))])
106        return
107
108class ReportJobTests(HelpersTests):
109    # Test asynchronous report functionality (simple cases)
110
111    def test_report_job_func(self):
112        # the report_job func really creates reports...
113        self.register_generator('report1')
114        report = report_job(None, 'report1')
115        self.assertTrue(IReport.providedBy(report))
116        self.assertTrue(isinstance(report, Report))
117
118    def test_report_job_interfaces(self):
119        # the AsyncReportJob implements promised interfaces correctly...
120        job = AsyncReportJob(None, None)
121        verifyClass(IJob, AsyncReportJob)
122        verifyObject(IJob, job)
123        verifyClass(IReportJob, AsyncReportJob)
124        verifyObject(IReportJob, job)
125        return
126
127
128class FakeJobWithResult(FakeJob):
129
130    def __init__(self):
131        #self.dir_path = tempfile.mkdtemp()
132        #self.result = os.path.join(self.dir_path, 'fake.csv')
133        #open(self.result, 'wb').write('a fake result')
134        self.result = Report()
135        return
136
137class ReportJobContainerTests(unittest.TestCase):
138    # Test ReportJobContainer
139
140    def setUp(self):
141        # register a suitable ICSVExporter as named utility
142        self.generator = FakeReportGenerator('report1')
143        self.job_manager = FakeJobManager()
144        self.gsm = getGlobalSiteManager()
145        self.gsm.registerUtility(
146            self.generator, IReportGenerator, name='report1')
147        self.gsm.registerUtility(
148            self.job_manager, IJobManager)
149
150    def tearDown(self):
151        self.gsm.unregisterUtility(
152            self.generator, IReportGenerator, name='report1')
153        self.gsm.unregisterUtility(self.job_manager, IJobManager)
154
155    def test_report_job_interfaces(self):
156        # the ExportJobContainer implements promised interfaces correctly...
157        container = ReportJobContainer()
158        verifyClass(IReportJobContainer, ReportJobContainer)
159        verifyObject(IReportJobContainer, container)
160        return
161
162    def test_start_report_job(self):
163        # we can start jobs
164        container = ReportJobContainer()
165        container.start_report_job('report3', 'bob')
166        result = self.job_manager._jobs.values()[0]
167        self.assertTrue(IJob.providedBy(result))
168        self.assertEqual(
169            container.running_report_jobs,
170            [('1', 'report3', 'bob')]
171            )
172        return
173
174    def test_get_running_report_jobs_all(self):
175        # we can get report jobs of all users
176        container = ReportJobContainer()
177        container.start_report_job('report3', 'bob')
178        container.start_report_job('report3', 'alice')
179        result = container.get_running_report_jobs()
180        self.assertEqual(
181            result,
182            [('1', 'report3', 'bob'),
183             ('2', 'report3', 'alice')]
184            )
185        return
186
187    def test_get_running_report_jobs_user(self):
188        # we can get the report jobs running for a certain user
189        container = ReportJobContainer()
190        container.start_report_job('report3', 'bob')
191        container.start_report_job('report3', 'alice')
192        result1 = container.get_running_report_jobs(user_id='alice')
193        result2 = container.get_running_report_jobs(user_id='foo')
194        self.assertEqual(
195            result1, [('2', 'report3', 'alice')])
196        self.assertEqual(
197            result2, [])
198        return
199
200    def test_get_running_report_jobs_only_if_exist(self):
201        # we get only jobs that are accessible through the job manager...
202        container = ReportJobContainer()
203        container.start_report_job('report3', 'bob')
204        container.start_report_job('report3', 'bob')
205        self.assertTrue(
206            ('2', 'report3', 'bob') in container.running_report_jobs)
207        # we remove the second entry from job manager
208        del self.job_manager._jobs['2']
209        result = container.get_running_report_jobs(user_id='bob')
210        self.assertEqual(
211            result, [('1', 'report3', 'bob')])
212        self.assertTrue(
213            ('2', 'report3', 'bob') not in container.running_report_jobs)
214        return
215
216    def test_get_report_job_status(self):
217        # we can get the stati of jobs...
218        container = ReportJobContainer()
219        container.start_report_job('report1', 'alice')
220        container.start_report_job('report1', 'bob')
221        container.start_report_job('report1', 'bob')
222        result = container.get_report_jobs_status(user_id='bob')
223        # we'll get the raw value, a translation and the title of the
224        # exporter
225        self.assertEqual(
226            result,
227            [('new', u'new', u'unnamed'),
228             ('completed', u'completed', u'unnamed')]
229            )
230        return
231
232    def test_delete_report_entry(self):
233        # we can remove report entries in local lists and the job
234        # manager as well...
235        container = ReportJobContainer()
236        container.start_report_job('report3', 'bob')
237        entry = container.running_report_jobs[0]
238        container.delete_report_entry(entry)
239        # both, running_report_jobs list and job manager are empty now
240        self.assertEqual(
241            container.running_report_jobs, [])
242        self.assertEqual(
243            self.job_manager._jobs, {})
244        return
245
246    def test_report_entry_from_job_id(self):
247        # we can get an report entry for a job_id if the id exists
248        container = ReportJobContainer()
249        entry = ('4', 'report3', 'bob')
250        container.running_report_jobs = [entry]
251        fake_job = FakeJobWithResult()
252        self.job_manager._jobs['4'] = fake_job
253        result1 = container.report_entry_from_job_id(None)
254        result2 = container.report_entry_from_job_id('4')
255        result3 = container.report_entry_from_job_id('23')
256        self.assertEqual(result1, None)
257        self.assertEqual(result2, ('4', 'report3', 'bob'))
258        self.assertEqual(result3, None)
259        #shutil.rmtree(fake_job.dir_path)
260        return
Note: See TracBrowser for help on using the repository browser.