Skip to content

Commit

Permalink
Corrige a recuperação do PDF do artigo através da URL legada
Browse files Browse the repository at this point in the history
  • Loading branch information
patymori authored and Cesar Augusto committed Jun 28, 2019
1 parent f5c4bfa commit ce8d027
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 228 deletions.
278 changes: 91 additions & 187 deletions opac/tests/test_controller.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# coding: utf-8
from unittest.mock import patch, call
from unittest.mock import patch

from werkzeug.security import check_password_hash

Expand All @@ -9,8 +9,6 @@

from flask_babelex import lazy_gettext as __

from mongoengine import Q

from . import utils


Expand Down Expand Up @@ -532,139 +530,6 @@ def test_get_issues_by_jid_with_unknow_ids(self):

self.assertIsNone(issues)

@patch('webapp.controllers.Q')
def test_get_issue_info_from_assets_code_returns_ahead_info(self, MockedQuery):
journal = utils.makeOneJournal()
result = controllers.get_issue_info_from_assets_code('2019nahead', journal)
calls = [
call(journal=journal),
call(year=2019),
call(number="ahead"),
]
MockedQuery.assert_has_calls(calls, any_order=True)

@patch('webapp.controllers.Q')
def test_get_issue_info_from_assets_code_returns_volume_info(self, MockedQuery):
journal = utils.makeOneJournal()
result = controllers.get_issue_info_from_assets_code('v58n', journal)
calls = [
call(journal=journal),
call(volume="58"),
call(number=None),
call(suppl_text=None),
call(suppl_text=""),
]
MockedQuery.assert_has_calls(calls, any_order=True)

@patch('webapp.controllers.Q')
def test_get_issue_info_from_assets_code_returns_volume_and_number_info(self, MockedQuery):
journal = utils.makeOneJournal()
result = controllers.get_issue_info_from_assets_code('v58n1', journal)
calls = [
call(journal=journal),
call(volume="58"),
call(number="1"),
call(suppl_text=None),
call(suppl_text=""),
]
MockedQuery.assert_has_calls(calls, any_order=True)

@patch('webapp.controllers.Q')
def test_get_issue_info_from_assets_code_returns_volume_and_special_number_info(
self, MockedQuery
):
journal = utils.makeOneJournal()
result = controllers.get_issue_info_from_assets_code('v58nspe', journal)
calls = [
call(journal=journal),
call(volume="58"),
call(number="spe"),
call(suppl_text=None),
call(suppl_text=""),
]
MockedQuery.assert_has_calls(calls, any_order=True)

result = controllers.get_issue_info_from_assets_code('v58nspe_1', journal)
calls = [
call(journal=journal),
call(volume="58"),
call(number="spe_1"),
call(suppl_text=None),
call(suppl_text=""),
]
MockedQuery.assert_has_calls(calls, any_order=True)

@patch('webapp.controllers.Q')
def test_get_issue_info_from_assets_code_returns_volume_and_supplement_info(
self, MockedQuery
):
journal = utils.makeOneJournal()
result = controllers.get_issue_info_from_assets_code('v58s1', journal)
calls = [
call(journal=journal),
call(volume="58"),
call(number=None),
call(suppl_text="1"),
]
MockedQuery.assert_has_calls(calls, any_order=True)

result = controllers.get_issue_info_from_assets_code('v58s0', journal)
calls = [
call(journal=journal),
call(volume="58"),
call(number=None),
call(suppl_text="0"),
]
MockedQuery.assert_has_calls(calls, any_order=True)

@patch('webapp.controllers.Q')
def test_get_issue_info_from_assets_code_returns_volume_number_and_supplement_info(
self, MockedQuery
):
journal = utils.makeOneJournal()
result = controllers.get_issue_info_from_assets_code('v58n1s2', journal)
calls = [
call(journal=journal),
call(volume="58"),
call(number="1"),
call(suppl_text="2"),
]
MockedQuery.assert_has_calls(calls, any_order=True)

result = controllers.get_issue_info_from_assets_code('v58n2s0', journal)
calls = [
call(journal=journal),
call(volume="58"),
call(number="2"),
call(suppl_text="0"),
]
MockedQuery.assert_has_calls(calls, any_order=True)

@patch('webapp.controllers.Q')
def test_get_issue_info_from_assets_code_returns_number_and_supplement_info(
self, MockedQuery
):
journal = utils.makeOneJournal()
result = controllers.get_issue_info_from_assets_code('n1', journal)
calls = [
call(journal=journal),
call(volume=None),
call(number="1"),
call(suppl_text=None),
call(suppl_text=""),
]
MockedQuery.assert_has_calls(calls, any_order=True)

result = controllers.get_issue_info_from_assets_code('nspe-1', journal)
calls = [
call(journal=journal),
call(volume=None),
call(number="spe-1"),
call(suppl_text=None),
call(suppl_text=""),
]
MockedQuery.assert_has_calls(calls, any_order=True)

