예제 #1
0
    def test_response_types(self):
        # ingest the poa and vor versions
        for path in [self.ajson_fixture_v1, self.ajson_fixture_v2]:
            ajson_ingestor.ingest_publish(json.load(open(path, 'r')))

        # map the known types to expected types
        art_list_type = 'application/vnd.elife.article-list+json;version=1'
        art_poa_type = 'application/vnd.elife.article-poa+json;version=1'
        art_vor_type = 'application/vnd.elife.article-vor+json;version=1'
        art_history_type = 'application/vnd.elife.article-history+json;version=1'

        case_list = {
            reverse('v2:article-list'): art_list_type,
            reverse('v2:article', kwargs={'id': self.msid}): art_vor_type,
            reverse('v2:article-version-list', kwargs={'id': self.msid}): art_history_type,
            reverse('v2:article-version', kwargs={'id': self.msid, 'version': 1}): art_poa_type,
            reverse('v2:article-version', kwargs={'id': self.msid, 'version': 2}): art_vor_type,
        }

        # test
        for url, expected_type in case_list.items():
            resp = self.c.get(url)
            self.assertEqual(resp.status_code, 200,
                             "url %r failed to complete: %s" % (url, resp.status_code))
            self.assertEqual(resp.content_type, expected_type,
                             "%r failed to return %r: %s" % (url, expected_type, resp.content_type))
예제 #2
0
    def setUp(self):
        self.journal = logic.journal()
        import_all = [
            '00353.1',  # discussion, VOR
            '00385.1',  # commentary, VOR
            '01328.1',  # correction, VOR
            '02619.1',  # editorial, VOR
            '03401.1',  # research, POA
            '03401.2',  # POA
            '03401.3',  # VOR
            '03665.1',  # research, VOR
            '06250.1',  # research, POA
            '06250.2',  # POA
            '06250.3',  # VOR
            '07301.1',  # research, VOR
            '08025.1',  # research, POA
            '08025.2',  # VOR
            '09571.1',  # research, POA
        ]
        for subdir in import_all:
            fname = subdir.replace('.', '-v')
            fname = "elife-%s.xml.json" % fname
            path = join(self.fixture_dir, 'ppp2', fname)
            ajson_ingestor.ingest_publish(
                self.load_ajson(path))  # strip relations

        self.vor_version_count = 9
        self.poa_version_count = 6
        self.total_version_count = self.vor_version_count + self.poa_version_count

        self.poa_art_count = 1
        self.vor_art_count = 9
        self.total_art_count = self.poa_art_count + self.vor_art_count
예제 #3
0
    def setUp(self):
        ingest_these = [
            "elife-01968-v1.xml.json",
            "elife-16695-v1.xml.json",
            "elife-16695-v2.xml.json",
            "elife-20125-v1.xml.json",
            #"elife-16695-v3.xml.json"
        ]
        ajson_dir = join(self.fixture_dir, 'ajson')
        for ingestable in ingest_these:
            data = self.load_ajson(join(ajson_dir, ingestable))
            ajson_ingestor.ingest_publish(data)

        self.msid1 = 1968
        self.msid2 = 16695
        self.msid3 = 20125

        self.av = models.ArticleVersion.objects.get(
            article__manuscript_id=self.msid1, version=1)
        self.a = models.Article.objects.get(
            manuscript_id=self.msid2)  # note: no version information

        self.citation = {
            "type": "external-article",
            "articleTitle":
            "Transcriptional amplification in tumor cells with elevated c-Myc",
            "journal": "Cell",
            "authorLine": "C. Y. Lin et al",
            "uri": "https://doi.org/10.1016/j.cell.2012.08.026"
        }
        self.citation2 = copy.deepcopy(self.citation)
        self.citation2['uri'] = 'https://doi.org/10.0000/foo'

        self.bad_citation = copy.deepcopy(self.citation)
        self.bad_citation['uri'] = 'paaaants'
예제 #4
0
    def setUp(self):
        ingest_these = [
            "elife-01968-v1.xml.json",  # => 01749
            "elife-16695-v1.xml.json",  # => []
            #"elife-16695-v2.xml.json",
            "elife-20125-v1.xml.json",  # poa
            #"elife-16695-v3.xml.json"
        ]
        ajson_dir = join(self.fixture_dir, 'ajson')
        for ingestable in ingest_these:
            path = join(ajson_dir, ingestable)
            data = json.load(open(path, 'r'))
            # remove these values here so they don't interfere in creation
            utils.delall(
                data,
                ['-related-articles-internal', '-related-articles-external'])
            ajson_ingestor.ingest_publish(data)

        self.msid1 = 1968
        self.msid2 = 16695
        self.msid3 = 20125

        self.av = models.ArticleVersion.objects.get(
            article__manuscript_id=self.msid1, version=1)
        self.a = models.Article.objects.get(
            manuscript_id=self.msid2)  # note: no version information
