Ejemplo n.º 1
0
    def test_02_request(self):
        # Check we can instantiate and work with a Request

        # first make a blank one
        req = Request()

        # now make one around the fixture
        source = RequestFixtureFactory.example()
        req = Request(source)

        # make one with a broken source
        broken = {"whatever" : "broken"}
        with self.assertRaises(dataobj.DataStructureException):
            req = Request(broken)

        # now make one bit by bit
        req = Request()
        req.record = source.get("record")
        req.owner = "test1"
        req.action = "update"
        req.public_id = "abcdefg"

        assert req.owner == "test1"
        assert req.action == "update"
        assert req.public_id == "abcdefg"

        # now make it broken
        req = Request()
        with self.assertRaises(dataobj.DataStructureException):
            req.record = {"random" : "stuff"}
Ejemplo n.º 2
0
    def delete(cls, record, account, public_id=None):
        """
        Record a "delete" request, with the associated (minimal) record data, requested by the given account

        Delete requests need only come with enough record data to identify the public record

        :param record: The mimimal record data for identifying the record
        :param account:    the account to carry out the request on behalf of
        :param public_id:  the public id of a public record for which this is a delete request
        :return: the Request object that was created
        """
        if record is None:
            raise RequestAPIException("You can't call 'delete' with a NoneType record argument")
        if account is None:
            raise RequestAPIException("You can't call 'delete' with a NoneType account argument")

        req = Request()
        req.record = record
        req.owner = account.id
        req.action = "delete"
        if public_id is not None:
            req.public_id = public_id

        req.save()
        return req
Ejemplo n.º 3
0
    def test_11_process_requests_exception(self):
        # What happens when the process_reuests method fails for a variety of reasons

        sources = RequestFixtureFactory.request_per_day("2001-01", 9)

        dois = ["10.1234/first", "10.1234/second", "10.1234/third"]

        # we're going to construct a series of requests for each doi
        # starting with a create, then an update, followed by a delete
        # (not that it matters, as we're going to pump them through a mock)
        for i in range(len(sources)):
            s = sources[i]
            doi_idx = i % 3  # iterate over the dois 3 times
            doi = dois[doi_idx]
            s["record"]["dc:identifier"] = [{"type": "doi", "id": doi}]
            if i < 3:
                s["record"]["dc:title"] = "Create"
                req = Request(s)
                req.action = "update"
                req.save()
            elif i < 6:
                s["record"]["dc:title"] = "Update"
                req = Request(s)
                req.action = "update"
                req.save()
            else:
                s["record"]["dc:title"] = "Delete"
                req = Request(s)
                req.action = "delete"
                req.save()

        time.sleep(2)

        # set up the mocks
        PublicApi.publish = publish_mock
        PublicApi.remove = delete_mock

        # now run the process job back to the first day
        with self.assertRaises(TestException):
            WorkflowApi.process_requests()

        # we know this died during the 6th update request being processed,
        # so just check that the workflow state reflects that
        wfs_dao = WorkflowState()
        wfs = wfs_dao.pull("requests")
        assert wfs.last_request == "2001-01-05T00:00:00Z"
        assert len(wfs.already_processed) == 1
Ejemplo n.º 4
0
    def test_05_request_dao(self):
        # Check the DAO methods on the Request object

        dao = Request()

        source = RequestFixtureFactory.example()
        req = Request(source)
        req.owner = "test1"
        req.action = "update"
        req.public_id = "abcdefg"
        req.save(blocking=True)

        req2 = dao.pull(req.id)
        assert req2 is not None

        # check successful queries for identifiers
        res = dao.find_by_identifier("doi", "10.1234/me", "test1")
        assert len(res) == 1

        res = dao.find_by_identifier("pmcid", "PMC1234", "test1")
        assert len(res) == 1

        res = dao.find_by_identifier("pmid", "87654321", "test1")
        assert len(res) == 1

        res = dao.find_by_identifier("url", "http://example.com/whatever", "test1")
        assert len(res) == 1

        # check unsuccessful ones
        res = dao.find_by_identifier("doi", "10.1234/you", "test1")
        assert len(res) == 0

        res = dao.find_by_identifier("pmcid", "PMC5678", "test1")
        assert len(res) == 0

        res = dao.find_by_identifier("pmid", "123456789", "test1")
        assert len(res) == 0

        res = dao.find_by_identifier("url", "http://example.com/this", "test1")
        assert len(res) == 0

        # and check using the wrong owner
        res = dao.find_by_identifier("doi", "10.1234/me", "test2")
        assert len(res) == 0

        res = dao.find_by_identifier("pmcid", "PMC1234", "test2")
        assert len(res) == 0

        res = dao.find_by_identifier("pmid", "87654321", "test2")
        assert len(res) == 0

        res = dao.find_by_identifier("url", "http://example.com/whatever", "test2")
        assert len(res) == 0
