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

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

Add webservice to check if graduated student exists.

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