예제 #5
0
    def setUp(self):
        ingest_these = [
            #"elife-01968-v1.xml.json",

            "dummyelife-20125-v1.xml.json", # poa
            "dummyelife-20125-v2.xml.json", # poa
            "dummyelife-20125-v3.xml.json", # vor

            # NOT VALID, doesn't ingest
            #"elife-16695-v1.xml.json",
            #"elife-16695-v2.xml.json",
            #"elife-16695-v3.xml.json", # vor

            "dummyelife-20105-v1.xml.json", # poa
            "dummyelife-20105-v2.xml.json", # poa
            "dummyelife-20105-v3.xml.json" # poa
        ]
        ajson_dir = join(self.fixture_dir, 'ajson')
        for ingestable in ingest_these:
            path = join(ajson_dir, ingestable)
            ajson_ingestor.ingest_publish(json.load(open(path, 'r')))

        self.msid1 = 20125
        self.msid2 = 20105

        av = models.ArticleVersion.objects.get(article__manuscript_id=self.msid1, version=3)
        av.datetime_published = av.datetime_published + timedelta(days=1) # helps debug ordering
        av.save()

        self.c = Client()
예제 #6
0
    def test_article_publish_v2_forced(self):
        "an unpublished v2 article can be successfully published again, if forced"
        # ingest and publish the v1
        _, _, av = ajson_ingestor.ingest(self.ajson)
        ajson_ingestor.publish(self.msid, self.version)
        av = self.freshen(av)
        self.assertTrue(av.published())

        # modify and ingest+publish a v2
        self.ajson['article']['version'] = 2
        _, _, av2 = ajson_ingestor.ingest_publish(self.ajson)
        av2 = self.freshen(av2)
        self.assertTrue(av2.published())

        # the v2 should have been published normally.
        self.assertEqual(utils.ymd(datetime.now()), utils.ymd(av2.datetime_published))

        # give the article-json a 'versionDate' - this won't ordinarily happen until further down the line
        # but lets embed this logic while it's still fresh in everybody's heads.

        # modify the versionDate of the v2 and ingest+publish again
        yesterday = datetime.now() - timedelta(days=1)
        self.ajson['article']['versionDate'] = yesterday
        _, _, av2v2 = ajson_ingestor.ingest_publish(self.ajson, force=True)
        av2v2 = self.freshen(av2v2)
        self.assertEqual(utils.ymd(yesterday), utils.ymd(av2v2.datetime_published))
예제 #7
0
 def test_ingest_publish_no_force(self):
     "attempting to do an update without force=True fails"
     # ingest once
     ajson_ingestor.ingest_publish(self.ajson)
     # attempt second ingest
     self.assertRaises(StateError, ajson_ingestor.ingest_publish,
                       self.ajson)
예제 #8
0
    def test_add_fragment_multiple_versions(self):
        path = join(self.fixture_dir, 'ajson', "elife-20105-v2.xml.json")
        ajson_ingestor.ingest_publish(json.load(open(path, 'r')))

        key = 'test-frag'
        url = reverse('v2:article-fragment',
                      kwargs={
                          'art_id': self.msid,
                          'fragment_id': key
                      })
        fragment = {'title': 'Electrostatic selection'}

        resp = self.ac.post(url,
                            json.dumps(fragment),
                            content_type="application/json")
        self.assertEqual(resp.status_code, 200)

        # fragment is served into all article versions
        article_url = reverse('v2:article-version-list',
                              kwargs={'id': self.msid})
        resp = self.c.get(article_url)
        data = utils.json_loads(resp.content)
        self.assertEquals(len(data['versions']), 2)
        self.assertEqual(data['versions'][0]['title'], fragment['title'])
        self.assertEqual(data['versions'][1]['title'], fragment['title'])
예제 #9
0
    def setUp(self):
        ingest_these = [
            #"elife-01968-v1.xml.json",
            "elife-20125-v1.xml.json",  # poa
            "elife-20125-v2.xml.json",  # poa
            "elife-20125-v3.xml.json",  # vor

            #"elife-16695-v1.xml.json",
            #"elife-16695-v2.xml.json",
            #"elife-16695-v3.xml.json", # vor
            "elife-20105-v1.xml.json",  # poa
            "elife-20105-v2.xml.json",  # poa
            "elife-20105-v3.xml.json"  # poa
        ]
        ajson_dir = join(self.fixture_dir, 'ajson')
        for ingestable in ingest_these:
            path = join(ajson_dir, ingestable)
            ajson_ingestor.ingest_publish(json.load(open(path, 'r')))

        self.msid1 = 20125
        self.msid2 = 20105

        av = models.ArticleVersion.objects.get(
            article__manuscript_id=self.msid1, version=3)
        av.datetime_published = av.datetime_published + timedelta(
            days=1)  # helps debug ordering: 20125 is published after 20105
        av.save()

        self.c = Client()
        self.ac = Client(**{
            mware.CGROUPS: 'admin',
        })
