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

Last change on this file was 17769, checked in by Henrik Bettermann, 4 months ago

After import with entry_mode 'transfer' we must ensure that after export and reimport the student is not transferred again.

  • Property svn:keywords set to Id
File size: 76.8 KB
Line 
1## $Id: test_export.py 17769 2024-05-13 06:26:57Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18
19import os
20import grok
21import datetime
22from cStringIO import StringIO
23from zope.component import queryUtility, getUtility, 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        exporter = SecondStudentStudyCourseExporter()
572        exporter.export_all(self.app, self.outfile)
573        result = open(self.outfile, 'rb').read()
574        self.assertEqual(
575            result,
576            'certificate,current_level,current_session,current_verdict,'
577            'entry_mode,entry_session,previous_verdict,student_id,previous\r\n'
578            )
579
580        # First Transfer
581        error = self.student.transfer(self.certificate2,
582                                      current_session=2013)
583        self.assertTrue(error == None)
584        exporter = FirstStudentStudyCourseExporter()
585        exporter.export_all(self.app, self.outfile)
586        result = open(self.outfile, 'rb').read()
587        # This is the original study course
588        self.assertEqual(
589            result,
590            'certificate,current_level,current_session,current_verdict,'
591            'entry_mode,entry_session,previous_verdict,student_id,previous\r\n'
592            'CERT1,200,2012,0,ug_ft,2010,0,A111111,1\r\n')
593        exporter = SecondStudentStudyCourseExporter()
594        exporter.export_all(self.app, self.outfile)
595        result = open(self.outfile, 'rb').read()
596        self.assertEqual(
597            result,
598            'certificate,current_level,current_session,current_verdict,'
599            'entry_mode,entry_session,previous_verdict,student_id,previous\r\n'
600            )
601
602        # Second transfer
603        error = self.student.transfer(self.certificate,
604                                      current_session=2014,
605                                      current_level=300)
606        self.assertTrue(error == None)
607        exporter = FirstStudentStudyCourseExporter()
608        exporter.export_all(self.app, self.outfile)
609        result = open(self.outfile, 'rb').read()
610        # This is the original study course
611        self.assertEqual(
612            result,
613            'certificate,current_level,current_session,current_verdict,'
614            'entry_mode,entry_session,previous_verdict,student_id,previous\r\n'
615            'CERT1,200,2012,0,ug_ft,2010,0,A111111,1\r\n')
616        # This is the second study course
617        exporter = SecondStudentStudyCourseExporter()
618        exporter.export_all(self.app, self.outfile)
619        result = open(self.outfile, 'rb').read()
620        self.assertEqual(
621            result,
622            'certificate,current_level,current_session,current_verdict,'
623            'entry_mode,entry_session,previous_verdict,student_id,previous\r\n'
624            'CERT2,,2013,,transferred,2010,,A111111,2\r\n')
625        # This is the third study course
626        exporter = StudentStudyCourseExporter()
627        exporter.export_all(self.app, self.outfile)
628        result = open(self.outfile, 'rb').read()
629        self.assertEqual(
630            result,
631            'certificate,current_level,current_session,current_verdict,'
632            'entry_mode,entry_session,previous_verdict,student_id,previous\r\n'
633            'CERT1,300,2014,,transferred,2010,,A111111,0\r\n')
634        return
635
636    def test_export_studylevels(self):
637        self.setup_student(self.student)
638        exporter = FirstStudentStudyLevelExporter()
639        exporter.export_all(self.app, self.outfile)
640        result = open(self.outfile, 'rb').read()
641        self.assertEqual(
642            result,
643            'gpa,level,level_session,level_verdict,total_credits,'
644            'transcript_remark,validated_by,validation_date,student_id,'
645            'number_of_tickets,certcode,previous\r\n'
646            )
647        error = self.student.transfer(self.certificate2, current_session=2013)
648        self.assertTrue(error == None)
649        exporter.export_all(self.app, self.outfile)
650        result = open(self.outfile, 'rb').read()
651        self.assertEqual(
652            result,
653            'gpa,level,level_session,level_verdict,total_credits,'
654            'transcript_remark,validated_by,validation_date,student_id,'
655            'number_of_tickets,certcode,previous\r\n'
656            '0.00,100,2012,A,100,,,,A111111,1,CERT1,1\r\n' )
657        study_level = StudentStudyLevel()
658        study_level.level_session = 2015
659        study_level.level_verdict = "C"
660        study_level.level = 400
661        self.student['studycourse'].addStudentStudyLevel(
662            self.certificate2, study_level)
663        error = self.student.transfer(self.certificate,
664                                      current_session=2014,
665                                      current_level=300)
666        self.assertTrue(error == None)
667        exporter = SecondStudentStudyLevelExporter()
668        exporter.export_all(self.app, self.outfile)
669        result = open(self.outfile, 'rb').read()
670        self.assertEqual(
671            result,
672            'gpa,level,level_session,level_verdict,total_credits,'
673            'transcript_remark,validated_by,validation_date,student_id,'
674            'number_of_tickets,certcode,previous\r\n'
675            '0.00,400,2015,C,0,,,,A111111,0,CERT2,2\r\n')
676        exporter = StudentStudyLevelExporter()
677        exporter.export_all(self.app, self.outfile)
678        result = open(self.outfile, 'rb').read()
679        self.assertEqual(
680            result,
681            'gpa,level,level_session,level_verdict,total_credits,'
682            'transcript_remark,validated_by,validation_date,student_id,'
683            'number_of_tickets,certcode,previous\r\n')
684        return
685
686    def test_export_coursetickets(self):
687        self.setup_student(self.student)
688        exporter = FirstCourseTicketExporter()
689        exporter.export_all(self.app, self.outfile)
690        result = open(self.outfile, 'rb').read()
691        self.assertEqual(
692            result,
693            'automatic,carry_over,code,course_category,credits,dcode,'
694            'fcode,level,level_session,mandatory,outstanding,passmark,'
695            'score,semester,ticket_session,title,student_id,certcode,'
696            'display_fullname,previous\r\n'
697            )
698        error = self.student.transfer(self.certificate2, current_session=2013)
699        self.assertTrue(error == None)
700        exporter.export_all(self.app, self.outfile)
701        result = open(self.outfile, 'rb').read()
702        self.assertEqual(
703            result,
704            'automatic,carry_over,code,course_category,credits,dcode,'
705            'fcode,level,level_session,mandatory,outstanding,passmark,'
706            'score,semester,ticket_session,title,student_id,certcode,'
707            'display_fullname,previous\r\n'
708            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,'
709            'A111111,CERT1,Anna M. Tester,1\r\n')
710        study_level = StudentStudyLevel()
711        study_level.level_session = 2015
712        study_level.level_verdict = "C"
713        study_level.level = 400
714        self.student['studycourse'].addStudentStudyLevel(
715            self.certificate2, study_level)
716        ticket = CourseTicket()
717        ticket.automatic = True
718        ticket.carry_over = True
719        ticket.code = u'CRS9'
720        ticket.title = u'Course 9'
721        ticket.fcode = u'FAC9'
722        ticket.dcode = u'DEP9'
723        ticket.credits = 150
724        ticket.passmark = 100
725        ticket.semester = 2
726        study_level[ticket.code] = ticket
727        error = self.student.transfer(self.certificate,
728                                      current_session=2014,
729                                      current_level=300)
730        self.assertTrue(error == None)
731        exporter = SecondCourseTicketExporter()
732        exporter.export_all(self.app, self.outfile)
733        result = open(self.outfile, 'rb').read()
734        self.assertEqual(
735            result,
736            'automatic,carry_over,code,course_category,credits,dcode,'
737            'fcode,level,level_session,mandatory,outstanding,passmark,'
738            'score,semester,ticket_session,title,student_id,certcode,'
739            'display_fullname,previous\r\n1,1,CRS9,,150,DEP9,FAC9,400,2015,0,0,'
740            '100,,2,,Course 9,A111111,CERT2,Anna M. Tester,2\r\n')
741        exporter = CourseTicketExporter()
742        exporter.export_all(self.app, self.outfile)
743        result = open(self.outfile, 'rb').read()
744        self.assertEqual(
745            result,
746            'automatic,carry_over,code,course_category,credits,dcode,'
747            'fcode,level,level_session,mandatory,outstanding,passmark,'
748            'score,semester,ticket_session,title,student_id,certcode,'
749            'display_fullname,previous\r\n'
750            )
751        return
752
753class StudentStudyLevelExporterTest(StudentImportExportSetup):
754
755    layer = FunctionalLayer
756
757    def setUp(self):
758        super(StudentStudyLevelExporterTest, self).setUp()
759        self.setup_for_export()
760        return
761
762    def test_ifaces(self):
763        # make sure we fullfill interface contracts
764        obj = StudentStudyLevelExporter()
765        verifyObject(ICSVStudentExporter, obj)
766        verifyClass(ICSVStudentExporter, StudentStudyLevelExporter)
767        return
768
769    def test_get_as_utility(self):
770        # we can get an student exporter as utility
771        result = queryUtility(ICSVExporter, name="studentstudylevels")
772        self.assertTrue(result is not None)
773        return
774
775    def test_export_empty(self):
776        # we can export a nearly empty study level
777        study_level = StudentStudyLevel()
778        exporter = StudentStudyLevelExporter()
779        exporter.export([study_level], 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,,,0,0,,,,,0,,0\r\n'
787            )
788        return
789
790    def test_export(self):
791        # we can really export study levels.
792        # set values we can expect in export file
793        self.setup_student(self.student)
794        study_course = self.student.get('studycourse')
795        study_level = study_course[study_course.keys()[0]]
796        exporter = StudentStudyLevelExporter()
797        exporter.export([study_level], self.outfile)
798        result = open(self.outfile, 'rb').read()
799        self.assertEqual(
800            result,
801            'gpa,level,level_session,level_verdict,total_credits,'
802            'transcript_remark,validated_by,validation_date,'
803            'student_id,number_of_tickets,certcode,previous\r\n'
804            '0.00,100,2012,A,100,,,,A111111,1,CERT1,0\r\n'
805            )
806        return
807
808    def test_export_all(self):
809        # we can really export study levels
810        # set values we can expect in export file
811        self.setup_student(self.student)
812        exporter = StudentStudyLevelExporter()
813        exporter.export_all(self.app, 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_student(self):
825        # we can really export study levels of a certain student
826        self.setup_student(self.student)
827        exporter = StudentStudyLevelExporter()
828        exporter.export_student(self.student, self.outfile)
829        result = open(self.outfile, 'rb').read()
830        self.assertEqual(
831            result,
832            'gpa,level,level_session,level_verdict,total_credits,'
833            'transcript_remark,validated_by,validation_date,'
834            'student_id,number_of_tickets,certcode,previous\r\n'
835            '0.00,100,2012,A,100,,,,A111111,1,CERT1,0\r\n'
836            )
837        return
838
839    def test_export_filtered(self):
840        # we can export studylevels of a filtered set of students
841        self.setup_student(self.student)
842        self.app['students'].addStudent(self.student)
843        notify(grok.ObjectModifiedEvent(self.student))
844
845        exporter = StudentStudyLevelExporter()
846        exporter.export_filtered(
847            self.student, self.outfile)
848        result = open(self.outfile, 'rb').read()
849        self.assertEqual(
850            result,
851            'gpa,level,level_session,level_verdict,total_credits,'
852            'transcript_remark,validated_by,validation_date,'
853            'student_id,number_of_tickets,certcode,previous\r\n'
854            '0.00,100,2012,A,100,,,,A111111,1,CERT1,0\r\n'
855            )
856        return
857
858    def test_export_selected(self):
859        # we can export studylevels of a filtered set of students
860        self.setup_student(self.student)
861        self.app['students'].addStudent(self.student)
862        notify(grok.ObjectModifiedEvent(self.student))
863
864        exporter = StudentStudyLevelExporter()
865        exporter.export_selected(
866            self.app, self.outfile, selected=['A111111'])
867        result = open(self.outfile, 'rb').read()
868        self.assertEqual(
869            result,
870            'gpa,level,level_session,level_verdict,total_credits,'
871            'transcript_remark,validated_by,validation_date,'
872            'student_id,number_of_tickets,certcode,previous\r\n'
873            '0.00,100,2012,A,100,,,,A111111,1,CERT1,0\r\n'
874            )
875        return
876
877class CourseTicketExporterTest(StudentImportExportSetup):
878
879    layer = FunctionalLayer
880
881    def setUp(self):
882        super(CourseTicketExporterTest, self).setUp()
883        self.setup_for_export()
884        return
885
886    def test_ifaces(self):
887        # make sure we fullfill interface contracts
888        obj = CourseTicketExporter()
889        verifyObject(ICSVStudentExporter, obj)
890        verifyClass(ICSVStudentExporter, CourseTicketExporter)
891        return
892
893    def test_get_as_utility(self):
894        # we can get an student exporter as utility
895        result = queryUtility(ICSVExporter, name="coursetickets")
896        self.assertTrue(result is not None)
897        return
898
899    def test_export_empty(self):
900        # we can export a nearly empty course ticket
901        ticket = CourseTicket()
902        exporter = CourseTicketExporter()
903        exporter.export([ticket], self.outfile)
904        result = open(self.outfile, 'rb').read()
905        self.assertEqual(
906            result,
907            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
908            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
909            'display_fullname,previous\r\n'
910            '0,0,,,,,,,,0,0,,,,,,,,,0\r\n'
911            )
912        return
913
914    def test_export(self):
915        # we can really export course tickets.
916        # set values we can expect in export file
917        self.setup_student(self.student)
918        study_course = self.student.get('studycourse')
919        study_level = study_course[study_course.keys()[0]]
920        ticket = study_level['CRS1']
921        exporter = CourseTicketExporter()
922        exporter.export([ticket], self.outfile)
923        result = open(self.outfile, 'rb').read()
924        self.assertEqual(
925            result,
926            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
927            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
928            'display_fullname,previous\r\n'
929            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
930            'Anna M. Tester,0\r\n'
931            )
932        return
933
934    def test_export_all(self):
935        # we can really export all course tickets
936        # set values we can expect in export file
937        self.setup_student(self.student)
938        exporter = CourseTicketExporter()
939        exporter.export_all(self.app, self.outfile)
940        result = open(self.outfile, 'rb').read()
941        self.assertEqual(
942            result,
943            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
944            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
945            'display_fullname,previous\r\n'
946            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
947            'Anna M. Tester,0\r\n'
948            )
949        return
950
951    def test_export_student(self):
952        # we can really export all course tickets of a certain student
953        self.setup_student(self.student)
954        exporter = CourseTicketExporter()
955        exporter.export_student(self.student, self.outfile)
956        result = open(self.outfile, 'rb').read()
957        self.assertEqual(
958            result,
959            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
960            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
961            'display_fullname,previous\r\n'
962            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
963            'Anna M. Tester,0\r\n'
964            )
965        return
966
967    def test_export_filtered(self):
968        # we can export course tickets of a filtered set of students
969        self.setup_student(self.student)
970        self.app['students'].addStudent(self.student)
971        notify(grok.ObjectModifiedEvent(self.student))
972
973        exporter = CourseTicketExporter()
974        exporter.export_filtered(self.student, self.outfile)
975        result = open(self.outfile, 'rb').read()
976        self.assertEqual(
977            result,
978            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
979            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
980            'display_fullname,previous\r\n'
981            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
982            'Anna M. Tester,0\r\n'
983            )
984        # We can set the course tickets level, semester and level_session
985        # without code (used in the datacenter)
986        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
987        exporter.export_filtered(self.student, self.outfile, ct_level='100',
988            ct_session='2012', ct_semester='2')
989        result = open(self.outfile, 'rb').read()
990        self.assertEqual(
991            result,
992            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
993            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
994            'display_fullname,previous\r\n'
995            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
996            'Anna M. Tester,0\r\n'
997            )
998        # 'all' does select all
999        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
1000        exporter.export_filtered(self.student, self.outfile, ct_level='all',
1001            ct_session='2012', ct_semester='all')
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            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
1009            'Anna M. Tester,0\r\n'
1010            )
1011        # Level 200 tickets do not exist.
1012        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
1013        exporter.export_filtered(self.student, self.outfile, ct_level='200')
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                        )
1021        # Session 2013 tickets do not exist.
1022        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
1023        exporter.export_filtered(self.student, self.outfile,
1024            ct_level='all', ct_session='2013')
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        # 1st semester tickets do not exist.
1033        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
1034        exporter.export_filtered(self.student, self.outfile,
1035            ct_level='all', ct_session='all', ct_semester='1')
1036        result = open(self.outfile, 'rb').read()
1037        self.assertEqual(
1038            result,
1039            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
1040            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
1041            'display_fullname,previous\r\n'
1042            )
1043        # If the coursetickets catalog is used to filter students
1044        # and (course) code is not None
1045        # only course tickets which belong to this course are exported
1046        exporter.export_filtered(
1047            self.student, self.outfile, catalog='coursetickets', code='CRS1')
1048        result = open(self.outfile, 'rb').read()
1049        self.assertEqual(
1050            result,
1051            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
1052            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
1053            'display_fullname,previous\r\n'
1054            '1,1,CRS1,,100,DEP1,FAC1,100,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
1055            'Anna M. Tester,0\r\n'
1056            )
1057        exporter.export_filtered(
1058            self.student, self.outfile, catalog='coursetickets', code='any code')
1059        result = open(self.outfile, 'rb').read()
1060        self.assertEqual(
1061            result,
1062            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
1063            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
1064            'display_fullname,previous\r\n'
1065            )
1066        # Also tickets in probating levels are exported. Therefore
1067        # we change the level attribute to fake a 110 level.
1068        self.student['studycourse']['100'].level = 110
1069        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
1070        exporter.export_filtered(
1071            self.student, self.outfile, catalog='coursetickets', code='CRS1', level='100')
1072        result = open(self.outfile, 'rb').read()
1073        self.assertEqual(
1074            result,
1075            'automatic,carry_over,code,course_category,credits,dcode,fcode,level,level_session,'
1076            'mandatory,outstanding,passmark,score,semester,ticket_session,title,student_id,certcode,'
1077            'display_fullname,previous\r\n'
1078            '1,1,CRS1,,100,DEP1,FAC1,110,2012,0,0,100,,2,,Course 1,A111111,CERT1,'
1079            'Anna M. Tester,0\r\n'
1080            )
1081        return
1082
1083class OutstandingCoursesExporterTest(StudentImportExportSetup):
1084
1085    layer = FunctionalLayer
1086
1087    def setUp(self):
1088        super(OutstandingCoursesExporterTest, self).setUp()
1089        self.setup_for_export()
1090        return
1091
1092    def test_ifaces(self):
1093        # make sure we fullfill interface contracts
1094        obj = OutstandingCoursesExporter()
1095        verifyObject(ICSVStudentExporter, obj)
1096        verifyClass(ICSVStudentExporter, OutstandingCoursesExporter)
1097        return
1098
1099    def test_get_as_utility(self):
1100        # we can get an student exporter as utility
1101        result = queryUtility(ICSVExporter, name="outstandingcourses")
1102        self.assertTrue(result is not None)
1103        return
1104
1105    def test_export_all(self):
1106        course1 = Course(u'Cheese Basics', 'C1')
1107        course2 = Course(u'Advanced Cheese Making', 'C2')
1108        course3 = Course(u'Selling Cheese', 'C3')
1109        self.app['faculties']['fac1']['dep1'].courses.addCourse(course1)
1110        self.app['faculties']['fac1']['dep1'].courses.addCourse(course2)
1111        self.app['faculties']['fac1']['dep1'].courses.addCourse(course3)
1112        self.certificate.addCertCourse(course1, 100, True)
1113        self.certificate.addCertCourse(course2, 400, False)
1114        self.certificate.addCertCourse(course3, 100, False)
1115        self.setup_student(self.student)
1116        self.student['studycourse']['100']['C3'].score = 25
1117        exporter = OutstandingCoursesExporter()
1118        exporter.export_all(self.app, self.outfile)
1119        result = open(self.outfile, 'rb').read()
1120        # The only student has registered C1, C3 and CRS1
1121        # She missed C2, has failed C3 and  did not
1122        # take C1 and CRS1
1123        self.assertEqual(
1124            result,
1125            'student_id,matric_number,certcode,display_fullname,missed,failed,nottaken\r\n'
1126            'A111111,234,CERT1,Anna M. Tester,C2_400,C3,C1 CRS1\r\n'
1127            )
1128        return
1129
1130class StudentPaymentExporterTest(StudentImportExportSetup):
1131
1132    layer = FunctionalLayer
1133
1134    def setUp(self):
1135        super(StudentPaymentExporterTest, self).setUp()
1136        self.setup_for_export()
1137        return
1138
1139    def test_ifaces(self):
1140        # make sure we fullfill interface contracts
1141        obj = StudentPaymentExporter()
1142        verifyObject(ICSVStudentExporter, obj)
1143        verifyClass(ICSVStudentExporter, StudentPaymentExporter)
1144        return
1145
1146    def test_get_as_utility(self):
1147        # we can get a payments exporter as utility
1148        result = queryUtility(ICSVExporter, name="studentpayments")
1149        self.assertTrue(result is not None)
1150        return
1151
1152    def test_export_empty(self):
1153        # we can export a nearly empty payment
1154        payment = StudentOnlinePayment()
1155        payment.creation_date = datetime.datetime(2012, 4, 1, 13, 12, 1)
1156        exporter = StudentPaymentExporter()
1157        exporter.export([payment], self.outfile)
1158        result = open(self.outfile, 'rb').read()
1159        self.assertEqual(
1160            result,
1161            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1162            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1163            'r_code,r_desc,student_id,state,current_session\r\n'
1164
1165            ',0.0,2012-04-01 13:12:01#,,[],1,,,,,unpaid,,0.0,,,,,\r\n'
1166            )
1167        return
1168
1169    def test_export(self):
1170        # we can really export student payments.
1171        # set values we can expect in export file
1172        self.setup_student(self.student)
1173        payment = self.student['payments']['my-payment']
1174        exporter = StudentPaymentExporter()
1175        exporter.export([payment], self.outfile)
1176        result = open(self.outfile, 'rb').read()
1177        self.assertEqual(
1178            result,
1179            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1180            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1181            'r_code,r_desc,student_id,state,current_session\r\n'
1182
1183            '666,12.12,%s-04-01 13:12:01#,schoolfee,[],1,my-id,'
1184            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
1185            'r-code,,A111111,created,2012\r\n'
1186            % (curr_year-6, curr_year-6, curr_year-6)
1187            )
1188        return
1189
1190    def test_export_all(self):
1191        # we can really export all payments
1192        # set values we can expect in export file
1193        self.setup_student(self.student)
1194        exporter = StudentPaymentExporter()
1195        exporter.export_all(self.app, self.outfile)
1196        result = open(self.outfile, 'rb').read()
1197        self.assertEqual(
1198            result,
1199            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1200            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1201            'r_code,r_desc,student_id,state,current_session\r\n'
1202
1203            '666,12.12,%s-04-01 13:12:01#,schoolfee,[],1,my-id,'
1204            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
1205            'r-code,,A111111,created,2012\r\n'
1206            % (curr_year-6, curr_year-6, curr_year-6)
1207            )
1208        return
1209
1210    def test_export_student(self):
1211        # we can really export all payments of a certain student
1212        # set values we can expect in export file
1213        self.setup_student(self.student)
1214        exporter = StudentPaymentExporter()
1215        exporter.export_student(self.student, self.outfile)
1216        result = open(self.outfile, 'rb').read()
1217        self.assertEqual(
1218            result,
1219            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1220            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1221            'r_code,r_desc,student_id,state,current_session\r\n'
1222
1223            '666,12.12,%s-04-01 13:12:01#,schoolfee,[],1,my-id,'
1224            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
1225            'r-code,,A111111,created,2012\r\n'
1226            % (curr_year-6, curr_year-6, curr_year-6)
1227            )
1228        return
1229
1230    def test_export_filtered(self):
1231        # we can export payments of a filtered set of students
1232        self.setup_student(self.student)
1233        self.app['students'].addStudent(self.student)
1234        notify(grok.ObjectModifiedEvent(self.student))
1235
1236        exporter = StudentPaymentExporter()
1237        exporter.export_filtered(
1238            self.student, self.outfile, current_level=200)
1239        result = open(self.outfile, 'rb').read()
1240        self.assertEqual(
1241            result,
1242            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1243            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1244            'r_code,r_desc,student_id,state,current_session\r\n'
1245
1246            '666,12.12,%s-04-01 13:12:01#,schoolfee,[],1,my-id,'
1247            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
1248            'r-code,,A111111,created,2012\r\n'
1249            % (curr_year-6, curr_year-6, curr_year-6)
1250            )
1251        return
1252
1253    def test_export_filtered_by_date(self):
1254        # payments_start and payments_end are being ignored
1255        self.setup_student(self.student)
1256        self.app['students'].addStudent(self.student)
1257        notify(grok.ObjectModifiedEvent(self.student))
1258        exporter = StudentPaymentExporter()
1259        # A key xxx does not exist
1260        self.assertRaises(
1261            KeyError, exporter.export_filtered, self.app, self.outfile,
1262            current_session=None,
1263            current_level=None, xxx='nonsense')
1264        # payments_start and payments_end do exist but must match format '%Y-%m-%d'
1265        self.assertRaises(
1266            ValueError, exporter.export_filtered, self.app, self.outfile,
1267            current_session=None, current_level=None,
1268            payments_start='nonsense', payments_end='nonsense')
1269        # If they match the format they are ignored by get_filtered and the
1270        # exporter works properly.
1271        # Attention: End day is included!
1272        exporter.export_filtered(
1273            self.app, self.outfile,
1274            current_session=None, current_level=None,
1275            payments_start='01/04/%s' % (curr_year-6),
1276            payments_end='01/04/%s' % (curr_year-6))
1277        result = open(self.outfile, 'rb').read()
1278        self.assertEqual(
1279            result,
1280            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1281            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1282            'r_code,r_desc,student_id,state,current_session\r\n'
1283
1284            '666,12.12,%s-04-01 13:12:01#,schoolfee,[],1,my-id,'
1285            'p-item,100,%s,paid,%s-04-01 14:12:01#,12.12,'
1286            'r-code,,A111111,created,2012\r\n'
1287            % (curr_year-6, curr_year-6, curr_year-6)
1288            )
1289        # Payment date is 2012-04-01, 14:12:01.
1290        # No results if payment_date is outside the given period.
1291        exporter.export_filtered(
1292            self.app, self.outfile,
1293            current_session=None, current_level=None,
1294            payments_start='30/03/2012', payments_end='31/03/2012')
1295        result = open(self.outfile, 'rb').read()
1296        self.assertEqual(
1297            result,
1298            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1299            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1300            'r_code,r_desc,student_id,state,current_session\r\n'
1301            )
1302        exporter.export_filtered(
1303            self.app, self.outfile,
1304            current_session=None, current_level=None,
1305            payments_start='02/04/2012', payments_end='03/04/2012')
1306        result = open(self.outfile, 'rb').read()
1307        self.assertEqual(
1308            result,
1309            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1310            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1311            'r_code,r_desc,student_id,state,current_session\r\n'
1312            )
1313        # No results if payment_date is not set
1314        self.payment.payment_date = None
1315        exporter.export_filtered(
1316            self.app, self.outfile,
1317            current_session=None, current_level=None,
1318            payments_start='31/03/2012', payments_end='02/04/2012')
1319        result = open(self.outfile, 'rb').read()
1320        self.assertEqual(
1321            result,
1322            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1323            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1324            'r_code,r_desc,student_id,state,current_session\r\n'
1325            )
1326        return
1327
1328class StudentTrimmedPaymentExporterTest(StudentImportExportSetup):
1329
1330    layer = FunctionalLayer
1331
1332    def setUp(self):
1333        super(StudentTrimmedPaymentExporterTest, self).setUp()
1334        self.setup_for_export()
1335        return
1336
1337    def test_ifaces(self):
1338        # make sure we fullfill interface contracts
1339        obj = StudentTrimmedPaymentExporter()
1340        verifyObject(ICSVStudentExporter, obj)
1341        verifyClass(ICSVStudentExporter, StudentTrimmedPaymentExporter)
1342        return
1343
1344    def test_get_as_utility(self):
1345        # we can get a payments exporter as utility
1346        result = queryUtility(ICSVExporter, name="trimmedpayments")
1347        self.assertTrue(result is not None)
1348        return
1349
1350    def test_export_all(self):
1351        # we can really export all payments
1352        # set values we can expect in export file
1353        self.setup_student(self.student)
1354        exporter = StudentTrimmedPaymentExporter()
1355        exporter.export_all(self.app, self.outfile)
1356        result = open(self.outfile, 'rb').read()
1357        self.assertEqual(
1358            result,
1359            'amount_auth,creation_date,p_category,p_combi,p_current,'
1360            'p_id,p_item,p_level,p_session,p_state,payment_date,'
1361            'r_amount_approved,r_code,r_desc,student_id,faccode,'
1362            'depcode,state,current_session\r\n'
1363
1364            '12.12,%s-04-01 13:12:01#,schoolfee,[],1,my-id,p-item,'
1365            '100,%s,paid,%s-04-01 14:12:01#,12.12,r-code,,'
1366            'A111111,NA,NA,created,2012\r\n'
1367            % (curr_year-6, curr_year-6, curr_year-6)
1368            )
1369        return
1370
1371
1372class UnpaidPaymentsExporterTest(StudentImportExportSetup):
1373
1374    layer = FunctionalLayer
1375
1376    def setUp(self):
1377        super(UnpaidPaymentsExporterTest, self).setUp()
1378        self.setup_for_export()
1379        return
1380
1381    def test_export_all(self):
1382        # we can really export all payments
1383        # set values we can expect in export file
1384        self.setup_student(self.student)
1385        exporter = UnpaidPaymentsExporter()
1386        exporter.export_all(self.app, self.outfile)
1387        result = open(self.outfile, 'rb').read()
1388        # No unpaid ticket exists
1389        self.assertEqual(
1390            result,
1391            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1392            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1393            'r_code,r_desc,student_id,state,current_session\r\n'
1394            )
1395        # Make ticket unpaid
1396        self.payment.p_state = 'unpaid'
1397        exporter.export_all(self.app, self.outfile)
1398        result = open(self.outfile, 'rb').read()
1399        self.assertEqual(
1400            result,
1401            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,'
1402            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
1403            'r_code,r_desc,student_id,state,current_session\r\n'
1404
1405            '666,12.12,%s-04-01 13:12:01#,schoolfee,[],1,my-id,'
1406            'p-item,100,%s,unpaid,%s-04-01 14:12:01#,12.12,'
1407            'r-code,,A111111,created,2012\r\n'
1408            % (curr_year-6, curr_year-6, curr_year-6)
1409            )
1410        return
1411
1412class BursaryDataExporterTest(StudentImportExportSetup):
1413
1414    layer = FunctionalLayer
1415
1416    def setUp(self):
1417        super(BursaryDataExporterTest, self).setUp()
1418        self.setup_for_export()
1419        return
1420
1421    def test_export_all(self):
1422        # we can really export all payments
1423        # set values we can expect in export file
1424        self.setup_student(self.student)
1425        exporter = DataForBursaryExporter()
1426        exporter.export_all(self.app, self.outfile)
1427        result = open(self.outfile, 'rb').read()
1428        self.assertEqual(
1429            result,
1430            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,p_item,'
1431            'p_level,p_session,p_state,payment_date,r_amount_approved,r_code,'
1432            'r_desc,student_id,matric_number,reg_number,firstname,middlename,lastname,'
1433            'sex,state,current_session,entry_session,entry_mode,faccode,depcode,certcode\r\n'
1434
1435            '666,12.12,%s-04-01 13:12:01#,schoolfee,[],1,my-id,p-item,100,%s,'
1436            'paid,%s-04-01 14:12:01#,12.12,r-code,,A111111,234,123,'
1437            'Anna,M.,Tester,f,created,2012,2010,ug_ft,NA,NA,CERT1\r\n'
1438            % (curr_year-6, curr_year-6, curr_year-6)
1439            )
1440        return
1441
1442class AccommodationPaymentsExporterTest(StudentImportExportSetup):
1443
1444    layer = FunctionalLayer
1445
1446    def setUp(self):
1447        super(AccommodationPaymentsExporterTest, self).setUp()
1448        self.setup_for_export()
1449        return
1450
1451    def test_export_all(self):
1452        self.setup_student(self.student)
1453        # add accommodation payments
1454        payment = StudentOnlinePayment()
1455        payment.creation_date = datetime.datetime(curr_year-6, 4, 1, 13, 12, 1)
1456        payment.p_id = 'id1'
1457        payment.p_category = u'bed_allocation'
1458        payment.p_state = 'paid'
1459        payment.ac = u'abc'
1460        payment.p_item = u'xyz'
1461        payment.p_level = 100
1462        payment.p_session = curr_year - 6
1463        payment.payment_date = datetime.datetime(curr_year-6, 4, 1, 14, 12, 1)
1464        payment.amount_auth = 12.12
1465        payment.r_amount_approved = 12.12
1466        payment.r_code = u'cde'
1467        payment2 = StudentOnlinePayment()
1468        payment2.creation_date = datetime.datetime(curr_year-6, 4, 1, 13, 12, 1)
1469        payment2.p_id = 'id2'
1470        payment2.p_category = u'hostel_maintenance'
1471        payment2.p_state = 'paid'
1472        payment2.ac = u'abc'
1473        payment2.p_item = u'xyz'
1474        payment2.p_level = 100
1475        payment2.p_session = curr_year - 6
1476        payment2.payment_date = datetime.datetime(curr_year-6, 4, 1, 14, 12, 1)
1477        payment2.amount_auth = 12.12
1478        payment2.r_amount_approved = 12.12
1479        payment2.r_code = u'cde'
1480        # XXX: there is no addPayment method to give predictable names
1481        self.payment = self.student['payments']['id1'] = payment
1482        self.payment = self.student['payments']['id2'] = payment2
1483        exporter = AccommodationPaymentsExporter()
1484        exporter.export_all(self.app, self.outfile)
1485        result = open(self.outfile, 'rb').read()
1486        # only accommodation payments are exported
1487        self.assertEqual(
1488            result,
1489            'ac,amount_auth,creation_date,p_category,p_combi,p_current,p_id,p_item,'
1490            'p_level,p_session,p_state,payment_date,r_amount_approved,r_code,'
1491            'r_desc,student_id,matric_number,reg_number,firstname,middlename,lastname,sex,'
1492            'state,current_session,entry_session,entry_mode,faccode,depcode,certcode\r\n'
1493            'abc,12.12,%s-04-01 13:12:01#,bed_allocation,[],1,id1,xyz,100,%s,'
1494            'paid,%s-04-01 14:12:01#,12.12,cde,,A111111,234,123,'
1495            'Anna,M.,Tester,f,created,2012,2010,ug_ft,NA,NA,CERT1\r\n'
1496            'abc,12.12,%s-04-01 13:12:01#,hostel_maintenance,[],1,id2,xyz,100,%s,'
1497            'paid,%s-04-01 14:12:01#,12.12,cde,,A111111,234,123,'
1498            'Anna,M.,Tester,f,created,2012,2010,ug_ft,NA,NA,CERT1\r\n'
1499            % (curr_year-6, curr_year-6, curr_year-6,
1500               curr_year-6, curr_year-6, curr_year-6)
1501            )
1502        return
1503
1504class BedTicketExporterTest(StudentImportExportSetup):
1505
1506    layer = FunctionalLayer
1507
1508    def setUp(self):
1509        super(BedTicketExporterTest, self).setUp()
1510        self.setup_for_export()
1511        return
1512
1513    def test_ifaces(self):
1514        # make sure we fullfill interface contracts
1515        obj = BedTicketExporter()
1516        verifyObject(ICSVStudentExporter, obj)
1517        verifyClass(ICSVStudentExporter, BedTicketExporter)
1518        return
1519
1520    def test_get_as_utility(self):
1521        # we can get a bedtickets exporter as utility
1522        result = queryUtility(ICSVExporter, name="bedtickets")
1523        self.assertTrue(result is not None)
1524        return
1525
1526    def test_export_empty(self):
1527        # we can export a nearly empty bedticket
1528        bedticket = BedTicket()
1529        bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
1530        bedticket.bed = bed
1531        exporter = BedTicketExporter()
1532        exporter.export([bedticket], self.outfile)
1533        result = open(self.outfile, 'rb').read()
1534        self.assertMatches(
1535            result,
1536            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1537            'booking_session,student_id,actual_bed_type\r\n'
1538            'hall-1_A_101_A,,,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,,,regular_male_fr\r\n'
1539            )
1540        return
1541
1542    def test_export(self):
1543        # we can really export student bedtickets.
1544        # set values we can expect in export file
1545        self.setup_student(self.student)
1546        bedticket = self.student['accommodation']['2004']
1547        exporter = BedTicketExporter()
1548        exporter.export([bedticket], self.outfile)
1549        result = open(self.outfile, 'rb').read()
1550        self.assertMatches(
1551            result,
1552            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1553            'booking_session,student_id,actual_bed_type\r\n'
1554            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
1555            'A111111,regular_male_fr\r\n'
1556            )
1557        return
1558
1559    def test_export_all(self):
1560        # we can really export all bedtickets
1561        # set values we can expect in export file
1562        self.setup_student(self.student)
1563        exporter = BedTicketExporter()
1564        exporter.export_all(self.app, self.outfile)
1565        result = open(self.outfile, 'rb').read()
1566        self.assertMatches(
1567            result,
1568            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1569            'booking_session,student_id,actual_bed_type\r\n'
1570            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
1571            'A111111,regular_male_fr\r\n'
1572            )
1573        return
1574
1575    def test_export_student(self):
1576        # we can really export all bedtickets of a certain student
1577        # set values we can expect in export file
1578        self.setup_student(self.student)
1579        exporter = BedTicketExporter()
1580        exporter.export_student(self.student, self.outfile)
1581        result = open(self.outfile, 'rb').read()
1582        self.assertMatches(
1583            result,
1584            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1585            'booking_session,student_id,actual_bed_type\r\n'
1586            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
1587            'A111111,regular_male_fr\r\n'
1588            )
1589        return
1590
1591    def test_export_filtered(self):
1592        # we can export payments of a filtered set of students
1593        self.setup_student(self.student)
1594        self.app['students'].addStudent(self.student)
1595        notify(grok.ObjectModifiedEvent(self.student))
1596
1597        exporter = BedTicketExporter()
1598        exporter.export_filtered(
1599            self.student, self.outfile, current_level=200)
1600        result = open(self.outfile, 'rb').read()
1601        self.assertMatches(
1602            result,
1603            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
1604            'booking_session,student_id,actual_bed_type\r\n'
1605            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,'
1606            '2004,A111111,regular_male_fr\r\n')
1607        return
1608
1609
1610class SchoolFeePaymentsOverviewExporterTest(StudentImportExportSetup):
1611
1612    layer = FunctionalLayer
1613
1614    def setUp(self):
1615        super(SchoolFeePaymentsOverviewExporterTest, self).setUp()
1616        self.setup_for_export()
1617        return
1618
1619    def test_ifaces(self):
1620        # make sure we fullfill interface contracts
1621        obj = SchoolFeePaymentsOverviewExporter()
1622        verifyObject(ICSVStudentExporter, obj)
1623        verifyClass(ICSVStudentExporter, SchoolFeePaymentsOverviewExporter)
1624        return
1625
1626    def test_get_as_utility(self):
1627        # we can get a payments exporter as utility
1628        result = queryUtility(ICSVExporter, name="sfpaymentsoverview")
1629        self.assertTrue(result is not None)
1630        return
1631
1632    def test_export(self):
1633        self.setup_student(self.student)
1634        exporter = SchoolFeePaymentsOverviewExporter()
1635        exporter.export([self.student], self.outfile)
1636        result = open(self.outfile, 'rb').read()
1637        self.assertTrue(
1638            'student_id,matric_number,display_fullname,state,certcode,'
1639            'faccode,depcode,is_postgrad,'
1640            'current_level,current_session,current_mode,entry_session,'
1641            'reg_number,%s\r\n'
1642            'A111111,234,Anna M. Tester,created,CERT1,NA,NA,0,'
1643            '200,2012,ug_ft,2010,'
1644            % year_range_str in result
1645            )
1646        return
1647
1648    def test_export_all(self):
1649        # we can really export students
1650        # set values we can expect in export file
1651        self.setup_student(self.student)
1652        # We add successful payments.
1653        payment_2 = StudentOnlinePayment()
1654        payment_2.p_id = 'my-id'
1655        payment_2.p_session = curr_year - 5
1656        payment_2.amount_auth = 13.13
1657        payment_2.p_state = 'paid'
1658        payment_2.p_category = u'schoolfee'
1659        self.student['payments']['my-2ndpayment'] = payment_2
1660        # This one could be a balance payment.
1661        # The amount is being added.
1662        payment_3 = StudentOnlinePayment()
1663        payment_3.p_id = 'my-id_2'
1664        payment_3.p_session = curr_year - 5
1665        payment_3.amount_auth = 1.01
1666        payment_3.p_state = 'paid'
1667        payment_3.p_category = u'schoolfee'
1668        self.student['payments']['my-3rdpayment'] = payment_3
1669        # One session school fee has been waived
1670        payment_4 = StudentOnlinePayment()
1671        payment_4.p_id = 'my-id_2'
1672        payment_4.p_session = curr_year - 4
1673        payment_4.amount_auth = 1.01
1674        payment_4.p_state = 'waived'
1675        payment_4.p_category = u'schoolfee'
1676        self.student['payments']['my-4thpayment'] = payment_4
1677        exporter = SchoolFeePaymentsOverviewExporter()
1678        exporter.export_all(self.app, self.outfile)
1679        result = open(self.outfile, 'rb').read()
1680        self.assertTrue(
1681            'student_id,matric_number,display_fullname,state,'
1682            'certcode,faccode,depcode,is_postgrad,'
1683            'current_level,current_session,current_mode,entry_session,'
1684            'reg_number,%s\r\nA111111,234,Anna M. Tester,created,CERT1,NA,NA,0,'
1685            '200,2012,ug_ft,2010,123,,,,,,12.12,14.14,waived,,,,\r\n'
1686            % year_range_str in result
1687            )
1688        return
1689
1690class SessionPaymentsOverviewExporterTest(StudentImportExportSetup):
1691
1692    layer = FunctionalLayer
1693
1694    def setUp(self):
1695        super(SessionPaymentsOverviewExporterTest, self).setUp()
1696        self.setup_for_export()
1697        paycats = ('schoolfee', 'clearance', 'gown', 'transcript')
1698        paycatyears = ''
1699        grok.getSite()['configuration'].current_academic_session = curr_year - 4
1700        year_range = range(curr_year-6, curr_year-3)
1701        year_range_tuple = tuple([str(year)[2:] for year in year_range])
1702        for cat in paycats:
1703            for year in year_range_tuple:
1704                paycatyears += '%s,'%(cat+str(year))
1705        self.paycatyears = paycatyears.strip(',')
1706        return
1707
1708    def test_ifaces(self):
1709        # make sure we fullfill interface contracts
1710        obj = SessionPaymentsOverviewExporter()
1711        verifyObject(ICSVStudentExporter, obj)
1712        verifyClass(ICSVStudentExporter, SessionPaymentsOverviewExporter)
1713        return
1714
1715    def test_get_as_utility(self):
1716        # we can get a payments exporter as utility
1717        result = queryUtility(ICSVExporter, name="sessionpaymentsoverview")
1718        self.assertTrue(result is not None)
1719        return
1720
1721    def test_export(self):
1722        self.setup_student(self.student)
1723        exporter = SessionPaymentsOverviewExporter()
1724        exporter.export([self.student], self.outfile)
1725        result = open(self.outfile, 'rb').read()
1726        self.assertTrue(
1727            'student_id,matric_number,display_fullname,state,certcode,'
1728            'faccode,depcode,is_postgrad,current_level,current_session,'
1729            'current_mode,entry_session,reg_number,%s\r\n'
1730            'A111111,234,Anna M. Tester,created,CERT1,NA,NA,0,200,'
1731            '2012,ug_ft,2010,123,'
1732            '12.12,,,,,,,,,,,\r\n' %self.paycatyears in result
1733            )
1734        return
1735
1736    def test_export_all(self):
1737        self.setup_student(self.student)
1738        # We add successful payments.
1739        payment_2 = StudentOnlinePayment()
1740        payment_2.p_id = 'my-id'
1741        payment_2.p_session = curr_year - 5
1742        payment_2.amount_auth = 13.13
1743        payment_2.p_state = 'paid'
1744        payment_2.p_category = u'schoolfee'
1745        self.student['payments']['my-2ndpayment'] = payment_2
1746        # This one could be a balance payment.
1747        # The amount is being added.
1748        payment_3 = StudentOnlinePayment()
1749        payment_3.p_id = 'my-id_2'
1750        payment_3.p_session = curr_year - 5
1751        payment_3.amount_auth = 1.01
1752        payment_3.p_state = 'paid'
1753        payment_3.p_category = u'schoolfee'
1754        self.student['payments']['my-3rdpayment'] = payment_3
1755        # One session school fee has been waived
1756        payment_4 = StudentOnlinePayment()
1757        payment_4.p_id = 'my-id_2'
1758        payment_4.p_session = curr_year - 4
1759        payment_4.amount_auth = 1.01
1760        payment_4.p_state = 'waived'
1761        payment_4.p_category = u'schoolfee'
1762        self.student['payments']['my-4thpayment'] = payment_4
1763        exporter = SessionPaymentsOverviewExporter()
1764        exporter.export_all(self.app, self.outfile)
1765        result = open(self.outfile, 'rb').read()
1766        self.assertTrue(
1767            'student_id,matric_number,display_fullname,state,certcode,faccode,'
1768            'depcode,is_postgrad,current_level,current_session,'
1769            'current_mode,entry_session,reg_number,%s\r\n'
1770            'A111111,234,Anna M. Tester,created,CERT1,NA,NA,0,200,2012,ug_ft,'
1771            '2010,123,'
1772            '12.12,14.14,1.01,,,,,,,,,\r\n'
1773            %self.paycatyears in result
1774            )
1775        return
1776
1777class StudyLevelsOverviewExporterTest(StudentImportExportSetup):
1778
1779    layer = FunctionalLayer
1780
1781    def setUp(self):
1782        super(StudyLevelsOverviewExporterTest, self).setUp()
1783        self.setup_for_export()
1784        return
1785
1786    def test_ifaces(self):
1787        obj = StudyLevelsOverviewExporter()
1788        verifyObject(ICSVStudentExporter, obj)
1789        verifyClass(ICSVStudentExporter, StudyLevelsOverviewExporter)
1790        return
1791
1792    def test_get_as_utility(self):
1793        result = queryUtility(ICSVExporter, name="studylevelsoverview")
1794        self.assertTrue(result is not None)
1795        return
1796
1797    def test_export(self):
1798        self.setup_student(self.student)
1799        exporter = StudyLevelsOverviewExporter()
1800        exporter.export([self.student], self.outfile)
1801        result = open(self.outfile, 'rb').read()
1802        self.assertEqual(
1803             'student_id,state,certcode,faccode,depcode,is_postgrad,'
1804             'entry_session,current_level,current_session,'
1805             '0,10,100,110,120,200,210,220,300,310,320,400,410,420,500,'
1806             '510,520,600,610,620,700,710,720,800,810,820,900,910,920,999,1000\r\n'
1807             'A111111,created,CERT1,NA,NA,0,2010,200,2012,,,2012'
1808             ',,,,,,,,,,,,,,,,,,,,,,,,,,,,\r\n',
1809            result
1810            )
1811        return
1812
1813    def test_export_all(self):
1814        self.setup_student(self.student)
1815        exporter = StudyLevelsOverviewExporter()
1816        exporter.export_all(self.app, self.outfile)
1817        result = open(self.outfile, 'rb').read()
1818        self.assertEqual(
1819            'student_id,state,certcode,faccode,depcode,is_postgrad,'
1820            'entry_session,current_level,current_session,'
1821            '0,10,100,110,120,200,210,220,300,310,320,400,410,420,500,'
1822            '510,520,600,610,620,700,710,720,800,810,820,900,910,920,999,1000\r\n'
1823            'A111111,created,CERT1,NA,NA,0,2010,200,2012,,,2012'
1824            ',,,,,,,,,,,,,,,,,,,,,,,,,,,,\r\n',
1825            result
1826            )
1827        return
1828
1829class ComboCardExporterTest(StudentImportExportSetup):
1830
1831    layer = FunctionalLayer
1832
1833    def setUp(self):
1834        super(ComboCardExporterTest, self).setUp()
1835        self.setup_for_export()
1836        return
1837
1838    def create_passport_img(self, student):
1839        # create some passport file for `student`
1840        storage = getUtility(IExtFileStore)
1841        image_path = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
1842        self.image_contents = open(image_path, 'rb').read()
1843        file_id = IFileStoreNameChooser(student).chooseName(
1844            attr='passport.jpg')
1845        storage.createFile(file_id, StringIO(self.image_contents))
1846
1847    def test_export_all(self):
1848        self.setup_student(self.student)
1849        self.create_passport_img(self.student)
1850        exporter = ComboCardDataExporter()
1851        exporter.export_all(self.app, self.outfile)
1852        result = open(self.outfile, 'rb').read()
1853        self.assertTrue(
1854            'display_fullname,student_id,matric_number,certificate,faculty,'
1855            'department,passport_path\r\nAnna M. Tester,A111111,234,'
1856            'Unnamed Certificate,Faculty of Unnamed Faculty (NA),'
1857            'Department of Unnamed Department (NA),'
1858            'students/00110/A111111/passport_A111111.jpg\r\n'
1859            in result
1860            )
1861        return
1862
1863class TranscriptDataExporterTest(StudentImportExportSetup):
1864
1865    layer = FunctionalLayer
1866
1867    def setUp(self):
1868        super(TranscriptDataExporterTest, self).setUp()
1869        self.setup_for_export()
1870        return
1871
1872    def test_export_all(self):
1873        self.setup_student(self.student)
1874        study_course = self.student.get('studycourse')
1875        study_level = study_course[study_course.keys()[0]]
1876        ticket = study_level['CRS1']
1877        ticket.score = 20
1878        exporter = TranscriptDataExporter()
1879        exporter.export_all(self.app, self.outfile)
1880        result = open(self.outfile, 'rb').read()
1881        self.assertTrue(
1882            'student_id,state,certcode,faccode,depcode,entry_session,'
1883            'current_level,current_session,transcript_data\r\n'
1884            'A111111,created,CERT1,NA,NA,2010,200,2012,'
1885            'Level 100; 1st: ; 2nd: CRS1; 3rd: ; sgpa: 0.0\r\n'
1886            in result
1887            )
1888        return
Note: See TracBrowser for help on using the repository browser.