def testValidXml(self):
        component = SruParser()
        sruHandler = SruHandler()
        component.addObserver(sruHandler)
        observer = CallTrace('observer')
        sruHandler.addObserver(observer)
        response = Response(total=2, hits=[Hit('id0'), Hit('id1')])
        def executeQuery(**kwargs):
            raise StopIteration(response)
            yield
        def retrieveData(**kwargs):
            raise StopIteration('<bike/>')
            yield
        observer.methods['executeQuery'] = executeQuery
        observer.returnValues['echoedExtraRequestData'] = (f for f in [])
        observer.returnValues['extraResponseData'] = (f for f in [])
        observer.methods['extraRecordData'] = lambda hit: (f for f in [])
        observer.methods['retrieveData'] = retrieveData

        result = ''.join(compose(component.handleRequest(arguments={'version':['1.1'], 'query': ['aQuery'], 'operation':['searchRetrieve']})))
        header, body = result.split('\r\n'*2)
        assertValid(body, join(schemasPath, 'srw-types1.2.xsd'))
        self.assertTrue('<bike/>' in body, body)

        result = ''.join(compose(component.handleRequest(arguments={'version':['1.1'], 'operation':['searchRetrieve']})))
        header, body = result.split('\r\n'*2)
        assertValid(body, join(schemasPath, 'srw-types1.2.xsd'))
        self.assertTrue('diagnostic' in body, body)
    def testExplainWithoutPresetValues(self):
        component = SruParser()

        result = "".join(compose(component.handleRequest(arguments={'operation': ['explain'], 'version': ['1.2']}, Headers={'Host': '1.2.3.4:8080'}, RequestURI="/sru?operation=explain&version=1.2")))
        self.assertEqualsWS("""HTTP/1.0 200 OK
Content-Type: text/xml; charset=utf-8

<?xml version="1.0" encoding="UTF-8"?>
<srw:explainResponse xmlns:srw="http://www.loc.gov/zing/srw/"
xmlns:zr="http://explain.z3950.org/dtd/2.0/">
<srw:version>1.2</srw:version>
<srw:record>
    <srw:recordPacking>xml</srw:recordPacking>
    <srw:recordSchema>http://explain.z3950.org/dtd/2.0/</srw:recordSchema>
    <srw:recordData>
        <zr:explain>
            <zr:serverInfo protocol="SRU" version="1.2">
                <zr:host>1.2.3.4</zr:host>
                <zr:port>8080</zr:port>
                <zr:database>sru</zr:database>
            </zr:serverInfo>
            <zr:databaseInfo>
                <zr:title lang="en" primary="true">SRU Database</zr:title>
                <zr:description lang="en" primary="true">Meresco SRU</zr:description>
            </zr:databaseInfo>
        </zr:explain>
    </srw:recordData>
</srw:record>
</srw:explainResponse>
""", result)
    def testExplainWithPresetValues(self):
        component = SruParser(host='TEST_SERVER_HOST', port='TEST_SERVER_PORT', description='TEST_SERVER_DESCRIPTION', modifiedDate='TEST_SERVER_DATE', database='DATABASE', wsdl='http://somewhe.re/wsdl')

        result = "".join(compose(component.handleRequest(arguments={}, Headers={'Host': '1.2.3.4:80'}, RequestURI="/sru")))
        self.assertEqualsWS("""HTTP/1.0 200 OK
Content-Type: text/xml; charset=utf-8

<?xml version="1.0" encoding="UTF-8"?>
<srw:explainResponse xmlns:srw="http://www.loc.gov/zing/srw/"
xmlns:zr="http://explain.z3950.org/dtd/2.0/">
<srw:version>1.1</srw:version>
<srw:record>
    <srw:recordPacking>xml</srw:recordPacking>
    <srw:recordSchema>http://explain.z3950.org/dtd/2.0/</srw:recordSchema>
    <srw:recordData>
        <zr:explain>
            <zr:serverInfo wsdl="http://somewhe.re/wsdl" protocol="SRU" version="1.1">
                <zr:host>TEST_SERVER_HOST</zr:host>
                <zr:port>TEST_SERVER_PORT</zr:port>
                <zr:database>DATABASE</zr:database>
            </zr:serverInfo>
            <zr:databaseInfo>
                <zr:title lang="en" primary="true">SRU Database</zr:title>
                <zr:description lang="en" primary="true">TEST_SERVER_DESCRIPTION</zr:description>
            </zr:databaseInfo>
            <zr:metaInfo>
                <zr:dateModified>TEST_SERVER_DATE</zr:dateModified>
            </zr:metaInfo>
        </zr:explain>
    </srw:recordData>
</srw:record>
</srw:explainResponse>
""", result)
    def testSearchRetrieve(self):
        component = SruParser()
        sruHandler = CallTrace('SRUHandler')
        sruHandler.returnValues['searchRetrieve'] = (
            x for x in ["<result>mock result XML</result>"])
        component.addObserver(sruHandler)

        response = "".join(
            compose(
                component.handleRequest(
                    arguments=dict(version=['1.1'],
                                   query=['aQuery'],
                                   operation=['searchRetrieve'],
                                   startRecord=['11'],
                                   maximumRecords=['15'],
                                   sortKeys=['aField,,1']))))

        self.assertEqual(['searchRetrieve'],
                         [m.name for m in sruHandler.calledMethods])
        self.assertEqual((), sruHandler.calledMethods[0].args)
        kwargs = sruHandler.calledMethods[0].kwargs
        self.assertEqual('1.1', kwargs['version'])
        self.assertEqual('aQuery', kwargs['query'])
        self.assertEqual('searchRetrieve', kwargs['operation'])
        self.assertEqual(11, kwargs['startRecord'])
        self.assertEqual(15, kwargs['maximumRecords'])
        self.assertEqual('aQuery', kwargs['sruArguments']['query'])
        self.assertEqual(['aField,,1'], kwargs['sruArguments']['sortKeys'])

        self.assertTrue("HTTP/1.0 200 OK" in response)
        self.assertTrue(XML_HEADER in response)
    def testSetAttribute(self):
        parser = SruParser(defaultRecordSchema='default')
        sruHandler = CallTrace('SRUHandler')
        def searchRetrieve(**kwargs):
            yield '<mockresult/>'
        sruHandler.methods['searchRetrieve'] = searchRetrieve
        parser.addObserver(sruHandler)

        consume(parser.handleRequest(arguments={'version':['1.1'], 'query': ['aQuery'], 'operation':['searchRetrieve']}))

        self.assertEqual(['searchRetrieve'], sruHandler.calledMethodNames())
        self.assertEqual('default', sruHandler.calledMethods[0].kwargs['recordSchema'])
        self.assertEqual('xml', sruHandler.calledMethods[0].kwargs['recordPacking'])
        sruHandler.calledMethods.reset()

        parser.setAttribute('defaultRecordSchema', 'newDefault')
        parser.setAttribute('defaultRecordPacking', 'string')
        consume(parser.handleRequest(arguments={'version':['1.1'], 'query': ['aQuery'], 'operation':['searchRetrieve']}))
        self.assertEqual('newDefault', sruHandler.calledMethods[0].kwargs['recordSchema'])
        self.assertEqual('string', sruHandler.calledMethods[0].kwargs['recordPacking'])
 def assertSortKeys(expectedSortedDescending, sortKeys, oldAndWrongStyleSortKeys):
     component = SruParser(oldAndWrongStyleSortKeys=oldAndWrongStyleSortKeys)
     sruHandler = CallTrace('SRUHandler', emptyGeneratorMethods=['searchRetrieve'])
     component.addObserver(sruHandler)
     response = "".join(compose(component.handleRequest(arguments=dict(
         version=['1.1'],
         query= ['aQuery'],
         operation=['searchRetrieve'],
         sortKeys=[sortKeys]))))
     kwargs = sruHandler.calledMethods[0].kwargs
     self.assertEquals([{'sortBy': 'aField', 'sortDescending': expectedSortedDescending}], kwargs['sortKeys'])
    def testSearchRetrieveWithXParameter(self):
        component = SruParser()
        sruHandler = CallTrace('SRUHandler')
        sruHandler.returnValues['searchRetrieve'] = (x for x in ["<result>mock result XML</result>"])
        component.addObserver(sruHandler)

        list(compose(component.handleRequest(arguments={'version':['1.1'], 'query': ['aQuery'], 'operation':['searchRetrieve'], 'x-something':['something']})))

        self.assertEquals(['searchRetrieve'], [m.name for m in sruHandler.calledMethods])
        self.assertEquals((), sruHandler.calledMethods[0].args)
        kwargs = sruHandler.calledMethods[0].kwargs
        self.assertEquals(['something'], kwargs['sruArguments']['x-something'])
    def testSetAttribute(self):
        parser = SruParser(defaultRecordSchema='default')
        sruHandler = CallTrace('SRUHandler')

        def searchRetrieve(**kwargs):
            yield '<mockresult/>'

        sruHandler.methods['searchRetrieve'] = searchRetrieve
        parser.addObserver(sruHandler)

        consume(
            parser.handleRequest(
                arguments={
                    'version': ['1.1'],
                    'query': ['aQuery'],
                    'operation': ['searchRetrieve']
                }))

        self.assertEqual(['searchRetrieve'], sruHandler.calledMethodNames())
        self.assertEqual('default',
                         sruHandler.calledMethods[0].kwargs['recordSchema'])
        self.assertEqual('xml',
                         sruHandler.calledMethods[0].kwargs['recordPacking'])
        sruHandler.calledMethods.reset()

        parser.setAttribute('defaultRecordSchema', 'newDefault')
        parser.setAttribute('defaultRecordPacking', 'string')
        consume(
            parser.handleRequest(
                arguments={
                    'version': ['1.1'],
                    'query': ['aQuery'],
                    'operation': ['searchRetrieve']
                }))
        self.assertEqual('newDefault',
                         sruHandler.calledMethods[0].kwargs['recordSchema'])
        self.assertEqual('string',
                         sruHandler.calledMethods[0].kwargs['recordPacking'])
    def testExplainWithPresetValues(self):
        component = SruParser(host='TEST_SERVER_HOST',
                              port='TEST_SERVER_PORT',
                              description='TEST_SERVER_DESCRIPTION',
                              modifiedDate='TEST_SERVER_DATE',
                              database='DATABASE',
                              wsdl='http://somewhe.re/wsdl')

        result = "".join(
            compose(
                component.handleRequest(arguments={},
                                        Headers={'Host': '1.2.3.4:80'},
                                        RequestURI="/sru")))
        self.assertEqualsWS(
            """HTTP/1.0 200 OK
Content-Type: text/xml; charset=utf-8

<?xml version="1.0" encoding="UTF-8"?>
<srw:explainResponse xmlns:srw="http://www.loc.gov/zing/srw/"
xmlns:zr="http://explain.z3950.org/dtd/2.0/">
<srw:version>1.1</srw:version>
<srw:record>
    <srw:recordPacking>xml</srw:recordPacking>
    <srw:recordSchema>http://explain.z3950.org/dtd/2.0/</srw:recordSchema>
    <srw:recordData>
        <zr:explain>
            <zr:serverInfo wsdl="http://somewhe.re/wsdl" protocol="SRU" version="1.1">
                <zr:host>TEST_SERVER_HOST</zr:host>
                <zr:port>TEST_SERVER_PORT</zr:port>
                <zr:database>DATABASE</zr:database>
            </zr:serverInfo>
            <zr:databaseInfo>
                <zr:title lang="en" primary="true">SRU Database</zr:title>
                <zr:description lang="en" primary="true">TEST_SERVER_DESCRIPTION</zr:description>
            </zr:databaseInfo>
            <zr:metaInfo>
                <zr:dateModified>TEST_SERVER_DATE</zr:dateModified>
            </zr:metaInfo>
        </zr:explain>
    </srw:recordData>
</srw:record>
</srw:explainResponse>
""", result)
 def assertSortKeys(expectedSortedDescending, sortKeys,
                    oldAndWrongStyleSortKeys):
     component = SruParser(
         oldAndWrongStyleSortKeys=oldAndWrongStyleSortKeys)
     sruHandler = CallTrace('SRUHandler',
                            emptyGeneratorMethods=['searchRetrieve'])
     component.addObserver(sruHandler)
     response = "".join(
         compose(
             component.handleRequest(
                 arguments=dict(version=['1.1'],
                                query=['aQuery'],
                                operation=['searchRetrieve'],
                                sortKeys=[sortKeys]))))
     kwargs = sruHandler.calledMethods[0].kwargs
     self.assertEqual([{
         'sortBy': 'aField',
         'sortDescending': expectedSortedDescending
     }], kwargs['sortKeys'])
    def testSearchRetrieve(self):
        component = SruParser()
        sruHandler = CallTrace('SRUHandler')
        sruHandler.returnValues['searchRetrieve'] = (x for x in ["<result>mock result XML</result>"])
        component.addObserver(sruHandler)

        response = "".join(compose(component.handleRequest(arguments=dict(version=['1.1'], query= ['aQuery'], operation=['searchRetrieve'], startRecord=['11'], maximumRecords = ['15'], sortKeys=['aField,,1']))))

        self.assertEquals(['searchRetrieve'], [m.name for m in sruHandler.calledMethods])
        self.assertEquals((), sruHandler.calledMethods[0].args)
        kwargs = sruHandler.calledMethods[0].kwargs
        self.assertEquals('1.1', kwargs['version'])
        self.assertEquals('aQuery', kwargs['query'])
        self.assertEquals('searchRetrieve', kwargs['operation'])
        self.assertEquals(11, kwargs['startRecord'])
        self.assertEquals(15, kwargs['maximumRecords'])
        self.assertEquals('aQuery', kwargs['sruArguments']['query'])
        self.assertEquals(['aField,,1'], kwargs['sruArguments']['sortKeys'])

        self.assertTrue("HTTP/1.0 200 OK" in response)
        self.assertTrue(XML_HEADER in response)
    def testExplainWithoutPresetValues(self):
        component = SruParser()

        result = "".join(
            compose(
                component.handleRequest(
                    arguments={
                        'operation': ['explain'],
                        'version': ['1.2']
                    },
                    Headers={'Host': '1.2.3.4:8080'},
                    RequestURI="/sru?operation=explain&version=1.2")))
        self.assertEqualsWS(
            """HTTP/1.0 200 OK
Content-Type: text/xml; charset=utf-8

<?xml version="1.0" encoding="UTF-8"?>
<srw:explainResponse xmlns:srw="http://www.loc.gov/zing/srw/"
xmlns:zr="http://explain.z3950.org/dtd/2.0/">
<srw:version>1.2</srw:version>
<srw:record>
    <srw:recordPacking>xml</srw:recordPacking>
    <srw:recordSchema>http://explain.z3950.org/dtd/2.0/</srw:recordSchema>
    <srw:recordData>
        <zr:explain>
            <zr:serverInfo protocol="SRU" version="1.2">
                <zr:host>1.2.3.4</zr:host>
                <zr:port>8080</zr:port>
                <zr:database>sru</zr:database>
            </zr:serverInfo>
            <zr:databaseInfo>
                <zr:title lang="en" primary="true">SRU Database</zr:title>
                <zr:description lang="en" primary="true">Meresco SRU</zr:description>
            </zr:databaseInfo>
        </zr:explain>
    </srw:recordData>
</srw:record>
</srw:explainResponse>
""", result)
    def testSearchRetrieveWithXParameter(self):
        component = SruParser()
        sruHandler = CallTrace('SRUHandler')
        sruHandler.returnValues['searchRetrieve'] = (
            x for x in ["<result>mock result XML</result>"])
        component.addObserver(sruHandler)

        list(
            compose(
                component.handleRequest(
                    arguments={
                        'version': ['1.1'],
                        'query': ['aQuery'],
                        'operation': ['searchRetrieve'],
                        'x-something': ['something']
                    })))

        self.assertEqual(['searchRetrieve'],
                         [m.name for m in sruHandler.calledMethods])
        self.assertEqual((), sruHandler.calledMethods[0].args)
        kwargs = sruHandler.calledMethods[0].kwargs
        self.assertEqual(['something'], kwargs['sruArguments']['x-something'])