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

Last change on this file since 17650 was 17640, checked in by Henrik Bettermann, 11 months ago

Get set of selected students also from list of payment ids.

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