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

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

Add TranscriptDataExporter and reorganize exporter names.

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