def setUp(self):
     super(TestAPI_M, self).setUp()
     self.pid = self.fedora_fixtures_ingested[0]
     self.api_m = API_M(self.opener)
     self.opener = AuthorizingServerConnection(FEDORA_ROOT_NONSSL, FEDORA_USER, FEDORA_PASSWORD)
     self.rest_api = REST_API(self.opener)
class TestAPI_M(FedoraTestCase):
    fixtures = ['object-with-pid.foxml']
    pidspace = FEDORA_PIDSPACE

    # relationship predicates for testing
    rel_isMemberOf = "info:fedora/fedora-system:def/relations-external#isMemberOf"
    rel_owner = "info:fedora/fedora-system:def/relations-external#owner"

    # save date-time before fixtures are created in fedora
    # getting time here instead of setUp should give a little more leeway if server times are not synced
    now = datetime.now(tzutc())   

    def setUp(self):
        super(TestAPI_M, self).setUp()
        self.pid = self.fedora_fixtures_ingested[0]
        self.api_m = API_M(self.opener)
        self.opener = AuthorizingServerConnection(FEDORA_ROOT_NONSSL, FEDORA_USER, FEDORA_PASSWORD)
        self.rest_api = REST_API(self.opener)
        
    def test_addRelationship(self):
        # rel to resource
        added = self.api_m.addRelationship(self.pid, unicode(modelns.hasModel), "info:fedora/pid:123", False)
        self.assertTrue(added)
        rels, url = self.rest_api.getDatastreamDissemination(self.pid, "RELS-EXT")
        self.assert_('<hasModel' in rels)
        self.assert_('rdf:resource="info:fedora/pid:123"' in rels)

        # literal
        added = self.api_m.addRelationship(self.pid, self.rel_owner, "johndoe", True)
        self.assertTrue(added)
        rels, url = self.rest_api.getDatastreamDissemination(self.pid, "RELS-EXT")
        self.assert_('<owner' in rels)
        self.assert_('>johndoe<' in rels)

        # bogus pid
        self.assertRaises(Exception, self.api_m.addRelationship,
            "bogus:pid", self.rel_owner, "johndoe", True)

    def test_getRelationships(self):
        # add relations
        self.api_m.addRelationship(self.pid, unicode(modelns.hasModel), "info:fedora/pid:123", False)
        self.api_m.addRelationship(self.pid, self.rel_owner, "johndoe", True)

        response = self.api_m.getRelationships(self.pid, unicode(modelns.hasModel))
        rels = response.relationships

        self.assertEqual(2, len(rels))  # includes fedora-system cmodel
        self.assertEqual(rels[0].subject, 'info:fedora/' + self.pid)
        self.assertEqual(rels[0].predicate, unicode(modelns.hasModel))
        cmodels = [rels[0].object, rels[1].object]
        self.assert_('info:fedora/fedora-system:FedoraObject-3.0' in cmodels)
        self.assert_('info:fedora/pid:123' in cmodels)

        response = self.api_m.getRelationships(self.pid, self.rel_owner)
        rels = response.relationships
        self.assertEqual(1, len(rels))
        self.assertEqual(rels[0].subject, 'info:fedora/' + self.pid)
        self.assertEqual(rels[0].predicate, self.rel_owner)
        self.assertEqual(rels[0].object, "johndoe")

    def test_purgeRelationship(self):
        # add relation to purge
        self.api_m.addRelationship(self.pid, unicode(modelns.hasModel), "info:fedora/pid:123", False)
        
        purged = self.api_m.purgeRelationship(self.pid, unicode(modelns.hasModel), "info:fedora/pid:123", False)
        self.assertEqual(purged, True)

        # purge non-existent rel on valid pid
        purged = self.api_m.purgeRelationship(self.pid, self.rel_owner, "johndoe", True)
        self.assertFalse(purged)

        # bogus pid
        self.assertRaises(Exception, self.api_m.purgeRelationship, "bogus:pid",
            self.rel_owner, "johndoe", True)        

    def test_getDatastreamHistory(self):
        history = self.api_m.getDatastreamHistory(self.pid, "DC")
        self.assertEqual(1, len(history.datastreams))
        dc_info = history.datastreams[0]
        self.assertEqual('X', dc_info.controlGroup)
        self.assertEqual('DC', dc_info.ID)
        self.assertEqual('DC.0', dc_info.versionID)
         # altIDs unused
        self.assertEqual('Dublin Core', dc_info.label)
        self.assertTrue(dc_info.versionable)
        self.assertEqual("text/xml", dc_info.MIMEType)
        # formatURI not set in test fixture
        self.assert_(self.now < dc_info.createDate)     # created after 'now' in setup
        self.assert_(dc_info.size) # size should be non-zero - number comparison not reliable
        self.assertEqual('A', dc_info.state) 
        # location, checksumType, and checksum not set in current fixture
        
        # modify DC so there are multiple versions        
        new_dc = """<oai_dc:dc
            xmlns:dc='http://purl.org/dc/elements/1.1/'
            xmlns:oai_dc='http://www.openarchives.org/OAI/2.0/oai_dc/'>
          <dc:title>Test-Object</dc:title>
          <dc:description>modified!</dc:description>
        </oai_dc:dc>"""
        self.rest_api.modifyDatastream(self.pid, "DC", "DCv2Dublin Core",
            mimeType="text/xml", logMessage="updating DC", content=new_dc)
        history = self.api_m.getDatastreamHistory(self.pid, "DC")
        self.assertEqual(2, len(history.datastreams))
        self.assertEqual('DC.1', history.datastreams[0].versionID)      # newest version is first
        self.assertNotEqual(history.datastreams[0].createDate, history.datastreams[1].createDate)

        # bogus datastream
        self.assertEqual(None, self.api_m.getDatastreamHistory(self.pid, "BOGUS"))

        # bogus pid
        self.assertRaises(Exception, self.api_m.getDatastreamHistory, "bogus:pid", "DC")