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

Last change on this file since 16058 was 15811, checked in by Henrik Bettermann, 5 years ago

Return array of structs and not array of arrays.

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