diff --git a/commentaries/forms.py b/commentaries/forms.py index d9664a43261d985084eb18f1e33ae0ae78c542f0..8eabe7a28271d453fe643365e9b3963919d5b0ad 100644 --- a/commentaries/forms.py +++ b/commentaries/forms.py @@ -4,16 +4,12 @@ from django import forms from django.shortcuts import get_object_or_404 from django.urls import reverse -from .models import Commentary +from .models import Commentary, COMMENTARY_PUBLISHED, COMMENTARY_PREPRINT from scipost.services import DOICaller, ArxivCaller from scipost.models import Contributor -def commentary_exists(input_doi): - return Commentary.objects.filter(pub_DOI=input_doi).exists() - - class DOIToQueryForm(forms.Form): VALID_DOI_REGEXP = r'^(?i)10.\d{4,9}/[-._;()/:A-Z0-9]+$' doi = forms.RegexField(regex=VALID_DOI_REGEXP, strip=False, widget=forms.TextInput( @@ -22,7 +18,7 @@ class DOIToQueryForm(forms.Form): def clean_doi(self): input_doi = self.cleaned_data['doi'] - if commentary_exists(input_doi): + if Commentary.objects.filter(pub_DOI=input_doi).exists(): error_message = 'There already exists a Commentary Page on this publication.' raise forms.ValidationError(error_message) @@ -69,35 +65,6 @@ class ArxivQueryForm(forms.Form): return {**self.arxiv_data, **additional_form_data} -# class IdentifierToQueryForm(forms.Form): -# identifier = forms.CharField(widget=forms.TextInput( -# {'label': 'arXiv identifier', -# 'placeholder': 'new style ####.####(#)v# or old-style e.g. cond-mat/#######'})) -# -# def clean(self, *args, **kwargs): -# cleaned_data = super(IdentifierToQueryForm, self).clean(*args, **kwargs) -# -# identifierpattern_new = re.compile("^[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}$") -# identifierpattern_old = re.compile("^[-.a-z]+/[0-9]{7,}v[0-9]{1,2}$") -# -# if not (identifierpattern_new.match(cleaned_data['identifier']) or -# identifierpattern_old.match(cleaned_data['identifier'])): -# msg = ('The identifier you entered is improperly formatted ' -# '(did you forget the version number?)') -# self.add_error('identifier', msg) -# -# try: -# commentary = Commentary.objects.get(arxiv_identifier=cleaned_data['identifier']) -# except (Commentary.DoesNotExist, KeyError): -# # Commentary either does not exists or form is invalid -# commentary = None -# -# if commentary: -# msg = 'There already exists a Commentary Page on this preprint, see %s' % ( -# commentary.title_label()) -# self.add_error('identifier', msg) -# return cleaned_data - class RequestCommentaryForm(forms.ModelForm): class Meta: model = Commentary @@ -114,6 +81,26 @@ class RequestArxivPreprintForm(RequestCommentaryForm): model = Commentary fields = RequestCommentaryForm.Meta.fields + ['arxiv_identifier'] + def __init__(self, *args, **kwargs): + super(RequestArxivPreprintForm, self).__init__(*args, **kwargs) + # We want arxiv_identifier to be a required field. + # Since it can be blank on the model, we have to override this property here. + self.fields['arxiv_identifier'].required = True + + # TODO: add regex here? + def clean_arxiv_identifier(self): + arxiv_identifier = self.cleaned_data['arxiv_identifier'] + + if Commentary.objects.filter(arxiv_identifier=arxiv_identifier).exists(): + error_message = 'There already exists a Commentary Page on this arXiv preprint.' + raise forms.ValidationError(error_message) + + return arxiv_identifier + + def save(self, *args, **kwargs): + self.instance.type = COMMENTARY_PREPRINT + return super(RequestArxivPreprintForm, self).save(*args, **kwargs) + class RequestPublishedArticleForm(RequestCommentaryForm): class Meta(RequestCommentaryForm.Meta): @@ -130,73 +117,15 @@ class RequestPublishedArticleForm(RequestCommentaryForm): def clean_pub_DOI(self): input_doi = self.cleaned_data['pub_DOI'] - if commentary_exists(input_doi): + if Commentary.objects.filter(pub_DOI=input_doi).exists(): error_message = 'There already exists a Commentary Page on this publication.' raise forms.ValidationError(error_message) return input_doi - -# class RequestCommentaryForm(forms.ModelForm): -# """Create new valid Commetary by user request""" -# existing_commentary = None -# -# class Meta: -# model = Commentary -# fields = ['type', 'discipline', 'domain', 'subject_area', -# 'pub_title', 'author_list', -# 'metadata', -# 'journal', 'volume', 'pages', 'pub_date', -# 'arxiv_identifier', -# 'pub_DOI', 'pub_abstract'] -# -# def __init__(self, *args, **kwargs): -# self.user = kwargs.pop('user', None) -# super(RequestCommentaryForm, self).__init__(*args, **kwargs) -# self.fields['metadata'].widget = forms.HiddenInput() -# self.fields['pub_date'].widget.attrs.update({'placeholder': 'Format: YYYY-MM-DD'}) -# self.fields['arxiv_identifier'].widget.attrs.update( -# {'placeholder': 'ex.: 1234.56789v1 or cond-mat/1234567v1'}) -# self.fields['pub_DOI'].widget.attrs.update({'placeholder': 'ex.: 10.21468/00.000.000000'}) -# self.fields['pub_abstract'].widget.attrs.update({'cols': 100}) -# -# def clean(self, *args, **kwargs): -# """Check if form is valid and contains an unique identifier""" -# cleaned_data = super(RequestCommentaryForm, self).clean(*args, **kwargs) -# -# # Either Arxiv-ID or DOI is given -# if not cleaned_data['arxiv_identifier'] and not cleaned_data['pub_DOI']: -# msg = ('You must provide either a DOI (for a published paper) ' -# 'or an arXiv identifier (for a preprint).') -# self.add_error('arxiv_identifier', msg) -# self.add_error('pub_DOI', msg) -# elif (cleaned_data['arxiv_identifier'] and -# (Commentary.objects -# .filter(arxiv_identifier=cleaned_data['arxiv_identifier']).exists())): -# msg = 'There already exists a Commentary Page on this preprint, see' -# self.existing_commentary = get_object_or_404( -# Commentary, -# arxiv_identifier=cleaned_data['arxiv_identifier']) -# self.add_error('arxiv_identifier', msg) -# elif (cleaned_data['pub_DOI'] and -# Commentary.objects.filter(pub_DOI=cleaned_data['pub_DOI']).exists()): -# msg = 'There already exists a Commentary Page on this publication, see' -# self.existing_commentary = get_object_or_404( -# Commentary, pub_DOI=cleaned_data['pub_DOI']) -# self.add_error('pub_DOI', msg) -# -# # Current user is not known -# if not self.user or not Contributor.objects.filter(user=self.user).exists(): -# self.add_error(None, 'Sorry, current user is not known to SciPost.') -# -# def save(self, *args, **kwargs): -# """Prefill instance before save""" -# self.instance.requested_by = Contributor.objects.get(user=self.user) -# return super(RequestCommentaryForm, self).save(*args, **kwargs) -# -# def get_existing_commentary(self): -# """Get Commentary if found after validation""" -# return self.existing_commentary + def save(self, *args, **kwargs): + self.instance.type = COMMENTARY_PUBLISHED + return super(RequestPublishedArticleForm, self).save(*args, **kwargs) class VetCommentaryForm(forms.Form): diff --git a/commentaries/test_forms.py b/commentaries/test_forms.py index 2dcbe54c618a0d576b41da5e4a1f6034251d7e46..b894b0cd12c5454d101fed4ee34a3beacb2fdf95 100644 --- a/commentaries/test_forms.py +++ b/commentaries/test_forms.py @@ -178,73 +178,3 @@ class TestRequestPublishedArticleForm(TestCase): invalid_data = {**self.valid_form_data, **{'pub_DOI': ''}} form = RequestPublishedArticleForm(invalid_data) self.assertEqual(form.is_valid(), False) - - -class TestRequestCommentaryForm(TestCase): - def setUp(self): - add_groups_and_permissions() - factory_instance = UnvettedCommentaryFactory.build() - self.user = UserFactory() - self.valid_form_data = model_form_data(factory_instance, RequestCommentaryForm) - - def empty_and_return_form_data(self, key): - """Empty specific valid_form_data field and return""" - self.valid_form_data[key] = None - return self.valid_form_data - - def test_valid_data_is_valid_for_arxiv(self): - """Test valid form for Arxiv identifier""" - form_data = self.valid_form_data - form_data['pub_DOI'] = '' - form = RequestCommentaryForm(form_data, user=self.user) - self.assertTrue(form.is_valid()) - - # Check if the user is properly saved to the new Commentary as `requested_by` - commentary = form.save() - self.assertTrue(commentary.requested_by) - - def test_valid_data_is_valid_for_DOI(self): - """Test valid form for DOI""" - form_data = self.valid_form_data - form_data['arxiv_identifier'] = '' - form = RequestCommentaryForm(form_data, user=self.user) - self.assertTrue(form.is_valid()) - - def test_form_has_no_identifiers(self): - """Test invalid form has no DOI nor Arxiv ID""" - form_data = self.valid_form_data - form_data['pub_DOI'] = '' - form_data['arxiv_identifier'] = '' - form = RequestCommentaryForm(form_data, user=self.user) - self.assertFalse(form.is_valid()) - self.assertTrue('arxiv_identifier' in form.errors) - self.assertTrue('pub_DOI' in form.errors) - - def test_form_with_duplicate_DOI(self): - """Test form response with already existing DOI""" - # Create a factory instance containing Arxiv ID and DOI - VettedCommentaryFactory.create() - - # Test duplicate DOI entry - form_data = self.empty_and_return_form_data('arxiv_identifier') - form = RequestCommentaryForm(form_data, user=self.user) - self.assertTrue('pub_DOI' in form.errors) - self.assertFalse(form.is_valid()) - - # Check is existing commentary is valid - existing_commentary = form.get_existing_commentary() - self.assertEqual(existing_commentary.pub_DOI, form_data['pub_DOI']) - - def test_form_with_duplicate_arxiv_id(self): - """Test form response with already existing Arxiv ID""" - VettedCommentaryFactory.create() - - # Test duplicate Arxiv entry - form_data = self.empty_and_return_form_data('pub_DOI') - form = RequestCommentaryForm(form_data, user=self.user) - self.assertTrue('arxiv_identifier' in form.errors) - self.assertFalse(form.is_valid()) - - # Check is existing commentary is valid - existing_commentary = form.get_existing_commentary() - self.assertEqual(existing_commentary.arxiv_identifier, form_data['arxiv_identifier']) diff --git a/commentaries/test_views.py b/commentaries/test_views.py index 9e7164c7d2e354f06ed2d088bac49c820662118a..66fff2218a25f2e3f337902ac91c99bed421d07a 100644 --- a/commentaries/test_views.py +++ b/commentaries/test_views.py @@ -13,41 +13,6 @@ from common.helpers.test import add_groups_and_permissions from common.helpers import model_form_data -class RequestCommentaryTest(TestCase): - """Test cases for `request_commentary` view method""" - def setUp(self): - add_groups_and_permissions() - self.view_url = reverse('commentaries:request_commentary') - self.login_url = reverse('scipost:login') - self.redirected_login_url = '%s?next=%s' % (self.login_url, self.view_url) - - def test_redirects_if_not_logged_in(self): - request = self.client.get(self.view_url) - self.assertRedirects(request, self.redirected_login_url) - - def test_valid_response_if_logged_in(self): - """Test different GET requests on view""" - request = RequestFactory().get(self.view_url) - request.user = UserFactory() - response = RequestCommentary.as_view()(request) - self.assertEqual(response.status_code, 200) - - def test_post_invalid_forms(self): - """Test different kind of invalid RequestCommentaryForm submits""" - raise NotImplementedError - - def test_saved_commentary_has_a_type(self): - self.assertEqual(Commentary.objects.count(), 0) - commentary = UnvettedCommentaryFactory.build() - valid_post_data = model_form_data(commentary, RequestPublishedArticleForm) - print(valid_post_data) - request = RequestFactory().post(reverse('commentaries:request_published_article'), valid_post_data) - request.user = UserFactory() - response = RequestPublishedArticle.as_view()(request) - - self.assertEqual(Commentary.objects.count(), 1) - - class PrefillUsingDOITest(TestCase): def setUp(self): add_groups_and_permissions() @@ -70,14 +35,16 @@ class RequestPublishedArticleTest(TestCase): self.commentary_instance = UnvettedCommentaryFactory.build() self.valid_form_data = model_form_data(self.commentary_instance, RequestPublishedArticleForm) - def test_commentary_gets_created(self): + def test_commentary_gets_created_with_correct_type(self): request = RequestFactory().post(self.target, self.valid_form_data) request.user = UserFactory() self.assertEqual(Commentary.objects.count(), 0) response = RequestPublishedArticle.as_view()(request) self.assertEqual(Commentary.objects.count(), 1) - self.assertEqual(Commentary.objects.first().pub_DOI, self.valid_form_data['pub_DOI']) + commentary = Commentary.objects.first() + self.assertEqual(commentary.pub_DOI, self.valid_form_data['pub_DOI']) + self.assertEqual(commentary.type, 'published') class RequestArxivPreprintTest(TestCase): @@ -90,14 +57,16 @@ class RequestArxivPreprintTest(TestCase): # so model_form_data doesn't include it. self.valid_form_data['arxiv_identifier'] = self.commentary_instance.arxiv_identifier - def test_commentary_gets_created(self): + def test_commentary_gets_created_with_correct_type(self): request = RequestFactory().post(self.target, self.valid_form_data) request.user = UserFactory() self.assertEqual(Commentary.objects.count(), 0) response = RequestArxivPreprint.as_view()(request) self.assertEqual(Commentary.objects.count(), 1) - self.assertEqual(Commentary.objects.first().arxiv_identifier, self.valid_form_data['arxiv_identifier']) + commentary = Commentary.objects.first() + self.assertEqual(commentary.arxiv_identifier, self.valid_form_data['arxiv_identifier']) + self.assertEqual(commentary.type, 'preprint') class VetCommentaryRequestsTest(TestCase): """Test cases for `vet_commentary_requests` view method""" diff --git a/commentaries/views.py b/commentaries/views.py index 012ce38a43df6548bb49dd6d2060f36b24790311..61dce5040952d147127c5070d2a2c640425d9290 100644 --- a/commentaries/views.py +++ b/commentaries/views.py @@ -27,43 +27,6 @@ from scipost.services import ArxivCaller import strings -################ -# Commentaries -################ - -# class RequestCommentaryMixin(object): -# def get_context_data(self, **kwargs): -# '''Pass the DOI and identifier forms to the context.''' -# if 'request_commentary_form' not in kwargs: -# # Only intercept if not prefilled -# kwargs['request_commentary_form'] = RequestCommentaryForm() -# -# context = super(RequestCommentaryMixin, self).get_context_data(**kwargs) -# -# context['existing_commentary'] = None -# context['doiform'] = DOIToQueryForm() -# context['identifierform'] = IdentifierToQueryForm() -# return context - - -# @method_decorator(permission_required( -# 'scipost.can_request_commentary_pages', raise_exception=True), name='dispatch') -# class RequestCommentary(LoginRequiredMixin, RequestCommentaryMixin, CreateView): -# form_class = RequestCommentaryForm -# template_name = 'commentaries/request_commentary.html' -# success_url = reverse_lazy('scipost:personal_page') -# -# def get_form_kwargs(self, *args, **kwargs): -# '''User should be included in the arguments to have a valid form.''' -# form_kwargs = super(RequestCommentary, self).get_form_kwargs(*args, **kwargs) -# form_kwargs['user'] = self.request.user -# return form_kwargs -# -# def form_valid(self, form): -# form.instance.parse_links_into_urls() -# messages.success(self.request, strings.acknowledge_request_commentary) -# return super(RequestCommentary, self).form_valid(form) - @permission_required('scipost.can_request_commentary_pages', raise_exception=True) def request_commentary(request): return render(request, 'commentaries/request_commentary.html') @@ -133,144 +96,6 @@ def prefill_using_arxiv_identifier(request): raise Http404 -# def prefill_using_DOI(request): -# """ Probes CrossRef API with the DOI, to pre-fill the form. """ -# if request.method == "POST": -# doiform = DOIToQueryForm(request.POST) -# if doiform.is_valid(): -# # Check if given doi is of expected form: -# doipattern = re.compile("^10.[0-9]{4,9}/[-._;()/:a-zA-Z0-9]+") -# errormessage = '' -# existing_commentary = None -# if not doipattern.match(doiform.cleaned_data['doi']): -# errormessage = 'The DOI you entered is improperly formatted.' -# elif Commentary.objects.filter(pub_DOI=doiform.cleaned_data['doi']).exists(): -# errormessage = 'There already exists a Commentary Page on this publication, see' -# existing_commentary = get_object_or_404(Commentary, -# pub_DOI=doiform.cleaned_data['doi']) -# if errormessage: -# form = RequestCommentaryForm() -# identifierform = IdentifierToQueryForm() -# context = { -# 'request_commentary_form': form, -# 'doiform': doiform, -# 'identifierform': identifierform, -# 'errormessage': errormessage, -# 'existing_commentary': existing_commentary} -# return render(request, 'commentaries/request_commentary.html', context) -# -# # Otherwise we query Crossref for the information: -# try: -# queryurl = 'http://api.crossref.org/works/%s' % doiform.cleaned_data['doi'] -# doiquery = requests.get(queryurl) -# doiqueryJSON = doiquery.json() -# metadata = doiqueryJSON -# pub_title = doiqueryJSON['message']['title'][0] -# authorlist = (doiqueryJSON['message']['author'][0]['given'] + ' ' + -# doiqueryJSON['message']['author'][0]['family']) -# for author in doiqueryJSON['message']['author'][1:]: -# authorlist += ', ' + author['given'] + ' ' + author['family'] -# journal = doiqueryJSON['message']['container-title'][0] -# -# try: -# volume = doiqueryJSON['message']['volume'] -# except KeyError: -# volume = '' -# -# pages = '' -# try: -# pages = doiqueryJSON['message']['article-number'] # for Phys Rev -# except KeyError: -# pass -# try: -# pages = doiqueryJSON['message']['page'] -# except KeyError: -# pass -# -# pub_date = '' -# try: -# pub_date = (str(doiqueryJSON['message']['issued']['date-parts'][0][0]) + '-' + -# str(doiqueryJSON['message']['issued']['date-parts'][0][1])) -# try: -# pub_date += '-' + str( -# doiqueryJSON['message']['issued']['date-parts'][0][2]) -# except (IndexError, KeyError): -# pass -# except (IndexError, KeyError): -# pass -# pub_DOI = doiform.cleaned_data['doi'] -# form = RequestCommentaryForm( -# initial={'type': 'published', 'metadata': metadata, -# 'pub_title': pub_title, 'author_list': authorlist, -# 'journal': journal, 'volume': volume, -# 'pages': pages, 'pub_date': pub_date, -# 'pub_DOI': pub_DOI}) -# identifierform = IdentifierToQueryForm() -# context = { -# 'request_commentary_form': form, -# 'doiform': doiform, -# 'identifierform': identifierform -# } -# context['title'] = pub_title -# return render(request, 'commentaries/request_commentary.html', context) -# except (IndexError, KeyError, ValueError): -# pass -# else: -# pass -# return redirect(reverse('commentaries:request_commentary')) - - -# @method_decorator(permission_required( -# 'scipost.can_request_commentary_pages', raise_exception=True), name='dispatch') -# class PrefillUsingIdentifierView(RequestCommentaryMixin, FormView): -# form_class = IdentifierToQueryForm -# template_name = 'commentaries/request_commentary.html' -# -# def form_invalid(self, identifierform): -# for field, errors in identifierform.errors.items(): -# for error in errors: -# messages.warning(self.request, error) -# return render(self.request, 'commentaries/request_commentary.html', -# self.get_context_data(**{})) -# -# def form_valid(self, identifierform): -# '''Prefill using the ArxivCaller if the Identifier is valid''' -# caller = ArxivCaller(Commentary, identifierform.cleaned_data['identifier']) -# caller.process() -# -# if caller.is_valid(): -# # Prefill the form -# metadata = caller.metadata -# pub_title = metadata['entries'][0]['title'] -# authorlist = metadata['entries'][0]['authors'][0]['name'] -# for author in metadata['entries'][0]['authors'][1:]: -# authorlist += ', ' + author['name'] -# arxiv_link = metadata['entries'][0]['id'] -# abstract = metadata['entries'][0]['summary'] -# -# initialdata = { -# 'type': 'preprint', -# 'metadata': metadata, -# 'pub_title': pub_title, -# 'author_list': authorlist, -# 'arxiv_identifier': identifierform.cleaned_data['identifier'], -# 'arxiv_link': arxiv_link, -# 'pub_abstract': abstract -# } -# context = { -# 'title': pub_title, -# 'request_commentary_form': RequestCommentaryForm(initial=initialdata) -# } -# messages.success(self.request, 'Arxiv completed') -# return render(self.request, 'commentaries/request_commentary.html', -# self.get_context_data(**context)) -# else: -# msg = caller.get_error_message() -# messages.error(self.request, msg) -# return render(self.request, 'commentaries/request_commentary.html', -# self.get_context_data(**{})) - - @permission_required('scipost.can_vet_commentary_requests', raise_exception=True) def vet_commentary_requests(request): """Show the first commentary thats awaiting vetting""" @@ -280,7 +105,6 @@ def vet_commentary_requests(request): context = {'contributor': contributor, 'commentary_to_vet': commentary_to_vet, 'form': form} return render(request, 'commentaries/vet_commentary_requests.html', context) - @permission_required('scipost.can_vet_commentary_requests', raise_exception=True) def vet_commentary_request_ack(request, commentary_id): if request.method == 'POST':