예제 #10
0
    def test_article_publish_v2_forced(self):
        "an unpublished v2 article can be successfully published again, if forced"
        # ingest and publish the v1
        av = ajson_ingestor.ingest(self.ajson)
        ajson_ingestor.publish(self.msid, self.version)
        av = self.freshen(av)
        self.assertTrue(av.published())

        # modify and ingest+publish a v2
        self.ajson['article']['version'] = 2
        av2 = ajson_ingestor.ingest_publish(self.ajson)
        av2 = self.freshen(av2)
        self.assertTrue(av2.published())

        # the v2 should have been published normally.
        self.assertEqual(utils.ymd(datetime.now()),
                         utils.ymd(av2.datetime_published))

        # give the article-json a 'versionDate' - this won't ordinarily happen until further down the line
        # but lets embed this logic while it's still fresh in everybody's heads.

        # modify the versionDate of the v2 and ingest+publish again
        yesterday = datetime.now() - timedelta(days=1)
        self.ajson['article']['versionDate'] = yesterday
        av2v2 = ajson_ingestor.ingest_publish(self.ajson, force=True)
        av2v2 = self.freshen(av2v2)
        self.assertEqual(utils.ymd(yesterday),
                         utils.ymd(av2v2.datetime_published))
예제 #11
0
    def test_article_publish_v2_forced2(self):
        "a PUBLISHED v2 article can be successfully published (again), if forced"
        av = ajson_ingestor.ingest(self.ajson)
        ajson_ingestor.publish(self.msid, self.version)
        av = self.freshen(av)
        self.assertTrue(av.published())

        # modify and ingest+publish a v2
        self.ajson['article']['version'] = 2
        # there is a versionDate here, but because we're not forcing it, it doesn't get looked for
        # lax is the distributor of non-v1 pub dates. this may find their way into xml later, but
        # they will always come from lax.
        av2 = ajson_ingestor.ingest_publish(self.ajson)
        av2 = self.freshen(av2)
        self.assertTrue(av2.published())
        self.assertEqual(utils.ymd(datetime.now()),
                         utils.ymd(av2.datetime_published))

        # don't set a versionDate, just force a publish
        # we expect the v2.datetime_publish to remain unchanged
        del self.ajson['article'][
            'versionDate']  # remember, this was copied from a v1 that had a versionDate!
        av2v2 = ajson_ingestor.ingest_publish(self.ajson, force=True)
        av2v2 = self.freshen(av2v2)

        self.assertEqual(av2.datetime_published, av2v2.datetime_published)
예제 #12
0
 def test_ingest_publish_force(self):
     "we can do silent corrections/updates if we force it to"
     av = ajson_ingestor.ingest_publish(self.ajson)
     expected_title = 'pants-party'
     self.ajson['article']['title'] = expected_title
     av = ajson_ingestor.ingest_publish(self.ajson, force=True)
     av = self.freshen(av)
     self.assertEqual(av.title, expected_title)
예제 #13
0
 def test_ingest_publish_force(self):
     "we can do silent corrections/updates if we force it to"
     _, _, av = ajson_ingestor.ingest_publish(self.ajson)
     expected_title = 'pants-party'
     self.ajson['article']['title'] = expected_title
     _, _, av = ajson_ingestor.ingest_publish(self.ajson, force=True)
     av = self.freshen(av)
     self.assertEqual(av.title, expected_title)
예제 #14
0
 def test_publish_fails_if_invalid(self):
     "an article cannot be published if it's article-json is invalid."
     self.ajson['article']['title'] = ''
     # ValidationError is raised during ingest
     try:
         ajson_ingestor.ingest_publish(self.ajson)
     except StateError as err:
         self.assertEqual(err.code, codes.INVALID)
         self.assertEqual(err.trace.strip()[:15], "'' is too short")
예제 #15
0
 def setUp(self):
     ingest_these = [
         "elife-16695-v1.xml.json",  # research article
     ]
     ajson_dir = join(self.fixture_dir, 'ajson')
     for ingestable in ingest_these:
         path = join(ajson_dir, ingestable)
         ajson_ingestor.ingest_publish(json.load(open(path, 'r')))
     self.msid = 16695
예제 #16
0
 def setUp(self):
     ingest_these = [
         "elife-04718-v1.xml.json",  # reverse relation to 13038
         "elife-13038-v1.xml.json",  # int relation to 04718
         "elife-13620-v1.xml.json",  # ext relation
     ]
     ajson_dir = join(self.fixture_dir, 'relatedness')
     for ingestable in ingest_these:
         data = json.load(open(join(ajson_dir, ingestable), 'r'))
         ajson_ingestor.ingest_publish(data)
     self.assertEqual(models.ArticleVersion.objects.count(), 3)
예제 #17
0
 def setUp(self):
     ingest_these = [
         "elife-01968-v1.xml.json", "elife-16695-v1.xml.json",
         "elife-16695-v2.xml.json", "elife-16695-v3.xml.json"
     ]
     ajson_dir = join(self.fixture_dir, 'ajson')
     for ingestable in ingest_these:
         path = join(ajson_dir, ingestable)
         ajson_ingestor.ingest_publish(json.load(open(path, 'r')))
     self.msid1 = 1968
     self.msid2 = 16695
예제 #18
0
    def setUp(self):
        path = join(self.fixture_dir, 'ajson', "dummyelife-20105-v1.xml.json")
        ajson_ingestor.ingest_publish(json.load(open(path, 'r')))

        self.msid = 20105
        self.version = 1

        self.av = models.ArticleVersion.objects.filter(article__manuscript_id=self.msid)[0]
        self.assertTrue(self.av.published())
        self.assertTrue(fragments.merge_if_valid(self.av))

        self.c = Client()
