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

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

Extend webservice.

  • Property svn:keywords set to Id
File size: 24.9 KB
Line 
1# Tests for webservices
2import xmlrpclib
3import os
4from cStringIO import StringIO
5from zope.app.testing.xmlrpc import ServerProxy
6from zope.component import getUtility
7from waeup.kofa.interfaces import (
8    IExtFileStore, IFileStoreNameChooser, IKofaUtils)
9from waeup.kofa.testing import FunctionalLayer
10from waeup.kofa.utils.helpers import to_timezone
11from waeup.kofa.students.payments import StudentOnlinePayment
12from waeup.kofa.students.tests.test_browser import StudentsFullSetup
13from waeup.kofa.students.studylevel import StudentStudyLevel, CourseTicket
14
15
16class XMLRPCTests(StudentsFullSetup):
17    # check XMLRPC services for university portal
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_student_info(self):
225        server = ServerProxy('http://mgr:mgrpw@localhost/app')
226        self.setup_student(self.student)
227        result = server.get_student_info('123')
228        self.assertEqual(result,
229            ['Anna Tester', 'CERT1', '1234', 'aa@aa.ng'])
230        REQUEST_XML = """\
231<?xml version="1.0"?>
232<methodCall>
233<methodName>get_student_info</methodName>
234<params>
235<param>
236<value><string>K1000000</string></value>
237</param>
238</params>
239</methodCall>"""
240        RESPONSE_XML = """\
241<?xml version='1.0'?>
242<methodResponse>
243<params>
244<param>
245<value><array><data>
246<value><string>Anna Tester</string></value>
247<value><string>CERT1</string></value>
248<value><string>1234</string></value>
249<value><string>aa@aa.ng</string></value>
250</data></array></value>
251</param>
252</params>
253</methodResponse>
254"""
255        xmlout = self.XMLRPC_post(REQUEST_XML)
256        self.assertEqual(xmlout, RESPONSE_XML)
257        return
258
259    def test_get_grad_student(self):
260        server = ServerProxy('http://localhost/app')
261        self.setup_student(self.student)
262        result = server.get_grad_student('123', 'aa@aa.ng')
263        self.assertEqual(result,
264            [True, False, False])
265        REQUEST_XML = """\
266<?xml version="1.0"?>
267<methodCall>
268<methodName>get_grad_student</methodName>
269<params>
270<param>
271<value><string>K1000000</string></value>
272</param>
273<param>
274<value><string>aa@aa.ng</string></value>
275</param>
276</params>
277</methodCall>"""
278        RESPONSE_XML = """\
279<?xml version='1.0'?>
280<methodResponse>
281<params>
282<param>
283<value><array><data>
284<value><boolean>1</boolean></value>
285<value><boolean>0</boolean></value>
286<value><boolean>0</boolean></value>
287</data></array></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_passport(self):
297        server = ServerProxy('http://mgr:mgrpw@localhost/app')
298        self.setup_student(self.student)
299        self.create_passport_img(self.student)
300        result = server.get_student_passport('123')
301        img = getUtility(IExtFileStore).getFileByContext(
302            self.student, attr='passport.jpg')
303        binary = img.read()
304        self.assertEqual(binary, result)
305        REQUEST_XML = """\
306<?xml version="1.0"?>
307<methodCall>
308<methodName>get_student_passport</methodName>
309<params>
310<param>
311<value><string>K1000000</string></value>
312</param>
313</params>
314</methodCall>"""
315        RESPONSE_XML = """\
316<?xml version='1.0'?>
317<methodResponse>
318<params>
319<param>
320<value><base64>
321/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAPAAA/+4ADkFkb2JlAGTAAAAAAf/b
322"""
323        xmlout = self.XMLRPC_post(REQUEST_XML)
324        self.assertTrue(xmlout.startswith(RESPONSE_XML))
325
326    def test_get_paid_sessions(self):
327        server = ServerProxy('http://mgr:mgrpw@localhost/app')
328        self.setup_student(self.student)
329        payment = StudentOnlinePayment()
330        payment.p_id = 'my-id'
331        payment.p_session = 2009
332        payment.amount_auth = 12.12
333        payment.p_state = u'paid'
334        payment.p_category = u'schoolfee'
335        self.student['payments']['my-payment'] = payment
336        result = server.get_paid_sessions('123')
337        self.assertEqual(result, {'2009': 12.12})
338        REQUEST_XML = """\
339<?xml version="1.0"?>
340<methodCall>
341<methodName>get_paid_sessions</methodName>
342<params>
343<param>
344<value><string>K1000000</string></value>
345</param>
346</params>
347</methodCall>"""
348        RESPONSE_XML = """\
349<?xml version='1.0'?>
350<methodResponse>
351<params>
352<param>
353<value><struct>
354<member>
355<name>2009</name>
356<value><double>12.12</double></value>
357</member>
358</struct></value>
359</param>
360</params>
361</methodResponse>
362"""
363        xmlout = self.XMLRPC_post(REQUEST_XML)
364        self.assertEqual(xmlout, RESPONSE_XML)
365        return
366
367    def test_check_student_credentials(self):
368        # make sure we can get student infos providing valid creds
369        server = ServerProxy('http://mgr:mgrpw@localhost/app')
370        self.setup_student(self.student)
371        stud_id = self.student.student_id
372        result = server.check_student_credentials(stud_id, 'spwd')
373        self.assertEqual(
374            result, {
375                'description': 'Anna Tester',
376                'email': 'aa@aa.ng',
377                'id': 'K1000000',
378                'type': 'student'}
379            )
380        return
381
382    def test_get_student_moodle_data(self):
383        server = ServerProxy('http://mgr:mgrpw@localhost/app')
384        self.setup_student(self.student)
385        result = server.get_student_moodle_data(self.student.student_id)
386        self.assertEqual(result,
387            {'lastname': 'Tester', 'email': 'aa@aa.ng', 'firstname': 'Anna'})
388        REQUEST_XML = """\
389<?xml version="1.0"?>
390<methodCall>
391<methodName>get_student_moodle_data</methodName>
392<params>
393<param>
394<value><string>K1000000</string></value>
395</param>
396</params>
397</methodCall>"""
398        RESPONSE_XML = """\
399<?xml version='1.0'?>
400<methodResponse>
401<params>
402<param>
403<value><struct>
404<member>
405<name>lastname</name>
406<value><string>Tester</string></value>
407</member>
408<member>
409<name>email</name>
410<value><string>aa@aa.ng</string></value>
411</member>
412<member>
413<name>firstname</name>
414<value><string>Anna</string></value>
415</member>
416</struct></value>
417</param>
418</params>
419</methodResponse>
420"""
421        xmlout = self.XMLRPC_post(REQUEST_XML)
422        self.assertEqual(xmlout, RESPONSE_XML)
423        return
424
425    def test_put_student_fingerprints_no_stud(self):
426        # invalid student ids will result in `False`
427        server = ServerProxy('http://mgr:mgrpw@localhost/app')
428        self.assertRaises(
429            xmlrpclib.Fault, server.put_student_fingerprints,
430            'invalid id', {})
431
432    def test_put_student_fingerprints_non_dict(self):
433        # fingerprints must be passed in in a dict
434        server = ServerProxy('http://mgr:mgrpw@localhost/app')
435        self.setup_student(self.student)
436        self.assertRaises(
437            xmlrpclib.Fault, server.put_student_fingerprints,
438            self.student.student_id, 'not-a-dict')
439
440    def test_put_student_fingerprints_non_num_keys_ignored(self):
441        # non-numeric keys in fingerprint dict are ignored
442        server = ServerProxy('http://mgr:mgrpw@localhost/app')
443        self.setup_student(self.student)
444        result = server.put_student_fingerprints(
445            self.student.student_id, {'not-a-num': 'foo',
446                                      '12.2': 'bar',
447                                      '123': 'baz'})
448        self.assertEqual(result, False)
449
450    def test_put_student_fingerprints_non_fpm_data(self):
451        # we cannot pass non-.fpm files as values
452        server = ServerProxy('http://mgr:mgrpw@localhost/app')
453        self.setup_student(self.student)
454        self.assertRaises(
455            xmlrpclib.Fault, server.put_student_fingerprints,
456            self.student.student_id, {'1': 'not-a-fingerprint'})
457
458    def test_put_student_fingerprints_invalid_file_format(self):
459        # invalid files will result in `False`
460        server = ServerProxy('http://mgr:mgrpw@localhost/app')
461        self.setup_student(self.student)
462        invalid_fpm = xmlrpclib.Binary('invalid file')
463        self.assertRaises(
464            xmlrpclib.Fault, server.put_student_fingerprints,
465            self.student.student_id, {'1': invalid_fpm})
466
467    def test_put_student_fingerprints(self):
468        # we can store fingerprints
469        server = ServerProxy('http://mgr:mgrpw@localhost/app')
470        self.setup_student(self.student)
471        fpm = xmlrpclib.Binary('FP1faked_fpm')
472        result = server.put_student_fingerprints(
473            self.student.student_id, {'1': fpm})
474        self.assertEqual(result, True)
475        stored_file = getUtility(IExtFileStore).getFileByContext(
476            self.student, attr="finger1.fpm")
477        self.assertEqual(stored_file.read(), 'FP1faked_fpm')
478        # storing is logged
479        logfile = os.path.join(
480            self.app['datacenter'].storage, 'logs', 'students.log')
481        logcontent = open(logfile).read()
482        self.assertTrue(
483            'zope.mgr - grok.meta.StudentsXMLRPC '
484            '- K1000000 - fingerprint stored' in logcontent)
485
486    def test_put_student_fingerprints_existing(self):
487        # existing fingerprints are overwritten
488        server = ServerProxy('http://mgr:mgrpw@localhost/app')
489        self.setup_student(self.student)
490        self.create_fpm_file(self.student, '1')
491        fpm1 = xmlrpclib.Binary('FP1faked_fpm1')
492        fpm2 = xmlrpclib.Binary('FP1faked_fpm2')
493        result = server.put_student_fingerprints(
494            self.student.student_id, {'1': fpm1, '3': fpm2})
495        self.assertEqual(result, True)
496        stored_file1 = getUtility(IExtFileStore).getFileByContext(
497            self.student, attr="finger1.fpm")
498        stored_file2 = getUtility(IExtFileStore).getFileByContext(
499            self.student, attr="finger3.fpm")
500        self.assertEqual(stored_file1.read(), 'FP1faked_fpm1')
501        self.assertEqual(stored_file2.read(), 'FP1faked_fpm2')
502
503    def test_get_student_fingerprints_no_stud(self):
504        # invalid student ids result in empty dict
505        server = ServerProxy('http://mgr:mgrpw@localhost/app')
506        result = server.get_student_fingerprints('invalid id')
507        self.assertEqual(result, {})
508
509    def test_get_student_fingerprints_no_files(self):
510        # we get student data, but no fingerprints if not stored before
511        server = ServerProxy('http://mgr:mgrpw@localhost/app')
512        self.setup_student(self.student)
513        result = server.get_student_fingerprints(self.student.student_id)
514        self.assertEqual(
515            result,
516            {'lastname': 'Tester',
517             'email': 'aa@aa.ng',
518             'firstname': 'Anna',
519             'fingerprints': {},
520             'img': None,
521             'img_name': None,
522             })
523
524    def test_get_student_fingerprints_passport(self):
525        # we get a photograph of the student if avail.
526        server = ServerProxy('http://mgr:mgrpw@localhost/app')
527        self.setup_student(self.student)
528        self.create_passport_img(self.student)
529        result = server.get_student_fingerprints(self.student.student_id)
530        self.assertTrue(
531            isinstance(result['img'], xmlrpclib.Binary))
532        self.assertEqual(result['img_name'], 'passport_K1000000.jpg')
533
534    def test_get_student_fingerprints_fpm(self):
535        # we get minutiae files if any are avail.
536        server = ServerProxy('http://mgr:mgrpw@localhost/app')
537        self.setup_student(self.student)
538        self.create_fpm_file(self.student, 'finger1')
539        result = server.get_student_fingerprints(self.student.student_id)
540        self.assertTrue('1' in result['fingerprints'].keys())
541        self.assertTrue(
542            isinstance(result['fingerprints']['1'], xmlrpclib.Binary))
543
544    def test_get_student_fingerprints_block_unauthorized(self):
545        # requests from unauthorized users are blocked
546        # no username nor password
547        server = ServerProxy('http://localhost/app')
548        self.setup_student(self.student)
549        stud_id = self.student.student_id
550        self.assertRaises(
551            xmlrpclib.ProtocolError, server.get_student_id, stud_id)
552        # wrong password
553        server = ServerProxy('http://mgr:WRONGPW@localhost/app')
554        self.assertRaises(
555            xmlrpclib.ProtocolError, server.get_student_id, stud_id)
556        # wrong username
557        server = ServerProxy('http://WRONGUSER:mgrpw@localhost/app')
558        self.assertRaises(
559            xmlrpclib.ProtocolError, server.get_student_id, stud_id)
560        return
561
562    def test_get_bursary_data(self):
563        tz = getUtility(IKofaUtils).tzinfo
564        payment1 = StudentOnlinePayment()
565        payment1.p_id = 'my-id1'
566        payment1.p_session = 2012
567        payment1.amount_auth = 12.12
568        payment1.p_state = u'paid'
569        payment1.p_category = u'schoolfee'
570        self.student['payments']['my-payment1'] = payment1
571        payment2 = StudentOnlinePayment()
572        payment2.p_id = 'my-id2'
573        payment2.p_session = 2012
574        payment2.amount_auth = 12.12
575        payment2.p_state = u'paid'
576        payment2.p_category = u'clearance'
577        self.student['payments']['my-payment2'] = payment2
578        server = ServerProxy('http://mgr:mgrpw@localhost/app', allow_none=True)
579        result = server.get_bursary_data(None,None,None,None,'dep1')
580        self.assertEqual(
581            result,[
582            {'entry_mode': None, 'reg_number': '123', 'display_item': None,
583                'firstname': 'Anna', 'payment_date': 'None#',
584                'middlename': None, 'student_id': 'K1000000', 'p_id':
585                'my-id1', 'certcode': 'CERT1', 'entry_session': 2004,
586                'creation_date': str('%s#' % to_timezone(payment1.creation_date, tz)),
587                'state': 'created', 'current_session': 2004,
588                'faccode': 'fac1', 'lastname': 'Tester',
589                'p_category': 'schoolfee', 'amount_auth': 12.12,
590                'p_state': 'paid', 'p_session': 2012, 'matric_number': '234',
591                'depcode': 'dep1'},
592            {'entry_mode': None, 'reg_number': '123', 'display_item': None,
593                'firstname': 'Anna', 'payment_date': 'None#',
594                'middlename': None, 'student_id': 'K1000000',
595                'p_id': 'my-id2', 'certcode': 'CERT1', 'entry_session': 2004,
596                'creation_date': str('%s#' % to_timezone(payment2.creation_date, tz)),
597                'state': 'created', 'current_session': 2004, 'faccode': 'fac1',
598                'lastname': 'Tester', 'p_category': 'clearance',
599                'amount_auth': 12.12, 'p_state': 'paid', 'p_session': 2012,
600                'matric_number': '234', 'depcode': 'dep1'}
601            ]
602            )
603
604        REQUEST_XML = """\
605<?xml version="1.0"?>
606<methodCall>
607<methodName>get_bursary_data</methodName>
608<params>
609<param>
610<value><string></string></value>
611<value><string></string></value>
612<value><string></string></value>
613<value><string></string></value>
614<value><string>dep1</string></value>
615</param>
616</params>
617</methodCall>"""
618        RESPONSE_XML = """\
619<?xml version='1.0'?>
620<methodResponse>
621<params>
622<param>
623<value><array><data>
624<value><struct>
625<member>
626<name>entry_mode</name>
627<value><nil/></value></member>
628<member>
629<name>reg_number</name>
630<value><string>123</string></value>
631</member>
632<member>
633<name>display_item</name>
634<value><nil/></value></member>
635<member>
636<name>firstname</name>
637<value><string>Anna</string></value>
638</member>
639<member>
640<name>payment_date</name>
641<value><string>None#</string></value>
642</member>
643<member>
644<name>middlename</name>
645<value><nil/></value></member>
646<member>
647<name>student_id</name>
648<value><string>K1000000</string></value>
649</member>
650<member>
651<name>p_id</name>
652<value><string>my-id1</string></value>
653</member>
654<member>
655<name>certcode</name>
656<value><string>CERT1</string></value>
657</member>
658<member>
659<name>creation_date</name>
660<value><string>%s</string></value>
661</member>
662<member>
663<name>matric_number</name>
664<value><string>234</string></value>
665</member>
666<member>
667<name>state</name>
668<value><string>created</string></value>
669</member>
670<member>
671<name>lastname</name>
672<value><string>Tester</string></value>
673</member>
674<member>
675<name>current_session</name>
676<value><int>2004</int></value>
677</member>
678<member>
679<name>faccode</name>
680<value><string>fac1</string></value>
681</member>
682<member>
683<name>entry_session</name>
684<value><int>2004</int></value>
685</member>
686<member>
687<name>p_category</name>
688<value><string>schoolfee</string></value>
689</member>
690<member>
691<name>amount_auth</name>
692<value><double>12.12</double></value>
693</member>
694<member>
695<name>p_session</name>
696<value><int>2012</int></value>
697</member>
698<member>
699<name>p_state</name>
700<value><string>paid</string></value>
701</member>
702<member>
703<name>depcode</name>
704<value><string>dep1</string></value>
705</member>
706</struct></value>
707<value><struct>
708<member>
709<name>entry_mode</name>
710<value><nil/></value></member>
711<member>
712<name>reg_number</name>
713<value><string>123</string></value>
714</member>
715<member>
716<name>display_item</name>
717<value><nil/></value></member>
718<member>
719<name>firstname</name>
720<value><string>Anna</string></value>
721</member>
722<member>
723<name>payment_date</name>
724<value><string>None#</string></value>
725</member>
726<member>
727<name>middlename</name>
728<value><nil/></value></member>
729<member>
730<name>student_id</name>
731<value><string>K1000000</string></value>
732</member>
733<member>
734<name>p_id</name>
735<value><string>my-id2</string></value>
736</member>
737<member>
738<name>certcode</name>
739<value><string>CERT1</string></value>
740</member>
741<member>
742<name>creation_date</name>
743<value><string>%s</string></value>
744</member>
745<member>
746<name>matric_number</name>
747<value><string>234</string></value>
748</member>
749<member>
750<name>state</name>
751<value><string>created</string></value>
752</member>
753<member>
754<name>lastname</name>
755<value><string>Tester</string></value>
756</member>
757<member>
758<name>current_session</name>
759<value><int>2004</int></value>
760</member>
761<member>
762<name>faccode</name>
763<value><string>fac1</string></value>
764</member>
765<member>
766<name>entry_session</name>
767<value><int>2004</int></value>
768</member>
769<member>
770<name>p_category</name>
771<value><string>clearance</string></value>
772</member>
773<member>
774<name>amount_auth</name>
775<value><double>12.12</double></value>
776</member>
777<member>
778<name>p_session</name>
779<value><int>2012</int></value>
780</member>
781<member>
782<name>p_state</name>
783<value><string>paid</string></value>
784</member>
785<member>
786<name>depcode</name>
787<value><string>dep1</string></value>
788</member>
789</struct></value>
790</data></array></value>
791</param>
792</params>
793</methodResponse>
794"""
795        xmlout = self.XMLRPC_post(REQUEST_XML)
796        response = RESPONSE_XML % (str('%s#' % to_timezone(payment1.creation_date, tz)),
797                                   str('%s#' % to_timezone(payment2.creation_date, tz))
798                                   )
799        self.assertEqual(xmlout, response)
800        return
Note: See TracBrowser for help on using the repository browser.