def testPostAnnotation(self):
        identifier = "urn:uuid:%s" % uuid4()
        annotationBody = """<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:oa="http://www.w3.org/ns/openannotation/core/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:dcterms="http://purl.org/dc/terms/"
    xmlns:foaf="http://xmlns.com/foaf/0.1/">

    <rdf:Description rdf:about="%(identifier)s">
        <rdf:type rdf:resource="http://www.w3.org/ns/openannotation/core/Annotation"/>
        <oa:hasBody rdf:resource="ex:HDFI-2"/>
        <oa:hasTarget rdf:resource="ex:HDFV2"/>
        <dc:title>An Annotions submitted through a form</dc:title>
        <oa:annotatedBy rdf:resource="ex:AnotherUser"/>
        <oa:annotatedAt>2000-02-01 12:34:56</oa:annotatedAt>
    </rdf:Description>
</rdf:RDF>""" % locals()
        self.assertQuery('RDF.Annotation.title = "An Annotions submitted through a form"', 0)

        header, body = postRequest(self.portNumber, '/uploadform', urlencode(dict(annotation=annotationBody, apiKey=self.apiKeyForPostUser)), parse='lxml')
        self.assertQuery('RDF.Annotation.title = "An Annotions submitted through a form"', 1)
        textarea = xpath(body, '//textarea[@name="annotation"]/text()')
        apiKey = xpath(body, '//input[@name="apiKey"]/@value')[0]
        message = xpath(body, '//p[@class="success"]/text()')[0]
        self.assertEquals(self.apiKeyForPostUser, apiKey)
        self.assertEquals([], textarea)
        self.assertTrue('success' in message, message)
    def testAdmin(self):
        headers, body = getRequest(self.portNumber, "/login", parse='lxml')
        cookie = parseHeaders(headers)['Set-Cookie']

        headers, body = postRequest(self.portNumber, '/login.action', urlencode(dict(username="******", password="******", formUrl='/login')), parse='lxml', additionalHeaders={'Cookie': cookie})
        self.assertTrue('302' in headers, headers)
        self.assertEquals('/', parseHeaders(headers)['Location'])
        
        headers, body = getRequest(self.portNumber, "/index", parse='lxml', additionalHeaders={'Cookie': cookie})
        self.assertEquals(['Logged in as: admin | ', ' | ', ' | ', ' | '], xpath(body, '//div[@id="loginbar"]/p/text()'))

        headers, body = getRequest(self.portNumber, "/changepassword", parse='lxml', additionalHeaders={'Cookie': cookie})
        self.assertEquals(['admin'], xpath(body, '/html/body/div[@id="content"]/div[@id="login"]/form/input[@type="hidden" and @name="username"]/@value'), tostring(body))
        self.assertEquals(['oldPassword', 'newPassword', 'retypedPassword'], xpath(body, '/html/body/div[@id="content"]/div[@id="login"]/form/dl/dd/input[@type="password"]/@name'), tostring(body))
        self.assertEquals(['/login.action/changepassword'], xpath(body, '/html/body/div[@id="content"]/div[@id="login"]/form/@action'))

        headers, body = postRequest(self.portNumber, '/login.action/changepassword', urlencode(dict(username="******", oldPassword="******", newPassword="******", retypedPassword="******", formUrl="/changepassword")), parse='lxml', additionalHeaders={'Cookie': cookie})
        self.assertTrue('302' in headers, headers)
        self.assertEquals('/', parseHeaders(headers)['Location'])

        # Test new password
        headers, body = getRequest(self.portNumber, "/login", parse='lxml')
        newcookie = parseHeaders(headers)['Set-Cookie']

        headers, body = postRequest(self.portNumber, '/login.action', urlencode(dict(username="******", password="******", formUrl='/login')), parse='lxml', additionalHeaders={'Cookie': newcookie})
        self.assertTrue('302' in headers, headers)
        self.assertEquals('/login', parseHeaders(headers)['Location'])

        headers, body = postRequest(self.portNumber, '/login.action', urlencode(dict(username="******", password="******", formUrl='/login')), parse='lxml', additionalHeaders={'Cookie': newcookie})
        self.assertTrue('302' in headers, headers)
        self.assertEquals('/', parseHeaders(headers)['Location'])
    def testRecursionStopsOnAnnotation(self):
        query = "urn:test:a:0"
        headers, body = getRequest(self.portNumber, "/sru", arguments=dict(
            version="1.2", operation="searchRetrieve", query=query), parse='lxml')

        a_0 = xpath(body, "/srw:searchRetrieveResponse/srw:records/srw:record/srw:recordData/rdf:RDF")[0]

        self.assertEquals(["urn:test:a:1", "urn:test:a:2"], xpath(a_0, "oa:Annotation/oa:hasTarget/@rdf:resource"))
 def checkResponse(self, response):
     header, body = response.split('\r\n\r\n', 1)
     lxmlNode = parse(StringIO(body))
     success = not xpath(lxmlNode, "//srw:diagnostics")
     if not success:
         raise SruUploadException(
                 uri=xpath(lxmlNode, "//diag:uri/text()")[0],
                 details=xpath(lxmlNode, "//diag:details/text()")[0],
                 message=xpath(lxmlNode, "//diag:message/text()")[0])            
    def testImageAnnotations_ia1(self):
        query = "urn:id:ia:1"
        headers, body = getRequest(self.portNumber, "/sru", arguments=dict(
            version="1.2", operation="searchRetrieve", query=query), parse='lxml')

        ia_1 = xpath(body, "/srw:searchRetrieveResponse/srw:records/srw:record/srw:recordData/rdf:RDF")[0]

        self.assertEquals(['http://catchplus.nl/annotation/imageScan1.jpg'], xpath(ia_1, 'oa:Annotation/oa:hasBody/@rdf:resource'))
        self.assertEquals(['Canvas for imageScan1.jpg'], xpath(ia_1, 'oa:Annotation/oa:hasTarget/dms:Canvas[@rdf:about="http://catchplus.nl/annotation/Canvas1"]/dc:title/text()'))
    def testTextAnnotations_ta0(self):
        query = "urn:id:ta:0"
        headers, body = getRequest(self.portNumber, "/sru", arguments=dict(
            version="1.2", operation="searchRetrieve", query=query), parse='lxml')

        ta_0 = xpath(body, "/srw:searchRetrieveResponse/srw:records/srw:record/srw:recordData/rdf:RDF")[0]

        self.assertEquals(['Dit is een beschrijving van Den Haag. En dit is een tweede zin.'], xpath(ta_0, 'oa:Annotation/oa:hasBody/cnt:ContentAsText[@rdf:about="urn:id:ib:0"]/cnt:chars/text()'))
        self.assertEquals(['Canvas for imageScan1.jpg'], xpath(ta_0, 'oa:Annotation/oa:hasTarget/dms:Canvas[@rdf:about="http://catchplus.nl/annotation/Canvas1"]/dc:title/text()'))
    def testTextAnnotations_ta2(self):
        query = "urn:id:ta:2"
        headers, body = getRequest(self.portNumber, "/sru", arguments=dict(
            version="1.2", operation="searchRetrieve", query=query), parse='lxml')

        ta_2 = xpath(body, "/srw:searchRetrieveResponse/srw:records/srw:record/srw:recordData/rdf:RDF")[0]
        specificResourceUrl = "http://*****:*****@rdf:about="%s"]/oa:hasSource/cnt:ContentAsText[@rdf:about="urn:id:ib:0"]/cnt:chars/text()' % specificResourceUrl))
        self.assertEquals(['Canvas for imageScan1.jpg'], xpath(ta_2, 'oa:Annotation/oa:hasTarget/oa:SpecificResource[dc:identifier/text()="urn:id:ct:2"]/oa:hasSource/dms:Canvas[@rdf:about="http://catchplus.nl/annotation/Canvas1"]/dc:title/text()'))
 def testOne(self):
     query='oa:hasTarget="http://catchplus.nl/annotation/Canvas1"'
     headers, body = getRequest(self.portNumber, "/sru", arguments=dict(
         version="1.2", operation="searchRetrieve", query=query), parse='lxml')
     self.assertEquals(["4"], xpath(body, '//srw:numberOfRecords/text()'))
     self.assertEquals([
             'http://localhost:%s/resolve/urn%%3Aid%%3Aia%%3A1' % self.portNumber, 
             'http://localhost:%s/resolve/urn%%3Aid%%3Ata%%3A0' % self.portNumber, 
             'http://localhost:%s/resolve/urn%%3Aid%%3Ata%%3A1' % self.portNumber, 
             'http://localhost:%s/resolve/urn%%3Aid%%3Ata%%3A2' % self.portNumber
         ], xpath(body, '//srw:records/srw:record/srw:recordIdentifier/text()'))
    def assertNotAValidAnnotiation(self, errorText, annotationBody):
        annotationBody = """<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:oa="http://www.w3.org/ns/openannotation/core/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:dcterms="http://purl.org/dc/terms/"
    xmlns:foaf="http://xmlns.com/foaf/0.1/">
    %s
</rdf:RDF>""" % annotationBody

        header,body = postRequest(self.portNumber, '/uploadform', urlencode(dict(annotation=annotationBody, apiKey=self.apiKeyForPostUser)), parse='lxml')
        self.assertEquals([errorText], xpath(body, '//p[@class="error"]/text()'))
        self.assertEquals([], xpath(body, '//p[@class="success"]/text()'))
    def testEntityAnnotation(self):
        query = "urn:id:ea:1"
        headers, body = getRequest(self.portNumber, "/sru", arguments=dict(
            version="1.2", operation="searchRetrieve", query=query), parse='lxml')

        ea_1 = xpath(body, "/srw:searchRetrieveResponse/srw:records/srw:record/srw:recordData/rdf:RDF")[0]

        self.assertEquals(["urn:id:ea:1"], xpath(ea_1, 'oa:Annotation/dc:identifier/text()'))
        self.assertEquals(["location"], xpath(ea_1, 'oa:Annotation/oa:hasBody/cnt:ContentAsText[@rdf:about="urn:id:ib:1"]/cnt:chars/text()'))

        self.assertEquals(['Dit is een beschrijving van Den Haag. En dit is een tweede zin.'], xpath(ea_1, 'oa:Annotation/oa:hasTarget/oa:SpecificResource[dc:identifier/text()="urn:id:ct:3"]/oa:hasSource/cnt:ContentAsText[@rdf:about="urn:id:ib:0"]/cnt:chars/text()'))
        self.assertEquals(['Dit is een beschrijving van Den Haag. En dit is een tweede zin.'], xpath(ea_1, 'oa:Annotation/oa:hasTarget/oa:SpecificResource[dc:identifier/text()="urn:id:ct:4"]/oa:hasSource/cnt:ContentAsText[@rdf:about="urn:id:ib:0"]/cnt:chars/text()'))

        self.assertEquals(["UTF-8"], xpath(ea_1, 'oa:Annotation/oa:hasTarget/oa:SpecificResource[dc:identifier/text()="urn:id:ct:3"]/oa:hasSelector/oa:Selector[@rdf:about="urn:id:c:5"]/cnt:characterEncoding/text()'))
    def _inlineURNs(self, root, rdfContainer):
        for relation in [
            {"tag": "oa:annotatedBy", "partname": "foafAgent"},
            {"tag": "oa:hasBody", "partname": "oacBody"},
            {"tag": "oa:hasSource"},
            {"tag": "oa:hasSelector"},
            {"tag": "oa:hasTarget", "partname": "oacConstrainedTarget"},
        ]:

            nodes = xpath(root, "%s[@rdf:resource]" % relation["tag"])
            for node in nodes:
                urn = getAttrib(node, "rdf:resource")
                if urn:
                    resolvedNode = rdfContainer.resolve(urn)
                    if resolvedNode is not None and not isAnnotation(resolvedNode):
                        node.append(resolvedNode)
                        self._inlineURNs(resolvedNode, rdfContainer)
                        del node.attrib[expandNs("rdf:resource")]
                    elif urn.startswith(self._baseUrl):
                        if self.call.isAvailable(identifier=urn, partname="oacBody") == (True, True):
                            data = self.call.getStream(identifier=urn, partname="oacBody")
                            node.append(parse(StringIO(data.read())).getroot())
                            del node.attrib[expandNs("rdf:resource")]
                    elif "partname" in relation and self.call.isAvailable(
                        identifier=urn, partname=relation["partname"]
                    ) == (True, True):
                        data = self.call.getStream(identifier=urn, partname=relation["partname"])
                        node.append(parse(StringIO(data.read())).getroot())
                        del node.attrib[expandNs("rdf:resource")]
 def assertQuery(self, query, count):
     headers, body = getRequest(self.portNumber, "/sru", arguments=dict(
         version="1.1", operation="searchRetrieve", query=query), parse='lxml')
     recordCount = int(xpath(body, '/srw:searchRetrieveResponse/srw:numberOfRecords/text()')[0])
     if recordCount != count:
         print tostring(body)
     self.assertEquals(count, recordCount)
    def _setupUsers(self):
        headers, body = postRequest(self.portNumber, '/login.action', urlencode(dict(username="******", password="******")), parse=False)
        cookie = parseHeaders(headers)['Set-Cookie']

        headers, body = postRequest(self.portNumber, '/apikey.action/create', urlencode(dict(formUrl='/user_management', username='******')), parse=False, additionalHeaders=dict(cookie=cookie))
        headers, body = postRequest(self.portNumber, '/apikey.action/create', urlencode(dict(formUrl='/user_management', username='******')), parse=False, additionalHeaders=dict(cookie=cookie))
        headers, body = postRequest(self.portNumber, '/apikey.action/create', urlencode(dict(formUrl='/user_management', username='******')), parse=False, additionalHeaders=dict(cookie=cookie))

        headers, body = getRequest(self.portNumber, '/user_management', additionalHeaders={'Cookie': cookie})
        self.apiKeyForTestUser =  xpath(body, '//div[@id="apiKeys"]/table/tr[form/td[text()="testUser"]]/form/td[@class="apiKey"]/text()')[0]
        assert self.apiKeyForTestUser != None

        self.apiKeyForAnotherTestUser = xpath(body, '//div[@id="apiKeys"]/table/tr[form/td[text()="anotherTestUser"]]/form/td[@class="apiKey"]/text()')[0]
        assert self.apiKeyForAnotherTestUser != None
        
        self.apiKeyForPostUser = xpath(body, '//div[@id="apiKeys"]/table/tr[form/td[text()="postUser"]]/form/td[@class="apiKey"]/text()')[0]
        assert self.apiKeyForPostUser != None
 def testDocumentationPage(self):
     header, body = getRequest(self.portNumber, '/documentation', {}, parse='lxml')
     nodes = xpath(body, '/html/body/div/div[@id="filelist"]/ul/li/a')
     expected = sorted(listdir(self.publicDocumentationPath))
     self.assertTrue(len(expected) > 1)
     self.assertEquals(expected, [node.text for node in nodes])
     self.assertTrue(all(['target' in node.attrib for node in nodes]))
     self.assertEquals(['/public/%s' % f for f in expected], [node.attrib['href'] for node in nodes])
    def listResolvables(self):
        response = self.call.searchRetrieve(self._query)

        records = xpath(response, "/srw:searchRetrieveResponse/srw:records/srw:record")
        nodes = xpath(response, "/srw:searchRetrieveResponse/srw:records/srw:record/srw:recordData/rdf:RDF")
        for record in records:
            node = xpath(record, "srw:recordData/rdf:RDF")[0]
            items = []
            yield {
                'identifier': xpath(record, "srw:recordIdentifier/text()")[0],
                'items': [
                    {   'filter': filterFoafAgents, 
                        'partname': 'foafAgent', 
                        'urls': xpath(node, "oa:Annotation/oa:annotatedBy/@rdf:resource")
                    },
                ]
            }
 def _listRecordIds(self, username):
     query = urlencode(dict(
         operation='searchRetrieve',
         version='1.2',
         query='api.user="******"' % username
     ))
     result = parse(urlopen('%s?%s' % (self._sruUrl, query)))
     return xpath(result, '//srw:records/srw:record/srw:recordIdentifier/text()')
    def testOne(self):

        uuid = "urn:uuid:8ab4ee28-651a-45bd-9206-59763f9e5487"
        query = uuid 
        headers, body = getRequest(self.portNumber, "/sru", arguments=dict(
            version="1.1", 
            operation="searchRetrieve", 
            query=query), parse='lxml')

        self.assertEquals(2, len(xpath(body, '//oa:hasSource/oa:Body/cnt:chars')))
    def testApiKeyAddition(self):
        headers, body = postRequest(
            self.portNumber, "/login.action", urlencode(dict(username="******", password="******"))
        )
        cookie = parseHeaders(headers)["Set-Cookie"]

        headers, body = getRequest(self.portNumber, "/user_management", additionalHeaders={"Cookie": cookie})
        self.assertEquals(["/apikey.action/create"], xpath(body, '//form[@name="create"]/@action'))
        self.assertEquals(
            ["/user_management"], xpath(body, '//form[@name="create"]/input[@type="hidden" and @name="formUrl"]/@value')
        )

        headers, body = postRequest(
            self.portNumber,
            "/apikey.action/create",
            urlencode(dict(formUrl="/user_management", username="******")),
            additionalHeaders=dict(cookie=cookie),
        )
        self.assertTrue("302" in headers, headers)
        self.assertEquals("/user_management", parseHeaders(headers)["Location"], headers)

        headers, body = getRequest(self.portNumber, "/user_management", additionalHeaders={"Cookie": cookie})

        self.assertEquals("", xpath(body, '//div[@id="apiKeys"]/table/tr/form/td/input[@name="description"]/@value')[0])
        apiKey = xpath(body, '//div[@id="apiKeys"]/table/tr/form/td[@class="apiKey"]/text()')[0]
        self.assertNotEqual("", apiKey)

        headers, body = postRequest(
            self.portNumber,
            "/apikey.action/update",
            urlencode(dict(formUrl="/user_management", apiKey=apiKey, description="Some description")),
            additionalHeaders=dict(cookie=cookie),
        )
        self.assertTrue("302" in headers, headers)
        self.assertEquals("/user_management", parseHeaders(headers)["Location"], headers)
        headers, body = getRequest(self.portNumber, "/user_management", additionalHeaders={"Cookie": cookie})
        self.assertEquals(
            "Some description",
            xpath(body, '//div[@id="apiKeys"]/table/tr/form/td/input[@name="description"]/@value')[0],
        )
    def testOacBodiesStored(self):
        headers, body = getRequest(self.portNumber, "/sru", arguments=dict(
            version="1.1", operation="searchRetrieve", query="IamUnique42"), parse='lxml')

        oacBody = xpath(body, "/srw:searchRetrieveResponse/srw:records/srw:record/srw:recordData/rdf:RDF/oa:Annotation/oa:hasBody/oa:Body")[0]

        about = getAttrib(oacBody, "rdf:about")
        _,_,path,_,_ = urlsplit(about)
        headers, body = getRequest(self.portNumber, path, parse=False)
        self.assertTrue('200' in headers, headers)
        lines = body.split('\n')
        self.assertEquals('<?xml version="1.0" encoding="utf-8"?>', lines[0])
        self.assertEquals('<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">', lines[1])
        self.assertEquals('</rdf:RDF>', lines[-1])
 def add(self, identifier, lxmlNode):
     for record in xpath(lxmlNode, "/oai:record/oai:metadata/*"):
         # construct the body, insert the identifier and supplied XML.
         body = """<ucp:updateRequest xmlns:ucp="info:lc/xmlns/update-v1">
         <srw:version xmlns:srw="http://www.loc.gov/zing/srw/">1.0</srw:version>
         <ucp:action>info:srw/action/1/replace</ucp:action>
         <ucp:recordIdentifier>IGNORED</ucp:recordIdentifier>
         <srw:record xmlns:srw="http://www.loc.gov/zing/srw/">
             <srw:recordPacking>xml</srw:recordPacking>
             <srw:recordSchema>rdf</srw:recordSchema>
             <srw:recordData>%s</srw:recordData>
         </srw:record>
     </ucp:updateRequest>""" % tostring(record)
         response = self._send(body)
         self.checkResponse(response)
     yield
    def testResolveAgent(self):
        identifier = "urn:uuid:%s" % uuid4()
        resourceUrl = "http://localhost:%s/rdf/testResolve" % self.httpPortNumber
        sruUpdateBody = """<ucp:updateRequest xmlns:ucp="info:lc/xmlns/update-v1">
    <srw:version xmlns:srw="http://www.loc.gov/zing/srw/">1.0</srw:version>
    <ucp:action>info:srw/action/1/replace</ucp:action>
    <ucp:recordIdentifier>ex:Anno</ucp:recordIdentifier>
    <srw:record xmlns:srw="http://www.loc.gov/zing/srw/">
        <srw:recordPacking>xml</srw:recordPacking>
        <srw:recordSchema>rdf</srw:recordSchema>
        <srw:recordData><rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:oa="http://www.w3.org/ns/openannotation/core/"
    xmlns:dc="http://purl.org/dc/elements/1.1/">

    <oa:Annotation rdf:about="http://oas.dev.seecr.nl/resolve/%s">
        <dc:title>This is an annotation</dc:title>
        <oa:annotatedBy rdf:resource="%s"/>
    </oa:Annotation>

</rdf:RDF></srw:recordData></srw:record>
</ucp:updateRequest>""" % (identifier, resourceUrl)
        header, body = postRequest(self.portNumber, '/update', sruUpdateBody, parse='lxml', additionalHeaders={'Authorization':self.apiKeyForTestUser})
        self.assertEquals("success", xpath(body, "/srw:updateResponse/ucp:operationStatus/text()")[0])

        before = self.countUnresolved()

        destDir = join(self.httpDataDir, "rdf")
        if not isdir(destDir):
            makedirs(destDir)
        open(join(destDir, "testResolve"), "w").write("""<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:foaf="http://xmlns.com/foaf/0.1/"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <rdf:Description rdf:about="%s">
        <rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Agent"/>
        <foaf:name>Pietje Puk</foaf:name>
        <dc:title>Gewillig slachtoffer</dc:title>    
    </rdf:Description>
</rdf:RDF>""" % resourceUrl)

        self.runResolveService()
        self.assertEquals(before-1, self.countUnresolved())
    def testErrorWhenBadApiKey(self):
        identifier = "urn:uuid:%s" % uuid4()
        annotationBody = """<rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:oa="http://www.w3.org/ns/openannotation/core/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:dcterms="http://purl.org/dc/terms/"
    xmlns:foaf="http://xmlns.com/foaf/0.1/">

    <rdf:Description rdf:about="%(identifier)s">
        <rdf:type rdf:resource="http://www.w3.org/ns/openannotation/core/Annotation"/>
        <oa:hasBody rdf:resource="ex:HDFI-2"/>
        <oa:hasTarget rdf:resource="ex:HDFV2"/>
        <dc:title>An Annotions submitted through a form</dc:title>
        <oa:annotatedBy rdf:resource="ex:AnotherUser"/>
        <oa:annotatedAt>2000-02-01 12:34:56</oa:annotatedAt>
    </rdf:Description>
</rdf:RDF>""" % locals()

        header, body = postRequest(self.portNumber, '/uploadform', urlencode(dict(annotation=annotationBody, apiKey="WRONGKEY")), parse='lxml')
        error =  xpath(body, '//p[@class="error"]/text()')[0]
        self.assertEquals('No valid API Key given', error)
    def testErrorWhenNotAnnotationSruUpdate(self):
        identifier = "urn:uuid:%s" % uuid4()
        sruUpdateBody = """<ucp:updateRequest xmlns:ucp="info:lc/xmlns/update-v1">
    <srw:version xmlns:srw="http://www.loc.gov/zing/srw/">1.0</srw:version>
    <ucp:action>info:srw/action/1/replace</ucp:action>
    <ucp:recordIdentifier>ex:Anno</ucp:recordIdentifier>
    <srw:record xmlns:srw="http://www.loc.gov/zing/srw/">
        <srw:recordPacking>xml</srw:recordPacking>
        <srw:recordSchema>rdf</srw:recordSchema>
        <srw:recordData><rdf:RDF 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:oa="http://www.w3.org/ns/openannotation/core/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:dcterms="http://purl.org/dc/terms/"
    xmlns:foaf="http://xmlns.com/foaf/0.1/">

    <rdf:Description rdf:about="%(identifier)s">
        <dc:title>This is a wannabe annotation</dc:title>
    </rdf:Description>
</rdf:RDF></srw:recordData></srw:record>
</ucp:updateRequest>""" % locals()

        header, body = postRequest(self.portNumber, '/update', sruUpdateBody, parse='lxml', additionalHeaders={'Authorization':self.apiKeyForTestUser})
        self.assertEquals(['info:srw/diagnostic/12/12'], xpath(body, '/srw:updateResponse/srw:diagnostics/diag:diagnostic/diag:uri/text()'))
    def testLoginPage(self):
        headers, body = getRequest(self.portNumber, "/login")
        cookie = parseHeaders(headers)["Set-Cookie"]
        self.assertTrue("200" in headers, headers)
        self.assertEquals(
            1, len(xpath(body, '/html/body/div[@id="content"]/div[@id="login"]/form/dl/dd/input[@name="username"]'))
        )
        self.assertEquals(
            1,
            len(
                xpath(
                    body,
                    '/html/body/div[@id="content"]/div[@id="login"]/form/dl/dd/input[@type="password" and @name="password"]',
                )
            ),
        )
        self.assertEquals(
            1, len(xpath(body, '/html/body/div[@id="content"]/div[@id="login"]/form/dl/dd/input[@type="submit"]'))
        )
        self.assertEquals(["/login.action"], xpath(body, '/html/body/div[@id="content"]/div[@id="login"]/form/@action'))

        headers, body = postRequest(
            self.portNumber,
            "/login.action",
            urlencode(dict(username="******", password="******")),
            additionalHeaders={"Cookie": cookie},
        )
        self.assertTrue("302" in headers, headers)
        self.assertEquals("/login", parseHeaders(headers)["Location"], headers)

        headers, body = getRequest(self.portNumber, "/login", additionalHeaders={"Cookie": cookie})
        self.assertEquals(
            ["doesnotexist"],
            xpath(body, '/html/body/div[@id="content"]/div[@id="login"]/form/dl/dd/input[@name="username"]/@value'),
        )
        self.assertEquals(
            ["Invalid username or password"],
            xpath(body, '/html/body/div[@id="content"]/div[@id="login"]/p[@class="error"]/text()'),
        )
 def testOaiListRecords(self):
     headers,body = getRequest(self.portNumber, "/oai", arguments=dict(verb='ListRecords', metadataPrefix="rdf"), parse='lxml')
     self.assertEquals(21, len(xpath(body, "/oai:OAI-PMH/oai:ListRecords/oai:record/oai:metadata")))
