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

Last change on this file since 16391 was 16391, checked in by Henrik Bettermann, 4 years ago

Add webservice.

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