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

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

Implement combi payments (tests will follow).

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