def isAnnotation(node):
    return ("{%(oa)s}Annotation" % namespaces) == node.tag or ("%(oa)sAnnotation" % namespaces) in xpath(
        node, "rdf:type/@rdf:resource"
    )
 def testOaiIdentify(self):
     headers,body = getRequest(self.portNumber, "/oai", arguments=dict(verb='Identify'), parse='lxml')
     self.assertEquals("CatchPlus OpenAnnotation", xpath(body, "/oai:OAI-PMH/oai:Identify/oai:repositoryName/text()")[0])
 def testResolveConstrainedTargets(self):
     header, body = getRequest(self.portNumber, '/resolve/urn%3Aid%3Act%3A1', {}, parse='lxml')
     self.assertEquals(["http://*****:*****@rdf:about'))
    def testUrnResolvable(self):
        header, body = getRequest(self.portNumber, '/resolve/urn%3Aex%3AAnno', {}, parse='lxml')
        self.assertEquals(["http://*****:*****@rdf:about'))

        header, body = getRequest(self.portNumber, '/resolve/urn%3Anr%3A0%3Fb', {}, parse='lxml')
        self.assertEquals(["http://*****:*****@rdf:about'))
    def testOaiListRecordsWithUserAsSet(self):
        headers,body = getRequest(self.portNumber, "/oai", arguments=dict(verb='ListRecords', metadataPrefix="rdf", set='testUser'), parse='lxml')
        self.assertEquals(11, len(xpath(body, "/oai:OAI-PMH/oai:ListRecords/oai:record/oai:metadata")))

        headers,body = getRequest(self.portNumber, "/oai", arguments=dict(verb='ListRecords', metadataPrefix="rdf", set='anotherTestUser'), parse='lxml')
        self.assertEquals(10, len(xpath(body, "/oai:OAI-PMH/oai:ListRecords/oai:record/oai:metadata")))