예제 #19
0
 def test_validate_forced_action(self):
     "a dry ingest can be sent with a force flag on existing article to test validity of a silent correction"
     # article exists
     ajson = json.load(open(self.ajson_fixture_v1, 'r'))
     ajson_ingestor.ingest_publish(ajson)
     # a silent correction happens without problems
     args = [
         self.nom, '--ingest', '--dry-run', '--id', self.msid, '--version',
         1, '--force', self.ajson_fixture_v1
     ]
     errcode, stdout = self.call_command(*args)
     self.assertEqual(errcode, 0)
예제 #20
0
 def test_unacceptable_types(self):
     ajson_ingestor.ingest_publish(json.load(open(self.ajson_fixture_v1, 'r')))
     cases = [
         # vor v2 or v3
         "application/vnd.elife.article-vor+json; version=2, application/vnd.elife.article-vor+json; version=3",
         # poa v2
         "application/vnd.elife.article-poa+json; version=2",
         # ??
         "application/foo.bar.baz; version=1"
     ]
     for header in cases:
         resp = self.c.get(reverse('v2:article-version', kwargs={'id': self.msid, 'version': 1}), HTTP_ACCEPT=header)
         self.assertEqual(resp.status_code, 406, "failed on case %r, got: %s" % (header, resp.status_code))
예제 #21
0
 def test_validate_non_existant_av(self):
     "a dry ingest can be done for a non-existant article version"
     ajson = json.load(open(self.ajson_fixture_v1, 'r'))
     ajson_ingestor.ingest_publish(ajson)  # *v1*
     self.assertEqual(models.ArticleVersion.objects.count(), 1)
     args = [
         self.nom, '--ingest', '--dry-run', '--id', self.msid, '--version',
         2, self.ajson_fixture_v2
     ]  # *v2*
     errcode, stdout = self.call_command(*args)
     self.assertEqual(errcode, 0)
     self.assertEqual(models.ArticleVersion.objects.count(),
                      1)  # still just one
예제 #22
0
 def setUp(self):
     ingest_these = [
         "elife-01968-v1.xml.json",
         "elife-16695-v1.xml.json",
         "elife-16695-v2.xml.json",
         "elife-16695-v3.xml.json"
     ]
     ajson_dir = join(self.fixture_dir, 'ajson')
     for ingestable in ingest_these:
         path = join(ajson_dir, ingestable)
         ajson_ingestor.ingest_publish(json.load(open(path, 'r')))
     self.msid1 = 1968
     self.msid2 = 16695
예제 #23
0
 def test_accept_types(self):
     "various accept headers return expected response"
     ajson_ingestor.ingest_publish(json.load(open(self.ajson_fixture_v1, 'r')))
     cases = [
         "*/*",
         "application/vnd.elife.article-poa+json; version=1, application/vnd.elife.article-vor+json; version=1",
         "application/vnd.elife.article-poa+json; version=1",
         "application/vnd.elife.article-vor+json; version=1", # yes, even though the returned result is a poa
         # vor v1 or v2
         "application/vnd.elife.article-vor+json; version=1, application/vnd.elife.article-vor+json; version=2",
     ]
     for header in cases:
         resp = self.c.get(reverse('v2:article-version', kwargs={'id': self.msid, 'version': 1}), HTTP_ACCEPT=header)
         self.assertEqual(resp.status_code, 200)
예제 #24
0
 def test_validate_without_force_flag(self):
     "an invalid dry ingest fails obviously"
     # article exists
     ajson = json.load(open(self.ajson_fixture_v1, 'r'))
     ajson_ingestor.ingest_publish(ajson)
     # attempt validation of given data
     args = [
         self.nom, '--ingest', '--dry-run', '--id', self.msid, '--version',
         1, self.ajson_fixture_v1
     ]  # no force flag present
     errcode, stdout = self.call_command(*args)
     self.assertEqual(errcode, 1)  # 1 = error
     # error resp has a bucket of info
     resp = json.loads(stdout)
     self.assertTrue(
         utils.has_all_keys(resp, ['code', 'message', 'comment', 'trace']))
예제 #25
0
    def test_publish_creates_events(self):
        expected_events = [
            models.DATE_XML_RECEIVED,
            models.DATE_XML_ACCEPTED,
            models.DATETIME_ACTION_INGEST,
            models.DATETIME_ACTION_PUBLISH,
        ]
        ajson_ingestor.ingest_publish(self.with_history)
        ael = models.ArticleEvent.objects.all()
        self.assertEqual(ael.count(), len(expected_events))

        # order should be preserved
        for event_type, event_obj in zip(expected_events, ael):
            self.assertEqual(event_obj.event, event_type)
            if event_type == models.DATETIME_ACTION_PUBLISH:
                self.assertEqual(event_obj.value, "forced=False")
예제 #26
0
    def test_article_versions_list_placeholder(self):
        "invalid article-json causes a placeholder to be served instead"
        invalid_ajson = json.load(
            open(join(self.fixture_dir, 'ajson', 'elife-20125-v4.xml.json'),
                 'r'))
        invalid_ajson['article']['title'] = ''
        av = ajson_ingestor.ingest_publish(invalid_ajson, force=True)
        self.freshen(av)

        # we now have a published article in lax with invalid article-json

        resp = self.c.get(
            reverse('v2:article-version-list', kwargs={'id': self.msid1}))
        data = utils.json_loads(resp.content)

        # the invalid-but-published culprit
        v4 = data['versions'][-1]

        expected_struct = utils.json_loads(
            utils.json_dumps({
                '-invalid': True,
                'id': av.article.manuscript_id,
                'status': av.status,
                'published': av.article.datetime_published,
                'version': 4,
                'versionDate': av.datetime_published
            }))
        self.assertEqual(expected_struct, v4)
