source: main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py @ 14395

Last change on this file since 14395 was 14366, checked in by Henrik Bettermann, 8 years ago

Fix tests after turn of the year.

  • Property svn:keywords set to Id
File size: 49.3 KB
Line 
1## $Id: test_export.py 14366 2017-01-05 08:31:51Z 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
19import os
20import grok
21import datetime
22from cStringIO import StringIO
23from zope.component import queryUtility, getUtility
24from zope.event import notify
25from zope.interface.verify import verifyObject, verifyClass
26from waeup.kofa.interfaces import (
27    ICSVExporter, IExtFileStore, IFileStoreNameChooser)
28from waeup.kofa.students.catalog import StudentsQuery
29from waeup.kofa.students.export import (
30    StudentExporter, StudentStudyCourseExporter, StudentStudyLevelExporter,
31    CourseTicketExporter, StudentPaymentExporter, BedTicketExporter,
32    StudentPaymentsOverviewExporter, StudentStudyLevelsOverviewExporter,
33    ComboCardDataExporter, DataForBursaryExporter,
34    StudentUnpaidPaymentExporter,
35    get_students,)
36from waeup.kofa.students.accommodation import BedTicket
37from waeup.kofa.students.interfaces import ICSVStudentExporter
38from waeup.kofa.students.payments import StudentOnlinePayment
39from waeup.kofa.students.student import Student
40from waeup.kofa.students.studycourse import StudentStudyCourse
41from waeup.kofa.students.studylevel import StudentStudyLevel, CourseTicket
42from waeup.kofa.students.tests.test_batching import StudentImportExportSetup
43from waeup.kofa.testing import FunctionalLayer
44
45curr_year = datetime.datetime.now().year
46year_range = range(curr_year - 10, curr_year + 1)
47year_range_str = ','.join([str(i) for i in year_range])
48
49class ExportHelperTests(StudentImportExportSetup):
50    layer = FunctionalLayer
51    def setUp(self):
52        super(ExportHelperTests, self).setUp()
53        student = Student()
54        self.app['students'].addStudent(student)
55        student = self.setup_student(student)
56        notify(grok.ObjectModifiedEvent(student))
57        self.student = self.app['students'][student.student_id]
58        return
59
60    def test_get_students_plain(self):
61        # without a filter we get all students
62        result = get_students(self.app)
63        self.assertEqual(len(list(result)), 1)
64        return
65
66    def test_get_students_by_session(self):
67        # we can filter out students of a certain session
68        my_filter1 = StudentsQuery(current_session=2012)
69        result = get_students(self.app, stud_filter=my_filter1)
70        self.assertEqual(len(list(result)), 1)
71
72        my_filter2 = StudentsQuery(current_session=1964)
73        result = get_students(self.app, stud_filter=my_filter2)
74        self.assertEqual(len(list(result)), 0)
75        return
76
77    def test_get_students_by_level(self):
78        # we can filter out students of a certain level
79        my_filter1 = StudentsQuery(current_level=200)
80        result = get_students(self.app, stud_filter=my_filter1)
81        self.assertEqual(len(list(result)), 1)
82
83        my_filter2 = StudentsQuery(current_level=300)
84        result = get_students(self.app, stud_filter=my_filter2)
85        self.assertEqual(len(list(result)), 0)
86        return
87
88    def test_get_students_by_deptcode(self):
89        # we can filter out students of a certain dept.
90        my_filter1 = StudentsQuery(depcode='NA')
91        result = get_students(self.app, stud_filter=my_filter1)
92        self.assertEqual(len(list(result)), 1)
93
94        my_filter2 = StudentsQuery(depcode='NOTEXISTING')
95        result = get_students(self.app, stud_filter=my_filter2)
96        self.assertEqual(len(list(result)), 0)
97        return
98
99    def test_get_students_by_faccode(self):
100        # we can filter out students of a certain faculty.
101        my_filter1 = StudentsQuery(faccode='NA')
102        result = get_students(self.app, stud_filter=my_filter1)
103        self.assertEqual(len(list(result)), 1)
104
105        my_filter2 = StudentsQuery(faccode='NOTEXISTING')
106        result = get_students(self.app, stud_filter=my_filter2)
107        self.assertEqual(len(list(result)), 0)
108        return
109
110    def test_get_students_by_current_mode(self):
111        # we can filter out students in a certain mode.
112        my_filter1 = StudentsQuery(current_mode='ug_ft')
113        result = get_students(self.app, stud_filter=my_filter1)
114        self.assertEqual(len(list(result)), 1)
115
116        my_filter2 = StudentsQuery(current_mode='NOTEXISTING')
117        result = get_students(self.app, stud_filter=my_filter2)
118        self.assertEqual(len(list(result)), 0)
119        return
120
121
122class StudentExporterTest(StudentImportExportSetup):
123
124    layer = FunctionalLayer
125
126    std_csv_entry = (
127        'my adm code,my clr code,1981-02-04#,anna@sample.com,,'
128        'Anna,,Tester,234,M.,NG,,"Studentroad 21\nLagos 123456\n",,'
129        '+234-123-12345#,123,f,A111111,0,,,,created'
130        )
131
132    def setUp(self):
133        super(StudentExporterTest, self).setUp()
134        self.setup_for_export()
135        return
136
137    def test_ifaces(self):
138        # make sure we fullfill interface contracts
139        obj = StudentExporter()
140        verifyObject(ICSVStudentExporter, obj)
141        verifyClass(ICSVStudentExporter, StudentExporter)
142        return
143
144    def test_get_as_utility(self):
145        # we can get an student exporter as utility
146        result = queryUtility(ICSVExporter, name="students")
147        self.assertTrue(result is not None)
148        return
149
150    def test_export(self):
151        # we can really export students
152        # set values we can expect in export file
153        self.setup_student(self.student)
154        exporter = StudentExporter()
155        exporter.export([self.student], self.outfile)
156        result = open(self.outfile, 'rb').read()
157        self.assertTrue(
158            'adm_code,clr_code,date_of_birth,email,'
159            'employer,firstname,flash_notice,lastname,matric_number,middlename,'
160            'nationality,officer_comment,perm_address,personal_updated,'
161            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
162            'transcript_comment,password,state,history,certcode,is_postgrad,'
163            'current_level,current_session\r\n'
164            'my adm code,my clr code,'
165            '1981-02-04#,anna@sample.com,,Anna,,Tester,234,M.,NG,,'
166            '"Studentroad 21\nLagos 123456\n",,+234-123-12345#,123,f,'
167            'A111111,0,,,,created'
168            in result
169            )
170        return
171
172    def test_export_all(self):
173        # we can really export students
174        # set values we can expect in export file
175        self.setup_student(self.student)
176        exporter = StudentExporter()
177        exporter.export_all(self.app, self.outfile)
178        result = open(self.outfile, 'rb').read()
179        self.assertTrue(
180            'adm_code,clr_code,date_of_birth,email,'
181            'employer,firstname,flash_notice,lastname,matric_number,middlename,'
182            'nationality,officer_comment,perm_address,personal_updated,'
183            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
184            'transcript_comment,password,state,history,certcode,'
185            'is_postgrad,current_level,current_session\r\n'
186            'my adm code,my clr code,1981-02-04#,anna@sample.com,,'
187            'Anna,,Tester,234,M.,NG,,"Studentroad 21\nLagos 123456\n"'
188            ',,+234-123-12345#,123,f,A111111,0,,,,created'
189            in result
190            )
191        return
192
193    def test_export_student(self):
194        # we can export a single student
195        self.setup_student(self.student)
196        exporter = StudentExporter()
197        exporter.export_student(self.student, self.outfile)
198        result = open(self.outfile, 'rb').read()
199        self.assertTrue(
200            'adm_code,clr_code,date_of_birth,email,'
201            'employer,firstname,flash_notice,lastname,matric_number,middlename,'
202            'nationality,officer_comment,perm_address,personal_updated,'
203            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
204            'transcript_comment,password,state,history,certcode,'
205            'is_postgrad,current_level,current_session\r\n'
206            'my adm code,my clr code,1981-02-04#,anna@sample.com,,'
207            'Anna,,Tester,234,M.,NG,,"Studentroad 21\nLagos 123456\n"'
208            ',,+234-123-12345#,123,f,A111111,0,,,,created'
209            in result
210            )
211        return
212
213    def test_export_filtered(self):
214        # we can export a filtered set of students (filtered by session/level)
215        self.setup_student(self.student)
216        self.app['students'].addStudent(self.student)
217        notify(grok.ObjectModifiedEvent(self.student))
218        exporter = StudentExporter()
219
220        exporter.export_filtered(
221            self.app, self.outfile,
222            current_session=None, current_level=None)
223        result1 = open(self.outfile, 'rb').read()
224        exporter.export_filtered(
225            self.app, self.outfile,
226            current_session=2012, current_level=None)
227        result2 = open(self.outfile, 'rb').read()
228        # current_level and current_session can be both a string ...
229        exporter.export_filtered(
230            self.app, self.outfile,
231            current_session='2012', current_level=u'200')
232        result3 = open(self.outfile, 'rb').read()
233        exporter.export_filtered(
234            self.app, self.outfile,
235            current_session=2011, current_level=None)
236        result4 = open(self.outfile, 'rb').read()
237        # ... and an integer
238        exporter.export_filtered(
239            self.app, self.outfile,
240            current_session=None, current_level=100)
241        result5 = open(self.outfile, 'rb').read()
242        # Also students at probating levels are being exported ...
243        self.student['studycourse'].current_level = 210
244        notify(grok.ObjectModifiedEvent(self.student))
245        exporter.export_filtered(
246            self.app, self.outfile,
247            current_session=None, current_level=200)
248        result6 = open(self.outfile, 'rb').read()
249        # ... but not in the wrong level range.
250        self.student['studycourse'].current_level = 310
251        notify(grok.ObjectModifiedEvent(self.student))
252        exporter.export_filtered(
253            self.app, self.outfile,
254            current_session=None, current_level=200)
255        result7 = open(self.outfile, 'rb').read()
256        self.assertTrue(self.std_csv_entry in result1)
257        self.assertTrue(self.std_csv_entry in result2)
258        self.assertTrue(self.std_csv_entry in result3)
259        self.assertFalse(self.std_csv_entry in result4)
260        self.assertFalse(self.std_csv_entry in result5)
261        self.assertTrue(self.std_csv_entry in result6)
262        self.assertFalse(self.std_csv_entry in result7)
263        return
264
265    def test_export_selected(self):
266        # we can export a filtered set of students (filtered by session/level)
267        self.setup_student(self.student)
268        self.app['students'].addStudent(self.student)
269        notify(grok.ObjectModifiedEvent(self.student))
270        exporter = StudentExporter()
271        exporter.export_selected(
272            self.app, self.outfile, selected=['A111111'])
273        result1 = open(self.outfile, 'rb').read()
274        exporter.export_selected(
275            self.app, self.outfile, selected=[])
276        result2 = open(self.outfile, 'rb').read()
277        self.assertTrue(self.std_csv_entry in result1)
278        self.assertFalse(self.std_csv_entry in result2)
279        return
280
281    def test_export_filtered_by_dept(self):
282        # we can export a set of students filtered by department
283        self.setup_student(self.student)
284        self.app['students'].addStudent(self.student)
285        notify(grok.ObjectModifiedEvent(self.student))
286        exporter = StudentExporter()
287        # current_session can be both a string ...
288        exporter.export_filtered(
289            self.app, self.outfile,
290            current_session='2012', current_level=u'200', depcode='NA')
291        result1 = open(self.outfile, 'rb').read()
292        # ... and an integer
293        exporter.export_filtered(
294            self.app, self.outfile,
295            current_session=2012, current_level=200, depcode='NODEPT')
296        result2 = open(self.outfile, 'rb').read()
297        self.assertTrue(self.std_csv_entry in result1)
298        self.assertTrue(self.std_csv_entry not in result2)
299        return
300
301    def test_export_filtered_by_faculty(self):
302        # we can export a set of students filtered by faculty
303        self.setup_student(self.student)
304        self.app['students'].addStudent(self.student)
305        notify(grok.ObjectModifiedEvent(self.student))
306        exporter = StudentExporter()
307
308        exporter.export_filtered(
309            self.app, self.outfile,
310            current_session=2012, current_level='200', faccode='NA')
311        result1 = open(self.outfile, 'rb').read()
312        exporter.export_filtered(
313            self.app, self.outfile,
314            current_session=2012, current_level=200, faccode='NOFAC')
315        result2 = open(self.outfile, 'rb').read()
316        self.assertTrue(self.std_csv_entry in result1)
317        self.assertTrue(self.std_csv_entry not in result2)
318        return
319
320class StudentStudyCourseExporterTest(StudentImportExportSetup):
321
322    layer = FunctionalLayer
323
324    def setUp(self):
325        super(StudentStudyCourseExporterTest, self).setUp()
326        self.setup_for_export()
327        return
328
329    def test_ifaces(self):
330        # make sure we fullfill interface contracts
331        obj = StudentStudyCourseExporter()
332        verifyObject(ICSVStudentExporter, obj)
333        verifyClass(ICSVStudentExporter, StudentStudyCourseExporter)
334        return
335
336    def test_get_as_utility(self):
337        # we can get an student exporter as utility
338        result = queryUtility(ICSVExporter, name="studentstudycourses")
339        self.assertTrue(result is not None)
340        return
341
342    def test_export_empty(self):
343        # we can export a nearly empty study course
344        study_course = StudentStudyCourse()
345        exporter = StudentStudyCourseExporter()
346        exporter.export([study_course], self.outfile)
347        result = open(self.outfile, 'rb').read()
348        self.assertEqual(
349            result,
350            'certificate,current_level,current_session,current_verdict,'
351            'entry_mode,entry_session,previous_verdict,student_id\r\n'
352
353            ',,,0,,,0,\r\n'
354            )
355        return
356
357    def test_export(self):
358        # we can really export study courses.
359        # set values we can expect in export file
360        self.setup_student(self.student)
361        study_course = self.student.get('studycourse')
362        exporter = StudentStudyCourseExporter()
363        exporter.export([study_course], self.outfile)
364        result = open(self.outfile, 'rb').read()
365        self.assertEqual(
366            result,
367            'certificate,current_level,current_session,current_verdict,'
368            'entry_mode,entry_session,previous_verdict,student_id\r\n'
369
370            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
371            )
372        return
373
374    def test_export_all(self):
375        # we can really export students
376        # set values we can expect in export file
377        self.setup_student(self.student)
378        exporter = StudentStudyCourseExporter()
379        exporter.export_all(self.app, self.outfile)
380        result = open(self.outfile, 'rb').read()
381        self.assertEqual(
382            result,
383            'certificate,current_level,current_session,current_verdict,'
384            'entry_mode,entry_session,previous_verdict,student_id\r\n'
385
386            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
387            )
388        return
389
390    def test_export_student(self):
391        # we can export studycourse of a certain student
392        self.setup_student(self.student)
393        exporter = StudentStudyCourseExporter()
394        exporter.export_student(self.student, self.outfile)
395        result = open(self.outfile, 'rb').read()
396        self.assertEqual(
397            result,
398            'certificate,current_level,current_session,current_verdict,'
399            'entry_mode,entry_session,previous_verdict,student_id\r\n'
400
401            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
402            )
403        return
404
405    def test_export_filtered(self):
406        # we can export studycourses of a filtered set of students
407        self.setup_student(self.student)
408        self.app['students'].addStudent(self.student)
409        notify(grok.ObjectModifiedEvent(self.student))
410
411        exporter = StudentStudyCourseExporter()
412        exporter.export_filtered(
413            self.student, self.outfile, current_session=2012)
414        result = open(self.outfile, 'rb').read()
415        self.assertEqual(
416            result,
417            'certificate,current_level,current_session,current_verdict,'
418            'entry_mode,entry_session,previous_verdict,student_id\r\n'
419
420            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
421            )
422        return
423
424    def test_export_selected(self):
425        # we can export a filtered set of students (filtered by session/level)
426        self.setup_student(self.student)
427        self.app['students'].addStudent(self.student)
428        notify(grok.ObjectModifiedEvent(self.student))
429        exporter = StudentStudyCourseExporter()
430        exporter.export_selected(
431            self.app, self.outfile, selected=['A111111'])
432        result = open(self.outfile, 'rb').read()
433        self.assertEqual(
434            result,
435            'certificate,current_level,current_session,current_verdict,'
436            'entry_mode,entry_session,previous_verdict,student_id\r\n'
437
438            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
439            )
440        return
441
442
443class StudentStudyLevelExporterTest(StudentImportExportSetup):
444
445    layer = FunctionalLayer
446
447    def setUp(self):
448        super(StudentStudyLevelExporterTest, self).setUp()
449        self.setup_for_export()
450        return
451
452    def test_ifaces(self):
453        # make sure we fullfill interface contracts
454        obj = StudentStudyLevelExporter()
455        verifyObject(ICSVStudentExporter, obj)
456        verifyClass(ICSVStudentExporter, StudentStudyLevelExporter)
457        return
458
459    def test_get_as_utility(self):
460        # we can get an student exporter as utility
461        result = queryUtility(ICSVExporter, name="studentstudylevels")
462        self.assertTrue(result is not None)
463        return
464
465    def test_export_empty(self):
466        # we can export a nearly empty study level
467        study_level = StudentStudyLevel()
468        exporter = StudentStudyLevelExporter()
469        exporter.export([study_level], self.outfile)
470        result = open(self.outfile, 'rb').read()
471        self.assertEqual(
472            result,
473            'gpa,level,level_session,level_verdict,total_credits,'
474            'validated_by,validation_date,'
475            'student_id,number_of_tickets,certcode\r\n'
476            '0.0,,,0,0,,,,0,\r\n'
477            )
478        return
479
480    def test_export(self):
481        # we can really export study levels.
482        # set values we can expect in export file
483        self.setup_student(self.student)
484        study_course = self.student.get('studycourse')
485        study_level = study_course[study_course.keys()[0]]
486        exporter = StudentStudyLevelExporter()
487        exporter.export([study_level], self.outfile)
488        result = open(self.outfile, 'rb').read()
489        self.assertEqual(
490            result,
491            'gpa,level,level_session,level_verdict,total_credits,'
492            'validated_by,validation_date,'
493            'student_id,number_of_tickets,certcode\r\n'
494            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
495            )
496        return
497
498    def test_export_all(self):
499        # we can really export study levels
500        # set values we can expect in export file
501        self.setup_student(self.student)
502        exporter = StudentStudyLevelExporter()
503        exporter.export_all(self.app, self.outfile)
504        result = open(self.outfile, 'rb').read()
505        self.assertEqual(
506            result,
507            'gpa,level,level_session,level_verdict,total_credits,'
508            'validated_by,validation_date,'
509            'student_id,number_of_tickets,certcode\r\n'
510            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
511            )
512        return
513
514    def test_export_student(self):
515        # we can really export study levels of a certain student
516        self.setup_student(self.student)
517        exporter = StudentStudyLevelExporter()
518        exporter.export_student(self.student, self.outfile)
519        result = open(self.outfile, 'rb').read()
520        self.assertEqual(
521            result,
522            'gpa,level,level_session,level_verdict,total_credits,'
523            'validated_by,validation_date,'
524            'student_id,number_of_tickets,certcode\r\n'
525            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
526            )
527        return
528
529    def test_export_filtered(self):
530        # we can export studylevels of a filtered set of students
531        self.setup_student(self.student)
532        self.app['students'].addStudent(self.student)
533        notify(grok.ObjectModifiedEvent(self.student))
534
535        exporter = StudentStudyLevelExporter()
536        exporter.export_filtered(
537            self.student, self.outfile)
538        result = open(self.outfile, 'rb').read()
539        self.assertEqual(
540            result,
541            'gpa,level,level_session,level_verdict,total_credits,'
542            'validated_by,validation_date,'
543            'student_id,number_of_tickets,certcode\r\n'
544            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
545            )
546        return
547
548    def test_export_selected(self):
549        # we can export studylevels of a filtered set of students
550        self.setup_student(self.student)
551        self.app['students'].addStudent(self.student)
552        notify(grok.ObjectModifiedEvent(self.student))
553
554        exporter = StudentStudyLevelExporter()
555        exporter.export_selected(
556            self.app, self.outfile, selected=['A111111'])
557        result = open(self.outfile, 'rb').read()
558        self.assertEqual(
559            result,
560            'gpa,level,level_session,level_verdict,total_credits,'
561            'validated_by,validation_date,'
562            'student_id,number_of_tickets,certcode\r\n'
563            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
564            )
565        return
566
567class CourseTicketExporterTest(StudentImportExportSetup):
568
569    layer = FunctionalLayer
570
571    def setUp(self):
572        super(CourseTicketExporterTest, self).setUp()
573        self.setup_for_export()
574        return
575
576    def test_ifaces(self):
577        # make sure we fullfill interface contracts
578        obj = CourseTicketExporter()
579        verifyObject(ICSVStudentExporter, obj)
580        verifyClass(ICSVStudentExporter, CourseTicketExporter)
581        return
582
583    def test_get_as_utility(self):
584        # we can get an student exporter as utility
585        result = queryUtility(ICSVExporter, name="coursetickets")
586        self.assertTrue(result is not None)
587        return
588
589    def test_export_empty(self):
590        # we can export a nearly empty course ticket
591        ticket = CourseTicket()
592        exporter = CourseTicketExporter()
593        exporter.export([ticket], self.outfile)
594        result = open(self.outfile, 'rb').read()
595        self.assertEqual(
596            result,
597            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
598            'mandatory,passmark,score,semester,title,student_id,certcode,'
599            'display_fullname\r\n'
600            '0,0,,,,,,,0,,,,,,,\r\n'
601            )
602        return
603
604    def test_export(self):
605        # we can really export course tickets.
606        # set values we can expect in export file
607        self.setup_student(self.student)
608        study_course = self.student.get('studycourse')
609        study_level = study_course[study_course.keys()[0]]
610        ticket = study_level['CRS1']
611        exporter = CourseTicketExporter()
612        exporter.export([ticket], self.outfile)
613        result = open(self.outfile, 'rb').read()
614        self.assertEqual(
615            result,
616            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
617            'mandatory,passmark,score,semester,title,student_id,certcode,'
618            'display_fullname\r\n'
619            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
620            'Anna M. Tester\r\n'
621            )
622        return
623
624    def test_export_all(self):
625        # we can really export all course tickets
626        # set values we can expect in export file
627        self.setup_student(self.student)
628        exporter = CourseTicketExporter()
629        exporter.export_all(self.app, self.outfile)
630        result = open(self.outfile, 'rb').read()
631        self.assertEqual(
632            result,
633            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
634            'mandatory,passmark,score,semester,title,student_id,certcode,'
635            'display_fullname\r\n'
636            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
637            'Anna M. Tester\r\n'
638            )
639        return
640
641    def test_export_student(self):
642        # we can really export all course tickets of a certain student
643        self.setup_student(self.student)
644        exporter = CourseTicketExporter()
645        exporter.export_student(self.student, self.outfile)
646        result = open(self.outfile, 'rb').read()
647        self.assertEqual(
648            result,
649            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
650            'mandatory,passmark,score,semester,title,student_id,certcode,'
651            'display_fullname\r\n'
652            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
653            'Anna M. Tester\r\n'
654            )
655        return
656
657    def test_export_filtered(self):
658        # we can export course tickets of a filtered set of students
659        self.setup_student(self.student)
660        self.app['students'].addStudent(self.student)
661        notify(grok.ObjectModifiedEvent(self.student))
662
663        exporter = CourseTicketExporter()
664        exporter.export_filtered(
665            self.student, self.outfile)
666        result = open(self.outfile, 'rb').read()
667        self.assertEqual(
668            result,
669            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
670            'mandatory,passmark,score,semester,title,student_id,certcode,'
671            'display_fullname\r\n'
672            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
673            'Anna M. Tester\r\n'
674            )
675        # if the coursetickets catalog is used to filter students
676        # and (course) code is not None
677        # only course tickets which belong to this course are exported
678        exporter.export_filtered(
679            self.student, self.outfile, catalog='coursetickets', code='CRS1')
680        result = open(self.outfile, 'rb').read()
681        self.assertEqual(
682            result,
683            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
684            'mandatory,passmark,score,semester,title,student_id,certcode,'
685            'display_fullname\r\n'
686            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
687            'Anna M. Tester\r\n'
688            )
689        exporter.export_filtered(
690            self.student, self.outfile, catalog='coursetickets', code='any code')
691        result = open(self.outfile, 'rb').read()
692        self.assertEqual(
693            result,
694            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
695            'mandatory,passmark,score,semester,title,student_id,certcode,'
696            'display_fullname\r\n'
697            )
698        # Also tickets in probating levels are exported. Therefore
699        # we change the level attribute to fake a 110 level.
700        self.student['studycourse']['100'].level = 110
701        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
702        exporter.export_filtered(
703            self.student, self.outfile, catalog='coursetickets', code='CRS1', level='100')
704        result = open(self.outfile, 'rb').read()
705        self.assertEqual(
706            result,
707            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
708            'mandatory,passmark,score,semester,title,student_id,certcode,'
709            'display_fullname\r\n'
710            '1,1,CRS1,100,DEP1,FAC1,110,2012,0,100,,2,Course 1,A111111,CERT1,'
711            'Anna M. Tester\r\n'
712            )
713        return
714
715class StudentPaymentExporterTest(StudentImportExportSetup):
716
717    layer = FunctionalLayer
718
719    def setUp(self):
720        super(StudentPaymentExporterTest, self).setUp()
721        self.setup_for_export()
722        return
723
724    def test_ifaces(self):
725        # make sure we fullfill interface contracts
726        obj = StudentPaymentExporter()
727        verifyObject(ICSVStudentExporter, obj)
728        verifyClass(ICSVStudentExporter, StudentPaymentExporter)
729        return
730
731    def test_get_as_utility(self):
732        # we can get a payments exporter as utility
733        result = queryUtility(ICSVExporter, name="studentpayments")
734        self.assertTrue(result is not None)
735        return
736
737    def test_export_empty(self):
738        # we can export a nearly empty payment
739        payment = StudentOnlinePayment()
740        payment.creation_date = datetime.datetime(2012, 4, 1, 13, 12, 1)
741        exporter = StudentPaymentExporter()
742        exporter.export([payment], self.outfile)
743        result = open(self.outfile, 'rb').read()
744        self.assertEqual(
745            result,
746            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
747            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
748            'r_code,r_desc,student_id,state,current_session\r\n'
749
750            ',0.0,2012-04-01 13:12:01#,,1,,,,,unpaid,,0.0,,,,,\r\n'
751            )
752        return
753
754    def test_export(self):
755        # we can really export student payments.
756        # set values we can expect in export file
757        self.setup_student(self.student)
758        payment = self.student['payments']['my-payment']
759        exporter = StudentPaymentExporter()
760        exporter.export([payment], self.outfile)
761        result = open(self.outfile, 'rb').read()
762        self.assertEqual(
763            result,
764            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
765            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
766            'r_code,r_desc,student_id,state,current_session\r\n'
767
768            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
769            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
770            'r-code,,A111111,created,2012\r\n'
771            % (curr_year-6, curr_year-6, curr_year-6)
772            )
773        return
774
775    def test_export_all(self):
776        # we can really export all payments
777        # set values we can expect in export file
778        self.setup_student(self.student)
779        exporter = StudentPaymentExporter()
780        exporter.export_all(self.app, self.outfile)
781        result = open(self.outfile, 'rb').read()
782        self.assertEqual(
783            result,
784            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
785            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
786            'r_code,r_desc,student_id,state,current_session\r\n'
787
788            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
789            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
790            'r-code,,A111111,created,2012\r\n'
791            % (curr_year-6, curr_year-6, curr_year-6)
792            )
793        return
794
795    def test_export_student(self):
796        # we can really export all payments of a certain student
797        # set values we can expect in export file
798        self.setup_student(self.student)
799        exporter = StudentPaymentExporter()
800        exporter.export_student(self.student, self.outfile)
801        result = open(self.outfile, 'rb').read()
802        self.assertEqual(
803            result,
804            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
805            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
806            'r_code,r_desc,student_id,state,current_session\r\n'
807
808            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
809            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
810            'r-code,,A111111,created,2012\r\n'
811            % (curr_year-6, curr_year-6, curr_year-6)
812            )
813        return
814
815    def test_export_filtered(self):
816        # we can export payments of a filtered set of students
817        self.setup_student(self.student)
818        self.app['students'].addStudent(self.student)
819        notify(grok.ObjectModifiedEvent(self.student))
820
821        exporter = StudentPaymentExporter()
822        exporter.export_filtered(
823            self.student, self.outfile, current_level=200)
824        result = open(self.outfile, 'rb').read()
825        self.assertEqual(
826            result,
827            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
828            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
829            'r_code,r_desc,student_id,state,current_session\r\n'
830
831            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
832            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
833            'r-code,,A111111,created,2012\r\n'
834            % (curr_year-6, curr_year-6, curr_year-6)
835            )
836        return
837
838    def test_export_filtered_by_date(self):
839        # payments_start and payments_end are being ignored
840        self.setup_student(self.student)
841        self.app['students'].addStudent(self.student)
842        notify(grok.ObjectModifiedEvent(self.student))
843        exporter = StudentPaymentExporter()
844        # A key xxx does not exist
845        self.assertRaises(
846            KeyError, exporter.export_filtered, self.app, self.outfile,
847            current_session=None,
848            current_level=None, xxx='nonsense')
849        # payments_start and payments_end do exist but must match format '%Y-%m-%d'
850        self.assertRaises(
851            ValueError, exporter.export_filtered, self.app, self.outfile,
852            current_session=None, current_level=None,
853            payments_start='nonsense', payments_end='nonsense')
854        # If they match the format they are ignored by get_filtered and the
855        # exporter works properly.
856        # Attention: End day is included!
857        exporter.export_filtered(
858            self.app, self.outfile,
859            current_session=None, current_level=None,
860            payments_start='01/04/%s' % (curr_year-6),
861            payments_end='01/04/%s' % (curr_year-6))
862        result = open(self.outfile, 'rb').read()
863        self.assertEqual(
864            result,
865            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
866            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
867            'r_code,r_desc,student_id,state,current_session\r\n'
868
869            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
870            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
871            'r-code,,A111111,created,2012\r\n'
872            % (curr_year-6, curr_year-6, curr_year-6)
873            )
874        # Payment date is 2012-04-01, 14:12:01.
875        # No results if payment_date is outside the given period.
876        exporter.export_filtered(
877            self.app, self.outfile,
878            current_session=None, current_level=None,
879            payments_start='30/03/2012', payments_end='31/03/2012')
880        result = open(self.outfile, 'rb').read()
881        self.assertEqual(
882            result,
883            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
884            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
885            'r_code,r_desc,student_id,state,current_session\r\n'
886            )
887        exporter.export_filtered(
888            self.app, self.outfile,
889            current_session=None, current_level=None,
890            payments_start='02/04/2012', payments_end='03/04/2012')
891        result = open(self.outfile, 'rb').read()
892        self.assertEqual(
893            result,
894            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
895            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
896            'r_code,r_desc,student_id,state,current_session\r\n'
897            )
898        # No results if payment_date is not set
899        self.payment.payment_date = None
900        exporter.export_filtered(
901            self.app, self.outfile,
902            current_session=None, current_level=None,
903            payments_start='31/03/2012', payments_end='02/04/2012')
904        result = open(self.outfile, 'rb').read()
905        self.assertEqual(
906            result,
907            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
908            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
909            'r_code,r_desc,student_id,state,current_session\r\n'
910            )
911        return
912
913class StudentUnpaidPaymentExporterTest(StudentImportExportSetup):
914
915    layer = FunctionalLayer
916
917    def setUp(self):
918        super(StudentUnpaidPaymentExporterTest, self).setUp()
919        self.setup_for_export()
920        return
921
922    def test_export_all(self):
923        # we can really export all payments
924        # set values we can expect in export file
925        self.setup_student(self.student)
926        exporter = StudentUnpaidPaymentExporter()
927        exporter.export_all(self.app, self.outfile)
928        result = open(self.outfile, 'rb').read()
929        # No unpaid ticket exists
930        self.assertEqual(
931            result,
932            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
933            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
934            'r_code,r_desc,student_id,state,current_session\r\n'
935            )
936        # Make ticket unpaid
937        self.payment.p_state = 'unpaid'
938        exporter.export_all(self.app, self.outfile)
939        result = open(self.outfile, 'rb').read()
940        self.assertEqual(
941            result,
942            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
943            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
944            'r_code,r_desc,student_id,state,current_session\r\n'
945
946            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
947            'p-item,100,%s,unpaid,%s-04-01 14:12:01#,12.12,'
948            'r-code,,A111111,created,2012\r\n'
949            % (curr_year-6, curr_year-6, curr_year-6)
950            )
951        return
952
953class BursaryDataExporterTest(StudentImportExportSetup):
954
955    layer = FunctionalLayer
956
957    def setUp(self):
958        super(BursaryDataExporterTest, self).setUp()
959        self.setup_for_export()
960        return
961
962    def test_export_all(self):
963        # we can really export all payments
964        # set values we can expect in export file
965        self.setup_student(self.student)
966        exporter = DataForBursaryExporter()
967        exporter.export_all(self.app, self.outfile)
968        result = open(self.outfile, 'rb').read()
969        self.assertEqual(
970            result,
971            'ac,amount_auth,creation_date,p_category,p_current,p_id,p_item,'
972            'p_level,p_session,p_state,payment_date,r_amount_approved,r_code,'
973            'r_desc,student_id,matric_number,reg_number,firstname,middlename,lastname,'
974            'state,current_session,entry_session,entry_mode,faccode,depcode,certcode\r\n'
975
976            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,p-item,100,%s,'
977            'paid,%s-04-01 14:12:01#,12.12,r-code,,A111111,234,123,'
978            'Anna,M.,Tester,created,2012,2010,ug_ft,NA,NA,CERT1\r\n'
979            % (curr_year-6, curr_year-6, curr_year-6)
980            )
981        return
982
983class BedTicketExporterTest(StudentImportExportSetup):
984
985    layer = FunctionalLayer
986
987    def setUp(self):
988        super(BedTicketExporterTest, self).setUp()
989        self.setup_for_export()
990        return
991
992    def test_ifaces(self):
993        # make sure we fullfill interface contracts
994        obj = BedTicketExporter()
995        verifyObject(ICSVStudentExporter, obj)
996        verifyClass(ICSVStudentExporter, BedTicketExporter)
997        return
998
999    def test_get_as_utility(self):
1000        # we can get a bedtickets exporter as utility
1001        result = queryUtility(ICSVExporter, name="bedtickets")
1002        self.assertTrue(result is not None)
1003        return
1004
1005    def test_export_empty(self):
1006        # we can export a nearly empty bedticket
1007        bedticket = BedTicket()
1008        bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
1009        bedticket.bed = bed
1010        exporter = BedTicketExporter()
1011        exporter.export([bedticket], self.outfile)
1012        result = open(self.outfile, 'rb').read()
1013        self.assertMatches(
1014            result,
1015            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1016            'booking_session,student_id,actual_bed_type\r\n'
1017            'hall-1_A_101_A,,,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,,,regular_male_fr\r\n'
1018            )
1019        return
1020
1021    def test_export(self):
1022        # we can really export student bedtickets.
1023        # set values we can expect in export file
1024        self.setup_student(self.student)
1025        bedticket = self.student['accommodation']['2004']
1026        exporter = BedTicketExporter()
1027        exporter.export([bedticket], self.outfile)
1028        result = open(self.outfile, 'rb').read()
1029        self.assertMatches(
1030            result,
1031            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1032            'booking_session,student_id,actual_bed_type\r\n'
1033            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
1034            'A111111,regular_male_fr\r\n'
1035            )
1036        return
1037
1038    def test_export_all(self):
1039        # we can really export all bedtickets
1040        # set values we can expect in export file
1041        self.setup_student(self.student)
1042        exporter = BedTicketExporter()
1043        exporter.export_all(self.app, self.outfile)
1044        result = open(self.outfile, 'rb').read()
1045        self.assertMatches(
1046            result,
1047            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1048            'booking_session,student_id,actual_bed_type\r\n'
1049            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
1050            'A111111,regular_male_fr\r\n'
1051            )
1052        return
1053
1054    def test_export_student(self):
1055        # we can really export all bedtickets of a certain student
1056        # set values we can expect in export file
1057        self.setup_student(self.student)
1058        exporter = BedTicketExporter()
1059        exporter.export_student(self.student, self.outfile)
1060        result = open(self.outfile, 'rb').read()
1061        self.assertMatches(
1062            result,
1063            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1064            'booking_session,student_id,actual_bed_type\r\n'
1065            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
1066            'A111111,regular_male_fr\r\n'
1067            )
1068        return
1069
1070    def test_export_filtered(self):
1071        # we can export payments of a filtered set of students
1072        self.setup_student(self.student)
1073        self.app['students'].addStudent(self.student)
1074        notify(grok.ObjectModifiedEvent(self.student))
1075
1076        exporter = BedTicketExporter()
1077        exporter.export_filtered(
1078            self.student, self.outfile, current_level=200)
1079        result = open(self.outfile, 'rb').read()
1080        self.assertMatches(
1081            result,
1082            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1083            'booking_session,student_id,actual_bed_type\r\n'
1084            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,'
1085            '2004,A111111,regular_male_fr\r\n')
1086        return
1087
1088
1089class StudentPaymentsOverviewExporterTest(StudentImportExportSetup):
1090
1091    layer = FunctionalLayer
1092
1093    def setUp(self):
1094        super(StudentPaymentsOverviewExporterTest, self).setUp()
1095        self.setup_for_export()
1096        return
1097
1098    def test_ifaces(self):
1099        # make sure we fullfill interface contracts
1100        obj = StudentPaymentsOverviewExporter()
1101        verifyObject(ICSVStudentExporter, obj)
1102        verifyClass(ICSVStudentExporter, StudentPaymentsOverviewExporter)
1103        return
1104
1105    def test_get_as_utility(self):
1106        # we can get a payments exporter as utility
1107        result = queryUtility(ICSVExporter, name="paymentsoverview")
1108        self.assertTrue(result is not None)
1109        return
1110
1111    def test_export(self):
1112        self.setup_student(self.student)
1113        exporter = StudentPaymentsOverviewExporter()
1114        exporter.export([self.student], self.outfile)
1115        result = open(self.outfile, 'rb').read()
1116        self.assertTrue(
1117            'student_id,matric_number,display_fullname,state,certcode,'
1118            'faccode,depcode,is_postgrad,'
1119            'current_level,current_session,current_mode,entry_session,'
1120            'reg_number,%s\r\n'
1121            'A111111,234,Anna M. Tester,created,CERT1,NA,NA,0,'
1122            '200,2012,ug_ft,2010,'
1123            % year_range_str in result
1124            )
1125        return
1126
1127    def test_export_all(self):
1128        # we can really export students
1129        # set values we can expect in export file
1130        self.setup_student(self.student)
1131        # We add successful payments.
1132        payment_2 = StudentOnlinePayment()
1133        payment_2.p_id = 'my-id'
1134        payment_2.p_session = curr_year - 5
1135        payment_2.amount_auth = 13.13
1136        payment_2.p_state = 'paid'
1137        payment_2.p_category = u'schoolfee'
1138        self.student['payments']['my-2ndpayment'] = payment_2
1139        # This one could be a balance payment.
1140        # The amount is being added.
1141        payment_3 = StudentOnlinePayment()
1142        payment_3.p_id = 'my-id_2'
1143        payment_3.p_session = curr_year - 5
1144        payment_3.amount_auth = 1.01
1145        payment_3.p_state = 'paid'
1146        payment_3.p_category = u'schoolfee'
1147        self.student['payments']['my-3rdpayment'] = payment_3
1148        # One session school fee has been waived
1149        payment_4 = StudentOnlinePayment()
1150        payment_4.p_id = 'my-id_2'
1151        payment_4.p_session = curr_year - 4
1152        payment_4.amount_auth = 1.01
1153        payment_4.p_state = 'waived'
1154        payment_4.p_category = u'schoolfee'
1155        self.student['payments']['my-4thpayment'] = payment_4
1156        exporter = StudentPaymentsOverviewExporter()
1157        exporter.export_all(self.app, self.outfile)
1158        result = open(self.outfile, 'rb').read()
1159        self.assertTrue(
1160            'student_id,matric_number,display_fullname,state,'
1161            'certcode,faccode,depcode,is_postgrad,'
1162            'current_level,current_session,current_mode,entry_session,'
1163            'reg_number,%s\r\nA111111,234,Anna M. Tester,created,CERT1,NA,NA,0,'
1164            '200,2012,ug_ft,2010,123,,,,,12.12,14.14,waived,,,,\r\n'
1165            % year_range_str in result
1166            )
1167        return
1168
1169class StudentStudyLevelsOverviewExporterTest(StudentImportExportSetup):
1170
1171    layer = FunctionalLayer
1172
1173    def setUp(self):
1174        super(StudentStudyLevelsOverviewExporterTest, self).setUp()
1175        self.setup_for_export()
1176        return
1177
1178    def test_ifaces(self):
1179        obj = StudentStudyLevelsOverviewExporter()
1180        verifyObject(ICSVStudentExporter, obj)
1181        verifyClass(ICSVStudentExporter, StudentStudyLevelsOverviewExporter)
1182        return
1183
1184    def test_get_as_utility(self):
1185        result = queryUtility(ICSVExporter, name="studylevelsoverview")
1186        self.assertTrue(result is not None)
1187        return
1188
1189    def test_export(self):
1190        self.setup_student(self.student)
1191        exporter = StudentStudyLevelsOverviewExporter()
1192        exporter.export([self.student], self.outfile)
1193        result = open(self.outfile, 'rb').read()
1194        self.assertEqual(
1195             'student_id,state,certcode,faccode,depcode,is_postgrad,'
1196             'entry_session,current_level,current_session,'
1197             '10,100,110,120,200,210,220,300,310,320,400,410,420,500,'
1198             '510,520,600,610,620,700,710,720,800,810,820,900,910,920,999\r\n'
1199             'A111111,created,CERT1,NA,NA,0,2010,200,2012,,2012'
1200             ',,,,,,,,,,,,,,,,,,,,,,,,,,,\r\n',
1201            result
1202            )
1203        return
1204
1205    def test_export_all(self):
1206        self.setup_student(self.student)
1207        exporter = StudentStudyLevelsOverviewExporter()
1208        exporter.export_all(self.app, self.outfile)
1209        result = open(self.outfile, 'rb').read()
1210        self.assertEqual(
1211            'student_id,state,certcode,faccode,depcode,is_postgrad,'
1212            'entry_session,current_level,current_session,'
1213            '10,100,110,120,200,210,220,300,310,320,400,410,420,500,'
1214            '510,520,600,610,620,700,710,720,800,810,820,900,910,920,999\r\n'
1215            'A111111,created,CERT1,NA,NA,0,2010,200,2012,,2012'
1216            ',,,,,,,,,,,,,,,,,,,,,,,,,,,\r\n',
1217            result
1218            )
1219        return
1220
1221class ComboCardExporterTest(StudentImportExportSetup):
1222
1223    layer = FunctionalLayer
1224
1225    def setUp(self):
1226        super(ComboCardExporterTest, self).setUp()
1227        self.setup_for_export()
1228        return
1229
1230    def create_passport_img(self, student):
1231        # create some passport file for `student`
1232        storage = getUtility(IExtFileStore)
1233        image_path = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
1234        self.image_contents = open(image_path, 'rb').read()
1235        file_id = IFileStoreNameChooser(student).chooseName(
1236            attr='passport.jpg')
1237        storage.createFile(file_id, StringIO(self.image_contents))
1238
1239    def test_export_all(self):
1240        self.setup_student(self.student)
1241        self.create_passport_img(self.student)
1242        exporter = ComboCardDataExporter()
1243        exporter.export_all(self.app, self.outfile)
1244        result = open(self.outfile, 'rb').read()
1245        self.assertTrue(
1246            'display_fullname,student_id,matric_number,certificate,faculty,'
1247            'department,passport_path\r\nAnna M. Tester,A111111,234,'
1248            'Unnamed Certificate,Faculty of Unnamed Faculty (NA),'
1249            'Department of Unnamed Department (NA),'
1250            'students/00110/A111111/passport_A111111.jpg\r\n'
1251            in result
1252            )
1253        return
Note: See TracBrowser for help on using the repository browser.