source: main/waeup.sirp/trunk/src/waeup/sirp/students/tests/test_batching.py @ 7263

Last change on this file since 7263 was 7263, checked in by Henrik Bettermann, 13 years ago

Add tests for applicant batch importer.

Make reg_no filed unique.

Two tests still fail because the importer only accepts the application_number as location field and does not yet search for registration numbers.

  • Property svn:keywords set to Id
File size: 10.2 KB
Line 
1## $Id: test_batching.py 7263 2011-12-04 12:59:40Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""Unit tests for students-related data importers.
19"""
20import os
21import shutil
22import tempfile
23import unittest
24from zope.component import createObject
25from zope.component.hooks import setSite, clearSite
26from zope.interface.verify import verifyClass, verifyObject
27
28from waeup.sirp.app import University
29from waeup.sirp.university.faculty import Faculty
30from waeup.sirp.university.department import Department
31from waeup.sirp.students.batching import (
32    StudentProcessor, StudentStudyCourseProcessor)
33from waeup.sirp.students.student import Student
34from waeup.sirp.testing import FunctionalLayer, FunctionalTestCase
35from waeup.sirp.interfaces import IBatchProcessor
36
37STUDENT_SAMPLE_DATA = open(
38    os.path.join(os.path.dirname(__file__), 'sample_student_data.csv'),
39    'rb').read()
40
41STUDENT_HEADER_FIELDS = STUDENT_SAMPLE_DATA.split(
42    '\n')[0].split(',')
43
44STUDENT_SAMPLE_DATA_UPDATE = open(
45    os.path.join(os.path.dirname(__file__), 'sample_student_data_update.csv'),
46    'rb').read()
47
48STUDENT_HEADER_FIELDS_UPDATE = STUDENT_SAMPLE_DATA_UPDATE.split(
49    '\n')[0].split(',')
50
51STUDENT_SAMPLE_DATA_UPDATE2 = open(
52    os.path.join(os.path.dirname(__file__), 'sample_student_data_update2.csv'),
53    'rb').read()
54
55STUDENT_HEADER_FIELDS_UPDATE2 = STUDENT_SAMPLE_DATA_UPDATE2.split(
56    '\n')[0].split(',')
57
58STUDYCOURSE_SAMPLE_DATA = open(
59    os.path.join(os.path.dirname(__file__), 'sample_studycourse_data.csv'),
60    'rb').read()
61
62STUDYCOURSE_HEADER_FIELDS = STUDYCOURSE_SAMPLE_DATA.split(
63    '\n')[0].split(',')
64
65class StudentImporterTest(FunctionalTestCase):
66
67    layer = FunctionalLayer
68
69    def setUp(self):
70        super(StudentImporterTest, self).setUp()
71        # Setup a sample site for each test
72        app = University()
73        self.dc_root = tempfile.mkdtemp()
74        app['datacenter'].setStoragePath(self.dc_root)
75
76        # Prepopulate the ZODB...
77        self.getRootFolder()['app'] = app
78        # we add the site immediately after creation to the
79        # ZODB. Catalogs and other local utilities are not setup
80        # before that step.
81        self.app = self.getRootFolder()['app']
82        # Set site here. Some of the following setup code might need
83        # to access grok.getSite() and should get our new app then
84        setSite(app)
85
86        # Add student with subobjects
87        student = Student()
88        student.fullname = u'Anna Tester'
89        student.reg_number = u'123'
90        student.matric_number = u'234'
91        self.app['students'].addStudent(student)
92        self.student = self.app['students'][student.student_id]
93        self.importer = StudentProcessor()
94        self.workdir = tempfile.mkdtemp()
95        self.csv_file = os.path.join(self.workdir, 'sample_student_data.csv')
96        self.csv_file_update = os.path.join(
97            self.workdir, 'sample_student_data_update.csv')
98        self.csv_file_update2 = os.path.join(
99            self.workdir, 'sample_student_data_update2.csv')
100        open(self.csv_file, 'wb').write(STUDENT_SAMPLE_DATA)
101        open(self.csv_file_update, 'wb').write(STUDENT_SAMPLE_DATA_UPDATE)
102        open(self.csv_file_update2, 'wb').write(STUDENT_SAMPLE_DATA_UPDATE2)
103
104    def tearDown(self):
105        super(StudentImporterTest, self).tearDown()
106        shutil.rmtree(self.workdir)
107        shutil.rmtree(self.dc_root)
108        clearSite()
109        return
110
111    def test_interface(self):
112        # Make sure we fulfill the interface contracts.
113        assert verifyObject(IBatchProcessor, self.importer) is True
114        assert verifyClass(
115            IBatchProcessor, StudentProcessor) is True
116
117    def test_parentsExist(self):
118        assert self.importer.parentsExist(None, dict()) is False
119        assert self.importer.parentsExist(None, self.app) is True
120
121    def test_entryExists(self):
122        assert self.importer.entryExists(
123            dict(student_id='ID_NONE'), self.app) is None
124        student = self.importer.getEntry(
125            dict(student_id=self.student.student_id), self.app)
126        self.assertEqual(student.reg_number, u'123')
127
128    def test_getParent(self):
129        parent = self.importer.getParent(None, self.app)
130        assert parent is self.app['students']
131
132    def test_getEntry(self):
133        assert self.importer.getEntry(
134            dict(student_id='ID_NONE'), self.app) is None
135        assert self.importer.getEntry(
136            dict(student_id=self.student.student_id), self.app) is self.student
137
138    def test_addEntry(self):
139        new_student = Student()
140        self.importer.addEntry(
141            new_student, dict(), self.app)
142        assert len(self.app['students'].keys()) == 2
143
144    def test_delEntry(self):
145        assert self.student.student_id in self.app['students'].keys()
146        self.importer.delEntry(
147            dict(reg_number=self.student.reg_number), self.app)
148        assert self.student.student_id not in self.app['students'].keys()
149
150    def test_import(self):
151        num, num_warns, fin_file, fail_file = self.importer.doImport(
152            self.csv_file, STUDENT_HEADER_FIELDS)
153        self.assertEqual(num_warns,0)
154        assert len(self.app['students'].keys()) == 4
155        shutil.rmtree(os.path.dirname(fin_file))
156
157    def test_import_update(self):
158        num, num_warns, fin_file, fail_file = self.importer.doImport(
159            self.csv_file, STUDENT_HEADER_FIELDS)
160        shutil.rmtree(os.path.dirname(fin_file))
161        num, num_warns, fin_file, fail_file = self.importer.doImport(
162            self.csv_file_update, STUDENT_HEADER_FIELDS_UPDATE, 'update')
163        self.assertEqual(num_warns,0)
164        shutil.rmtree(os.path.dirname(fin_file))
165
166    def test_import_update2(self):
167        num, num_warns, fin_file, fail_file = self.importer.doImport(
168            self.csv_file, STUDENT_HEADER_FIELDS)
169        shutil.rmtree(os.path.dirname(fin_file))
170        num, num_warns, fin_file, fail_file = self.importer.doImport(
171            self.csv_file_update2, STUDENT_HEADER_FIELDS_UPDATE2, 'update')
172        self.assertEqual(num_warns,0)
173        shutil.rmtree(os.path.dirname(fin_file))
174
175    def test_import_remove(self):
176        num, num_warns, fin_file, fail_file = self.importer.doImport(
177            self.csv_file, STUDENT_HEADER_FIELDS)
178        shutil.rmtree(os.path.dirname(fin_file))
179        num, num_warns, fin_file, fail_file = self.importer.doImport(
180            self.csv_file_update, STUDENT_HEADER_FIELDS_UPDATE, 'remove')
181        self.assertEqual(num_warns,0)
182        shutil.rmtree(os.path.dirname(fin_file))
183
184class StudentStudyCourseImporterTest(FunctionalTestCase):
185
186    layer = FunctionalLayer
187
188    def setUp(self):
189        super(StudentStudyCourseImporterTest, self).setUp()
190        app = University()
191        self.dc_root = tempfile.mkdtemp()
192        app['datacenter'].setStoragePath(self.dc_root)
193
194        self.getRootFolder()['app'] = app
195        self.app = self.getRootFolder()['app']
196        setSite(app)
197
198        self.workdir = tempfile.mkdtemp()
199        self.importer = StudentStudyCourseProcessor()
200        self.csv_file = os.path.join(
201            self.workdir, 'sample_studycourse_data.csv')
202        open(self.csv_file, 'wb').write(STUDYCOURSE_SAMPLE_DATA)
203
204        # Import students with subobjects
205        student_file = os.path.join(self.workdir, 'sample_student_data.csv')
206        open(student_file, 'wb').write(STUDENT_SAMPLE_DATA)
207        num, num_warns, fin_file, fail_file = StudentProcessor().doImport(
208            student_file, STUDENT_HEADER_FIELDS)
209        shutil.rmtree(os.path.dirname(fin_file))
210
211        # Populate university
212        self.certificate = createObject('waeup.Certificate')
213        self.certificate.code = 'CERT1'
214        self.certificate.application_category = 'basic'
215        self.certificate.start_level = 100
216        self.certificate.end_level = 500
217        self.app['faculties']['fac1'] = Faculty()
218        self.app['faculties']['fac1']['dep1'] = Department()
219        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
220            self.certificate)
221        return
222
223    def tearDown(self):
224        super(StudentStudyCourseImporterTest, self).tearDown()
225        shutil.rmtree(self.workdir)
226        shutil.rmtree(self.dc_root)
227        clearSite()
228        return
229
230    def test_interface(self):
231        # Make sure we fulfill the interface contracts.
232        assert verifyObject(IBatchProcessor, self.importer) is True
233        assert verifyClass(
234            IBatchProcessor, StudentStudyCourseProcessor) is True
235
236    def test_entryExists(self):
237        assert self.importer.entryExists(
238            dict(reg_number='REG_NONE'), self.app) is None
239        student = self.importer.entryExists(dict(reg_number='1'), self.app)
240        self.assertEqual(student.reg_number, u'1')
241
242    def test_getEntry(self):
243        studycourse = self.importer.getEntry(dict(reg_number='1'), self.app)
244        student = studycourse.__parent__
245        s_id = student.student_id
246        assert studycourse is self.app['students'][s_id]['studycourse']
247
248    def test_import(self):
249        num, num_warns, fin_file, fail_file = self.importer.doImport(
250            self.csv_file, STUDYCOURSE_HEADER_FIELDS,'update')
251        studycourse = self.importer.getEntry(dict(reg_number='1'), self.app)
252        self.assertEqual(num_warns,0)
253        self.assertEqual(studycourse.certificate.code, u'CERT1')
254        shutil.rmtree(os.path.dirname(fin_file))
255
256def test_suite():
257    suite = unittest.TestSuite()
258    for testcase in [
259        StudentImporterTest,StudentStudyCourseImporterTest,
260        ]:
261        suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
262                testcase
263                )
264        )
265    return suite
Note: See TracBrowser for help on using the repository browser.