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

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

Add StudentOutstandingCoursesExporter.

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