def testWithoutLogging(self): self.sruRecordUpdate = SruRecordUpdate(stderr=self.stderr, logErrors=True, enableCollectLog=False) self.sruRecordUpdate.addObserver(self.observer) requestBody = self.createRequestBody( recordData='<my:data xmlns:my="mine">data</my:data> ') headers, result = self.performRequest(requestBody) self.assertTrue( '<ucp:operationStatus>success</ucp:operationStatus>' in result) self.assertEquals(dict(), self.logCollector)
def testWithoutLogging(self): self.sruRecordUpdate = SruRecordUpdate(stderr=self.stderr, logErrors=True, enableCollectLog=False) self.sruRecordUpdate.addObserver(self.observer) requestBody = self.createRequestBody(recordData='<my:data xmlns:my="mine">data</my:data> ') headers, result = self.performRequest(requestBody) self.assertTrue('<ucp:operationStatus>success</ucp:operationStatus>' in result) self.assertEquals(dict(), self.logCollector)
def setUp(self): SeecrTestCase.setUp(self) self.stderr = StringIO() self.sruRecordUpdate = SruRecordUpdate(stderr=self.stderr, logErrors=True, enableCollectLog=True) @asyncnoreturnvalue def addOrDelete(*args, **kwargs): pass self.observer = CallTrace("Observer", methods={ 'add': addOrDelete, 'delete': addOrDelete }) self.sruRecordUpdate.addObserver(self.observer)
def setUp(self): SeecrTestCase.setUp(self) self.stderr = StringIO() self.sruRecordUpdate = SruRecordUpdate(stderr=self.stderr, logErrors=True, enableCollectLog=True) @asyncnoreturnvalue def addOrDelete(*args, **kwargs): pass self.observer = CallTrace("Observer", methods={'add': addOrDelete, 'delete': addOrDelete}) self.sruRecordUpdate.addObserver(self.observer)
class SruRecordUpdateTest(SeecrTestCase): """http://www.loc.gov/standards/sru/record-update/""" def setUp(self): SeecrTestCase.setUp(self) self.stderr = StringIO() self.sruRecordUpdate = SruRecordUpdate(stderr=self.stderr, logErrors=True, enableCollectLog=True) @asyncnoreturnvalue def addOrDelete(*args, **kwargs): pass self.observer = CallTrace("Observer", methods={ 'add': addOrDelete, 'delete': addOrDelete }) self.sruRecordUpdate.addObserver(self.observer) def createRequestBody(self, action=CREATE, recordIdentifier="123", recordData="<dc>empty</dc>"): return UPDATE_REQUEST % { "action": action, "recordIdentifier": recordIdentifier, "recordPacking": "text/xml", "recordSchema": "irrelevantXML", "recordData": recordData, } def performRequest(self, requestBody): __callstack_var_logCollector__ = self.logCollector = dict() result = ''.join( compose(self.sruRecordUpdate.handleRequest(Body=requestBody))) return result.split('\r\n\r\n') def testAddXML(self): requestBody = self.createRequestBody( recordData='<my:data xmlns:my="mine">data</my:data> ') headers, result = self.performRequest(requestBody) self.assertEqualsWS( """<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", result) self.assertEquals(1, len(self.observer.calledMethods)) method = self.observer.calledMethods[0] self.assertEquals(3, len(method.kwargs)) self.assertEquals("add", method.name) self.assertEquals("123", method.kwargs['identifier']) self.assertEquals(str, type(method.kwargs['identifier'])) self.assertEquals("irrelevantXML", method.kwargs['partname']) resultNode = method.kwargs['lxmlNode'] self.assertEqualsLxml(XML('<my:data xmlns:my="mine">data</my:data>'), resultNode) self.assertEquals(['data'], resultNode.xpath('/my:data/text()', namespaces={'my': 'mine'})) self.assertEquals(ElementTreeType, type(resultNode)) self.assertEquals(None, resultNode.getroot().tail) def testWithoutLogging(self): self.sruRecordUpdate = SruRecordUpdate(stderr=self.stderr, logErrors=True, enableCollectLog=False) self.sruRecordUpdate.addObserver(self.observer) requestBody = self.createRequestBody( recordData='<my:data xmlns:my="mine">data</my:data> ') headers, result = self.performRequest(requestBody) self.assertTrue( '<ucp:operationStatus>success</ucp:operationStatus>' in result) self.assertEquals(dict(), self.logCollector) def testDelete(self): requestBody = self.createRequestBody(action=DELETE) headers, result = self.performRequest(requestBody) self.assertEqualsWS( """<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", result) self.assertEquals(1, len(self.observer.calledMethods)) method = self.observer.calledMethods[0] self.assertEquals("delete", method.name) def testReplaceIsAdd(self): requestBody = self.createRequestBody(action=REPLACE) headers, result = self.performRequest(requestBody) self.assertEqualsWS( """<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", result) self.assertEquals(1, len(self.observer.calledMethods)) method = self.observer.calledMethods[0] self.assertEquals("add", method.name) def testAddXMLWithUcpUpdateRequest(self): """It is not entirely sure if updateRequest is in the 'srw' or 'ucp' namespace. We now assume it is in 'srw', but versions of meresco-harvester use 'ucp'. We will accept both. """ requestBody = self.createRequestBody() requestBody = requestBody.replace('srw:updateRequest', 'ucp:updateRequest') headers, result = self.performRequest(requestBody) self.assertEqualsWS( """<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", result) self.assertEquals(['add'], self.observer.calledMethodNames()) def testPassCallableObjectForAdd(self): def callable(): pass self.observer.returnValues['add'] = (f for f in [callable]) requestBody = self.createRequestBody(action=REPLACE) __callstack_var_logCollector__ = defaultdict(list) result = list( compose(self.sruRecordUpdate.handleRequest(Body=requestBody))) self.assertTrue(callable in result) result.remove(callable) header, body = (''.join(result)).split('\r\n\r\n') self.assertEqualsWS( """<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", body) def testPassCallableObjectForDelete(self): def callable(): pass self.observer.returnValues['delete'] = (f for f in [callable]) requestBody = self.createRequestBody(action=DELETE) __callstack_var_logCollector__ = defaultdict(list) result = list( compose(self.sruRecordUpdate.handleRequest(Body=requestBody))) self.assertTrue(callable in result) result.remove(callable) header, body = (''.join(result)).split('\r\n\r\n') self.assertEqualsWS( """<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", body) def testNotCorrectXml(self): headers, result = self.performRequest("not_xml") self.assertTrue( '<ucp:operationStatus>fail</ucp:operationStatus>' in result, result) self.assertEquals(0, len(self.observer.calledMethods)) self.assertTrue('XMLSyntaxError' in self.stderr.getvalue(), self.stderr.getvalue()) def testErrorsAreNotPassed(self): self.observer.exceptions['add'] = Exception('Some <Exception>') headers, result = self.performRequest(self.createRequestBody()) self.assertTrue( """<ucp:operationStatus>fail</ucp:operationStatus>""" in result, result) diag = parse(StringIO(result)) self.assertTrue( "Some <Exception>" in xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:details/text()' ), result) def testValidationErrors(self): self.observer.exceptions['add'] = ValidateException('Some <Exception>') headers, result = self.performRequest(self.createRequestBody()) self.assertTrue( """<ucp:operationStatus>fail</ucp:operationStatus>""" in result, result) diag = parse(StringIO(result)) self.assertEquals( "info:srw/diagnostic/12/12", xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:uri/text()' )) self.assertEquals( "Some <Exception>", xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:details/text()' )) self.assertEquals( "Invalid data: record rejected", xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:message/text()' )) def testEmptyIdentifierNotAccepted(self): requestBody = self.createRequestBody(recordIdentifier="") headers, result = self.performRequest(requestBody) self.assertTrue( """<ucp:operationStatus>fail</ucp:operationStatus>""" in result, result) diag = parse(StringIO(result)) self.assertEquals( "info:srw/diagnostic/12/1", xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:uri/text()' )) self.assertTrue( "recordIdentifier is mandatory." in xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:details/text()' ), result) self.assertTrue( "Invalid component: record rejected" in xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:message/text()' ), result) def testNoIdentifierNotAccepted(self): requestBody = """<?xml version="1.0" encoding="UTF-8"?> <srw:updateRequest xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:action>info:srw/action/1/%(action)s</ucp:action> <srw:record> <srw:recordPacking>xml</srw:recordPacking> <srw:recordSchema>ascheme</srw:recordSchema> <srw:recordData>some data</srw:recordData> </srw:record> </srw:updateRequest>""" headers, result = self.performRequest(requestBody) self.assertTrue( """<ucp:operationStatus>fail</ucp:operationStatus>""" in result, result) diag = parse(StringIO(result)) self.assertEquals( "info:srw/diagnostic/12/1", xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:uri/text()' )) self.assertTrue( "recordIdentifier is mandatory." in xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:details/text()' ), result) self.assertEquals( "Invalid component: record rejected", xpathFirst( diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:message/text()' )) def testCollectLog(self): requestBody = self.createRequestBody(action=DELETE, recordIdentifier='idDelete') headers, result = self.performRequest(requestBody) self.assertEquals(dict(sruRecordUpdate=dict(delete=['idDelete'])), self.logCollector) requestBody = self.createRequestBody(action=CREATE, recordIdentifier='idAdd') headers, result = self.performRequest(requestBody) self.assertEquals(dict(sruRecordUpdate=dict(add=['idAdd'])), self.logCollector) def testCollectLogWithErrors(self): self.observer.exceptions['delete'] = Exception('Some <Exception>') requestBody = self.createRequestBody(action=DELETE, recordIdentifier='idDelete') headers, result = self.performRequest(requestBody) self.assertEquals( dict(sruRecordUpdate=dict(delete=['idDelete'], errorType=['Exception'], errorMessage=["Some <Exception>"])), self.logCollector) self.observer.exceptions['add'] = ValidateException('Nee') requestBody = self.createRequestBody(action=CREATE, recordIdentifier='idAdd') headers, result = self.performRequest(requestBody) self.assertEquals( dict(sruRecordUpdate=dict(add=['idAdd'], invalid=['idAdd'], errorType=['ValidateException'], errorMessage=["Nee"])), self.logCollector) headers, result = self.performRequest( '<srw:updateRequest>Will raise XMLSyntaxError') sru_error = self.logCollector['sruRecordUpdate'] self.assertEqual(['XMLSyntaxError'], sru_error['errorType']) self.assertTrue(sru_error['errorMessage'][0].startswith( 'Namespace prefix srw on updateRequest is not defined, line 1, column 19' ))
def initSruRecordUpdate(self, **kwargs): self.sruRecordUpdate = SruRecordUpdate(**kwargs) self.observer = CallTrace( "Observer", emptyGeneratorMethods=['add', 'delete', 'deleteRecord']) self.sruRecordUpdate.addObserver(self.observer)
def initSruRecordUpdate(self, **kwargs): self.sruRecordUpdate = SruRecordUpdate(**kwargs) self.observer = CallTrace("Observer", emptyGeneratorMethods=['add', 'delete', 'deleteRecord']) self.sruRecordUpdate.addObserver(self.observer)
class SruRecordUpdateTest(SeecrTestCase): """http://www.loc.gov/standards/sru/record-update/""" def setUp(self): SeecrTestCase.setUp(self) self.stderr = StringIO() self.initSruRecordUpdate(stderr=self.stderr, logErrors=True, enableCollectLog=True) def initSruRecordUpdate(self, **kwargs): self.sruRecordUpdate = SruRecordUpdate(**kwargs) self.observer = CallTrace("Observer", emptyGeneratorMethods=['add', 'delete', 'deleteRecord']) self.sruRecordUpdate.addObserver(self.observer) def createRequestBody(self, action=CREATE, recordIdentifier="123", recordData="<dc>empty</dc>"): return UPDATE_REQUEST% { "action": action, "recordIdentifier": recordIdentifier, "recordPacking": "text/xml", "recordSchema": "irrelevantXML", "recordData": recordData, } def performRequest(self, requestBody): __callstack_var_logCollector__ = self.logCollector = dict() result = ''.join(compose(self.sruRecordUpdate.handleRequest(Body=requestBody))) return result.split('\r\n\r\n') def testAddXML(self): requestBody = self.createRequestBody(recordData='<my:data xmlns:my="mine">data</my:data> ') headers, result = self.performRequest(requestBody) self.assertEqualsWS("""<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", result) self.assertEquals(1, len(self.observer.calledMethods)) method = self.observer.calledMethods[0] self.assertEquals(3, len(method.kwargs)) self.assertEquals("add", method.name) self.assertEquals("123", method.kwargs['identifier']) self.assertEquals(str, type(method.kwargs['identifier'])) self.assertEquals("irrelevantXML", method.kwargs['partname']) resultNode = method.kwargs['lxmlNode'] self.assertEqualsLxml(XML('<my:data xmlns:my="mine">data</my:data>'), resultNode) self.assertEquals(['data'], resultNode.xpath('/my:data/text()', namespaces={'my':'mine'})) self.assertEquals(ElementTreeType, type(resultNode)) self.assertEquals(None, resultNode.getroot().tail) def testWithoutLogging(self): self.sruRecordUpdate = SruRecordUpdate(stderr=self.stderr, logErrors=True, enableCollectLog=False) self.sruRecordUpdate.addObserver(self.observer) requestBody = self.createRequestBody(recordData='<my:data xmlns:my="mine">data</my:data> ') headers, result = self.performRequest(requestBody) self.assertTrue('<ucp:operationStatus>success</ucp:operationStatus>' in result) self.assertEquals(dict(), self.logCollector) def testDelete(self): requestBody = self.createRequestBody(action=DELETE) headers, result = self.performRequest(requestBody) self.assertEqualsWS("""<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", result) self.assertEquals(1, len(self.observer.calledMethods)) method = self.observer.calledMethods[0] self.assertEquals("delete", method.name) def testReplaceIsAdd(self): requestBody = self.createRequestBody(action=REPLACE) headers, result = self.performRequest(requestBody) self.assertEqualsWS("""<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", result) self.assertEquals(1, len(self.observer.calledMethods)) method = self.observer.calledMethods[0] self.assertEquals("add", method.name) def testDeleteRecord(self): self.initSruRecordUpdate(stderr=self.stderr, logErrors=True, enableCollectLog=True, supportDeleteRecord=True) requestBody = self.createRequestBody(action=DELETE) headers, result = self.performRequest(requestBody) self.assertEqualsWS("""<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", result) self.assertEquals(1, len(self.observer.calledMethods)) method = self.observer.calledMethods[0] self.assertEquals("deleteRecord", method.name) self.assertEqual('123', method.kwargs['identifier']) self.assertEqualsWS('''<srw:record xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:recordPacking>text/xml</srw:recordPacking> <srw:recordSchema>irrelevantXML</srw:recordSchema> <srw:recordData><dc>empty</dc></srw:recordData> </srw:record>''', lxmltostring(method.kwargs['record'])) def testAddXMLWithUcpUpdateRequest(self): """It is not entirely sure if updateRequest is in the 'srw' or 'ucp' namespace. We now assume it is in 'srw', but versions of meresco-harvester use 'ucp'. We will accept both. """ requestBody = self.createRequestBody() requestBody = requestBody.replace('srw:updateRequest', 'ucp:updateRequest') headers, result = self.performRequest(requestBody) self.assertEqualsWS("""<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", result) self.assertEquals(['add'], self.observer.calledMethodNames()) def testPassCallableObjectForAdd(self): def callable(): pass self.observer.returnValues['add'] = (f for f in [callable]) requestBody = self.createRequestBody(action=REPLACE) __callstack_var_logCollector__ = defaultdict(list) result = list(compose(self.sruRecordUpdate.handleRequest(Body=requestBody))) self.assertTrue(callable in result) result.remove(callable) header,body = (''.join(result)).split('\r\n\r\n') self.assertEqualsWS("""<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", body) def testPassCallableObjectForDelete(self): def callable(): pass self.observer.returnValues['delete'] = (f for f in [callable]) requestBody = self.createRequestBody(action=DELETE) __callstack_var_logCollector__ = defaultdict(list) result = list(compose(self.sruRecordUpdate.handleRequest(Body=requestBody))) self.assertTrue(callable in result) result.remove(callable) header,body = (''.join(result)).split('\r\n\r\n') self.assertEqualsWS("""<?xml version="1.0" encoding="UTF-8"?> <srw:updateResponse xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:operationStatus>success</ucp:operationStatus> </srw:updateResponse>""", body) def testNotCorrectXml(self): headers, result = self.performRequest("not_xml") self.assertTrue('<ucp:operationStatus>fail</ucp:operationStatus>' in result, result) self.assertEquals(0, len(self.observer.calledMethods)) self.assertTrue('XMLSyntaxError' in self.stderr.getvalue(), self.stderr.getvalue()) def testErrorsAreNotPassed(self): self.observer.exceptions['add'] = Exception('Some <Exception>') headers, result = self.performRequest(self.createRequestBody()) self.assertTrue("""<ucp:operationStatus>fail</ucp:operationStatus>""" in result, result) diag = parse(StringIO(result)) self.assertTrue("Some <Exception>" in xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:details/text()'), result) def testValidationErrors(self): self.observer.exceptions['add'] = ValidateException('Some <Exception>') headers, result = self.performRequest(self.createRequestBody()) self.assertTrue("""<ucp:operationStatus>fail</ucp:operationStatus>""" in result, result) diag = parse(StringIO(result)) self.assertEquals("info:srw/diagnostic/12/12", xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:uri/text()')) self.assertEquals("Some <Exception>", xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:details/text()')) self.assertEquals("Invalid data: record rejected", xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:message/text()')) def testEmptyIdentifierNotAccepted(self): requestBody = self.createRequestBody(recordIdentifier="") headers, result = self.performRequest(requestBody) self.assertTrue("""<ucp:operationStatus>fail</ucp:operationStatus>""" in result, result) diag = parse(StringIO(result)) self.assertEquals("info:srw/diagnostic/12/1", xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:uri/text()')) self.assertTrue("recordIdentifier is mandatory." in xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:details/text()'), result) self.assertTrue("Invalid component: record rejected" in xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:message/text()'), result) def testNoIdentifierNotAccepted(self): requestBody = """<?xml version="1.0" encoding="UTF-8"?> <srw:updateRequest xmlns:srw="http://www.loc.gov/zing/srw/" xmlns:ucp="info:lc/xmlns/update-v1"> <srw:version>1.0</srw:version> <ucp:action>info:srw/action/1/%(action)s</ucp:action> <srw:record> <srw:recordPacking>xml</srw:recordPacking> <srw:recordSchema>ascheme</srw:recordSchema> <srw:recordData>some data</srw:recordData> </srw:record> </srw:updateRequest>""" headers, result = self.performRequest(requestBody) self.assertTrue("""<ucp:operationStatus>fail</ucp:operationStatus>""" in result, result) diag = parse(StringIO(result)) self.assertEquals("info:srw/diagnostic/12/1", xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:uri/text()')) self.assertTrue("recordIdentifier is mandatory." in xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:details/text()'), result) self.assertEquals("Invalid component: record rejected", xpathFirst(diag, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:message/text()')) def testCollectLog(self): requestBody = self.createRequestBody(action=DELETE, recordIdentifier='idDelete') headers, result = self.performRequest(requestBody) self.assertEquals(dict(sruRecordUpdate=dict(delete=['idDelete'])), self.logCollector) requestBody = self.createRequestBody(action=CREATE, recordIdentifier='idAdd') headers, result = self.performRequest(requestBody) self.assertEquals(dict(sruRecordUpdate=dict(add=['idAdd'])), self.logCollector) def testCollectLogWithErrors(self): self.observer.exceptions['delete'] = Exception('Some <Exception>') requestBody = self.createRequestBody(action=DELETE, recordIdentifier='idDelete') headers, result = self.performRequest(requestBody) self.assertEquals(dict( sruRecordUpdate=dict( delete=['idDelete'], errorType=['Exception'], errorMessage=["Some <Exception>"] )), self.logCollector) self.observer.exceptions['add'] = ValidateException('Nee') requestBody = self.createRequestBody(action=CREATE, recordIdentifier='idAdd') headers, result = self.performRequest(requestBody) self.assertEquals(dict( sruRecordUpdate=dict( add=['idAdd'], invalid=['idAdd'], errorType=['ValidateException'], errorMessage=["Nee"] )), self.logCollector) headers, result = self.performRequest('<srw:updateRequest>Will raise XMLSyntaxError') sru_error = self.logCollector['sruRecordUpdate'] self.assertEqual(['XMLSyntaxError'], sru_error['errorType']) self.assertTrue(sru_error['errorMessage'][0].startswith('Namespace prefix srw on updateRequest is not defined, line 1, column 19'))