def test_get_issue_by_journal_and_assets_code_raises_error_if_no_assets_code(self):
"""
Teste da função controllers.get_issue_by_journal_and_issue_info() com assets_code
Expand All @@ -684,24 +549,9 @@ def test_get_issue_by_journal_and_assets_code_raises_error_if_no_journal(self):
controllers.get_issue_by_journal_and_assets_code('v1n1', {})
self.assertEqual(str(exc_info.exception), __('Obrigatório um journal.'))

@patch('webapp.controllers.get_issue_info_from_assets_code')
@patch('webapp.controllers.Issue.objects')
def test_get_issue_by_journal_and_assets_code_calls_get_issue_info_from_assets_code_if_issue_not_found(
self, mk_issue_objects, mk_get_issue_info_from_assets_code
):
"""
Teste da função controllers.get_issue_by_journal_and_issue_info() com issue não
encontrado com o assets_code e journal informado.
"""
journal = utils.makeOneJournal()
mk_issue_objects.filter.return_value.first.return_value = None
controllers.get_issue_by_journal_and_assets_code('v1n1', journal)
mk_get_issue_info_from_assets_code.assert_called_once_with('v1n1', journal)

@patch('webapp.controllers.get_issue_info_from_assets_code')
@patch('webapp.controllers.Issue.objects')
def test_get_issue_by_journal_and_assets_code_does_not_call_get_issue_info_from_assets_code_if_issue_found(
self, mk_issue_objects, mk_get_issue_info_from_assets_code
def test_get_issue_by_journal_and_assets_code_returns_filter_first_result(
self, mk_issue_objects
):
"""
Teste da função controllers.get_issue_by_journal_and_issue_info() com issue não
Expand All @@ -711,40 +561,6 @@ def test_get_issue_by_journal_and_assets_code_does_not_call_get_issue_info_from_
issue = utils.makeOneIssue()
mk_issue_objects.filter.return_value.first.return_value = issue
result = controllers.get_issue_by_journal_and_assets_code('v1n1', journal)
mk_get_issue_info_from_assets_code.assert_not_called()
self.assertEqual(result, issue)

@patch('webapp.controllers.get_issue_info_from_assets_code')
@patch('webapp.controllers.Issue.objects')
def test_get_issue_by_journal_and_assets_code_calls_Issue_filter_with_issue_info_from_assets_code(
self, mk_issue_objects, mk_get_issue_info_from_assets_code
):
"""
Teste da função controllers.get_issue_by_journal_and_issue_info() com issue não
encontrado com o assets_code e journal informado.
"""
journal = utils.makeOneJournal()
mk_issue_objects.filter.return_value.first.return_value = None
issue_query = Q(journal=journal) & Q(volume="1") & Q(number="1") & (
Q(suppl_text=None) | Q(suppl_text="")
)
mk_get_issue_info_from_assets_code.return_value = issue_query
controllers.get_issue_by_journal_and_assets_code('v1n1', journal)
mk_issue_objects.filter.assert_any_call(issue_query)

@patch('webapp.controllers.get_issue_info_from_assets_code')
@patch('webapp.controllers.Issue.objects')
def test_get_issue_by_journal_and_assets_code_returns_issue_with_issue_info(
self, mk_issue_objects, mk_get_issue_info_from_assets_code
):
"""
Teste da função controllers.get_issue_by_journal_and_issue_info() com issue não
encontrado com o assets_code e journal informado.
"""
journal = utils.makeOneJournal()
issue = utils.makeOneIssue()
mk_issue_objects.filter.return_value.first.side_effect = [None, issue]
result = controllers.get_issue_by_journal_and_assets_code('v1n1', journal)
self.assertEqual(result, issue)

def test_get_issue_by_iid(self):
Expand Down Expand Up @@ -1244,6 +1060,94 @@ def test_get_recent_articles_of_issue(self):
'2183ikoD9F', '012ijs9y14']
self.assertEqual(set(result), set(expected))

@patch('webapp.controllers.Article.objects')
def test_get_article_by_pdf_filename_retrieves_articles_by_pdf_file_path(
self, mk_article_objects
):
controllers.get_article_by_pdf_filename("abc", "v1n3s2", "article.pdf")
mk_article_objects.only.assert_called_once_with(
"pdfs"
)
mk_article_objects.only.return_value.filter.assert_called_once_with(
pdfs__url__endswith="abc/v1n3s2/article.pdf", is_public=True
)

@patch('webapp.controllers.Article.objects')
def test_get_article_by_pdf_filename_retrieves_articles_by_pdf_file_path(
self, mk_article_objects
):
controllers.get_article_by_pdf_filename("abc", "v1n3s2", "en tomo53(f2-3-4) 273-277.pdf")
mk_article_objects.only.assert_called_once_with(
"pdfs"
)
mk_article_objects.only.return_value.filter.assert_called_once_with(
pdfs__url__endswith="abc/v1n3s2/en_tomo53f2-3-4_273-277.pdf", is_public=True
)

