/
test_openurl.py
198 lines (164 loc) · 10.2 KB
/
test_openurl.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import time
from flask import url_for
from doajtest.fixtures import JournalFixtureFactory, ArticleFixtureFactory
from doajtest.helpers import DoajTestCase
from portality import app, models
from urllib.parse import urlparse
QUERY = 'url_ver=Z39.88-2004' \
'&url_ctx_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Actx' \
'&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Ajournal'
class TestOpenURL(DoajTestCase):
@classmethod
def setUpClass(cls):
app.testing = True
super(TestOpenURL, cls).setUpClass()
def test_01_openurl_no_atrrs(self):
""" Check we get the correct response from the OpenURL endpoints"""
with self.app_test.test_request_context():
with self.app_test.test_client() as t_client:
# No object requested - not found
resp = t_client.get(url_for('openurl.openurl'))
assert resp.status_code == 404
# Help requested - help page is displayed
resp = t_client.get(url_for('openurl.help'))
assert resp.status_code == 200
assert resp.mimetype == 'text/html'
def test_02_openurl_journal_retrieve(self):
""" Check journal retrieval via OpenURL """
[j_public_source, j_private_source] = JournalFixtureFactory.make_many_journal_sources(2, in_doaj=True)
j_public1 = models.Journal(**j_public_source)
j_public1.set_in_doaj(True)
j_public1.save(blocking=True)
j_private1 = models.Journal(**j_private_source)
j_private1.set_in_doaj(False)
j_private1.save(blocking=True)
def compare_queries(q1, q2):
q1bits = q1.split("&")
q2bits = q2.split("&")
q1bits.sort()
q2bits.sort()
return q1bits == q2bits
# Check we receive only journals in DOAJ
with self.app_test.test_request_context():
with self.app_test.test_client() as t_client:
# Make an OpenURL 0.1 request, it should be redirected into an OpenURL 1.0 request.
resp = t_client.get(url_for('openurl.openurl', issn=j_public1.bibjson().get_one_identifier('pissn')))
assert resp.status_code == 301
# Check the redirect is of the format we expect and that the in_doaj journal is accessible
query = urlparse(resp.location).query
assert compare_queries(query, QUERY + '&rft.issn=' + j_public1.bibjson().get_one_identifier('pissn'))
resp = t_client.get(resp.location)
assert resp.status_code == 302
# The same redirect should happen for a journal that's not public, but it should return a 404.
resp = t_client.get(url_for('openurl.openurl', issn=j_private1.bibjson().get_one_identifier('pissn')))
assert resp.status_code == 301
query = urlparse(resp.location).query
assert compare_queries(query, QUERY + '&rft.issn=' + j_private1.bibjson().get_one_identifier('pissn'))
resp = t_client.get(resp.location)
assert resp.status_code == 404
# Check a request in the correct format isn't redirected
resp = t_client.get(url_for('openurl.openurl',
url_ver='Z39.88-2004',
url_ctx_fmt='info:ofi/fmt:kev:mtx:ctx',
ft_val_fmt='info:ofi/fmt:kev:mtx:journal',
issn=j_public1.bibjson().get_one_identifier('pissn')))
assert resp.status_code == 302
def test_03_openurl_multiple_prarameters(self):
""" Check journal retrieval via multiple OpenURL parameters """
[j_matching_source, j_nonmatching_source] = JournalFixtureFactory.make_many_journal_sources(2, in_doaj=True)
j_matching = models.Journal(**j_matching_source)
j_matching.set_in_doaj(True)
j_matching.save(blocking=True)
param_eissn = j_matching.bibjson().first_eissn
param_pissn = j_matching.bibjson().first_pissn
param_title = j_matching.bibjson().title
art_source = ArticleFixtureFactory.make_article_source(eissn=param_eissn, pissn=param_pissn)
art_source["bibjson"]["journal"]["volume"] = "1"
art = models.Article(**art_source)
art.save(blocking=True)
j_nonmatching = models.Journal(**j_nonmatching_source)
j_nonmatching.set_in_doaj(True)
param_different_title = "A new title not the same as the old title"
j_nonmatching.bibjson().title = param_different_title
j_nonmatching.bibjson().eissn = param_eissn
j_nonmatching.bibjson().pissn = param_pissn
j_nonmatching.save(blocking=True)
with self.app_test.test_request_context():
with self.app_test.test_client() as t_client:
# A query with 3 criteria + genre journal
resp = t_client.get(url_for('openurl.openurl',
url_ver='Z39.88-2004',
url_ctx_fmt='info:ofi/fmt:kev:mtx:ctx',
ft_val_fmt='info:ofi/fmt:kev:mtx:journal',
pissn=param_pissn,
eissn=param_eissn,
jtitle=param_title,
genre='journal',
volume="1"))
assert resp.status_code == 302
# FIXME: we have removed volumes from the ToC so we can't resolve the volume in the query
# assert resp.location == url_for('doaj.toc', identifier=j_matching.id, volume="1")
assert resp.location == url_for('doaj.toc', identifier=j_matching.id)
# A query without genre to show it's the default
resp = t_client.get(url_for('openurl.openurl',
url_ver='Z39.88-2004',
url_ctx_fmt='info:ofi/fmt:kev:mtx:ctx',
ft_val_fmt='info:ofi/fmt:kev:mtx:journal',
pissn=param_pissn,
eissn=param_eissn,
jtitle=param_title))
assert resp.status_code == 302
assert resp.location == url_for('doaj.toc', identifier=j_matching.id)
# Search for the second journal by its differing title
resp = t_client.get(url_for('openurl.openurl',
url_ver='Z39.88-2004',
url_ctx_fmt='info:ofi/fmt:kev:mtx:ctx',
ft_val_fmt='info:ofi/fmt:kev:mtx:journal',
issn=param_pissn,
eissn=param_eissn,
jtitle=param_different_title,
genre='journal'))
assert resp.status_code == 302
assert resp.location == url_for('doaj.toc', identifier=j_nonmatching.id)
# Relaxing title constraint means both journals match, but we're served the 'best match' according to ES
resp = t_client.get(url_for('openurl.openurl',
url_ver='Z39.88-2004',
url_ctx_fmt='info:ofi/fmt:kev:mtx:ctx',
ft_val_fmt='info:ofi/fmt:kev:mtx:journal',
issn=param_pissn,
eissn=param_eissn))
assert resp.status_code == 302
def test_04_openurl_article_retrieve(self):
""" Check we can retrieve articles from OpenURL """
[j_indoaj_source, j_notindoaj_source] = JournalFixtureFactory.make_many_journal_sources(2, in_doaj=True)
j_indoaj = models.Journal(**j_indoaj_source)
j_indoaj.save(blocking=True)
j_indoaj_arts = ArticleFixtureFactory.make_many_article_sources(2, in_doaj=True,
pissn=j_indoaj.bibjson().first_pissn,
eissn=j_indoaj.bibjson().first_eissn)
[models.Article(**m).save(blocking=True) for m in j_indoaj_arts]
j_notindoaj = models.Journal(**j_notindoaj_source)
j_notindoaj.set_in_doaj(False)
j_notindoaj.save(blocking=True)
notindoaj_arts = ArticleFixtureFactory.make_many_article_sources(2, in_doaj=False,
pissn=j_notindoaj.bibjson().first_pissn,
eissn=j_notindoaj.bibjson().first_eissn)
[models.Article(**m).save(blocking=True) for m in notindoaj_arts]
# Check we can get an in_doaj article from an openURL request
with self.app_test.test_request_context():
with self.app_test.test_client() as t_client:
# Make an OpenURL 0.1 request, it should be redirected into an OpenURL 1.0 request.
resp = t_client.get(url_for('openurl.openurl', genre='article', aulast='The Author'))
assert resp.status_code == 301
# Check the redirect works and the in_doaj article is accessible
resp = t_client.get(resp.location)
assert resp.status_code == 302
retrieved_article_id = resp.location.split('/').pop()
art = models.Article.pull(retrieved_article_id)
assert art.is_in_doaj() is True
# Check we can't retrieve an article that's not in_doaj (but the redirect occurs)
title = notindoaj_arts.pop()['bibjson']['title']
resp = t_client.get(url_for('openurl.openurl', genre='article', atitle=title))
assert resp.status_code == 301
resp = t_client.get(resp.location)
assert resp.status_code == 404