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

Last change on this file since 15546 was 15546, checked in by Henrik Bettermann, 5 years ago

Add semester filter to Fix CourseTicketExporter.

  • Property svn:keywords set to Id
File size: 59.9 KB
Line 
1## $Id: test_export.py 15546 2019-08-16 12:40:20Z 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    SchoolFeePaymentsOverviewExporter, StudentStudyLevelsOverviewExporter,
33    ComboCardDataExporter, DataForBursaryExporter,
34    StudentUnpaidPaymentExporter, SessionPaymentsOverviewExporter,
35    AccommodationPaymentsExporter, 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 - 11, 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            'password,state,history,'
163            'certcode,is_postgrad,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            '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            '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_student_id(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    def test_export_selected_matric_number(self):
443        # we can export a filtered set of students (filtered by session/level)
444        self.setup_student(self.student)
445        self.app['students'].addStudent(self.student)
446        notify(grok.ObjectModifiedEvent(self.student))
447        exporter = StudentStudyCourseExporter()
448        exporter.export_selected(
449            self.app, self.outfile, selected=['234'])
450        result = open(self.outfile, 'rb').read()
451        self.assertEqual(
452            result,
453            'certificate,current_level,current_session,current_verdict,'
454            'entry_mode,entry_session,previous_verdict,student_id\r\n'
455
456            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
457            )
458        return
459
460
461class StudentStudyLevelExporterTest(StudentImportExportSetup):
462
463    layer = FunctionalLayer
464
465    def setUp(self):
466        super(StudentStudyLevelExporterTest, self).setUp()
467        self.setup_for_export()
468        return
469
470    def test_ifaces(self):
471        # make sure we fullfill interface contracts
472        obj = StudentStudyLevelExporter()
473        verifyObject(ICSVStudentExporter, obj)
474        verifyClass(ICSVStudentExporter, StudentStudyLevelExporter)
475        return
476
477    def test_get_as_utility(self):
478        # we can get an student exporter as utility
479        result = queryUtility(ICSVExporter, name="studentstudylevels")
480        self.assertTrue(result is not None)
481        return
482
483    def test_export_empty(self):
484        # we can export a nearly empty study level
485        study_level = StudentStudyLevel()
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            'transcript_remark,validated_by,validation_date,'
493            'student_id,number_of_tickets,certcode\r\n'
494            '0.00,,,0,0,,,,,0,\r\n'
495            )
496        return
497
498    def test_export(self):
499        # we can really export study levels.
500        # set values we can expect in export file
501        self.setup_student(self.student)
502        study_course = self.student.get('studycourse')
503        study_level = study_course[study_course.keys()[0]]
504        exporter = StudentStudyLevelExporter()
505        exporter.export([study_level], self.outfile)
506        result = open(self.outfile, 'rb').read()
507        self.assertEqual(
508            result,
509            'gpa,level,level_session,level_verdict,total_credits,'
510            'transcript_remark,validated_by,validation_date,'
511            'student_id,number_of_tickets,certcode\r\n'
512            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
513            )
514        return
515
516    def test_export_all(self):
517        # we can really export study levels
518        # set values we can expect in export file
519        self.setup_student(self.student)
520        exporter = StudentStudyLevelExporter()
521        exporter.export_all(self.app, self.outfile)
522        result = open(self.outfile, 'rb').read()
523        self.assertEqual(
524            result,
525            'gpa,level,level_session,level_verdict,total_credits,'
526            'transcript_remark,validated_by,validation_date,'
527            'student_id,number_of_tickets,certcode\r\n'
528            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
529            )
530        return
531
532    def test_export_student(self):
533        # we can really export study levels of a certain student
534        self.setup_student(self.student)
535        exporter = StudentStudyLevelExporter()
536        exporter.export_student(self.student, self.outfile)
537        result = open(self.outfile, 'rb').read()
538        self.assertEqual(
539            result,
540            'gpa,level,level_session,level_verdict,total_credits,'
541            'transcript_remark,validated_by,validation_date,'
542            'student_id,number_of_tickets,certcode\r\n'
543            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
544            )
545        return
546
547    def test_export_filtered(self):
548        # we can export studylevels of a filtered set of students
549        self.setup_student(self.student)
550        self.app['students'].addStudent(self.student)
551        notify(grok.ObjectModifiedEvent(self.student))
552
553        exporter = StudentStudyLevelExporter()
554        exporter.export_filtered(
555            self.student, self.outfile)
556        result = open(self.outfile, 'rb').read()
557        self.assertEqual(
558            result,
559            'gpa,level,level_session,level_verdict,total_credits,'
560            'transcript_remark,validated_by,validation_date,'
561            'student_id,number_of_tickets,certcode\r\n'
562            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
563            )
564        return
565
566    def test_export_selected(self):
567        # we can export studylevels of a filtered set of students
568        self.setup_student(self.student)
569        self.app['students'].addStudent(self.student)
570        notify(grok.ObjectModifiedEvent(self.student))
571
572        exporter = StudentStudyLevelExporter()
573        exporter.export_selected(
574            self.app, self.outfile, selected=['A111111'])
575        result = open(self.outfile, 'rb').read()
576        self.assertEqual(
577            result,
578            'gpa,level,level_session,level_verdict,total_credits,'
579            'transcript_remark,validated_by,validation_date,'
580            'student_id,number_of_tickets,certcode\r\n'
581            '0.00,100,2012,A,100,,,,A111111,1,CERT1\r\n'
582            )
583        return
584
585class CourseTicketExporterTest(StudentImportExportSetup):
586
587    layer = FunctionalLayer
588
589    def setUp(self):
590        super(CourseTicketExporterTest, self).setUp()
591        self.setup_for_export()
592        return
593
594    def test_ifaces(self):
595        # make sure we fullfill interface contracts
596        obj = CourseTicketExporter()
597        verifyObject(ICSVStudentExporter, obj)
598        verifyClass(ICSVStudentExporter, CourseTicketExporter)
599        return
600
601    def test_get_as_utility(self):
602        # we can get an student exporter as utility
603        result = queryUtility(ICSVExporter, name="coursetickets")
604        self.assertTrue(result is not None)
605        return
606
607    def test_export_empty(self):
608        # we can export a nearly empty course ticket
609        ticket = CourseTicket()
610        exporter = CourseTicketExporter()
611        exporter.export([ticket], self.outfile)
612        result = open(self.outfile, 'rb').read()
613        self.assertEqual(
614            result,
615            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
616            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
617            'display_fullname\r\n'
618            '0,0,,,,,,,,0,0,,,,,,,,\r\n'
619            )
620        return
621
622    def test_export(self):
623        # we can really export course tickets.
624        # set values we can expect in export file
625        self.setup_student(self.student)
626        study_course = self.student.get('studycourse')
627        study_level = study_course[study_course.keys()[0]]
628        ticket = study_level['CRS1']
629        exporter = CourseTicketExporter()
630        exporter.export([ticket], self.outfile)
631        result = open(self.outfile, 'rb').read()
632        self.assertEqual(
633            result,
634            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
635            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
636            'display_fullname\r\n'
637            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
638            'Anna M. Tester\r\n'
639            )
640        return
641
642    def test_export_all(self):
643        # we can really export all course tickets
644        # set values we can expect in export file
645        self.setup_student(self.student)
646        exporter = CourseTicketExporter()
647        exporter.export_all(self.app, self.outfile)
648        result = open(self.outfile, 'rb').read()
649        self.assertEqual(
650            result,
651            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
652            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
653            'display_fullname\r\n'
654            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
655            'Anna M. Tester\r\n'
656            )
657        return
658
659    def test_export_student(self):
660        # we can really export all course tickets of a certain student
661        self.setup_student(self.student)
662        exporter = CourseTicketExporter()
663        exporter.export_student(self.student, self.outfile)
664        result = open(self.outfile, 'rb').read()
665        self.assertEqual(
666            result,
667            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
668            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
669            'display_fullname\r\n'
670            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
671            'Anna M. Tester\r\n'
672            )
673        return
674
675    def test_export_filtered(self):
676        # we can export course tickets of a filtered set of students
677        self.setup_student(self.student)
678        self.app['students'].addStudent(self.student)
679        notify(grok.ObjectModifiedEvent(self.student))
680
681        exporter = CourseTicketExporter()
682        exporter.export_filtered(self.student, self.outfile)
683        result = open(self.outfile, 'rb').read()
684        self.assertEqual(
685            result,
686            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
687            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
688            'display_fullname\r\n'
689            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
690            'Anna M. Tester\r\n'
691            )
692        # We can set the course tickets level, semester and level_session
693        # without code (used in the datacenter)
694        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
695        exporter.export_filtered(self.student, self.outfile, ct_level='100',
696            ct_session='2012', ct_semester='2')
697        result = open(self.outfile, 'rb').read()
698        self.assertEqual(
699            result,
700            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
701            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
702            'display_fullname\r\n'
703            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
704            'Anna M. Tester\r\n'
705            )
706        # 'all' does select all
707        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
708        exporter.export_filtered(self.student, self.outfile, ct_level='all',
709            ct_session='2012', ct_semester='all')
710        result = open(self.outfile, 'rb').read()
711        self.assertEqual(
712            result,
713            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
714            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
715            'display_fullname\r\n'
716            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
717            'Anna M. Tester\r\n'
718            )
719        # Level 200 tickets do not exist.
720        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
721        exporter.export_filtered(self.student, self.outfile, ct_level='200')
722        result = open(self.outfile, 'rb').read()
723        self.assertEqual(
724            result,
725            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
726            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
727            'display_fullname\r\n'
728                        )
729        # Session 2013 tickets do not exist.
730        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
731        exporter.export_filtered(self.student, self.outfile,
732            ct_level='all', ct_session='2013')
733        result = open(self.outfile, 'rb').read()
734        self.assertEqual(
735            result,
736            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
737            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
738            'display_fullname\r\n'
739            )
740        # 1st semester tickets do not exist.
741        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
742        exporter.export_filtered(self.student, self.outfile,
743            ct_level='all', ct_session='all', ct_semester='1')
744        result = open(self.outfile, 'rb').read()
745        self.assertEqual(
746            result,
747            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
748            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
749            'display_fullname\r\n'
750            )
751        # If the coursetickets catalog is used to filter students
752        # and (course) code is not None
753        # only course tickets which belong to this course are exported
754        exporter.export_filtered(
755            self.student, self.outfile, catalog='coursetickets', code='CRS1')
756        result = open(self.outfile, 'rb').read()
757        self.assertEqual(
758            result,
759            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
760            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
761            'display_fullname\r\n'
762            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
763            'Anna M. Tester\r\n'
764            )
765        exporter.export_filtered(
766            self.student, self.outfile, catalog='coursetickets', code='any code')
767        result = open(self.outfile, 'rb').read()
768        self.assertEqual(
769            result,
770            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
771            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
772            'display_fullname\r\n'
773            )
774        # Also tickets in probating levels are exported. Therefore
775        # we change the level attribute to fake a 110 level.
776        self.student['studycourse']['100'].level = 110
777        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
778        exporter.export_filtered(
779            self.student, self.outfile, catalog='coursetickets', code='CRS1', level='100')
780        result = open(self.outfile, 'rb').read()
781        self.assertEqual(
782            result,
783            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
784            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
785            'display_fullname\r\n'
786            '1,1,CRS1,,100,DEP1,FAC1,110,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
787            'Anna M. Tester\r\n'
788            )
789        return
790
791class StudentPaymentExporterTest(StudentImportExportSetup):
792
793    layer = FunctionalLayer
794
795    def setUp(self):
796        super(StudentPaymentExporterTest, self).setUp()
797        self.setup_for_export()
798        return
799
800    def test_ifaces(self):
801        # make sure we fullfill interface contracts
802        obj = StudentPaymentExporter()
803        verifyObject(ICSVStudentExporter, obj)
804        verifyClass(ICSVStudentExporter, StudentPaymentExporter)
805        return
806
807    def test_get_as_utility(self):
808        # we can get a payments exporter as utility
809        result = queryUtility(ICSVExporter, name="studentpayments")
810        self.assertTrue(result is not None)
811        return
812
813    def test_export_empty(self):
814        # we can export a nearly empty payment
815        payment = StudentOnlinePayment()
816        payment.creation_date = datetime.datetime(2012, 4, 1, 13, 12, 1)
817        exporter = StudentPaymentExporter()
818        exporter.export([payment], self.outfile)
819        result = open(self.outfile, 'rb').read()
820        self.assertEqual(
821            result,
822            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
823            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
824            'r_code,r_desc,student_id,state,current_session\r\n'
825
826            ',0.0,2012-04-01 13:12:01#,,1,,,,,unpaid,,0.0,,,,,\r\n'
827            )
828        return
829
830    def test_export(self):
831        # we can really export student payments.
832        # set values we can expect in export file
833        self.setup_student(self.student)
834        payment = self.student['payments']['my-payment']
835        exporter = StudentPaymentExporter()
836        exporter.export([payment], self.outfile)
837        result = open(self.outfile, 'rb').read()
838        self.assertEqual(
839            result,
840            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
841            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
842            'r_code,r_desc,student_id,state,current_session\r\n'
843
844            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
845            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
846            'r-code,,A111111,created,2012\r\n'
847            % (curr_year-6, curr_year-6, curr_year-6)
848            )
849        return
850
851    def test_export_all(self):
852        # we can really export all payments
853        # set values we can expect in export file
854        self.setup_student(self.student)
855        exporter = StudentPaymentExporter()
856        exporter.export_all(self.app, self.outfile)
857        result = open(self.outfile, 'rb').read()
858        self.assertEqual(
859            result,
860            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
861            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
862            'r_code,r_desc,student_id,state,current_session\r\n'
863
864            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
865            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
866            'r-code,,A111111,created,2012\r\n'
867            % (curr_year-6, curr_year-6, curr_year-6)
868            )
869        return
870
871    def test_export_student(self):
872        # we can really export all payments of a certain student
873        # set values we can expect in export file
874        self.setup_student(self.student)
875        exporter = StudentPaymentExporter()
876        exporter.export_student(self.student, self.outfile)
877        result = open(self.outfile, 'rb').read()
878        self.assertEqual(
879            result,
880            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
881            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
882            'r_code,r_desc,student_id,state,current_session\r\n'
883
884            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
885            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
886            'r-code,,A111111,created,2012\r\n'
887            % (curr_year-6, curr_year-6, curr_year-6)
888            )
889        return
890
891    def test_export_filtered(self):
892        # we can export payments of a filtered set of students
893        self.setup_student(self.student)
894        self.app['students'].addStudent(self.student)
895        notify(grok.ObjectModifiedEvent(self.student))
896
897        exporter = StudentPaymentExporter()
898        exporter.export_filtered(
899            self.student, self.outfile, current_level=200)
900        result = open(self.outfile, 'rb').read()
901        self.assertEqual(
902            result,
903            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
904            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
905            'r_code,r_desc,student_id,state,current_session\r\n'
906
907            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
908            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
909            'r-code,,A111111,created,2012\r\n'
910            % (curr_year-6, curr_year-6, curr_year-6)
911            )
912        return
913
914    def test_export_filtered_by_date(self):
915        # payments_start and payments_end are being ignored
916        self.setup_student(self.student)
917        self.app['students'].addStudent(self.student)
918        notify(grok.ObjectModifiedEvent(self.student))
919        exporter = StudentPaymentExporter()
920        # A key xxx does not exist
921        self.assertRaises(
922            KeyError, exporter.export_filtered, self.app, self.outfile,
923            current_session=None,
924            current_level=None, xxx='nonsense')
925        # payments_start and payments_end do exist but must match format '%Y-%m-%d'
926        self.assertRaises(
927            ValueError, exporter.export_filtered, self.app, self.outfile,
928            current_session=None, current_level=None,
929            payments_start='nonsense', payments_end='nonsense')
930        # If they match the format they are ignored by get_filtered and the
931        # exporter works properly.
932        # Attention: End day is included!
933        exporter.export_filtered(
934            self.app, self.outfile,
935            current_session=None, current_level=None,
936            payments_start='01/04/%s' % (curr_year-6),
937            payments_end='01/04/%s' % (curr_year-6))
938        result = open(self.outfile, 'rb').read()
939        self.assertEqual(
940            result,
941            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
942            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
943            'r_code,r_desc,student_id,state,current_session\r\n'
944
945            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
946            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
947            'r-code,,A111111,created,2012\r\n'
948            % (curr_year-6, curr_year-6, curr_year-6)
949            )
950        # Payment date is 2012-04-01, 14:12:01.
951        # No results if payment_date is outside the given period.
952        exporter.export_filtered(
953            self.app, self.outfile,
954            current_session=None, current_level=None,
955            payments_start='30/03/2012', payments_end='31/03/2012')
956        result = open(self.outfile, 'rb').read()
957        self.assertEqual(
958            result,
959            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
960            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
961            'r_code,r_desc,student_id,state,current_session\r\n'
962            )
963        exporter.export_filtered(
964            self.app, self.outfile,
965            current_session=None, current_level=None,
966            payments_start='02/04/2012', payments_end='03/04/2012')
967        result = open(self.outfile, 'rb').read()
968        self.assertEqual(
969            result,
970            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
971            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
972            'r_code,r_desc,student_id,state,current_session\r\n'
973            )
974        # No results if payment_date is not set
975        self.payment.payment_date = None
976        exporter.export_filtered(
977            self.app, self.outfile,
978            current_session=None, current_level=None,
979            payments_start='31/03/2012', payments_end='02/04/2012')
980        result = open(self.outfile, 'rb').read()
981        self.assertEqual(
982            result,
983            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
984            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
985            'r_code,r_desc,student_id,state,current_session\r\n'
986            )
987        return
988
989class StudentUnpaidPaymentExporterTest(StudentImportExportSetup):
990
991    layer = FunctionalLayer
992
993    def setUp(self):
994        super(StudentUnpaidPaymentExporterTest, self).setUp()
995        self.setup_for_export()
996        return
997
998    def test_export_all(self):
999        # we can really export all payments
1000        # set values we can expect in export file
1001        self.setup_student(self.student)
1002        exporter = StudentUnpaidPaymentExporter()
1003        exporter.export_all(self.app, self.outfile)
1004        result = open(self.outfile, 'rb').read()
1005        # No unpaid ticket exists
1006        self.assertEqual(
1007            result,
1008            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
1009            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1010            'r_code,r_desc,student_id,state,current_session\r\n'
1011            )
1012        # Make ticket unpaid
1013        self.payment.p_state = 'unpaid'
1014        exporter.export_all(self.app, self.outfile)
1015        result = open(self.outfile, 'rb').read()
1016        self.assertEqual(
1017            result,
1018            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
1019            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1020            'r_code,r_desc,student_id,state,current_session\r\n'
1021
1022            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,'
1023            'p-item,100,%s,unpaid,%s-04-01 14:12:01#,12.12,'
1024            'r-code,,A111111,created,2012\r\n'
1025            % (curr_year-6, curr_year-6, curr_year-6)
1026            )
1027        return
1028
1029class BursaryDataExporterTest(StudentImportExportSetup):
1030
1031    layer = FunctionalLayer
1032
1033    def setUp(self):
1034        super(BursaryDataExporterTest, self).setUp()
1035        self.setup_for_export()
1036        return
1037
1038    def test_export_all(self):
1039        # we can really export all payments
1040        # set values we can expect in export file
1041        self.setup_student(self.student)
1042        exporter = DataForBursaryExporter()
1043        exporter.export_all(self.app, self.outfile)
1044        result = open(self.outfile, 'rb').read()
1045        self.assertEqual(
1046            result,
1047            'ac,amount_auth,creation_date,p_category,p_current,p_id,p_item,'
1048            'p_level,p_session,p_state,payment_date,r_amount_approved,r_code,'
1049            'r_desc,student_id,matric_number,reg_number,firstname,middlename,lastname,'
1050            'state,current_session,entry_session,entry_mode,faccode,depcode,certcode\r\n'
1051
1052            '666,12.12,%s-04-01 13:12:01#,schoolfee,1,my-id,p-item,100,%s,'
1053            'paid,%s-04-01 14:12:01#,12.12,r-code,,A111111,234,123,'
1054            'Anna,M.,Tester,created,2012,2010,ug_ft,NA,NA,CERT1\r\n'
1055            % (curr_year-6, curr_year-6, curr_year-6)
1056            )
1057        return
1058
1059class AccommodationPaymentsExporterTest(StudentImportExportSetup):
1060
1061    layer = FunctionalLayer
1062
1063    def setUp(self):
1064        super(AccommodationPaymentsExporterTest, self).setUp()
1065        self.setup_for_export()
1066        return
1067
1068    def test_export_all(self):
1069        self.setup_student(self.student)
1070        # add accommodation payments
1071        payment = StudentOnlinePayment()
1072        payment.creation_date = datetime.datetime(curr_year-6, 4, 1, 13, 12, 1)
1073        payment.p_id = 'id1'
1074        payment.p_category = u'bed_allocation'
1075        payment.p_state = 'paid'
1076        payment.ac = u'abc'
1077        payment.p_item = u'xyz'
1078        payment.p_level = 100
1079        payment.p_session = curr_year - 6
1080        payment.payment_date = datetime.datetime(curr_year-6, 4, 1, 14, 12, 1)
1081        payment.amount_auth = 12.12
1082        payment.r_amount_approved = 12.12
1083        payment.r_code = u'cde'
1084        payment2 = StudentOnlinePayment()
1085        payment2.creation_date = datetime.datetime(curr_year-6, 4, 1, 13, 12, 1)
1086        payment2.p_id = 'id2'
1087        payment2.p_category = u'hostel_maintenance'
1088        payment2.p_state = 'paid'
1089        payment2.ac = u'abc'
1090        payment2.p_item = u'xyz'
1091        payment2.p_level = 100
1092        payment2.p_session = curr_year - 6
1093        payment2.payment_date = datetime.datetime(curr_year-6, 4, 1, 14, 12, 1)
1094        payment2.amount_auth = 12.12
1095        payment2.r_amount_approved = 12.12
1096        payment2.r_code = u'cde'
1097        # XXX: there is no addPayment method to give predictable names
1098        self.payment = self.student['payments']['id1'] = payment
1099        self.payment = self.student['payments']['id2'] = payment2
1100        exporter = AccommodationPaymentsExporter()
1101        exporter.export_all(self.app, self.outfile)
1102        result = open(self.outfile, 'rb').read()
1103        # only accommodation payments are exported
1104        self.assertEqual(
1105            result,
1106            'ac,amount_auth,creation_date,p_category,p_current,p_id,p_item,'
1107            'p_level,p_session,p_state,payment_date,r_amount_approved,r_code,'
1108            'r_desc,student_id,matric_number,reg_number,firstname,middlename,lastname,'
1109            'state,current_session,entry_session,entry_mode,faccode,depcode,certcode\r\n'
1110            'abc,12.12,%s-04-01 13:12:01#,bed_allocation,1,id1,xyz,100,%s,'
1111            'paid,%s-04-01 14:12:01#,12.12,cde,,A111111,234,123,'
1112            'Anna,M.,Tester,created,2012,2010,ug_ft,NA,NA,CERT1\r\n'
1113            'abc,12.12,%s-04-01 13:12:01#,hostel_maintenance,1,id2,xyz,100,%s,'
1114            'paid,%s-04-01 14:12:01#,12.12,cde,,A111111,234,123,'
1115            'Anna,M.,Tester,created,2012,2010,ug_ft,NA,NA,CERT1\r\n'
1116            % (curr_year-6, curr_year-6, curr_year-6,
1117               curr_year-6, curr_year-6, curr_year-6)
1118            )
1119        return
1120
1121class BedTicketExporterTest(StudentImportExportSetup):
1122
1123    layer = FunctionalLayer
1124
1125    def setUp(self):
1126        super(BedTicketExporterTest, self).setUp()
1127        self.setup_for_export()
1128        return
1129
1130    def test_ifaces(self):
1131        # make sure we fullfill interface contracts
1132        obj = BedTicketExporter()
1133        verifyObject(ICSVStudentExporter, obj)
1134        verifyClass(ICSVStudentExporter, BedTicketExporter)
1135        return
1136
1137    def test_get_as_utility(self):
1138        # we can get a bedtickets exporter as utility
1139        result = queryUtility(ICSVExporter, name="bedtickets")
1140        self.assertTrue(result is not None)
1141        return
1142
1143    def test_export_empty(self):
1144        # we can export a nearly empty bedticket
1145        bedticket = BedTicket()
1146        bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
1147        bedticket.bed = bed
1148        exporter = BedTicketExporter()
1149        exporter.export([bedticket], self.outfile)
1150        result = open(self.outfile, 'rb').read()
1151        self.assertMatches(
1152            result,
1153            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1154            'booking_session,student_id,actual_bed_type\r\n'
1155            'hall-1_A_101_A,,,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,,,regular_male_fr\r\n'
1156            )
1157        return
1158
1159    def test_export(self):
1160        # we can really export student bedtickets.
1161        # set values we can expect in export file
1162        self.setup_student(self.student)
1163        bedticket = self.student['accommodation']['2004']
1164        exporter = BedTicketExporter()
1165        exporter.export([bedticket], self.outfile)
1166        result = open(self.outfile, 'rb').read()
1167        self.assertMatches(
1168            result,
1169            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1170            'booking_session,student_id,actual_bed_type\r\n'
1171            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
1172            'A111111,regular_male_fr\r\n'
1173            )
1174        return
1175
1176    def test_export_all(self):
1177        # we can really export all bedtickets
1178        # set values we can expect in export file
1179        self.setup_student(self.student)
1180        exporter = BedTicketExporter()
1181        exporter.export_all(self.app, self.outfile)
1182        result = open(self.outfile, 'rb').read()
1183        self.assertMatches(
1184            result,
1185            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1186            'booking_session,student_id,actual_bed_type\r\n'
1187            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
1188            'A111111,regular_male_fr\r\n'
1189            )
1190        return
1191
1192    def test_export_student(self):
1193        # we can really export all bedtickets of a certain student
1194        # set values we can expect in export file
1195        self.setup_student(self.student)
1196        exporter = BedTicketExporter()
1197        exporter.export_student(self.student, self.outfile)
1198        result = open(self.outfile, 'rb').read()
1199        self.assertMatches(
1200            result,
1201            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1202            'booking_session,student_id,actual_bed_type\r\n'
1203            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
1204            'A111111,regular_male_fr\r\n'
1205            )
1206        return
1207
1208    def test_export_filtered(self):
1209        # we can export payments of a filtered set of students
1210        self.setup_student(self.student)
1211        self.app['students'].addStudent(self.student)
1212        notify(grok.ObjectModifiedEvent(self.student))
1213
1214        exporter = BedTicketExporter()
1215        exporter.export_filtered(
1216            self.student, self.outfile, current_level=200)
1217        result = open(self.outfile, 'rb').read()
1218        self.assertMatches(
1219            result,
1220            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1221            'booking_session,student_id,actual_bed_type\r\n'
1222            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,'
1223            '2004,A111111,regular_male_fr\r\n')
1224        return
1225
1226
1227class SchoolFeePaymentsOverviewExporterTest(StudentImportExportSetup):
1228
1229    layer = FunctionalLayer
1230
1231    def setUp(self):
1232        super(SchoolFeePaymentsOverviewExporterTest, self).setUp()
1233        self.setup_for_export()
1234        return
1235
1236    def test_ifaces(self):
1237        # make sure we fullfill interface contracts
1238        obj = SchoolFeePaymentsOverviewExporter()
1239        verifyObject(ICSVStudentExporter, obj)
1240        verifyClass(ICSVStudentExporter, SchoolFeePaymentsOverviewExporter)
1241        return
1242
1243    def test_get_as_utility(self):
1244        # we can get a payments exporter as utility
1245        result = queryUtility(ICSVExporter, name="sfpaymentsoverview")
1246        self.assertTrue(result is not None)
1247        return
1248
1249    def test_export(self):
1250        self.setup_student(self.student)
1251        exporter = SchoolFeePaymentsOverviewExporter()
1252        exporter.export([self.student], self.outfile)
1253        result = open(self.outfile, 'rb').read()
1254        self.assertTrue(
1255            'student_id,matric_number,display_fullname,state,certcode,'
1256            'faccode,depcode,is_postgrad,'
1257            'current_level,current_session,current_mode,entry_session,'
1258            'reg_number,%s\r\n'
1259            'A111111,234,Anna M. Tester,created,CERT1,NA,NA,0,'
1260            '200,2012,ug_ft,2010,'
1261            % year_range_str in result
1262            )
1263        return
1264
1265    def test_export_all(self):
1266        # we can really export students
1267        # set values we can expect in export file
1268        self.setup_student(self.student)
1269        # We add successful payments.
1270        payment_2 = StudentOnlinePayment()
1271        payment_2.p_id = 'my-id'
1272        payment_2.p_session = curr_year - 5
1273        payment_2.amount_auth = 13.13
1274        payment_2.p_state = 'paid'
1275        payment_2.p_category = u'schoolfee'
1276        self.student['payments']['my-2ndpayment'] = payment_2
1277        # This one could be a balance payment.
1278        # The amount is being added.
1279        payment_3 = StudentOnlinePayment()
1280        payment_3.p_id = 'my-id_2'
1281        payment_3.p_session = curr_year - 5
1282        payment_3.amount_auth = 1.01
1283        payment_3.p_state = 'paid'
1284        payment_3.p_category = u'schoolfee'
1285        self.student['payments']['my-3rdpayment'] = payment_3
1286        # One session school fee has been waived
1287        payment_4 = StudentOnlinePayment()
1288        payment_4.p_id = 'my-id_2'
1289        payment_4.p_session = curr_year - 4
1290        payment_4.amount_auth = 1.01
1291        payment_4.p_state = 'waived'
1292        payment_4.p_category = u'schoolfee'
1293        self.student['payments']['my-4thpayment'] = payment_4
1294        exporter = SchoolFeePaymentsOverviewExporter()
1295        exporter.export_all(self.app, self.outfile)
1296        result = open(self.outfile, 'rb').read()
1297        self.assertTrue(
1298            'student_id,matric_number,display_fullname,state,'
1299            'certcode,faccode,depcode,is_postgrad,'
1300            'current_level,current_session,current_mode,entry_session,'
1301            'reg_number,%s\r\nA111111,234,Anna M. Tester,created,CERT1,NA,NA,0,'
1302            '200,2012,ug_ft,2010,123,,,,,,12.12,14.14,waived,,,,\r\n'
1303            % year_range_str in result
1304            )
1305        return
1306
1307class SessionPaymentsOverviewExporterTest(StudentImportExportSetup):
1308
1309    layer = FunctionalLayer
1310
1311    def setUp(self):
1312        super(SessionPaymentsOverviewExporterTest, self).setUp()
1313        self.setup_for_export()
1314        grok.getSite()['configuration'].current_academic_session = curr_year - 4
1315        return
1316
1317    def test_ifaces(self):
1318        # make sure we fullfill interface contracts
1319        obj = SessionPaymentsOverviewExporter()
1320        verifyObject(ICSVStudentExporter, obj)
1321        verifyClass(ICSVStudentExporter, SessionPaymentsOverviewExporter)
1322        return
1323
1324    def test_get_as_utility(self):
1325        # we can get a payments exporter as utility
1326        result = queryUtility(ICSVExporter, name="sessionpaymentsoverview")
1327        self.assertTrue(result is not None)
1328        return
1329
1330    def test_export(self):
1331        self.setup_student(self.student)
1332        exporter = SessionPaymentsOverviewExporter()
1333        exporter.export([self.student], self.outfile)
1334        result = open(self.outfile, 'rb').read()
1335        self.assertTrue(
1336            'student_id,matric_number,display_fullname,state,certcode,'
1337            'faccode,depcode,is_postgrad,current_level,current_session,'
1338            'current_mode,entry_session,reg_number,schoolfee13,'
1339            'schoolfee14,schoolfee15,clearance13,clearance14,clearance15,'
1340            'gown13,gown14,gown15,transcript13,transcript14,transcript15\r\n'
1341            'A111111,234,Anna M. Tester,created,CERT1,NA,NA,0,200,'
1342            '2012,ug_ft,2010,123,'
1343            '12.12,,,,,,,,,,,\r\n' in result
1344            )
1345        return
1346
1347    def test_export_all(self):
1348        self.setup_student(self.student)
1349        # We add successful payments.
1350        payment_2 = StudentOnlinePayment()
1351        payment_2.p_id = 'my-id'
1352        payment_2.p_session = curr_year - 5
1353        payment_2.amount_auth = 13.13
1354        payment_2.p_state = 'paid'
1355        payment_2.p_category = u'schoolfee'
1356        self.student['payments']['my-2ndpayment'] = payment_2
1357        # This one could be a balance payment.
1358        # The amount is being added.
1359        payment_3 = StudentOnlinePayment()
1360        payment_3.p_id = 'my-id_2'
1361        payment_3.p_session = curr_year - 5
1362        payment_3.amount_auth = 1.01
1363        payment_3.p_state = 'paid'
1364        payment_3.p_category = u'schoolfee'
1365        self.student['payments']['my-3rdpayment'] = payment_3
1366        # One session school fee has been waived
1367        payment_4 = StudentOnlinePayment()
1368        payment_4.p_id = 'my-id_2'
1369        payment_4.p_session = curr_year - 4
1370        payment_4.amount_auth = 1.01
1371        payment_4.p_state = 'waived'
1372        payment_4.p_category = u'schoolfee'
1373        self.student['payments']['my-4thpayment'] = payment_4
1374        exporter = SessionPaymentsOverviewExporter()
1375        exporter.export_all(self.app, self.outfile)
1376        result = open(self.outfile, 'rb').read()
1377        self.assertTrue(
1378            'student_id,matric_number,display_fullname,state,certcode,faccode,'
1379            'depcode,is_postgrad,current_level,current_session,'
1380            'current_mode,entry_session,reg_number,'
1381            'schoolfee13,schoolfee14,schoolfee15,'
1382            'clearance13,clearance14,clearance15,'
1383            'gown13,gown14,gown15,'
1384            'transcript13,transcript14,transcript15\r\n'
1385            'A111111,234,Anna M. Tester,created,CERT1,NA,NA,0,200,2012,ug_ft,'
1386            '2010,123,'
1387            '12.12,14.14,1.01,,,,,,,,,\r\n'
1388            in result
1389            )
1390        return
1391
1392class StudentStudyLevelsOverviewExporterTest(StudentImportExportSetup):
1393
1394    layer = FunctionalLayer
1395
1396    def setUp(self):
1397        super(StudentStudyLevelsOverviewExporterTest, self).setUp()
1398        self.setup_for_export()
1399        return
1400
1401    def test_ifaces(self):
1402        obj = StudentStudyLevelsOverviewExporter()
1403        verifyObject(ICSVStudentExporter, obj)
1404        verifyClass(ICSVStudentExporter, StudentStudyLevelsOverviewExporter)
1405        return
1406
1407    def test_get_as_utility(self):
1408        result = queryUtility(ICSVExporter, name="studylevelsoverview")
1409        self.assertTrue(result is not None)
1410        return
1411
1412    def test_export(self):
1413        self.setup_student(self.student)
1414        exporter = StudentStudyLevelsOverviewExporter()
1415        exporter.export([self.student], self.outfile)
1416        result = open(self.outfile, 'rb').read()
1417        self.assertEqual(
1418             'student_id,state,certcode,faccode,depcode,is_postgrad,'
1419             'entry_session,current_level,current_session,'
1420             '0,10,100,110,120,200,210,220,300,310,320,400,410,420,500,'
1421             '510,520,600,610,620,700,710,720,800,810,820,900,910,920,999\r\n'
1422             'A111111,created,CERT1,NA,NA,0,2010,200,2012,,,2012'
1423             ',,,,,,,,,,,,,,,,,,,,,,,,,,,\r\n',
1424            result
1425            )
1426        return
1427
1428    def test_export_all(self):
1429        self.setup_student(self.student)
1430        exporter = StudentStudyLevelsOverviewExporter()
1431        exporter.export_all(self.app, self.outfile)
1432        result = open(self.outfile, 'rb').read()
1433        self.assertEqual(
1434            'student_id,state,certcode,faccode,depcode,is_postgrad,'
1435            'entry_session,current_level,current_session,'
1436            '0,10,100,110,120,200,210,220,300,310,320,400,410,420,500,'
1437            '510,520,600,610,620,700,710,720,800,810,820,900,910,920,999\r\n'
1438            'A111111,created,CERT1,NA,NA,0,2010,200,2012,,,2012'
1439            ',,,,,,,,,,,,,,,,,,,,,,,,,,,\r\n',
1440            result
1441            )
1442        return
1443
1444class ComboCardExporterTest(StudentImportExportSetup):
1445
1446    layer = FunctionalLayer
1447
1448    def setUp(self):
1449        super(ComboCardExporterTest, self).setUp()
1450        self.setup_for_export()
1451        return
1452
1453    def create_passport_img(self, student):
1454        # create some passport file for `student`
1455        storage = getUtility(IExtFileStore)
1456        image_path = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
1457        self.image_contents = open(image_path, 'rb').read()
1458        file_id = IFileStoreNameChooser(student).chooseName(
1459            attr='passport.jpg')
1460        storage.createFile(file_id, StringIO(self.image_contents))
1461
1462    def test_export_all(self):
1463        self.setup_student(self.student)
1464        self.create_passport_img(self.student)
1465        exporter = ComboCardDataExporter()
1466        exporter.export_all(self.app, self.outfile)
1467        result = open(self.outfile, 'rb').read()
1468        self.assertTrue(
1469            'display_fullname,student_id,matric_number,certificate,faculty,'
1470            'department,passport_path\r\nAnna M. Tester,A111111,234,'
1471            'Unnamed Certificate,Faculty of Unnamed Faculty (NA),'
1472            'Department of Unnamed Department (NA),'
1473            'students/00110/A111111/passport_A111111.jpg\r\n'
1474            in result
1475            )
1476        return
Note: See TracBrowser for help on using the repository browser.