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

Last change on this file since 16901 was 16831, checked in by Henrik Bettermann, 3 years ago

Improve export and reimport of previous study course data.

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