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

Last change on this file was 17856, checked in by Henrik Bettermann, 2 months ago

Change output of get_bursary_data.

  • Property svn:keywords set to Id
File size: 37.6 KB
Line 
1# Tests for webservices
2import xmlrpclib
3import os
4from time import time
5from cStringIO import StringIO
6from zope.app.testing.xmlrpc import ServerProxy
7from zope.component import getUtility, createObject
8from waeup.kofa.interfaces import (
9    IExtFileStore, IFileStoreNameChooser, IKofaUtils)
10from waeup.kofa.testing import FunctionalLayer
11from waeup.kofa.utils.helpers import to_timezone
12from waeup.kofa.students.payments import StudentOnlinePayment
13from waeup.kofa.students.tests.test_browser import StudentsFullSetup
14from waeup.kofa.students.studylevel import StudentStudyLevel, CourseTicket
15
16
17class XMLRPCTests(StudentsFullSetup):
18
19    layer = FunctionalLayer
20
21    def setup_student(self, student):
22        study_level = StudentStudyLevel()
23        study_level.level_session = 2012
24        study_level.level_verdict = "A"
25        study_level.level = 100
26        study_level.validated_by = u"my adviser"
27        student['studycourse'].addStudentStudyLevel(
28            self.certificate, study_level)
29
30        ticket = CourseTicket()
31        ticket.automatic = True
32        ticket.carry_over = True
33        ticket.code = u'CRS1'
34        ticket.title = u'Course 1'
35        ticket.fcode = u'fac1'
36        ticket.dcode = u'dep1'
37        ticket.credits = 100
38        ticket.passmark = 100
39        ticket.semester = 2
40        study_level[ticket.code] = ticket
41
42    def create_passport_img(self, student):
43        # create some passport file for `student`
44        storage = getUtility(IExtFileStore)
45        image_path = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
46        self.image_contents = open(image_path, 'rb').read()
47        file_id = IFileStoreNameChooser(student).chooseName(
48            attr='passport.jpg')
49        storage.createFile(file_id, StringIO(self.image_contents))
50
51    def create_fpm_file(self, student, finger_num):
52        # create some .fpm file for `student` finger `finger_num`
53        storage = getUtility(IExtFileStore)
54        file_id = IFileStoreNameChooser(student).chooseName(
55            attr='%s.fpm' % finger_num)
56        storage.createFile(file_id, StringIO('FP1FakedMintiaeFile1'))
57
58    def XMLRPC_post(self, body):
59        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
60        self.browser.addHeader('Content-Length', len(body))
61        self.browser.post('http://localhost/app', body,
62            'text/xml; charset=utf-8')
63        return self.browser.contents
64
65    def test_get_student_id_no_match(self):
66        # w/o any students we get none
67        server = ServerProxy('http://mgr:mgrpw@localhost/app')
68        result = server.get_student_id('Nonsense')
69        self.assertTrue(result is None)
70        return
71
72    def test_get_student_id_regno_exists(self):
73        # we can get the id of an existing student with matching reg_no
74        server = ServerProxy('http://mgr:mgrpw@localhost/app')
75        result = server.get_student_id('123')
76        self.assertEqual(result, 'K1000000')
77        self.assertEqual(self.student_id, result)
78        REQUEST_XML = """\
79<?xml version="1.0"?>
80<methodCall>
81<methodName>get_student_id</methodName>
82<params>
83<param>
84<value><string>123</string></value>
85</param>
86</params>
87</methodCall>"""
88        RESPONSE_XML = """\
89<?xml version='1.0'?>
90<methodResponse>
91<params>
92<param>
93<value><string>K1000000</string></value>
94</param>
95</params>
96</methodResponse>
97"""
98        xmlout = self.XMLRPC_post(REQUEST_XML)
99        self.assertEqual(xmlout, RESPONSE_XML)
100        return
101
102    def test_get_student_id_block_unauthorized(self):
103        # requests from unauthorized users are blocked
104        # no username nor password
105        server = ServerProxy('http://localhost/app')
106        self.assertRaises(
107            xmlrpclib.ProtocolError, server.get_student_id, '123')
108        # wrong password
109        server = ServerProxy('http://mgr:WRONGPW@localhost/app')
110        self.assertRaises(
111            xmlrpclib.ProtocolError, server.get_student_id, '123')
112        # wrong username
113        server = ServerProxy('http://WRONGUSER:mgrpw@localhost/app')
114        self.assertRaises(
115            xmlrpclib.ProtocolError, server.get_student_id, '123')
116        return
117
118    def test_get_courses_by_session(self):
119        server = ServerProxy('http://mgr:mgrpw@localhost/app')
120        result = server.get_courses_by_session('K1000000')
121        self.assertEqual(result, None)
122        self.setup_student(self.student)
123        result = server.get_courses_by_session('K1000000', '2010')
124        self.assertEqual(result, None)
125        result = server.get_courses_by_session('K1000000', '2012')
126        self.assertEqual(result,
127            {'100|CRS1': 'Course 1', '100|COURSE1': 'Unnamed Course'})
128        result = server.get_courses_by_session('K1000000')
129        self.assertEqual(result,
130            {'100|CRS1': 'Course 1', '100|COURSE1': 'Unnamed Course'})
131        # Also matric_number ...
132        result = server.get_courses_by_session('234')
133        self.assertEqual(result,
134            {'100|CRS1': 'Course 1', '100|COURSE1': 'Unnamed Course'})
135        # ... or reg_number can be used.
136        result = server.get_courses_by_session('123')
137        self.assertEqual(result,
138            {'100|CRS1': 'Course 1', '100|COURSE1': 'Unnamed Course'})
139        result = server.get_courses_by_session('Nonsense')
140        self.assertEqual(result, None)
141        REQUEST_XML = """\
142<?xml version="1.0"?>
143<methodCall>
144<methodName>get_courses_by_session</methodName>
145<params>
146<param>
147<value><string>K1000000</string></value>
148</param>
149</params>
150</methodCall>"""
151        RESPONSE_XML = """\
152<?xml version='1.0'?>
153<methodResponse>
154<params>
155<param>
156<value><struct>
157<member>
158<name>100|CRS1</name>
159<value><string>Course 1</string></value>
160</member>
161<member>
162<name>100|COURSE1</name>
163<value><string>Unnamed Course</string></value>
164</member>
165</struct></value>
166</param>
167</params>
168</methodResponse>
169"""
170        xmlout = self.XMLRPC_post(REQUEST_XML)
171        self.assertEqual(xmlout, RESPONSE_XML)
172        return
173
174    def test_get_students_by_course(self):
175        self.setup_student(self.student)
176        server = ServerProxy('http://mgr:mgrpw@localhost/app')
177        result = server.get_students_by_course('CRS1', '2010')
178        self.assertEqual(result, None)
179        result = server.get_students_by_course('CRS1', '2012')
180        self.assertEqual(result, [['K1000000', '234', 'my adviser', 0], ])
181        result = server.get_students_by_course('CRS1')
182        self.assertEqual(result, [['K1000000', '234', 'my adviser', 0], ])
183        payment = StudentOnlinePayment()
184        payment.p_id = 'my-id'
185        payment.p_session = 2012
186        payment.amount_auth = 12.12
187        payment.p_state = u'paid'
188        payment.p_category = u'schoolfee'
189        self.student['payments']['my-payment'] = payment
190        result = server.get_students_by_course('CRS1')
191        self.assertEqual(result, [['K1000000', '234', 'my adviser', 12.12], ])
192        REQUEST_XML = """\
193<?xml version="1.0"?>
194<methodCall>
195<methodName>get_students_by_course</methodName>
196<params>
197<param>
198<value><string>CRS1</string></value>
199<value><string>2012</string></value>
200</param>
201</params>
202</methodCall>"""
203        RESPONSE_XML = """\
204<?xml version='1.0'?>
205<methodResponse>
206<params>
207<param>
208<value><array><data>
209<value><array><data>
210<value><string>K1000000</string></value>
211<value><string>234</string></value>
212<value><string>my adviser</string></value>
213<value><double>12.12</double></value>
214</data></array></value>
215</data></array></value>
216</param>
217</params>
218</methodResponse>
219"""
220        xmlout = self.XMLRPC_post(REQUEST_XML)
221        self.assertEqual(xmlout, RESPONSE_XML)
222        return
223
224    def test_get_students_by_department(self):
225        self.course2 = createObject('waeup.Course')
226        self.course2.code = 'COURSE2'
227        self.app['faculties']['fac1']['dep1'].courses.addCourse(
228            self.course2)
229        self.setup_student(self.student)
230        ticket = CourseTicket()
231        ticket.code = u'COURSE2'
232        ticket.title = u'Course 2'
233        ticket.fcode = u'fac1'
234        ticket.dcode = u'fac1'
235        self.student['studycourse']['100'][ticket.code] = ticket
236        server = ServerProxy('http://mgr:mgrpw@localhost/app')
237        result = server.get_students_by_department('fac1','dep1', '2011')
238        self.assertEqual(result, {})
239        result = server.get_students_by_department('fac1','dep1', '2012', '200')
240        self.assertEqual(result, {})
241        result = server.get_students_by_department('fac1','dep1', '2012', '100')
242        self.assertEqual(
243            result, {'K1000000': [
244            '234', 'Anna Tester', 2004, 100, ['COURSE1', 'COURSE2']]})
245        result = server.get_students_by_department('fac1','dep1', '0', '100')
246        self.assertEqual(
247            result, {'K1000000': [
248            '234', 'Anna Tester', 2004, 100, ['COURSE1', 'COURSE2']]})
249        result = server.get_students_by_department('fac1','dep1')
250        self.assertEqual(
251            result, {'K1000000': [
252            '234', 'Anna Tester', 2004, 100, ['COURSE1', 'COURSE2']]})
253        result = server.get_students_by_department('fac1','dep2')
254        self.assertEqual(result, None)
255        REQUEST_XML = """\
256<?xml version="1.0"?>
257<methodCall>
258<methodName>get_students_by_department</methodName>
259<params>
260<param>
261<value><string>fac1</string></value>
262<value><string>dep1</string></value>
263<value><int>0</int></value>
264<value><int>100</int></value>
265</param>
266</params>
267</methodCall>"""
268        RESPONSE_XML = """\
269<?xml version='1.0'?>
270<methodResponse>
271<params>
272<param>
273<value><struct>
274<member>
275<name>K1000000</name>
276<value><array><data>
277<value><string>234</string></value>
278<value><string>Anna Tester</string></value>
279<value><int>2004</int></value>
280<value><int>100</int></value>
281<value><array><data>
282<value><string>COURSE1</string></value>
283<value><string>COURSE2</string></value>
284</data></array></value>
285</data></array></value>
286</member>
287</struct></value>
288</param>
289</params>
290</methodResponse>
291"""
292        xmlout = self.XMLRPC_post(REQUEST_XML)
293        self.assertEqual(xmlout, RESPONSE_XML)
294        return
295
296    def test_get_student_info(self):
297        server = ServerProxy('http://mgr:mgrpw@localhost/app')
298        self.setup_student(self.student)
299        result = server.get_student_info('123')
300        self.assertEqual(result,
301            ['Anna Tester', 'CERT1', '1234', 'aa@aa.ng'])
302        REQUEST_XML = """\
303<?xml version="1.0"?>
304<methodCall>
305<methodName>get_student_info</methodName>
306<params>
307<param>
308<value><string>K1000000</string></value>
309</param>
310</params>
311</methodCall>"""
312        RESPONSE_XML = """\
313<?xml version='1.0'?>
314<methodResponse>
315<params>
316<param>
317<value><array><data>
318<value><string>Anna Tester</string></value>
319<value><string>CERT1</string></value>
320<value><string>1234</string></value>
321<value><string>aa@aa.ng</string></value>
322</data></array></value>
323</param>
324</params>
325</methodResponse>
326"""
327        xmlout = self.XMLRPC_post(REQUEST_XML)
328        self.assertEqual(xmlout, RESPONSE_XML)
329        return
330
331    def test_get_grad_student(self):
332        server = ServerProxy('http://localhost/app')
333        self.setup_student(self.student)
334        result = server.get_grad_student('123', 'aa@aa.ng')
335        self.assertEqual(result,
336            [True, False, False])
337        REQUEST_XML = """\
338<?xml version="1.0"?>
339<methodCall>
340<methodName>get_grad_student</methodName>
341<params>
342<param>
343<value><string>K1000000</string></value>
344</param>
345<param>
346<value><string>aa@aa.ng</string></value>
347</param>
348</params>
349</methodCall>"""
350        RESPONSE_XML = """\
351<?xml version='1.0'?>
352<methodResponse>
353<params>
354<param>
355<value><array><data>
356<value><boolean>1</boolean></value>
357<value><boolean>0</boolean></value>
358<value><boolean>0</boolean></value>
359</data></array></value>
360</param>
361</params>
362</methodResponse>
363"""
364        xmlout = self.XMLRPC_post(REQUEST_XML)
365        self.assertEqual(xmlout, RESPONSE_XML)
366        return
367
368    def test_get_student_passport(self):
369        server = ServerProxy('http://mgr:mgrpw@localhost/app')
370        self.setup_student(self.student)
371        self.create_passport_img(self.student)
372        result = server.get_student_passport('123')
373        img = getUtility(IExtFileStore).getFileByContext(
374            self.student, attr='passport.jpg')
375        binary = img.read()
376        self.assertEqual(binary, result)
377        REQUEST_XML = """\
378<?xml version="1.0"?>
379<methodCall>
380<methodName>get_student_passport</methodName>
381<params>
382<param>
383<value><string>K1000000</string></value>
384</param>
385</params>
386</methodCall>"""
387        RESPONSE_XML = """\
388<?xml version='1.0'?>
389<methodResponse>
390<params>
391<param>
392<value><base64>
393/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAPAAA/+4ADkFkb2JlAGTAAAAAAf/b
394"""
395        xmlout = self.XMLRPC_post(REQUEST_XML)
396        self.assertTrue(xmlout.startswith(RESPONSE_XML))
397
398    def test_get_paid_sessions(self):
399        server = ServerProxy('http://mgr:mgrpw@localhost/app')
400        self.setup_student(self.student)
401        payment = StudentOnlinePayment()
402        payment.p_id = 'my-id'
403        payment.p_session = 2009
404        payment.amount_auth = 12.12
405        payment.p_state = u'paid'
406        payment.p_category = u'schoolfee'
407        self.student['payments']['my-payment'] = payment
408        result = server.get_paid_sessions('123')
409        self.assertEqual(result, {'2009': 12.12})
410        REQUEST_XML = """\
411<?xml version="1.0"?>
412<methodCall>
413<methodName>get_paid_sessions</methodName>
414<params>
415<param>
416<value><string>K1000000</string></value>
417</param>
418</params>
419</methodCall>"""
420        RESPONSE_XML = """\
421<?xml version='1.0'?>
422<methodResponse>
423<params>
424<param>
425<value><struct>
426<member>
427<name>2009</name>
428<value><double>12.12</double></value>
429</member>
430</struct></value>
431</param>
432</params>
433</methodResponse>
434"""
435        xmlout = self.XMLRPC_post(REQUEST_XML)
436        self.assertEqual(xmlout, RESPONSE_XML)
437        return
438
439    def test_check_student_credentials(self):
440        # make sure we can get student infos providing valid creds
441        server = ServerProxy('http://mgr:mgrpw@localhost/app')
442        self.setup_student(self.student)
443        stud_id = self.student.student_id
444        result = server.check_student_credentials(stud_id, 'spwd')
445        self.assertEqual(
446            result, {
447                'description': 'Anna Tester',
448                'email': 'aa@aa.ng',
449                'id': 'K1000000',
450                'type': 'student'}
451            )
452        return
453
454    def test_get_student_moodle_data(self):
455        server = ServerProxy('http://mgr:mgrpw@localhost/app')
456        self.setup_student(self.student)
457        result = server.get_student_moodle_data(self.student.student_id)
458        self.assertEqual(result,
459            {'lastname': 'Tester', 'email': 'aa@aa.ng', 'firstname': 'Anna'})
460        REQUEST_XML = """\
461<?xml version="1.0"?>
462<methodCall>
463<methodName>get_student_moodle_data</methodName>
464<params>
465<param>
466<value><string>K1000000</string></value>
467</param>
468</params>
469</methodCall>"""
470        RESPONSE_XML = """\
471<?xml version='1.0'?>
472<methodResponse>
473<params>
474<param>
475<value><struct>
476<member>
477<name>lastname</name>
478<value><string>Tester</string></value>
479</member>
480<member>
481<name>email</name>
482<value><string>aa@aa.ng</string></value>
483</member>
484<member>
485<name>firstname</name>
486<value><string>Anna</string></value>
487</member>
488</struct></value>
489</param>
490</params>
491</methodResponse>
492"""
493        xmlout = self.XMLRPC_post(REQUEST_XML)
494        self.assertEqual(xmlout, RESPONSE_XML)
495        return
496
497    def test_put_student_fingerprints_no_stud(self):
498        # invalid student ids will result in `False`
499        server = ServerProxy('http://mgr:mgrpw@localhost/app')
500        self.assertRaises(
501            xmlrpclib.Fault, server.put_student_fingerprints,
502            'invalid id', {})
503
504    def test_put_student_fingerprints_non_dict(self):
505        # fingerprints must be passed in in a dict
506        server = ServerProxy('http://mgr:mgrpw@localhost/app')
507        self.setup_student(self.student)
508        self.assertRaises(
509            xmlrpclib.Fault, server.put_student_fingerprints,
510            self.student.student_id, 'not-a-dict')
511
512    def test_put_student_fingerprints_non_num_keys_ignored(self):
513        # non-numeric keys in fingerprint dict are ignored
514        server = ServerProxy('http://mgr:mgrpw@localhost/app')
515        self.setup_student(self.student)
516        result = server.put_student_fingerprints(
517            self.student.student_id, {'not-a-num': 'foo',
518                                      '12.2': 'bar',
519                                      '123': 'baz'})
520        self.assertEqual(result, False)
521
522    def test_put_student_fingerprints_non_fpm_data(self):
523        # we cannot pass non-.fpm files as values
524        server = ServerProxy('http://mgr:mgrpw@localhost/app')
525        self.setup_student(self.student)
526        self.assertRaises(
527            xmlrpclib.Fault, server.put_student_fingerprints,
528            self.student.student_id, {'1': 'not-a-fingerprint'})
529
530    def test_put_student_fingerprints_invalid_file_format(self):
531        # invalid files will result in `False`
532        server = ServerProxy('http://mgr:mgrpw@localhost/app')
533        self.setup_student(self.student)
534        invalid_fpm = xmlrpclib.Binary('invalid file')
535        self.assertRaises(
536            xmlrpclib.Fault, server.put_student_fingerprints,
537            self.student.student_id, {'1': invalid_fpm})
538
539    def test_put_student_fingerprints(self):
540        # we can store fingerprints
541        server = ServerProxy('http://mgr:mgrpw@localhost/app')
542        self.setup_student(self.student)
543        fpm = xmlrpclib.Binary('FP1faked_fpm')
544        result = server.put_student_fingerprints(
545            self.student.student_id, {'1': fpm})
546        self.assertEqual(result, True)
547        stored_file = getUtility(IExtFileStore).getFileByContext(
548            self.student, attr="finger1.fpm")
549        self.assertEqual(stored_file.read(), 'FP1faked_fpm')
550        # storing is logged
551        logfile = os.path.join(
552            self.app['datacenter'].storage, 'logs', 'students.log')
553        logcontent = open(logfile).read()
554        self.assertTrue(
555            'zope.mgr - grok.meta.StudentsXMLRPC '
556            '- K1000000 - fingerprint stored' in logcontent)
557
558    def test_put_student_fingerprints_existing(self):
559        # existing fingerprints are overwritten
560        server = ServerProxy('http://mgr:mgrpw@localhost/app')
561        self.setup_student(self.student)
562        self.create_fpm_file(self.student, '1')
563        fpm1 = xmlrpclib.Binary('FP1faked_fpm1')
564        fpm2 = xmlrpclib.Binary('FP1faked_fpm2')
565        result = server.put_student_fingerprints(
566            self.student.student_id, {'1': fpm1, '3': fpm2})
567        self.assertEqual(result, True)
568        stored_file1 = getUtility(IExtFileStore).getFileByContext(
569            self.student, attr="finger1.fpm")
570        stored_file2 = getUtility(IExtFileStore).getFileByContext(
571            self.student, attr="finger3.fpm")
572        self.assertEqual(stored_file1.read(), 'FP1faked_fpm1')
573        self.assertEqual(stored_file2.read(), 'FP1faked_fpm2')
574
575    def test_get_student_fingerprints_no_stud(self):
576        # invalid student ids result in empty dict
577        server = ServerProxy('http://mgr:mgrpw@localhost/app')
578        result = server.get_student_fingerprints('invalid id')
579        self.assertEqual(result, {})
580
581    def test_get_student_fingerprints_no_files(self):
582        # we get student data, but no fingerprints if not stored before
583        server = ServerProxy('http://mgr:mgrpw@localhost/app')
584        self.setup_student(self.student)
585        result = server.get_student_fingerprints(self.student.student_id)
586        self.assertEqual(
587            result,
588            {'lastname': 'Tester',
589             'email': 'aa@aa.ng',
590             'firstname': 'Anna',
591             'fingerprints': {},
592             'img': None,
593             'img_name': None,
594             })
595
596    def test_get_student_fingerprints_passport(self):
597        # we get a photograph of the student if avail.
598        server = ServerProxy('http://mgr:mgrpw@localhost/app')
599        self.setup_student(self.student)
600        self.create_passport_img(self.student)
601        result = server.get_student_fingerprints(self.student.student_id)
602        self.assertTrue(
603            isinstance(result['img'], xmlrpclib.Binary))
604        self.assertEqual(result['img_name'], 'passport_K1000000.jpg')
605
606    def test_get_student_fingerprints_fpm(self):
607        # we get minutiae files if any are avail.
608        server = ServerProxy('http://mgr:mgrpw@localhost/app')
609        self.setup_student(self.student)
610        self.create_fpm_file(self.student, 'finger1')
611        result = server.get_student_fingerprints(self.student.student_id)
612        self.assertTrue('1' in result['fingerprints'].keys())
613        self.assertTrue(
614            isinstance(result['fingerprints']['1'], xmlrpclib.Binary))
615
616    def test_get_student_fingerprints_block_unauthorized(self):
617        # requests from unauthorized users are blocked
618        # no username nor password
619        server = ServerProxy('http://localhost/app')
620        self.setup_student(self.student)
621        stud_id = self.student.student_id
622        self.assertRaises(
623            xmlrpclib.ProtocolError, server.get_student_id, stud_id)
624        # wrong password
625        server = ServerProxy('http://mgr:WRONGPW@localhost/app')
626        self.assertRaises(
627            xmlrpclib.ProtocolError, server.get_student_id, stud_id)
628        # wrong username
629        server = ServerProxy('http://WRONGUSER:mgrpw@localhost/app')
630        self.assertRaises(
631            xmlrpclib.ProtocolError, server.get_student_id, stud_id)
632        return
633
634    def test_get_bursary_data(self):
635        tz = getUtility(IKofaUtils).tzinfo
636        payment1 = StudentOnlinePayment()
637        payment1.p_id = 'my-id1'
638        payment1.p_session = 2012
639        payment1.amount_auth = 12.12
640        payment1.p_state = u'paid'
641        payment1.p_category = u'schoolfee'
642        self.student['payments']['my-payment1'] = payment1
643        payment2 = StudentOnlinePayment()
644        payment2.p_id = 'my-id2'
645        payment2.p_session = 2012
646        payment2.amount_auth = 12.12
647        payment2.p_state = u'paid'
648        payment2.p_category = u'clearance'
649        self.student['payments']['my-payment2'] = payment2
650        server = ServerProxy('http://mgr:mgrpw@localhost/app', allow_none=True)
651        result = server.get_bursary_data(None,2012,None,None,None,'dep1')
652        self.assertEqual(
653            result,[
654            {'entry_mode': None, 'reg_number': '123', 'display_item': None,
655                'firstname': 'Anna', 'payment_date': 'None#',
656                'p_combi': [],
657                'middlename': None, 'student_id': 'K1000000', 'p_id':
658                'my-id1', 'certcode': 'CERT1', 'entry_session': 2004,
659                'creation_date': str('%s#' % to_timezone(payment1.creation_date, tz)),
660                'p_level': None,
661                'state': 'created', 'current_session': 2004,
662                'faccode': 'fac1', 'lastname': 'Tester',
663                'p_category': 'schoolfee', 'amount_auth': 12.12,
664                'p_state': 'paid', 'p_session': 2012, 'matric_number': '234',
665                'depcode': 'dep1'},
666            {'entry_mode': None, 'reg_number': '123', 'display_item': None,
667                'firstname': 'Anna', 'payment_date': 'None#',
668                'p_combi': [],
669                'middlename': None, 'student_id': 'K1000000',
670                'p_id': 'my-id2', 'certcode': 'CERT1', 'entry_session': 2004,
671                'creation_date': str('%s#' % to_timezone(payment2.creation_date, tz)),
672                'p_level': None,
673                'state': 'created', 'current_session': 2004, 'faccode': 'fac1',
674                'lastname': 'Tester', 'p_category': 'clearance',
675                'amount_auth': 12.12, 'p_state': 'paid', 'p_session': 2012,
676                'matric_number': '234', 'depcode': 'dep1'}
677            ]
678            )
679
680        REQUEST_XML = """\
681<?xml version="1.0"?>
682<methodCall>
683<methodName>get_bursary_data</methodName>
684<params>
685<param>
686<value><string></string></value>
687<value><string>2012</string></value>
688<value><string></string></value>
689<value><string></string></value>
690<value><string></string></value>
691<value><string>dep1</string></value>
692</param>
693</params>
694</methodCall>"""
695        RESPONSE_XML = """\
696<?xml version='1.0'?>
697<methodResponse>
698<params>
699<param>
700<value><array><data>
701<value><struct>
702<member>
703<name>entry_mode</name>
704<value><nil/></value></member>
705<member>
706<name>creation_date</name>
707<value><string>%s</string></value>
708</member>
709<member>
710<name>p_level</name>
711<value><nil/></value></member>
712<member>
713<name>p_category</name>
714<value><string>schoolfee</string></value>
715</member>
716<member>
717<name>amount_auth</name>
718<value><double>12.12</double></value>
719</member>
720<member>
721<name>reg_number</name>
722<value><string>123</string></value>
723</member>
724<member>
725<name>payment_date</name>
726<value><string>None#</string></value>
727</member>
728<member>
729<name>p_combi</name>
730<value><array><data>
731</data></array></value>
732</member>
733<member>
734<name>student_id</name>
735<value><string>K1000000</string></value>
736</member>
737<member>
738<name>entry_session</name>
739<value><int>2004</int></value>
740</member>
741<member>
742<name>state</name>
743<value><string>created</string></value>
744</member>
745<member>
746<name>p_session</name>
747<value><int>2012</int></value>
748</member>
749<member>
750<name>matric_number</name>
751<value><string>234</string></value>
752</member>
753<member>
754<name>firstname</name>
755<value><string>Anna</string></value>
756</member>
757<member>
758<name>middlename</name>
759<value><nil/></value></member>
760<member>
761<name>lastname</name>
762<value><string>Tester</string></value>
763</member>
764<member>
765<name>certcode</name>
766<value><string>CERT1</string></value>
767</member>
768<member>
769<name>depcode</name>
770<value><string>dep1</string></value>
771</member>
772<member>
773<name>display_item</name>
774<value><nil/></value></member>
775<member>
776<name>p_id</name>
777<value><string>my-id1</string></value>
778</member>
779<member>
780<name>faccode</name>
781<value><string>fac1</string></value>
782</member>
783<member>
784<name>current_session</name>
785<value><int>2004</int></value>
786</member>
787<member>
788<name>p_state</name>
789<value><string>paid</string></value>
790</member>
791</struct></value>
792<value><struct>
793<member>
794<name>entry_mode</name>
795<value><nil/></value></member>
796<member>
797<name>creation_date</name>
798<value><string>%s</string></value>
799</member>
800<member>
801<name>p_level</name>
802<value><nil/></value></member>
803<member>
804<name>p_category</name>
805<value><string>clearance</string></value>
806</member>
807<member>
808<name>amount_auth</name>
809<value><double>12.12</double></value>
810</member>
811<member>
812<name>reg_number</name>
813<value><string>123</string></value>
814</member>
815<member>
816<name>payment_date</name>
817<value><string>None#</string></value>
818</member>
819<member>
820<name>p_combi</name>
821<value><array><data>
822</data></array></value>
823</member>
824<member>
825<name>student_id</name>
826<value><string>K1000000</string></value>
827</member>
828<member>
829<name>entry_session</name>
830<value><int>2004</int></value>
831</member>
832<member>
833<name>state</name>
834<value><string>created</string></value>
835</member>
836<member>
837<name>p_session</name>
838<value><int>2012</int></value>
839</member>
840<member>
841<name>matric_number</name>
842<value><string>234</string></value>
843</member>
844<member>
845<name>firstname</name>
846<value><string>Anna</string></value>
847</member>
848<member>
849<name>middlename</name>
850<value><nil/></value></member>
851<member>
852<name>lastname</name>
853<value><string>Tester</string></value>
854</member>
855<member>
856<name>certcode</name>
857<value><string>CERT1</string></value>
858</member>
859<member>
860<name>depcode</name>
861<value><string>dep1</string></value>
862</member>
863<member>
864<name>display_item</name>
865<value><nil/></value></member>
866<member>
867<name>p_id</name>
868<value><string>my-id2</string></value>
869</member>
870<member>
871<name>faccode</name>
872<value><string>fac1</string></value>
873</member>
874<member>
875<name>current_session</name>
876<value><int>2004</int></value>
877</member>
878<member>
879<name>p_state</name>
880<value><string>paid</string></value>
881</member>
882</struct></value>
883</data></array></value>
884</param>
885</params>
886</methodResponse>
887"""
888        xmlout = self.XMLRPC_post(REQUEST_XML)
889        response = RESPONSE_XML % (str('%s#' % to_timezone(payment1.creation_date, tz)),
890                                   str('%s#' % to_timezone(payment2.creation_date, tz))
891                                   )
892        self.assertEqual(xmlout, response)
893        return
894
895        def test_get_payment(self):
896            payment1 = StudentOnlinePayment()
897            payment1.p_id = 'my-id1'
898            payment1.p_session = 2012
899            payment1.amount_auth = 12.12
900            payment1.p_state = u'failed'
901            payment1.p_category = u'schoolfee'
902            payment1.r_company = u'xyz'
903            self.student['payments']['my-payment1'] = payment1
904            server = ServerProxy('http://mgr:mgrpw@localhost/app', allow_none=True)
905            results = server.get_payment()
906            self.assertEqual(results, None)
907            results = server.get_payment('nonsense')
908            self.assertEqual(results, None)
909            results = server.get_payment('my-id1')
910            self.assertEqual(
911                results,
912                    {'display_item': None,
913                    'p_id': 'my-id1',
914                    'p_category': 'schoolfee',
915                    'amount_auth': 12.12, 'p_session': 2012,
916                    'p_state': 'failed',
917                    'r_company': 'xyz',
918                    'fullname': 'Anna Tester',
919                    'id': 'K1000000',
920                    'matric_number': '234'}
921                    )
922
923            REQUEST_XML = """\
924    <?xml version="1.0"?>
925    <methodCall>
926    <methodName>get_payment</methodName>
927    <params>
928    <param>
929    <value><string>my-id1</string></value>
930    </param>
931    </params>
932    </methodCall>"""
933            RESPONSE_XML = """\
934    <?xml version='1.0'?>
935    <methodResponse>
936<params>
937<param>
938<value><struct>
939<member>
940<name>display_item</name>
941<value><nil/></value></member>
942<member>
943<name>amount_auth</name>
944<value><double>12.12</double></value>
945</member>
946<member>
947<name>p_id</name>
948<value><string>my-id1</string></value>
949</member>
950<member>
951<name>r_company</name>
952<value><string>xyz</string></value>
953</member>
954<member>
955<name>matric_number</name>
956<value><string>234</string></value>
957</member>
958<member>
959<name>p_category</name>
960<value><string>schoolfee</string></value>
961</member>
962<member>
963<name>fullname</name>
964<value><string>Anna Tester</string></value>
965</member>
966<member>
967<name>p_state</name>
968<value><string>failed</string></value>
969</member>
970<member>
971<name>p_session</name>
972<value><int>2012</int></value>
973</member>
974<member>
975<name>id</name>
976<value><string>K1000000</string></value>
977</member>
978</struct></value>
979</param>
980</params>
981</methodResponse>
982"""
983        xmlout = self.XMLRPC_post(REQUEST_XML)
984        self.assertEqual(xmlout, RESPONSE_XML)
985        return
986
987    def test_get_unpaid_payments(self):
988        timestamp1 = ("%d" % int((time()-10)*10000))[1:]
989        timestamp2 = ("%d" % int((time()-5)*10000))[1:]
990        timestamp3 = ("%d" % int((time()-(3*86400))*10000))[1:]
991        p_id_1 = ("p%s" % timestamp1)
992        p_id_2 = ("p%s" % timestamp2)
993        p_id_3 = ("p%s" % timestamp3)
994        payment1 = StudentOnlinePayment()
995        payment1.p_id = p_id_1
996        payment1.p_session = 2012
997        payment1.amount_auth = 12.12
998        payment1.p_state = u'failed'
999        payment1.p_category = u'schoolfee'
1000        payment1.r_company = u'xyz'
1001        self.student['payments']['my-payment1'] = payment1
1002        payment2 = StudentOnlinePayment()
1003        payment2.p_id = p_id_2
1004        payment2.p_session = 2012
1005        payment2.amount_auth = 12.12
1006        payment2.p_state = u'paid'
1007        payment2.p_category = u'clearance'
1008        self.student['payments']['my-payment2'] = payment2
1009        payment3 = StudentOnlinePayment()
1010        payment3.p_id = p_id_3
1011        payment3.p_session = 2012
1012        payment3.amount_auth = 12.12
1013        payment3.p_state = u'unpaid'
1014        payment3.p_category = u'schoolfee'
1015        self.student['payments']['my-payment3'] = payment3
1016        server = ServerProxy('http://mgr:mgrpw@localhost/app', allow_none=True)
1017        results = server.get_unpaid_payments(1)
1018        self.assertEqual(
1019            results,[
1020                {'display_item': None,
1021                'p_id': '%s' % p_id_1,
1022                'p_category': 'schoolfee',
1023                'amount_auth': 12.12, 'p_session': 2012,
1024                'p_state': 'failed',
1025                'r_company': 'xyz',
1026                'fullname': 'Anna Tester',
1027                'id': 'K1000000',
1028                'matric_number': '234'}
1029                ])
1030        results = server.get_unpaid_payments(4)
1031        self.assertEqual(
1032            results,[
1033                {'display_item': None,
1034                  'p_id': '%s' % p_id_3,
1035                  'p_category': 'schoolfee',
1036                  'amount_auth': 12.12,
1037                  'p_session': 2012,
1038                  'p_state': 'unpaid',
1039                  'r_company': None,
1040                  'fullname': 'Anna Tester',
1041                  'id': 'K1000000',
1042                  'matric_number': '234'},
1043                {'display_item': None,
1044                  'p_id': '%s' % p_id_1,
1045                  'p_category': 'schoolfee',
1046                  'amount_auth': 12.12,
1047                  'p_session': 2012,
1048                  'p_state': 'failed',
1049                  'r_company': 'xyz',
1050                  'fullname': 'Anna Tester',
1051                  'id': 'K1000000',
1052                  'matric_number': '234'},
1053                ])
1054        results = server.get_unpaid_payments(4,'xyz')
1055        self.assertEqual(
1056            results,[
1057                {'display_item': None,
1058                  'p_id': '%s' % p_id_1,
1059                  'p_category': 'schoolfee',
1060                  'amount_auth': 12.12,
1061                  'p_session': 2012,
1062                  'p_state': 'failed',
1063                  'r_company': 'xyz',
1064                  'fullname': 'Anna Tester',
1065                  'id': 'K1000000',
1066                  'matric_number': '234'},
1067                ])
1068
1069        REQUEST_XML = """\
1070<?xml version="1.0"?>
1071<methodCall>
1072<methodName>get_unpaid_payments</methodName>
1073<params>
1074<param>
1075<value><string>1</string></value>
1076</param>
1077</params>
1078</methodCall>"""
1079        RESPONSE_XML = """\
1080<?xml version='1.0'?>
1081<methodResponse>
1082<params>
1083<param>
1084<value><array><data>
1085<value><struct>
1086<member>
1087<name>display_item</name>
1088<value><nil/></value></member>
1089<member>
1090<name>amount_auth</name>
1091<value><double>12.12</double></value>
1092</member>
1093<member>
1094<name>p_id</name>
1095<value><string>%s</string></value>
1096</member>
1097<member>
1098<name>r_company</name>
1099<value><string>xyz</string></value>
1100</member>
1101<member>
1102<name>matric_number</name>
1103<value><string>234</string></value>
1104</member>
1105<member>
1106<name>p_category</name>
1107<value><string>schoolfee</string></value>
1108</member>
1109<member>
1110<name>fullname</name>
1111<value><string>Anna Tester</string></value>
1112</member>
1113<member>
1114<name>p_state</name>
1115<value><string>failed</string></value>
1116</member>
1117<member>
1118<name>p_session</name>
1119<value><int>2012</int></value>
1120</member>
1121<member>
1122<name>id</name>
1123<value><string>K1000000</string></value>
1124</member>
1125</struct></value>
1126</data></array></value>
1127</param>
1128</params>
1129</methodResponse>
1130""" % p_id_1
1131        xmlout = self.XMLRPC_post(REQUEST_XML)
1132        self.assertEqual(xmlout, RESPONSE_XML)
1133        return
1134
1135    def test_get_student_info(self):
1136        server = ServerProxy('http://mgr:mgrpw@localhost/app')
1137        self.setup_student(self.student)
1138        result = server.get_student_info('123')
1139        self.assertEqual(result,
1140            ['Anna Tester', 'CERT1', '1234', 'aa@aa.ng'])
1141        REQUEST_XML = """\
1142<?xml version="1.0"?>
1143<methodCall>
1144<methodName>get_student_info</methodName>
1145<params>
1146<param>
1147<value><string>K1000000</string></value>
1148</param>
1149</params>
1150</methodCall>"""
1151        RESPONSE_XML = """\
1152<?xml version='1.0'?>
1153<methodResponse>
1154<params>
1155<param>
1156<value><array><data>
1157<value><string>Anna Tester</string></value>
1158<value><string>CERT1</string></value>
1159<value><string>1234</string></value>
1160<value><string>aa@aa.ng</string></value>
1161</data></array></value>
1162</param>
1163</params>
1164</methodResponse>
1165"""
1166        xmlout = self.XMLRPC_post(REQUEST_XML)
1167        self.assertEqual(xmlout, RESPONSE_XML)
1168        return
1169
1170    def test_get_student_base_data(self):
1171        server = ServerProxy('http://mgr:mgrpw@localhost/app')
1172        result = server.get_student_base_data()
1173        self.assertEqual(result,
1174            [{'entry_mode': None,
1175              'reg_number': '123',
1176              'firstname': 'Anna',
1177              'middlename': None,
1178              'current_session': 2004,
1179              'entry_session': 2004,
1180              'certcode': 'CERT1',
1181              'state': 'created',
1182              'student_id': 'K1000000',
1183              'faccode': 'fac1',
1184              'lastname': 'Tester',
1185              'matric_number': '234',
1186              'depcode': 'dep1',
1187              'sex': 'm'}])
1188        REQUEST_XML = """\
1189<?xml version="1.0"?>
1190<methodCall>
1191<methodName>get_student_base_data</methodName>
1192<params>
1193</params>
1194</methodCall>"""
1195        RESPONSE_XML = """\
1196<?xml version='1.0'?>
1197<methodResponse>
1198<params>
1199<param>
1200<value><array><data>
1201<value><struct>
1202<member>
1203<name>entry_mode</name>
1204<value><nil/></value></member>
1205<member>
1206<name>reg_number</name>
1207<value><string>123</string></value>
1208</member>
1209<member>
1210<name>firstname</name>
1211<value><string>Anna</string></value>
1212</member>
1213<member>
1214<name>middlename</name>
1215<value><nil/></value></member>
1216<member>
1217<name>current_session</name>
1218<value><int>2004</int></value>
1219</member>
1220<member>
1221<name>entry_session</name>
1222<value><int>2004</int></value>
1223</member>
1224<member>
1225<name>certcode</name>
1226<value><string>CERT1</string></value>
1227</member>
1228<member>
1229<name>sex</name>
1230<value><string>m</string></value>
1231</member>
1232<member>
1233<name>matric_number</name>
1234<value><string>234</string></value>
1235</member>
1236<member>
1237<name>state</name>
1238<value><string>created</string></value>
1239</member>
1240<member>
1241<name>faccode</name>
1242<value><string>fac1</string></value>
1243</member>
1244<member>
1245<name>lastname</name>
1246<value><string>Tester</string></value>
1247</member>
1248<member>
1249<name>student_id</name>
1250<value><string>K1000000</string></value>
1251</member>
1252<member>
1253<name>depcode</name>
1254<value><string>dep1</string></value>
1255</member>
1256</struct></value>
1257</data></array></value>
1258</param>
1259</params>
1260</methodResponse>
1261"""
1262        xmlout = self.XMLRPC_post(REQUEST_XML)
1263        self.assertEqual(xmlout, RESPONSE_XML)
1264        return
Note: See TracBrowser for help on using the repository browser.