Ejemplo n.º 5
0
    def update(cls, record, account, public_id=None):
        """
        Record an "update" request, with the associated record data, requested by the given account

        :param record: The raw dict data (e.g. coming from the web API) which makes up the body of the request
        :param account: the account to carry out the request on behalf of
        :param public_id: The public id of a public record for which this is an update
        :return: the Request object that was created
        """
        if record is None:
            raise RequestAPIException("You can't call 'update' with a NoneType record argument")
        if account is None:
            raise RequestAPIException("You can't call 'update' with a NoneType account argument")

        req = Request()
        req.record = record
        req.owner = account.id
        req.action = "update"
        if public_id is not None:
            req.public_id = public_id

        req.save()
        return req
Ejemplo n.º 6
0
    def test_11_process_requests_cycle(self):
        # Run through the process of processing a Request into a PublicAPC

        source = RequestFixtureFactory.example()
        if "id" in source:
            del source["id"]

        pub_dao = PublicAPC()
        wfs_dao = WorkflowState()

        # first make a record for the first time
        first = deepcopy(source)
        del first["record"]["dc:title"]
        req = Request(first)
        req.owner = "test"
        req.action = "update"
        req.save(blocking=True)

        # run the job
        WorkflowApi.process_requests()

        time.sleep(2)

        # first check that a public record was made
        pubs = pub_dao.find_by_doi("10.1234/me")
        assert len(pubs) == 1
        assert pubs[0].record.get("dc:title") is None

        # check that the workflow state was created
        wfs = wfs_dao.pull("requests")
        assert wfs is not None
        assert wfs.last_request == req.created_date
        assert wfs.already_processed == [req.id]

        # now run an update with a different date
        second = deepcopy(source)
        second["record"]["dc:title"] = "Update"
        second["created_date"] = "2002-01-01T00:00:00Z"
        req2 = Request(second)
        req2.owner = "test"
        req2.action = "update"
        req2.save(blocking=True)

        # run the job again
        WorkflowApi.process_requests()

        time.sleep(2)

        # check the public record was updated
        pubs = pub_dao.find_by_doi("10.1234/me")
        assert len(pubs) == 1
        assert pubs[0].record.get("dc:title") == "Update"

        # check that the workflow state was updated
        wfs = wfs_dao.pull("requests")
        assert wfs is not None
        assert wfs.last_request == req2.created_date
        assert wfs.already_processed == [req2.id]

        # now run an update with the same date, to observe the difference in the workflow state
        third = deepcopy(source)
        third["record"]["dc:title"] = "Update 2"
        third["created_date"] = "2002-01-01T00:00:00Z"
        req3 = Request(third)
        req3.owner = "test"
        req3.action = "update"
        req3.save(blocking=True)

        # run the job again
        WorkflowApi.process_requests()

        time.sleep(2)

        # check the public record was updated
        pubs = pub_dao.find_by_doi("10.1234/me")
        assert len(pubs) == 1
        assert (
            pubs[0].record.get("dc:title") == "Update 2"
        )  # should have been updated, as there are only apc contributions from one source

        # check that the workflow state was updated
        wfs = wfs_dao.pull("requests")
        assert wfs is not None
        assert wfs.last_request == req3.created_date
        assert wfs.already_processed == [req2.id, req3.id]  # processed records should have been appended

        # finally issue a delete request
        fourth = deepcopy(source)
        fourth["created_date"] = "2003-01-01T00:00:00Z"
        req4 = Request(fourth)
        req4.owner = "test"
        req4.action = "delete"
        req4.save(blocking=True)

        # run the job again
        WorkflowApi.process_requests()

        time.sleep(2)

        # check the public record was updated
        pubs = pub_dao.find_by_doi("10.1234/me")
        assert len(pubs) == 0

        # check that the workflow state was updated
        wfs = wfs_dao.pull("requests")
        assert wfs is not None
        assert wfs.last_request == req4.created_date
        assert wfs.already_processed == [req4.id]  # processed records should have been appended