def test_get_article_by_pdf_filename_raises_error_if_no_journal_acronym(self):
with self.assertRaises(ValueError) as exc_info:
controllers.get_article_by_pdf_filename("", "v1n3s2", "article.pdf")
self.assertEqual(
str(exc_info.exception), __('Obrigatório o acrônimo do periódico.')
)

def test_get_article_by_pdf_filename_raises_error_if_no_issue_info(self):
with self.assertRaises(ValueError) as exc_info:
controllers.get_article_by_pdf_filename("abc", "", "article.pdf")
self.assertEqual(
str(exc_info.exception), __('Obrigatório o campo issue_info.')
)

def test_get_article_by_pdf_filename_raises_error_if_no_pdf_filename(self):
with self.assertRaises(ValueError) as exc_info:
controllers.get_article_by_pdf_filename("abc", "v1n3s2", "")
self.assertEqual(
str(exc_info.exception), __('Obrigatório o nome do arquivo PDF.')
)

@patch('webapp.controllers.Article.objects')
def test_get_article_by_pdf_filename_raises_error_if_article_filter_error(
self, mk_article_objects
):
mk_article_objects.only.return_value.filter.return_value.first.side_effect = Exception
self.assertRaises(
Exception,
controllers.get_article_by_pdf_filename,
"abc",
"v1n3s2",
"article.pdf"
)

@patch('webapp.controllers.Article.objects')
def test_get_article_by_pdf_filename_returns_article_filter_result(
self, mk_article_objects
):
attrib = {
"pdfs" : [
{
"lang" : "pt",
"url" : "https://ssm.scielo.br/media/assets/abc/v1n3s2/article.pdf",
"type" : "pdf"
},
{
"lang" : "en",
"url" : "https://ssm.scielo.br/media/assets/abc/v1n3s2/en_article.pdf",
"type" : "pdf"
},
]
}
article = utils.makeOneArticle(attrib)
mk_article_objects.only.return_value.filter.return_value.first.side_effect = [
None, article
]
article_filter_results = [None, attrib['pdfs'][0]["url"]]
for filter_result in article_filter_results:
with self.subTest(filter_result=filter_result):
result = controllers.get_article_by_pdf_filename(
"abc", "v1n3s2", "article.pdf"
)
self.assertEqual(result, filter_result)


class UserControllerTestCase(BaseTestCase):

Expand Down
39 changes: 34 additions & 5 deletions opac/webapp/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -760,11 +760,7 @@ def get_issue_by_journal_and_assets_code(assets_code, journal):

if not journal:
raise ValueError(__('Obrigatório um journal.'))
issue = Issue.objects.filter(assets_code=assets_code, journal=journal).first()
if not issue:
issue_info = get_issue_info_from_assets_code(assets_code, journal)
issue = Issue.objects.filter(issue_info).first()
return issue
return Issue.objects.filter(assets_code=assets_code, journal=journal).first()


# -------- ARTICLE --------
Expand Down Expand Up @@ -954,6 +950,39 @@ def get_recent_articles_of_issue(issue_iid, is_public=True):
issue=issue_iid, is_public=is_public,
type__in=HIGHLIGHTED_TYPES).order_by('-order')


def get_article_by_pdf_filename(journal_acron, issue_info, pdf_filename):
"""
Retorna dados dos pdfs de um artigo
"""
def get_valid_name(pdf_filename):
"""
Por conta do SSM salvar os arquivos com "clean filename", é necessário
fazer a busca por ele. Na prática, o nome do arquivo tem os espaços no
início e fim removidos; outros espaços são substituídos por underscore; e
qualquer caracter que não for um alphanumérico unicode, traço, underscore ou
ponto será removido. Ex:
>>> get_valid_filename("john's portrait in 2004.jpg")
'johns_portrait_in_2004.jpg'
"""
_filename = pdf_filename.strip().replace(' ', '_')
return re.sub(r'(?u)[^-\w.]', '', _filename)

if not journal_acron:
raise ValueError(__('Obrigatório o acrônimo do periódico.'))
if not issue_info:
raise ValueError(__('Obrigatório o campo issue_info.'))
if not pdf_filename:
raise ValueError(__('Obrigatório o nome do arquivo PDF.'))
pdf_path = "/".join([journal_acron, issue_info, get_valid_name(pdf_filename)])
article = Article.objects.only("pdfs").filter(
pdfs__url__endswith=pdf_path, is_public=True).first()
if article:
for pdf in article.pdfs:
if pdf["url"].endswith(pdf_path):
return pdf["url"]


# -------- NEWS --------


Expand Down
Loading

0 comments on commit ce8d027

Please sign in to comment.