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

Last change on this file since 12278 was 12111, checked in by Henrik Bettermann, 10 years ago

Parse subversion Id keyword.

  • Property svn:keywords set to Id
File size: 44.6 KB
Line 
1## $Id: test_export.py 12111 2014-12-02 06:47:07Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18
19import os
20import grok
21import datetime
22from cStringIO import StringIO
23from zope.component import queryUtility, getUtility
24from zope.event import notify
25from zope.interface.verify import verifyObject, verifyClass
26from waeup.kofa.interfaces import (
27    ICSVExporter, IExtFileStore, IFileStoreNameChooser)
28from waeup.kofa.students.catalog import StudentsQuery
29from waeup.kofa.students.export import (
30    StudentExporter, StudentStudyCourseExporter, StudentStudyLevelExporter,
31    CourseTicketExporter, StudentPaymentsExporter, BedTicketsExporter,
32    StudentPaymentsOverviewExporter, StudentStudyLevelsOverviewExporter,
33    ComboCardDataExporter, DataForBursaryExporter,
34    get_students,)
35from waeup.kofa.students.accommodation import BedTicket
36from waeup.kofa.students.interfaces import ICSVStudentExporter
37from waeup.kofa.students.payments import StudentOnlinePayment
38from waeup.kofa.students.student import Student
39from waeup.kofa.students.studycourse import StudentStudyCourse
40from waeup.kofa.students.studylevel import StudentStudyLevel, CourseTicket
41from waeup.kofa.students.tests.test_batching import StudentImportExportSetup
42from waeup.kofa.testing import FunctionalLayer
43
44curr_year = datetime.datetime.now().year
45year_range = range(curr_year - 9, curr_year + 1)
46year_range_str = ','.join([str(i) for i in year_range])
47
48class ExportHelperTests(StudentImportExportSetup):
49    layer = FunctionalLayer
50    def setUp(self):
51        super(ExportHelperTests, self).setUp()
52        student = Student()
53        self.app['students'].addStudent(student)
54        student = self.setup_student(student)
55        notify(grok.ObjectModifiedEvent(student))
56        self.student = self.app['students'][student.student_id]
57        return
58
59    def test_get_students_plain(self):
60        # without a filter we get all students
61        result = get_students(self.app)
62        self.assertEqual(len(list(result)), 1)
63        return
64
65    def test_get_students_by_session(self):
66        # we can filter out students of a certain session
67        my_filter1 = StudentsQuery(current_session=2012)
68        result = get_students(self.app, stud_filter=my_filter1)
69        self.assertEqual(len(list(result)), 1)
70
71        my_filter2 = StudentsQuery(current_session=1964)
72        result = get_students(self.app, stud_filter=my_filter2)
73        self.assertEqual(len(list(result)), 0)
74        return
75
76    def test_get_students_by_level(self):
77        # we can filter out students of a certain level
78        my_filter1 = StudentsQuery(current_level=200)
79        result = get_students(self.app, stud_filter=my_filter1)
80        self.assertEqual(len(list(result)), 1)
81
82        my_filter2 = StudentsQuery(current_level=300)
83        result = get_students(self.app, stud_filter=my_filter2)
84        self.assertEqual(len(list(result)), 0)
85        return
86
87    def test_get_students_by_deptcode(self):
88        # we can filter out students of a certain dept.
89        my_filter1 = StudentsQuery(depcode='NA')
90        result = get_students(self.app, stud_filter=my_filter1)
91        self.assertEqual(len(list(result)), 1)
92
93        my_filter2 = StudentsQuery(depcode='NOTEXISTING')
94        result = get_students(self.app, stud_filter=my_filter2)
95        self.assertEqual(len(list(result)), 0)
96        return
97
98    def test_get_students_by_faccode(self):
99        # we can filter out students of a certain faculty.
100        my_filter1 = StudentsQuery(faccode='NA')
101        result = get_students(self.app, stud_filter=my_filter1)
102        self.assertEqual(len(list(result)), 1)
103
104        my_filter2 = StudentsQuery(faccode='NOTEXISTING')
105        result = get_students(self.app, stud_filter=my_filter2)
106        self.assertEqual(len(list(result)), 0)
107        return
108
109    def test_get_students_by_current_mode(self):
110        # we can filter out students in a certain mode.
111        my_filter1 = StudentsQuery(current_mode='ug_ft')
112        result = get_students(self.app, stud_filter=my_filter1)
113        self.assertEqual(len(list(result)), 1)
114
115        my_filter2 = StudentsQuery(current_mode='NOTEXISTING')
116        result = get_students(self.app, stud_filter=my_filter2)
117        self.assertEqual(len(list(result)), 0)
118        return
119
120
121class StudentExporterTest(StudentImportExportSetup):
122
123    layer = FunctionalLayer
124
125    std_csv_entry = (
126        'my adm code,0,my clr code,1981-02-04#,anna@sample.com,,'
127        'Anna,Tester,234,M.,NG,,"Studentroad 21\nLagos 123456\n",,'
128        '+234-123-12345#,123,f,A111111,0,,,,created'
129        )
130
131    def setUp(self):
132        super(StudentExporterTest, self).setUp()
133        self.setup_for_export()
134        return
135
136    def test_ifaces(self):
137        # make sure we fullfill interface contracts
138        obj = StudentExporter()
139        verifyObject(ICSVStudentExporter, obj)
140        verifyClass(ICSVStudentExporter, StudentExporter)
141        return
142
143    def test_get_as_utility(self):
144        # we can get an student exporter as utility
145        result = queryUtility(ICSVExporter, name="students")
146        self.assertTrue(result is not None)
147        return
148
149    def test_export(self):
150        # we can really export students
151        # set values we can expect in export file
152        self.setup_student(self.student)
153        exporter = StudentExporter()
154        exporter.export([self.student], self.outfile)
155        result = open(self.outfile, 'rb').read()
156        self.assertTrue(
157            'adm_code,clearance_locked,clr_code,date_of_birth,email,'
158            'employer,firstname,lastname,matric_number,middlename,'
159            'nationality,officer_comment,perm_address,personal_updated,'
160            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
161            'transcript_comment,password,state,history,certcode,is_postgrad,'
162            'current_level,current_session\r\n'
163            'my adm code,0,my clr code,'
164            '1981-02-04#,anna@sample.com,,Anna,Tester,234,M.,NG,,'
165            '"Studentroad 21\nLagos 123456\n",,+234-123-12345#,123,f,'
166            'A111111,0,,,,created'
167            in result
168            )
169        return
170
171    def test_export_all(self):
172        # we can really export students
173        # set values we can expect in export file
174        self.setup_student(self.student)
175        exporter = StudentExporter()
176        exporter.export_all(self.app, self.outfile)
177        result = open(self.outfile, 'rb').read()
178        self.assertTrue(
179            'adm_code,clearance_locked,clr_code,date_of_birth,email,'
180            'employer,firstname,lastname,matric_number,middlename,'
181            'nationality,officer_comment,perm_address,personal_updated,'
182            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
183            'transcript_comment,password,state,history,certcode,'
184            'is_postgrad,current_level,current_session\r\n'
185            'my adm code,0,my clr code,1981-02-04#,anna@sample.com,,'
186            'Anna,Tester,234,M.,NG,,"Studentroad 21\nLagos 123456\n"'
187            ',,+234-123-12345#,123,f,A111111,0,,,,created'
188            in result
189            )
190        return
191
192    def test_export_student(self):
193        # we can export a single student
194        self.setup_student(self.student)
195        exporter = StudentExporter()
196        exporter.export_student(self.student, self.outfile)
197        result = open(self.outfile, 'rb').read()
198        self.assertTrue(
199            'adm_code,clearance_locked,clr_code,date_of_birth,email,'
200            'employer,firstname,lastname,matric_number,middlename,'
201            'nationality,officer_comment,perm_address,personal_updated,'
202            'phone,reg_number,sex,student_id,suspended,suspended_comment,'
203            'transcript_comment,password,state,history,certcode,'
204            'is_postgrad,current_level,current_session\r\n'
205            'my adm code,0,my clr code,1981-02-04#,anna@sample.com,,'
206            'Anna,Tester,234,M.,NG,,"Studentroad 21\nLagos 123456\n"'
207            ',,+234-123-12345#,123,f,A111111,0,,,,created'
208            in result
209            )
210        return
211
212    def test_export_filtered(self):
213        # we can export a filtered set of students (filtered by session/level)
214        self.setup_student(self.student)
215        self.app['students'].addStudent(self.student)
216        notify(grok.ObjectModifiedEvent(self.student))
217        exporter = StudentExporter()
218
219        exporter.export_filtered(
220            self.app, self.outfile,
221            current_session=None, current_level=None)
222        result1 = open(self.outfile, 'rb').read()
223        exporter.export_filtered(
224            self.app, self.outfile,
225            current_session=2012, current_level=None)
226        result2 = open(self.outfile, 'rb').read()
227        # current_level and current_session can be both a string ...
228        exporter.export_filtered(
229            self.app, self.outfile,
230            current_session='2012', current_level=u'200')
231        result3 = open(self.outfile, 'rb').read()
232        exporter.export_filtered(
233            self.app, self.outfile,
234            current_session=2011, current_level=None)
235        result4 = open(self.outfile, 'rb').read()
236        # ... and an integer
237        exporter.export_filtered(
238            self.app, self.outfile,
239            current_session=None, current_level=100)
240        result5 = open(self.outfile, 'rb').read()
241        # Also students at probating levels are being exported ...
242        self.student['studycourse'].current_level = 210
243        notify(grok.ObjectModifiedEvent(self.student))
244        exporter.export_filtered(
245            self.app, self.outfile,
246            current_session=None, current_level=200)
247        result6 = open(self.outfile, 'rb').read()
248        # ... but not in the wrong level range.
249        self.student['studycourse'].current_level = 310
250        notify(grok.ObjectModifiedEvent(self.student))
251        exporter.export_filtered(
252            self.app, self.outfile,
253            current_session=None, current_level=200)
254        result7 = open(self.outfile, 'rb').read()
255        self.assertTrue(self.std_csv_entry in result1)
256        self.assertTrue(self.std_csv_entry in result2)
257        self.assertTrue(self.std_csv_entry in result3)
258        self.assertFalse(self.std_csv_entry in result4)
259        self.assertFalse(self.std_csv_entry in result5)
260        self.assertTrue(self.std_csv_entry in result6)
261        self.assertFalse(self.std_csv_entry in result7)
262        return
263
264    def test_export_filtered_by_dept(self):
265        # we can export a set of students filtered by department
266        self.setup_student(self.student)
267        self.app['students'].addStudent(self.student)
268        notify(grok.ObjectModifiedEvent(self.student))
269        exporter = StudentExporter()
270        # current_session can be both a string ...
271        exporter.export_filtered(
272            self.app, self.outfile,
273            current_session='2012', current_level=u'200', depcode='NA')
274        result1 = open(self.outfile, 'rb').read()
275        # ... and an integer
276        exporter.export_filtered(
277            self.app, self.outfile,
278            current_session=2012, current_level=200, depcode='NODEPT')
279        result2 = open(self.outfile, 'rb').read()
280        self.assertTrue(self.std_csv_entry in result1)
281        self.assertTrue(self.std_csv_entry not in result2)
282        return
283
284    def test_export_filtered_by_faculty(self):
285        # we can export a set of students filtered by faculty
286        self.setup_student(self.student)
287        self.app['students'].addStudent(self.student)
288        notify(grok.ObjectModifiedEvent(self.student))
289        exporter = StudentExporter()
290
291        exporter.export_filtered(
292            self.app, self.outfile,
293            current_session=2012, current_level='200', faccode='NA')
294        result1 = open(self.outfile, 'rb').read()
295        exporter.export_filtered(
296            self.app, self.outfile,
297            current_session=2012, current_level=200, faccode='NOFAC')
298        result2 = open(self.outfile, 'rb').read()
299        self.assertTrue(self.std_csv_entry in result1)
300        self.assertTrue(self.std_csv_entry not in result2)
301        return
302
303class StudentStudyCourseExporterTest(StudentImportExportSetup):
304
305    layer = FunctionalLayer
306
307    def setUp(self):
308        super(StudentStudyCourseExporterTest, self).setUp()
309        self.setup_for_export()
310        return
311
312    def test_ifaces(self):
313        # make sure we fullfill interface contracts
314        obj = StudentStudyCourseExporter()
315        verifyObject(ICSVStudentExporter, obj)
316        verifyClass(ICSVStudentExporter, StudentStudyCourseExporter)
317        return
318
319    def test_get_as_utility(self):
320        # we can get an student exporter as utility
321        result = queryUtility(ICSVExporter, name="studentstudycourses")
322        self.assertTrue(result is not None)
323        return
324
325    def test_export_empty(self):
326        # we can export a nearly empty study course
327        study_course = StudentStudyCourse()
328        exporter = StudentStudyCourseExporter()
329        exporter.export([study_course], self.outfile)
330        result = open(self.outfile, 'rb').read()
331        self.assertEqual(
332            result,
333            'certificate,current_level,current_session,current_verdict,'
334            'entry_mode,entry_session,previous_verdict,student_id\r\n'
335
336            ',,,0,,,0,\r\n'
337            )
338        return
339
340    def test_export(self):
341        # we can really export study courses.
342        # set values we can expect in export file
343        self.setup_student(self.student)
344        study_course = self.student.get('studycourse')
345        exporter = StudentStudyCourseExporter()
346        exporter.export([study_course], self.outfile)
347        result = open(self.outfile, 'rb').read()
348        self.assertEqual(
349            result,
350            'certificate,current_level,current_session,current_verdict,'
351            'entry_mode,entry_session,previous_verdict,student_id\r\n'
352
353            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
354            )
355        return
356
357    def test_export_all(self):
358        # we can really export students
359        # set values we can expect in export file
360        self.setup_student(self.student)
361        exporter = StudentStudyCourseExporter()
362        exporter.export_all(self.app, self.outfile)
363        result = open(self.outfile, 'rb').read()
364        self.assertEqual(
365            result,
366            'certificate,current_level,current_session,current_verdict,'
367            'entry_mode,entry_session,previous_verdict,student_id\r\n'
368
369            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
370            )
371        return
372
373    def test_export_student(self):
374        # we can export studycourse of a certain student
375        self.setup_student(self.student)
376        exporter = StudentStudyCourseExporter()
377        exporter.export_student(self.student, self.outfile)
378        result = open(self.outfile, 'rb').read()
379        self.assertEqual(
380            result,
381            'certificate,current_level,current_session,current_verdict,'
382            'entry_mode,entry_session,previous_verdict,student_id\r\n'
383
384            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
385            )
386        return
387
388    def test_export_filtered(self):
389        # we can export studycourses of a filtered set of students
390        self.setup_student(self.student)
391        self.app['students'].addStudent(self.student)
392        notify(grok.ObjectModifiedEvent(self.student))
393
394        exporter = StudentStudyCourseExporter()
395        exporter.export_filtered(
396            self.student, self.outfile, current_session=2012)
397        result = open(self.outfile, 'rb').read()
398        self.assertEqual(
399            result,
400            'certificate,current_level,current_session,current_verdict,'
401            'entry_mode,entry_session,previous_verdict,student_id\r\n'
402
403            'CERT1,200,2012,0,ug_ft,2010,0,A111111\r\n'
404            )
405        return
406
407
408
409class StudentStudyLevelExporterTest(StudentImportExportSetup):
410
411    layer = FunctionalLayer
412
413    def setUp(self):
414        super(StudentStudyLevelExporterTest, self).setUp()
415        self.setup_for_export()
416        return
417
418    def test_ifaces(self):
419        # make sure we fullfill interface contracts
420        obj = StudentStudyLevelExporter()
421        verifyObject(ICSVStudentExporter, obj)
422        verifyClass(ICSVStudentExporter, StudentStudyLevelExporter)
423        return
424
425    def test_get_as_utility(self):
426        # we can get an student exporter as utility
427        result = queryUtility(ICSVExporter, name="studentstudylevels")
428        self.assertTrue(result is not None)
429        return
430
431    def test_export_empty(self):
432        # we can export a nearly empty study level
433        study_level = StudentStudyLevel()
434        exporter = StudentStudyLevelExporter()
435        exporter.export([study_level], self.outfile)
436        result = open(self.outfile, 'rb').read()
437        self.assertEqual(
438            result,
439            'gpa,level,level_session,level_verdict,total_credits,'
440            'validated_by,validation_date,'
441            'student_id,number_of_tickets,certcode\r\n'
442            '0.0,,,0,0,,,,0,\r\n'
443            )
444        return
445
446    def test_export(self):
447        # we can really export study levels.
448        # set values we can expect in export file
449        self.setup_student(self.student)
450        study_course = self.student.get('studycourse')
451        study_level = study_course[study_course.keys()[0]]
452        exporter = StudentStudyLevelExporter()
453        exporter.export([study_level], self.outfile)
454        result = open(self.outfile, 'rb').read()
455        self.assertEqual(
456            result,
457            'gpa,level,level_session,level_verdict,total_credits,'
458            'validated_by,validation_date,'
459            'student_id,number_of_tickets,certcode\r\n'
460            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
461            )
462        return
463
464    def test_export_all(self):
465        # we can really export study levels
466        # set values we can expect in export file
467        self.setup_student(self.student)
468        exporter = StudentStudyLevelExporter()
469        exporter.export_all(self.app, self.outfile)
470        result = open(self.outfile, 'rb').read()
471        self.assertEqual(
472            result,
473            'gpa,level,level_session,level_verdict,total_credits,'
474            'validated_by,validation_date,'
475            'student_id,number_of_tickets,certcode\r\n'
476            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
477            )
478        return
479
480    def test_export_student(self):
481        # we can really export study levels of a certain student
482        self.setup_student(self.student)
483        exporter = StudentStudyLevelExporter()
484        exporter.export_student(self.student, self.outfile)
485        result = open(self.outfile, 'rb').read()
486        self.assertEqual(
487            result,
488            'gpa,level,level_session,level_verdict,total_credits,'
489            'validated_by,validation_date,'
490            'student_id,number_of_tickets,certcode\r\n'
491            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
492            )
493        return
494
495    def test_export_filtered(self):
496        # we can export studylevels of a filtered set of students
497        self.setup_student(self.student)
498        self.app['students'].addStudent(self.student)
499        notify(grok.ObjectModifiedEvent(self.student))
500
501        exporter = StudentStudyLevelExporter()
502        exporter.export_filtered(
503            self.student, self.outfile)
504        result = open(self.outfile, 'rb').read()
505        self.assertEqual(
506            result,
507            'gpa,level,level_session,level_verdict,total_credits,'
508            'validated_by,validation_date,'
509            'student_id,number_of_tickets,certcode\r\n'
510            '0.0,100,2012,A,100,,,A111111,1,CERT1\r\n'
511            )
512        return
513
514class CourseTicketExporterTest(StudentImportExportSetup):
515
516    layer = FunctionalLayer
517
518    def setUp(self):
519        super(CourseTicketExporterTest, self).setUp()
520        self.setup_for_export()
521        return
522
523    def test_ifaces(self):
524        # make sure we fullfill interface contracts
525        obj = CourseTicketExporter()
526        verifyObject(ICSVStudentExporter, obj)
527        verifyClass(ICSVStudentExporter, CourseTicketExporter)
528        return
529
530    def test_get_as_utility(self):
531        # we can get an student exporter as utility
532        result = queryUtility(ICSVExporter, name="coursetickets")
533        self.assertTrue(result is not None)
534        return
535
536    def test_export_empty(self):
537        # we can export a nearly empty course ticket
538        ticket = CourseTicket()
539        exporter = CourseTicketExporter()
540        exporter.export([ticket], self.outfile)
541        result = open(self.outfile, 'rb').read()
542        self.assertEqual(
543            result,
544            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
545            'mandatory,passmark,score,semester,title,student_id,certcode,'
546            'display_fullname\r\n'
547            '0,0,,,,,,,0,,,,,,,\r\n'
548            )
549        return
550
551    def test_export(self):
552        # we can really export course tickets.
553        # set values we can expect in export file
554        self.setup_student(self.student)
555        study_course = self.student.get('studycourse')
556        study_level = study_course[study_course.keys()[0]]
557        ticket = study_level['CRS1']
558        exporter = CourseTicketExporter()
559        exporter.export([ticket], self.outfile)
560        result = open(self.outfile, 'rb').read()
561        self.assertEqual(
562            result,
563            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
564            'mandatory,passmark,score,semester,title,student_id,certcode,'
565            'display_fullname\r\n'
566            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
567            'Anna M. Tester\r\n'
568            )
569        return
570
571    def test_export_all(self):
572        # we can really export all course tickets
573        # set values we can expect in export file
574        self.setup_student(self.student)
575        exporter = CourseTicketExporter()
576        exporter.export_all(self.app, self.outfile)
577        result = open(self.outfile, 'rb').read()
578        self.assertEqual(
579            result,
580            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
581            'mandatory,passmark,score,semester,title,student_id,certcode,'
582            'display_fullname\r\n'
583            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
584            'Anna M. Tester\r\n'
585            )
586        return
587
588    def test_export_student(self):
589        # we can really export all course tickets of a certain student
590        self.setup_student(self.student)
591        exporter = CourseTicketExporter()
592        exporter.export_student(self.student, self.outfile)
593        result = open(self.outfile, 'rb').read()
594        self.assertEqual(
595            result,
596            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
597            'mandatory,passmark,score,semester,title,student_id,certcode,'
598            'display_fullname\r\n'
599            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
600            'Anna M. Tester\r\n'
601            )
602        return
603
604    def test_export_filtered(self):
605        # we can export course tickets of a filtered set of students
606        self.setup_student(self.student)
607        self.app['students'].addStudent(self.student)
608        notify(grok.ObjectModifiedEvent(self.student))
609
610        exporter = CourseTicketExporter()
611        exporter.export_filtered(
612            self.student, self.outfile)
613        result = open(self.outfile, 'rb').read()
614        self.assertEqual(
615            result,
616            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
617            'mandatory,passmark,score,semester,title,student_id,certcode,'
618            'display_fullname\r\n'
619            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
620            'Anna M. Tester\r\n'
621            )
622        # if the coursetickets catalog is used to filter students
623        # and (course) code is not None
624        # only course tickets which belong to this course are exported
625        exporter.export_filtered(
626            self.student, self.outfile, catalog='coursetickets', code='CRS1')
627        result = open(self.outfile, 'rb').read()
628        self.assertEqual(
629            result,
630            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
631            'mandatory,passmark,score,semester,title,student_id,certcode,'
632            'display_fullname\r\n'
633            '1,1,CRS1,100,DEP1,FAC1,100,2012,0,100,,2,Course 1,A111111,CERT1,'
634            'Anna M. Tester\r\n'
635            )
636        exporter.export_filtered(
637            self.student, self.outfile, catalog='coursetickets', code='any code')
638        result = open(self.outfile, 'rb').read()
639        self.assertEqual(
640            result,
641            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
642            'mandatory,passmark,score,semester,title,student_id,certcode,'
643            'display_fullname\r\n'
644            )
645        # Also tickets in probating levels are exported. Therefore
646        # we change the level attribute to fake a 110 level.
647        self.student['studycourse']['100'].level = 110
648        notify(grok.ObjectModifiedEvent(self.student['studycourse']['100']['CRS1']))
649        exporter.export_filtered(
650            self.student, self.outfile, catalog='coursetickets', code='CRS1', level='100')
651        result = open(self.outfile, 'rb').read()
652        self.assertEqual(
653            result,
654            'automatic,carry_over,code,credits,dcode,fcode,level,level_session,'
655            'mandatory,passmark,score,semester,title,student_id,certcode,'
656            'display_fullname\r\n'
657            '1,1,CRS1,100,DEP1,FAC1,110,2012,0,100,,2,Course 1,A111111,CERT1,'
658            'Anna M. Tester\r\n'
659            )
660        return
661
662class StudentPaymentsExporterTest(StudentImportExportSetup):
663
664    layer = FunctionalLayer
665
666    def setUp(self):
667        super(StudentPaymentsExporterTest, self).setUp()
668        self.setup_for_export()
669        return
670
671    def test_ifaces(self):
672        # make sure we fullfill interface contracts
673        obj = StudentPaymentsExporter()
674        verifyObject(ICSVStudentExporter, obj)
675        verifyClass(ICSVStudentExporter, StudentPaymentsExporter)
676        return
677
678    def test_get_as_utility(self):
679        # we can get a payments exporter as utility
680        result = queryUtility(ICSVExporter, name="studentpayments")
681        self.assertTrue(result is not None)
682        return
683
684    def test_export_empty(self):
685        # we can export a nearly empty payment
686        payment = StudentOnlinePayment()
687        payment.creation_date = datetime.datetime(2012, 4, 1, 13, 12, 1)
688        exporter = StudentPaymentsExporter()
689        exporter.export([payment], self.outfile)
690        result = open(self.outfile, 'rb').read()
691        self.assertEqual(
692            result,
693            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
694            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
695            'r_code,r_desc,student_id,state,current_session\r\n'
696
697            ',0.0,2012-04-01 13:12:01#,,1,,,,,unpaid,,0.0,,,,,\r\n'
698            )
699        return
700
701    def test_export(self):
702        # we can really export student payments.
703        # set values we can expect in export file
704        self.setup_student(self.student)
705        payment = self.student['payments']['my-payment']
706        exporter = StudentPaymentsExporter()
707        exporter.export([payment], self.outfile)
708        result = open(self.outfile, 'rb').read()
709        self.assertEqual(
710            result,
711            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
712            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
713            'r_code,r_desc,student_id,state,current_session\r\n'
714
715            '666,12.12,2012-04-01 13:12:01#,schoolfee,1,my-id,'
716            'p-item,100,2012,paid,2012-04-01 14:12:01#,12.12,'
717            'r-code,,A111111,created,2012\r\n'
718            )
719        return
720
721    def test_export_all(self):
722        # we can really export all payments
723        # set values we can expect in export file
724        self.setup_student(self.student)
725        exporter = StudentPaymentsExporter()
726        exporter.export_all(self.app, self.outfile)
727        result = open(self.outfile, 'rb').read()
728        self.assertEqual(
729            result,
730            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
731            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
732            'r_code,r_desc,student_id,state,current_session\r\n'
733
734            '666,12.12,2012-04-01 13:12:01#,schoolfee,1,my-id,'
735            'p-item,100,2012,paid,2012-04-01 14:12:01#,12.12,'
736            'r-code,,A111111,created,2012\r\n'
737            )
738        return
739
740    def test_export_student(self):
741        # we can really export all payments of a certain student
742        # set values we can expect in export file
743        self.setup_student(self.student)
744        exporter = StudentPaymentsExporter()
745        exporter.export_student(self.student, self.outfile)
746        result = open(self.outfile, 'rb').read()
747        self.assertEqual(
748            result,
749            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
750            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
751            'r_code,r_desc,student_id,state,current_session\r\n'
752
753            '666,12.12,2012-04-01 13:12:01#,schoolfee,1,my-id,'
754            'p-item,100,2012,paid,2012-04-01 14:12:01#,12.12,'
755            'r-code,,A111111,created,2012\r\n'
756            )
757        return
758
759    def test_export_filtered(self):
760        # we can export payments of a filtered set of students
761        self.setup_student(self.student)
762        self.app['students'].addStudent(self.student)
763        notify(grok.ObjectModifiedEvent(self.student))
764
765        exporter = StudentPaymentsExporter()
766        exporter.export_filtered(
767            self.student, self.outfile, current_level=200)
768        result = open(self.outfile, 'rb').read()
769        self.assertEqual(
770            result,
771            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
772            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
773            'r_code,r_desc,student_id,state,current_session\r\n'
774
775            '666,12.12,2012-04-01 13:12:01#,schoolfee,1,my-id,'
776            'p-item,100,2012,paid,2012-04-01 14:12:01#,12.12,'
777            'r-code,,A111111,created,2012\r\n'
778            )
779        return
780
781    def test_export_filtered_by_date(self):
782        # payments_start and payments_end are being ignored
783        self.setup_student(self.student)
784        self.app['students'].addStudent(self.student)
785        notify(grok.ObjectModifiedEvent(self.student))
786        exporter = StudentPaymentsExporter()
787        # A key xxx does not exist
788        self.assertRaises(
789            KeyError, exporter.export_filtered, self.app, self.outfile,
790            current_session=None,
791            current_level=None, xxx='nonsense')
792        # payments_start and payments_end do exist but must match format '%Y-%m-%d'
793        self.assertRaises(
794            ValueError, exporter.export_filtered, self.app, self.outfile,
795            current_session=None, current_level=None,
796            payments_start='nonsense', payments_end='nonsense')
797        # If they match the format they are ignored by get_filtered and the
798        # exporter works properly
799        exporter.export_filtered(
800            self.app, self.outfile,
801            current_session=None, current_level=None,
802            payments_start='01/04/2012', payments_end='02/04/2012')
803        result = open(self.outfile, 'rb').read()
804        self.assertEqual(
805            result,
806            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
807            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
808            'r_code,r_desc,student_id,state,current_session\r\n'
809
810            '666,12.12,2012-04-01 13:12:01#,schoolfee,1,my-id,'
811            'p-item,100,2012,paid,2012-04-01 14:12:01#,12.12,'
812            'r-code,,A111111,created,2012\r\n'
813            )
814        # no results if payment_date is outside the given period
815        exporter.export_filtered(
816            self.app, self.outfile,
817            current_session=None, current_level=None,
818            payments_start='31/03/2012', payments_end='01/04/2012')
819        result = open(self.outfile, 'rb').read()
820        self.assertEqual(
821            result,
822            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
823            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
824            'r_code,r_desc,student_id,state,current_session\r\n'
825            )
826        exporter.export_filtered(
827            self.app, self.outfile,
828            current_session=None, current_level=None,
829            payments_start='02/04/2012', payments_end='03/04/2012')
830        result = open(self.outfile, 'rb').read()
831        self.assertEqual(
832            result,
833            'ac,amount_auth,creation_date,p_category,p_current,p_id,'
834            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
835            'r_code,r_desc,student_id,state,current_session\r\n'
836            )
837        # no results if payment_date is not set
838        self.payment.payment_date = None
839        exporter.export_filtered(
840            self.app, self.outfile,
841            current_session=None, current_level=None,
842            payments_start='01/04/2012', payments_end='02/04/2012')
843        result = open(self.outfile, 'rb').read()
844       
845        return
846
847class BursaryDataExporterTest(StudentImportExportSetup):
848
849    layer = FunctionalLayer
850
851    def setUp(self):
852        super(BursaryDataExporterTest, self).setUp()
853        self.setup_for_export()
854        return
855
856    def test_export_all(self):
857        # we can really export all payments
858        # set values we can expect in export file
859        self.setup_student(self.student)
860        exporter = DataForBursaryExporter()
861        exporter.export_all(self.app, self.outfile)
862        result = open(self.outfile, 'rb').read()
863        self.assertEqual(
864            result,
865            'ac,amount_auth,creation_date,p_category,p_current,p_id,p_item,'
866            'p_level,p_session,p_state,payment_date,r_amount_approved,r_code,'
867            'r_desc,student_id,matric_number,reg_number,firstname,middlename,lastname,'
868            'state,current_session,entry_session,entry_mode,faccode,depcode,certcode\r\n'
869
870            '666,12.12,2012-04-01 13:12:01#,schoolfee,1,my-id,p-item,100,2012,'
871            'paid,2012-04-01 14:12:01#,12.12,r-code,,A111111,234,123,'
872            'Anna,M.,Tester,created,2012,2010,ug_ft,NA,NA,CERT1\r\n'
873            )
874        return
875
876class BedTicketsExporterTest(StudentImportExportSetup):
877
878    layer = FunctionalLayer
879
880    def setUp(self):
881        super(BedTicketsExporterTest, self).setUp()
882        self.setup_for_export()
883        return
884
885    def test_ifaces(self):
886        # make sure we fullfill interface contracts
887        obj = BedTicketsExporter()
888        verifyObject(ICSVStudentExporter, obj)
889        verifyClass(ICSVStudentExporter, BedTicketsExporter)
890        return
891
892    def test_get_as_utility(self):
893        # we can get a bedtickets exporter as utility
894        result = queryUtility(ICSVExporter, name="bedtickets")
895        self.assertTrue(result is not None)
896        return
897
898    def test_export_empty(self):
899        # we can export a nearly empty bedticket
900        bedticket = BedTicket()
901        bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
902        bedticket.bed = bed
903        exporter = BedTicketsExporter()
904        exporter.export([bedticket], self.outfile)
905        result = open(self.outfile, 'rb').read()
906        self.assertMatches(
907            result,
908            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
909            'booking_session,student_id,actual_bed_type\r\n'
910            'hall-1_A_101_A,,,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,,,regular_male_fr\r\n'
911            )
912        return
913
914    def test_export(self):
915        # we can really export student bedtickets.
916        # set values we can expect in export file
917        self.setup_student(self.student)
918        bedticket = self.student['accommodation']['2004']
919        exporter = BedTicketsExporter()
920        exporter.export([bedticket], self.outfile)
921        result = open(self.outfile, 'rb').read()
922        self.assertMatches(
923            result,
924            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
925            'booking_session,student_id,actual_bed_type\r\n'
926            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
927            'A111111,regular_male_fr\r\n'
928            )
929        return
930
931    def test_export_all(self):
932        # we can really export all bedtickets
933        # set values we can expect in export file
934        self.setup_student(self.student)
935        exporter = BedTicketsExporter()
936        exporter.export_all(self.app, self.outfile)
937        result = open(self.outfile, 'rb').read()
938        self.assertMatches(
939            result,
940            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
941            'booking_session,student_id,actual_bed_type\r\n'
942            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
943            'A111111,regular_male_fr\r\n'
944            )
945        return
946
947    def test_export_student(self):
948        # we can really export all bedtickets of a certain student
949        # set values we can expect in export file
950        self.setup_student(self.student)
951        exporter = BedTicketsExporter()
952        exporter.export_student(self.student, self.outfile)
953        result = open(self.outfile, 'rb').read()
954        self.assertMatches(
955            result,
956            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
957            'booking_session,student_id,actual_bed_type\r\n'
958            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,2004,'
959            'A111111,regular_male_fr\r\n'
960            )
961        return
962
963    def test_export_filtered(self):
964        # we can export payments of a filtered set of students
965        self.setup_student(self.student)
966        self.app['students'].addStudent(self.student)
967        notify(grok.ObjectModifiedEvent(self.student))
968
969        exporter = BedTicketsExporter()
970        exporter.export_filtered(
971            self.student, self.outfile, current_level=200)
972        result = open(self.outfile, 'rb').read()
973        self.assertMatches(
974            result,
975            'bed,bed_coordinates,bed_type,booking_code,booking_date,'
976            'booking_session,student_id,actual_bed_type\r\n'
977            'hall-1_A_101_A,,any bed type,,<YYYY-MM-DD hh:mm:ss>.<6-DIGITS>#,'
978            '2004,A111111,regular_male_fr\r\n')
979        return
980
981
982class StudentPaymentsOverviewExporterTest(StudentImportExportSetup):
983
984    layer = FunctionalLayer
985
986    def setUp(self):
987        super(StudentPaymentsOverviewExporterTest, self).setUp()
988        self.setup_for_export()
989        return
990
991    def test_ifaces(self):
992        # make sure we fullfill interface contracts
993        obj = StudentPaymentsOverviewExporter()
994        verifyObject(ICSVStudentExporter, obj)
995        verifyClass(ICSVStudentExporter, StudentPaymentsOverviewExporter)
996        return
997
998    def test_get_as_utility(self):
999        # we can get a payments exporter as utility
1000        result = queryUtility(ICSVExporter, name="paymentsoverview")
1001        self.assertTrue(result is not None)
1002        return
1003
1004    def test_export(self):
1005        self.setup_student(self.student)
1006        exporter = StudentPaymentsOverviewExporter()
1007        exporter.export([self.student], self.outfile)
1008        result = open(self.outfile, 'rb').read()
1009        self.assertTrue(
1010            'student_id,matric_number,display_fullname,state,certcode,'
1011            'faccode,depcode,is_postgrad,'
1012            'current_level,current_session,current_mode,'
1013            '%s\r\n'
1014            'A111111,234,Anna M. Tester,created,CERT1,NA,NA,0,200,2012,ug_ft,'
1015            % year_range_str in result
1016            )
1017        return
1018
1019    def test_export_all(self):
1020        # we can really export students
1021        # set values we can expect in export file
1022        self.setup_student(self.student)
1023        # We add successful payments.
1024        payment_2 = StudentOnlinePayment()
1025        payment_2.p_id = 'my-id'
1026        payment_2.p_session = curr_year - 5
1027        payment_2.amount_auth = 13.13
1028        payment_2.p_state = u'paid'
1029        payment_2.p_category = u'schoolfee'
1030        self.student['payments']['my-2ndpayment'] = payment_2
1031        # This one could be a balance payment.
1032        # The amount is being added.
1033        payment_3 = StudentOnlinePayment()
1034        payment_3.p_id = 'my-id_2'
1035        payment_3.p_session = curr_year - 5
1036        payment_3.amount_auth = 1.01
1037        payment_3.p_state = u'paid'
1038        payment_3.p_category = u'schoolfee'
1039        self.student['payments']['my-3rdpayment'] = payment_3
1040        exporter = StudentPaymentsOverviewExporter()
1041        exporter.export_all(self.app, self.outfile)
1042        result = open(self.outfile, 'rb').read()
1043        self.assertTrue(
1044            'student_id,matric_number,display_fullname,state,'
1045            'certcode,faccode,depcode,is_postgrad,'
1046            'current_level,current_session,current_mode,'
1047            '%s\r\nA111111,234,Anna M. Tester,created,CERT1,NA,NA,0,'
1048            '200,2012,ug_ft,,,,,14.14,,,12.12,,\r\n'
1049            % year_range_str in result
1050            )
1051        return
1052
1053class StudentStudyLevelsOverviewExporterTest(StudentImportExportSetup):
1054
1055    layer = FunctionalLayer
1056
1057    def setUp(self):
1058        super(StudentStudyLevelsOverviewExporterTest, self).setUp()
1059        self.setup_for_export()
1060        return
1061
1062    def test_ifaces(self):
1063        obj = StudentStudyLevelsOverviewExporter()
1064        verifyObject(ICSVStudentExporter, obj)
1065        verifyClass(ICSVStudentExporter, StudentStudyLevelsOverviewExporter)
1066        return
1067
1068    def test_get_as_utility(self):
1069        result = queryUtility(ICSVExporter, name="studylevelsoverview")
1070        self.assertTrue(result is not None)
1071        return
1072
1073    def test_export(self):
1074        self.setup_student(self.student)
1075        exporter = StudentStudyLevelsOverviewExporter()
1076        exporter.export([self.student], self.outfile)
1077        result = open(self.outfile, 'rb').read()
1078        self.assertEqual(
1079             'student_id,state,certcode,faccode,depcode,is_postgrad,'
1080             'entry_session,current_level,current_session,'
1081             '10,100,110,120,200,210,220,300,310,320,400,410,420,500,'
1082             '510,520,600,610,620,700,710,720,800,810,820,900,910,920,999\r\n'
1083             'A111111,created,CERT1,NA,NA,0,2010,200,2012,,2012'
1084             ',,,,,,,,,,,,,,,,,,,,,,,,,,,\r\n',
1085            result
1086            )
1087        return
1088
1089    def test_export_all(self):
1090        self.setup_student(self.student)
1091        exporter = StudentStudyLevelsOverviewExporter()
1092        exporter.export_all(self.app, self.outfile)
1093        result = open(self.outfile, 'rb').read()
1094        self.assertEqual(
1095            'student_id,state,certcode,faccode,depcode,is_postgrad,'
1096            'entry_session,current_level,current_session,'
1097            '10,100,110,120,200,210,220,300,310,320,400,410,420,500,'
1098            '510,520,600,610,620,700,710,720,800,810,820,900,910,920,999\r\n'
1099            'A111111,created,CERT1,NA,NA,0,2010,200,2012,,2012'
1100            ',,,,,,,,,,,,,,,,,,,,,,,,,,,\r\n',
1101            result
1102            )
1103        return
1104
1105class ComboCardExporterTest(StudentImportExportSetup):
1106
1107    layer = FunctionalLayer
1108
1109    def setUp(self):
1110        super(ComboCardExporterTest, self).setUp()
1111        self.setup_for_export()
1112        return
1113
1114    def create_passport_img(self, student):
1115        # create some passport file for `student`
1116        storage = getUtility(IExtFileStore)
1117        image_path = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
1118        self.image_contents = open(image_path, 'rb').read()
1119        file_id = IFileStoreNameChooser(student).chooseName(
1120            attr='passport.jpg')
1121        storage.createFile(file_id, StringIO(self.image_contents))
1122
1123    def test_export_all(self):
1124        self.setup_student(self.student)
1125        self.create_passport_img(self.student)
1126        exporter = ComboCardDataExporter()
1127        exporter.export_all(self.app, self.outfile)
1128        result = open(self.outfile, 'rb').read()
1129        self.assertTrue(
1130            'display_fullname,student_id,matric_number,certificate,faculty,'
1131            'department,passport_path\r\nAnna M. Tester,A111111,234,'
1132            'Unnamed Certificate,Faculty of Unnamed Faculty (NA),'
1133            'Department of Unnamed Department (NA),'
1134            'students/00110/A111111/passport_A111111.jpg\r\n'
1135            in result
1136            )
1137        return
Note: See TracBrowser for help on using the repository browser.