예제 #27
0
    def setUp(self):
        path = join(self.fixture_dir, 'ajson', "elife-20105-v1.xml.json")
        ajson_ingestor.ingest_publish(json.load(open(path, 'r')))

        self.msid = 20105
        self.version = 1

        self.av = models.ArticleVersion.objects.filter(
            article__manuscript_id=self.msid)[0]
        self.assertTrue(self.av.published())
        self.assertTrue(fragments.merge_if_valid(self.av))

        self.c = Client()
        self.ac = Client(**{
            mware.CGROUPS: 'admin',
        })
예제 #28
0
파일: base.py 프로젝트: Jenniferstrej/lax
    def add_or_update_article(self, **adata):
        "creates article+article-version stubs for testing"
        replacements = [
            ('pub-date', 'published'),
            ('update', 'versionDate'),
        ]
        renkeys(adata, replacements)

        struct = {
            'id':
            utils.doi2msid(adata['doi'])
            if 'doi' in adata else adata['manuscript_id'],
            'volume':
            1,
            'type':
            'research-article',
            'title':
            '[default]',
            'version':
            1,
            'status':
            models.VOR,
            'published':
            '2012-01-01T00:00:00Z'
        }
        struct.update(adata)
        delall(struct, ['journal'])  # can't be serialized, not utilised anyway

        with self.settings(VALIDATE_FAILS_FORCE=False):
            # bad ajson won't fail ingest
            av = ajson_ingestor.ingest_publish({'article': struct}, force=True)
            av.datetime_published = utils.todt(struct['published'])
            av.save()
            return av
예제 #29
0
    def test_logic_doesnt_mangle_unicode(self):
        "the api logic doesn't alter unicode values"
        ajson = json.load(open(self.ajson_fixture1, 'r'))
        ajson_ingestor.ingest_publish(ajson)

        expected = ajson['snippet']['authors'][1]['name']['preferred']

        # /articles/{id}
        given = logic.most_recent_article_version(
            self.msid).article_json_v1['authors'][1]['name']['preferred']
        self.assertEqual(expected, given)

        # /articles/{id}/versions/{version}
        given = logic.article_version(
            self.msid,
            self.version).article_json_v1['authors'][1]['name']['preferred']
        self.assertEqual(expected, given)
예제 #30
0
 def test_ingest_publish_dont_alter_unicode(self):
     "the unicode value in the scraped json isn't altered when it's ingested and published"
     ajson = json.load(open(self.ajson_fixture1, 'r'))
     av = ajson_ingestor.ingest_publish(ajson)
     av = utils.freshen(av)
     expected = ajson['snippet']['authors'][1]['name']['preferred']
     given = av.article_json_v1['authors'][1]['name']['preferred']
     self.assertEqual(expected, given)
예제 #31
0
 def setUp(self):
     # poa, published 2016-08-16T00:00:00Z
     self.ajson_fixture = join(self.fixture_dir, 'ajson',
                               'elife-16695-v1.xml.json')
     self.ajson = json.load(open(self.ajson_fixture, 'r'))
     self.msid = self.ajson['article']['id']
     self.version = self.ajson['article']['version']  # v1
     self.av = ajson_ingestor.ingest_publish(self.ajson)
예제 #32
0
    def setUp(self):
        ingest_these = [
            "elife-01968-v1.xml.json",
            "elife-16695-v1.xml.json",
            "elife-20125-v1.xml.json",
        ]
        ajson_dir = join(self.fixture_dir, 'ajson')
        for ingestable in ingest_these:
            data = self.load_ajson(join(ajson_dir, ingestable))
            ajson_ingestor.ingest_publish(data)

        self.msid1 = 1968
        self.msid2 = 16695
        self.msid3 = 20125

        self.av = models.ArticleVersion.objects.get(
            article__manuscript_id=self.msid1, version=1)
    def setUp(self):
        self.nom = 'check_article'
        self.msid_list = ["20125", "20105", "19264"] # 17267 17850 19083 18638 20143 21734 16578".split()

        ingest_these = [
            "dummyelife-20125-v1.xml.json", # poa
            "dummyelife-20125-v2.xml.json", # poa
            "dummyelife-20125-v3.xml.json", # vor

            "dummyelife-20105-v1.xml.json", # poa
            "dummyelife-20105-v2.xml.json", # poa
            "dummyelife-20105-v3.xml.json" # poa, UNPUBLISHED
        ]
        ajson_dir = join(self.fixture_dir, 'ajson')
        for ingestable in ingest_these:
            path = join(ajson_dir, ingestable)
            ajson_ingestor.ingest_publish(json.load(open(path, 'r')))
