diff --git a/geniza/corpus/tests/test_corpus_views.py b/geniza/corpus/tests/test_corpus_views.py index bf0b7ecf6..fbd760eef 100644 --- a/geniza/corpus/tests/test_corpus_views.py +++ b/geniza/corpus/tests/test_corpus_views.py @@ -96,6 +96,25 @@ def test_get_absolute_url(self, document): document.get_absolute_url() ) + def test_last_modified(self, client, document, join): + """Ensure that the last modified header is set in the HEAD response""" + SolrClient().update.index([document.index_data()], commit=True) + response = client.head(document.get_absolute_url()) + assert response["Last-Modified"] + init_last_modified = response["Last-Modified"] + + # Sleeping is required to ensure that the last modified header is different. + sleep(1) + + # Ensure that only one last modified header is updated when a document is updated. + SolrClient().update.index([join.index_data()], commit=True) + updated_doc_response = client.head(join.get_absolute_url()) + other_doc_response = client.head(document.get_absolute_url()) + assert ( + updated_doc_response["Last-Modified"] != other_doc_response["Last-Modified"] + ) + assert init_last_modified == other_doc_response["Last-Modified"] + @pytest.mark.django_db def test_old_pgp_tabulate_data(): @@ -601,6 +620,25 @@ def test_dispatch(self, client): # should not redirect assert response.status_code == 200 + def test_last_modified(self, client, document): + """Ensure that the last modified header is set in the response""" + SolrClient().update.index([document.index_data()], commit=True) + response = client.head(reverse("corpus:document-search")) + assert response["Last-Modified"] + init_last_modified = response["Last-Modified"] + + # Sleep to ensure the last modified header is different. Last-Modified only + # has a resolution of 1 second. + sleep(1) + + # Ensure that a document being suppressed changes the last modified header + document.status = Document.SUPPRESSED + document.save() + SolrClient().update.index([document.index_data()], commit=True) + response = client.head(reverse("corpus:document-search")) + new_last_modified = response["Last-Modified"] + assert new_last_modified != init_last_modified + class TestDocumentScholarshipView: def test_page_title(self, document, client, source): diff --git a/geniza/corpus/views.py b/geniza/corpus/views.py index 4a129158f..6dae8a3a6 100644 --- a/geniza/corpus/views.py +++ b/geniza/corpus/views.py @@ -15,6 +15,7 @@ from django.utils.translation import ngettext from django.views.generic import DetailView, FormView, ListView from django.views.generic.edit import FormMixin +from parasolr.django.views import SolrLastModifiedMixin from piffle.presentation import IIIFPresentation from tabular_export.admin import export_to_csv_response @@ -27,7 +28,7 @@ from geniza.footnotes.models import Footnote -class DocumentSearchView(ListView, FormMixin): +class DocumentSearchView(ListView, FormMixin, SolrLastModifiedMixin): model = Document form_class = DocumentSearchForm context_object_name = "documents" @@ -38,6 +39,7 @@ class DocumentSearchView(ListView, FormMixin): page_description = _("Search and browse Geniza documents.") paginate_by = 50 initial = {"sort": "random"} + solr_lastmodified_filters = {"item_type_s": "document"} # map form sort to solr sort field solr_sort = { @@ -192,8 +194,8 @@ def get_context_data(self, **kwargs): return context_data -class DocumentPastIdMixin: - """View mixin to handle redirects for documents with old PGPIDs. +class DocumentDetailBase(SolrLastModifiedMixin): + """View mixin to handle lastmodified and redirects for documents with old PGPIDs. Overrides get request in the case of a 404, looking for any records with passed PGPID in old_pgpids, and if found, redirects to that document with current PGPID.""" @@ -213,8 +215,12 @@ def get(self, request, *args, **kwargs): # otherwise, continue raising the 404 raise + def get_solr_lastmodified_filters(self): + """Filter solr last modified query by pgpid""" + return {"pgpid_i": self.kwargs["pk"], "item_type_s": "document"} -class DocumentDetailView(DocumentPastIdMixin, DetailView): + +class DocumentDetailView(DocumentDetailBase, DetailView): """public display of a single :class:`~geniza.corpus.models.Document`""" model = Document