예제 #34
0
    def test_revalidate_article_from_cli(self):
        "the revalidate command can be called from the CLI for all versions of an article"
        # we need to ingest some more versions here
        fixtures = sorted(
            glob.glob(
                join(self.fixture_dir, 'ajson',
                     'elife-%s-v*.xml.json' % self.msid2)))
        for fixture in fixtures[1:]:  # don't reingest v1
            ajson_ingestor.ingest_publish(json.load(open(fixture, 'r')))
        args = [self.nom, '--id', self.msid2]
        errcode, stdout = self.call_command(*args)
        self.assertEqual(errcode, 0)

        report = json.loads(stdout)
        self.assertEqual(
            report['total-reset'],
            3)  # msid2 is untouched, all are valid, all should be reset
예제 #35
0
    def test_response_types(self):
        # ingest the poa and vor versions
        for path in [self.ajson_fixture_v1, self.ajson_fixture_v2]:
            ajson_ingestor.ingest_publish(json.load(open(path, 'r')))

        # map the known types to expected types
        art_list_type = 'application/vnd.elife.article-list+json;version=1'
        art_poa_type = 'application/vnd.elife.article-poa+json;version=1'
        art_vor_type = 'application/vnd.elife.article-vor+json;version=1'
        art_history_type = 'application/vnd.elife.article-history+json;version=1'
        art_related_type = 'application/vnd.elife.article-related+json;version=1'

        case_list = {
            reverse('v2:article-list'):
            art_list_type,
            reverse('v2:article', kwargs={'id': self.msid}):
            art_vor_type,
            reverse('v2:article-version-list', kwargs={'id': self.msid}):
            art_history_type,
            reverse('v2:article-version',
                    kwargs={
                        'id': self.msid,
                        'version': 1
                    }):
            art_poa_type,
            reverse('v2:article-version',
                    kwargs={
                        'id': self.msid,
                        'version': 2
                    }):
            art_vor_type,
            reverse('v2:article-relations', kwargs={'id': self.msid}):
            art_related_type,
        }

        # test
        for url, expected_type in case_list.items():
            resp = self.c.get(url)
            self.assertEqual(
                resp.status_code, 200,
                "url %r failed to complete: %s" % (url, resp.status_code))
            self.assertEqual(
                resp.content_type, expected_type,
                "%r failed to return %r: %s" %
                (url, expected_type, resp.content_type))
예제 #36
0
    def setUp(self):
        self.ajson_fixture = join(self.fixture_dir, 'ajson',
                                  'elife-01968-v1.xml.json')
        self.ajson = json.load(open(self.ajson_fixture, 'r'))
        self.msid = self.ajson['article']['id']
        self.version = self.ajson['article']['version']  # v1

        # populate with an article. CREATES A FRAGMENT
        self.av = ajson_ingestor.ingest_publish(self.ajson)
예제 #37
0
    def setUp(self):
        self.journal = publogic.journal()
        import_all = [
            '00353.1',  # discussion, VOR
            '00385.1',  # commentary, VOR
            '01328.1',  # correction, VOR
            '02619.1',  # editorial, VOR
            '03401.1',  # research, POA
            '03401.2',  # POA
            '03401.3',  # VOR
            '03665.1',  # research, VOR
            '06250.1',  # research, POA
            '06250.2',  # POA
            '06250.3',  # VOR
            '07301.1',  # research, VOR
            '08025.1',  # research, POA
            '08025.2',  # VOR
            '09571.1',  # research, POA
        ]
        for subdir in import_all:
            fname = subdir.replace('.', '-v')
            fname = "elife-%s.xml.json" % fname
            path = join(self.fixture_dir, 'ppp2', fname)
            ajson_ingestor.ingest_publish(
                self.load_ajson(path))  # strip relations

        # we need to coerce the data of the non-v1 articles a little
        # as we removed the eif ingestor that bypassed business logic
        cases = [
            # vor
            (3401, 3, "2014-08-01"),
            (8025, 2, "2015-06-16"),
        ]
        for msid, ver, dtstr in cases:
            av = models.ArticleVersion.objects.get(article__manuscript_id=msid,
                                                   version=ver)
            av.datetime_published = utils.todt(dtstr)
            av.save()

        self.vor_version_count = 9
        self.poa_version_count = 6

        self.poa_art_count = 1
        self.vor_art_count = 9
예제 #38
0
    def setUp(self):
        self.nom = 'revalidate'

        # publish four valid articles, ensure each is in different states

        fixture_list = [
            '01968',  # SET
            '16695',  # RESET
            '20105',  # UNSET
            '20125',  # NOTSET
        ]
        self.msid1, self.msid2, self.msid3, self.msid4 = fixture_list
        self.version = '1'

        for msid in fixture_list:
            fixture_path = join(self.fixture_dir, 'ajson',
                                'elife-%s-v1.xml.json' % msid)
            ajson_ingestor.ingest_publish(json.load(open(fixture_path, 'r')))

        # SET
        # remove the valid ajson so it gets set
        av = article_logic.article_version(self.msid1, self.version)
        av.article_json_v1 = av.article_json_v1_snippet = None
        av.save()

        # RESET
        # already valid, nothing to do

        # UNSET
        # ensure the fragment is now invalid
        av = article_logic.article_version(self.msid3, self.version)
        frag = logic.get(av, models.XML2JSON)
        frag.fragment['title'] = ''
        frag.save()

        # NOTSET
        # remove the valid article-json
        # ensure fragment is invalid and won't be set
        av = article_logic.article_version(self.msid4, self.version)
        av.article_json_v1 = av.article_json_v1_snippet = None
        av.save()
        frag = logic.get(av, models.XML2JSON)
        frag.fragment['title'] = ''
        frag.save()
예제 #39
0
    def test_article_publish_succeeds_for_published_article_if_forced(self):
        "publication of an already published article can occur only if forced"
        _, _, av = ajson_ingestor.ingest(self.ajson)
        av = ajson_ingestor.publish(self.msid, self.version)
        av = self.freshen(av)
        expected_pubdate = utils.ymd(utils.todt(self.ajson['article']['published']))
        self.assertEqual(expected_pubdate, utils.ymd(av.datetime_published))

        # publish again, no changes to pubdate expected
        av = ajson_ingestor.publish(self.msid, self.version, force=True)
        av = self.freshen(av)
        self.assertEqual(expected_pubdate, utils.ymd(av.datetime_published))

        # ingest new pubdate, force publication
        new_pubdate = utils.todt('2016-01-01')
        self.ajson['article']['published'] = new_pubdate
        ajson_ingestor.ingest_publish(self.ajson, force=True)
        av = self.freshen(av)
        self.assertEqual(utils.ymd(new_pubdate), utils.ymd(av.datetime_published))
예제 #40
0
 def test_unacceptable_types(self):
     ajson_ingestor.ingest_publish(
         json.load(open(self.ajson_fixture_v1, 'r')))
     cases = [
         # vor v2 or v3
         "application/vnd.elife.article-vor+json; version=3, application/vnd.elife.article-vor+json; version=4",
         # poa v2
         "application/vnd.elife.article-poa+json; version=3",
         # ??
         "application/foo.bar.baz; version=1"
     ]
     for header in cases:
         resp = self.c.get(reverse('v2:article-version',
                                   kwargs={
                                       'id': self.msid,
                                       'version': 1
                                   }),
                           HTTP_ACCEPT=header)
         self.assertEqual(
             resp.status_code, 406,
             "failed on case %r, got: %s" % (header, resp.status_code))
예제 #41
0
파일: ingest.py 프로젝트: elifesciences/lax
def handle_single(print_queue, action, infile, msid, version, force, dry_run):
    data = None

    log_context = {"msid": msid, "version": version}

    LOG.info("attempting to %s article %s", action, msid, extra=log_context)

    # read and check the article-json given, if necessary
    try:
        if action in [INGEST, BOTH]:
            raw_data = infile.read()
            log_context["data"] = str(raw_data[:25]) + "... (truncated)" if raw_data else ""
            data = json.loads(raw_data)
            # vagary of the CLI interface: article id and version are required
            # these may not match the data given
            data_version = data["article"].get("version")
            if not data_version == version:
                raise StateError(
                    "version in the data (%s) does not match version passed to script (%s)" % (data_version, version)
                )
            data_msid = int(data["article"]["id"])
            if not data_msid == msid:
                raise StateError(
                    "manuscript-id in the data (%s) does not match id passed to script (%s)" % (data_msid, msid)
                )

    except StateError as err:
        error(print_queue, INVALID, err.message, log_context)

    except ValueError as err:
        msg = "could not decode the json you gave me: %r for data: %r" % (err.message, raw_data)
        error(print_queue, INVALID, msg, log_context)

    choices = {
        # all these return a models.ArticleVersion object
        INGEST: lambda msid, ver, force, data, dry: ajson_ingestor.ingest(data, force, dry_run=dry)[-1],
        PUBLISH: lambda msid, ver, force, data, dry: ajson_ingestor.publish(msid, ver, force, dry_run=dry),
        BOTH: lambda msid, ver, force, data, dry: ajson_ingestor.ingest_publish(data, force, dry_run=dry)[-1],
    }

    try:
        av = choices[action](msid, version, force, data, dry_run)
        success(print_queue, action, av, log_context, dry_run)

    except StateError as err:
        error(print_queue, INVALID, "failed to call action %r: %s" % (action, err.message), log_context)

    except Exception as err:
        msg = "unhandled exception attempting to %r article: %s" % (action, err)
        LOG.exception(msg, extra=log_context)
        error(print_queue, ERROR, msg, log_context)
예제 #42
0
    def setUp(self):
        ingest_these = [
            #"elife-01968-v1.xml.json",

            "dummyelife-20125-v1.xml.json", # poa
            "dummyelife-20125-v2.xml.json", # poa
            "dummyelife-20125-v3.xml.json", # vor

            # NOT VALID, doesn't ingest
            #"elife-16695-v1.xml.json",
            #"elife-16695-v2.xml.json",
            #"elife-16695-v3.xml.json", # vor

            "dummyelife-20105-v1.xml.json", # poa
            "dummyelife-20105-v2.xml.json", # poa
            "dummyelife-20105-v3.xml.json" # poa, UNPUBLISHED
        ]
        ajson_dir = join(self.fixture_dir, 'ajson')
        for ingestable in ingest_these:
            path = join(ajson_dir, ingestable)
            ajson_ingestor.ingest_publish(json.load(open(path, 'r')))

        self.msid1 = 20125
        self.msid2 = 20105

        # 2 article, 6 versions, 5 published, 1 unpublished
        self.unpublish(self.msid2, version=3)

        # an unauthenticated client
        self.c = Client()
        # an authenticated client
        self.ac = Client(**{
            'REMOTE_ADDR': '10.0.2.6',
            mware.CGROUPS: 'user',
            mware.CID: str(uuid.uuid4()),
            mware.CUSER: '******'
        })
예제 #43
0
    def test_article_publish_v2_forced2(self):
        "a PUBLISHED v2 article can be successfully published (again), if forced"
        _, _, av = ajson_ingestor.ingest(self.ajson)
        ajson_ingestor.publish(self.msid, self.version)
        av = self.freshen(av)
        self.assertTrue(av.published())

        # modify and ingest+publish a v2
        self.ajson['article']['version'] = 2
        # there is a versionDate here, but because we're not forcing it, it doesn't get looked for
        # lax is the distributor of non-v1 pub dates. this may find their way into xml later, but
        # they will always come from lax.
        _, _, av2 = ajson_ingestor.ingest_publish(self.ajson)
        av2 = self.freshen(av2)
        self.assertTrue(av2.published())
        self.assertEqual(utils.ymd(datetime.now()), utils.ymd(av2.datetime_published))

        # don't set a versionDate, just force a publish
        # we expect the v2.datetime_publish to remain unchanged
        del self.ajson['article']['versionDate'] # remember, this was copied from a v1 that had a versionDate!
        _, _, av2v2 = ajson_ingestor.ingest_publish(self.ajson, force=True)
        av2v2 = self.freshen(av2v2)

        self.assertEqual(av2.datetime_published, av2v2.datetime_published)
예제 #44
0
    def test_ingest_publish(self):
        "ensure the shortcut ingest_publish behaves as expected"
        self.assertEqual(models.Journal.objects.count(), 0)
        self.assertEqual(models.Article.objects.count(), 0)
        self.assertEqual(models.ArticleVersion.objects.count(), 0)

        _, _, av = ajson_ingestor.ingest_publish(self.ajson)

        self.assertEqual(models.Journal.objects.count(), 1)
        self.assertEqual(models.Article.objects.count(), 1)
        self.assertEqual(models.ArticleVersion.objects.count(), 1)

        av = self.freshen(av)
        self.assertEqual(av.version, 1)
        self.assertTrue(av.published())
예제 #45
0
    def test_ingest_publish_dry_run(self):
        "specifying a dry run does not commit changes to database"
        self.assertEqual(models.Journal.objects.count(), 0)
        self.assertEqual(models.Article.objects.count(), 0)
        self.assertEqual(models.ArticleVersion.objects.count(), 0)

        j, a, av = ajson_ingestor.ingest_publish(self.ajson, dry_run=True)

        # all counts are still zero
        self.assertEqual(models.Journal.objects.count(), 0)
        self.assertEqual(models.Article.objects.count(), 0)
        self.assertEqual(models.ArticleVersion.objects.count(), 0)

        # article version believes itself to be published
        self.assertTrue(av.published())
예제 #46
0
    def test_article_publish_v2(self):
        "an unpublished v2 article can be successfully published"
        _, _, av = ajson_ingestor.ingest(self.ajson)
        self.assertEqual(models.Journal.objects.count(), 1)
        self.assertEqual(models.Article.objects.count(), 1)
        self.assertEqual(models.ArticleVersion.objects.count(), 1)
        self.assertFalse(av.published())

        ajson_ingestor.publish(self.msid, self.version)
        av = self.freshen(av)
        self.assertTrue(av.published())

        # modify to a v2 and publish
        self.ajson['article']['version'] = 2
        _, _, av2 = ajson_ingestor.ingest_publish(self.ajson)

        av2 = self.freshen(av2)
        self.assertEqual(models.ArticleVersion.objects.count(), 2)
        self.assertTrue(av2.published())
        self.assertEqual(utils.ymd(datetime.now()), utils.ymd(av2.datetime_published))
예제 #47
0
    def test_article_versions_list_placeholder(self):
        invalid_ajson = json.load(open(join(self.fixture_dir, 'ajson', 'elife-20125-v4.xml.json'), 'r'))
        invalid_ajson['article']['title'] = ''
        _, _, av = ajson_ingestor.ingest_publish(invalid_ajson, force=True)
        self.freshen(av)

        # we now have a published article in lax with invalid article-json

        resp = self.c.get(reverse('v2:article-version-list', kwargs={'id': self.msid1}))
        data = json.loads(resp.content)

        # the invalid-but-published culprit
        v4 = data['versions'][-1]

        expected_struct = json.loads(utils.json_dumps({
            '-invalid': True,
            'status': av.status,
            'published': av.article.datetime_published,
            'version': 4,
            'versionDate': av.datetime_published
        }))
        self.assertEqual(expected_struct, v4)
예제 #48
0
 def test_ingest_publish_no_force(self):
     "attempting to do an update without force=True fails"
     # ingest once
     _, _, av = ajson_ingestor.ingest_publish(self.ajson)
     # attempt second ingest
     self.assertRaises(StateError, ajson_ingestor.ingest_publish, self.ajson)