Skip to content

Commit

Permalink
EREGCSC-2499 -- Enable subject lookup for non-logged in users (#1167)
Browse files Browse the repository at this point in the history
* feat: remove IsAuthenticatedMixin from PolicyRepo django view

* feat: disable doc type switcher and check Public if unauthenticated

* feat: add navigation guard to remove type query param if unauth

* feat: hide internal resource count in subj TOC if unAuth

* chore: restrict nav guard to policy-repository

* chore: tweak pluralization of resource number label in subject TOC

* feat: never cache content-search API responses on policy repository

* chore: remove unused import

* feat: change content-search response behavior if unAuth internal req

* feat: correct logic for response from content-search to unAuth user

* test: update content_search test_search tests

* test: remove space from string to assert against

* feat: add login banner to policy repo sidebar

* test: add e2e test coverage when not logged in

* refactor: convert confusing nested ternary to if/else blocks

* test: a11y check for logged out view

* test: update logout test

* test: assert that type query param is removed from URL when logged out

* chore: update comment
  • Loading branch information
PhilR8 authored Feb 12, 2024
1 parent 1d043a9 commit 55094bb
Show file tree
Hide file tree
Showing 13 changed files with 280 additions and 60 deletions.
6 changes: 4 additions & 2 deletions solution/backend/content_search/tests/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ def setUp(self):
index_group(UploadedFile.objects.all())

def test_no_query_not_logged_in(self):
response = self.client.get("/v3/content-search/?resource-type=internal")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
response = self.client.get("/v3/content-search/?resource-type=external")
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = get_paginated_data(response)
self.assertEqual(data['count'], 6)
response = self.client.get("/v3/content-search/?resource-type=internal")
response = self.client.get("/v3/content-search/?resource-type=all")
data = get_paginated_data(response)
self.assertEqual(data['count'], 6)
response = self.client.get("/v3/content-search/?resource-type=all")
response = self.client.get("/v3/content-search/")
data = get_paginated_data(response)
self.assertEqual(data['count'], 6)

Expand Down
12 changes: 9 additions & 3 deletions solution/backend/content_search/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from django.urls import reverse
from drf_spectacular.utils import extend_schema
from rest_framework import viewsets
from rest_framework.exceptions import NotAuthenticated
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
Expand Down Expand Up @@ -82,11 +83,16 @@ def list(self, request):
repo_category_prefetch = AbstractRepoCategory.objects.all().select_subclasses()\
.select_related("repositorysubcategory__parent")

# If they are not authenticated they csan only get 'external' documents
if not request.user.is_authenticated or resource_type == 'external':
query = query.filter(resource_type='external')
# If they are not authenticated and the resource type is internal, raise an error
if not request.user.is_authenticated:
if resource_type == 'internal':
raise NotAuthenticated()
else:
query = query.filter(resource_type='external')
elif resource_type == 'internal':
query = query.filter(resource_type='internal')
elif resource_type == 'external':
query = query.filter(resource_type='external')

context = self.get_serializer_context()
context['content_id'] = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
{% endblock %}

{% block body %}

<div
id="vite-app"
data-api-url="{{ API_BASE }}"
data-about-url="{% url 'about' %}"
data-custom-login-url="{% url 'custom_login' %}"
data-custom-url="{{ CUSTOM_URL }}"
data-home-url="{% url 'homepage' %}"
data-resources-url="{% url 'resources' %}"
Expand Down
4 changes: 1 addition & 3 deletions solution/backend/regulations/views/policy_repository.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from django.views.generic.base import TemplateView

from regulations.views.mixins import IsAuthenticatedMixin


class PolicyRepositoryView(IsAuthenticatedMixin, TemplateView):
class PolicyRepositoryView(TemplateView):

template_name = 'regulations/policy_repository.html'

Expand Down
149 changes: 130 additions & 19 deletions solution/ui/e2e/cypress/e2e/policy-repository.spec.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Cypress.Commands.add("getPolicyDocs", ({ username, password }) => {
fixture: "policy-docs.json",
}).as("subjectFiles");
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/"});
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.visit("/policy-repository/?q=mock");
cy.injectAxe();
cy.wait("@subjectFiles").then((interception) => {
Expand All @@ -42,15 +42,67 @@ Cypress.Commands.add("getPolicyDocs", ({ username, password }) => {
describe("Policy Repository", () => {
beforeEach(_beforeEach);

it("shows the custom eua login screen when you visit /policy-repository/ without logging in", () => {
it("shows the custom eua login screen when you visit /policy-repository/ and click 'sign in'", () => {
cy.viewport("macbook-15");
cy.visit("/policy-repository/");
cy.get(".div__login-sidebar a").click();
cy.url().should("include", "/login");
});

it("should show the policy repository page when logged in", () => {
it("should show only public items when logged out", () => {
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.visit("/policy-repository/");

cy.injectAxe();

cy.get("#loginIndicator").should("not.be.visible");
cy.get(".doc-type__toggle fieldset > div")
.eq(0)
.find("input")
.should("be.checked")
.and("be.disabled");
cy.get(".doc-type__toggle fieldset > div")
.eq(1)
.find("input")
.should("not.be.checked")
.and("be.disabled");

cy.checkAccessibility();

cy.get(
".subj-toc__list li[data-testid=subject-toc-li-3] a"
).scrollIntoView();
cy.get(
".subj-toc__list li[data-testid=subject-toc-li-3] div.subj-toc-li__count"
)
.should("be.visible")
.and("have.text", "0 public resources");
cy.get(
".subj-toc__list li[data-testid=subject-toc-li-63] a"
).scrollIntoView();
cy.get(".subj-toc__list li[data-testid=subject-toc-li-63] a")
.should("have.text", " Managed Care ")
.click({ force: true });
cy.url().should("include", "/policy-repository?subjects=63");
cy.get(".subject__heading")
.should("exist")
.and("have.text", "Managed Care");
cy.url().should("include", "/policy-repository?subjects=63");
})

it("should strip document-type query parameter from URL when not logged in", () => {
cy.viewport("macbook-15");
cy.visit("/policy-repository/?type=internal");
cy.url().should("not.include", "type");
})

it("should show public and internal items when logged in", () => {
cy.viewport("macbook-15");
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository");
cy.url().should("include", "/policy-repository/");
cy.get("#loginIndicator").should("be.visible");
Expand All @@ -62,7 +114,7 @@ describe("Policy Repository", () => {
".subj-toc__list li[data-testid=subject-toc-li-3] div.subj-toc-li__count"
)
.should("be.visible")
.and("have.text", "0 public and 1 internal resources ");
.and("have.text", "0 public and 1 internal resources");
cy.get(
".subj-toc__list li[data-testid=subject-toc-li-63] a"
).scrollIntoView();
Expand Down Expand Up @@ -139,7 +191,11 @@ describe("Policy Repository", () => {
it("should make a successful request to the content-search endpoint", () => {
cy.intercept("**/v3/content-search/?**").as("files");
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository");
cy.url().should("include", "/policy-repository/");
cy.get(".subj-toc__list li:nth-child(1) a").click({ force: true });
Expand All @@ -150,7 +206,11 @@ describe("Policy Repository", () => {

it("loads the correct subject and search query when the URL is changed", () => {
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});

cy.visit("/policy-repository");
cy.url().should("include", "/policy-repository/");
Expand Down Expand Up @@ -271,7 +331,11 @@ describe("Policy Repository", () => {
fixture: "policy-docs.json",
}).as("subjectFiles");
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});

cy.visit("/policy-repository/");
cy.get(".doc-type__toggle fieldset > div")
Expand Down Expand Up @@ -304,7 +368,9 @@ describe("Policy Repository", () => {
"include",
"/policy-repository?type=internal&subjects=3&q=test%20search"
);
cy.get(".search-form .form-helper-text .search-suggestion").should("not.exist");
cy.get(".search-form .form-helper-text .search-suggestion").should(
"not.exist"
);
cy.get(".document__subjects a")
.eq(0)
.should("have.text", " Access to Services ");
Expand Down Expand Up @@ -334,7 +400,11 @@ describe("Policy Repository", () => {

it("should display correct subject ID number in the URL if one is included in the URL on load and different one is selected via the Subject Selector", () => {
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository/?subjects=77");
cy.url().should("include", "/policy-repository/?subjects=77");
cy.get(`button[data-testid=remove-subject-77]`).should("exist");
Expand All @@ -356,7 +426,11 @@ describe("Policy Repository", () => {

it("should filter the subject list when a search term is entered into the subject filter", () => {
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository/");

cy.injectAxe();
Expand Down Expand Up @@ -407,7 +481,11 @@ describe("Policy Repository", () => {
it("should display and fetch the correct search query on load if it is included in URL", () => {
cy.intercept("**/v3/content-search/?q=test**").as("qFiles");
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository/?q=test");
cy.wait("@qFiles").then((interception) => {
expect(interception.response.statusCode).to.eq(200);
Expand All @@ -418,7 +496,11 @@ describe("Policy Repository", () => {

it("should have a Documents to Show checkbox list", () => {
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository");
cy.get(".doc-type__toggle-container h3").should(
"have.text",
Expand Down Expand Up @@ -448,7 +530,11 @@ describe("Policy Repository", () => {

it("should show only the Table of Contents if both or neither checkboxes are checked", () => {
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository");
cy.get(".subj-toc__container").should("exist");
cy.get(".doc-type__toggle fieldset > div")
Expand Down Expand Up @@ -476,7 +562,11 @@ describe("Policy Repository", () => {
it("should not make a request to the content-search endpoint if both checkboxes are checked on load", () => {
cy.intercept("**/v3/content-search/**").as("contentSearch");
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository");
cy.wait(2000);
cy.get("@contentSearch.all").then((interception) => {
Expand All @@ -486,7 +576,11 @@ describe("Policy Repository", () => {

it("goes to another SPA page from the policy repository page", () => {
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository");
cy.clickHeaderLink({ page: "Resources", screen: "wide" });
cy.url().should("include", "/resources");
Expand Down Expand Up @@ -548,10 +642,25 @@ describe("Policy Repository", () => {

it("returns you to the custom eua login page when you log out", () => {
cy.viewport("macbook-15");
cy.eregsLogin({ username, password, landingPage: "/policy-repository/" });
cy.eregsLogin({
username,
password,
landingPage: "/policy-repository/",
});
cy.visit("/policy-repository");
cy.get("#logout").click();
cy.url().should("include", "/login");
cy.url().should("include", "/policy-repository");
cy.get("#loginIndicator").should("not.be.visible");
cy.get(".doc-type__toggle fieldset > div")
.eq(0)
.find("input")
.should("be.checked")
.and("be.disabled");
cy.get(".doc-type__toggle fieldset > div")
.eq(1)
.find("input")
.should("not.be.checked")
.and("be.disabled");
});
});

Expand Down Expand Up @@ -593,7 +702,9 @@ describe("Policy Repository Search", () => {
force: true,
});
cy.url().should("include", "/policy-repository/search?q=test%20search");
cy.get(".search-form .form-helper-text .search-suggestion").should("not.exist");
cy.get(".search-form .form-helper-text .search-suggestion").should(
"not.exist"
);
cy.wait("@queriedFiles").then((interception) => {
expect(interception.response.statusCode).to.eq(200);
});
Expand Down
8 changes: 8 additions & 0 deletions solution/ui/regulations/css/scss/_application_settings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -575,3 +575,11 @@ select {
height: 32px;
padding: 0 12px;
}

.div__login-sidebar {
background-color: $secondary_background_color;
border: 1px solid $border_color;
border-radius: 0.25rem;
padding: 0.5rem;
margin: 1rem 0;
}
8 changes: 0 additions & 8 deletions solution/ui/regulations/css/scss/partials/_sidebar_right.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,6 @@ aside.right-sidebar {
margin-bottom: 0px !important;
}

.div__login-sidebar {
background-color: $secondary_background_color;
border: 1px solid $border_color;
border-radius: 0.25rem;
padding: 0.5rem;
margin: 1rem 0;
}

.label__container {
display: flex;
margin-top: 1rem;
Expand Down
5 changes: 5 additions & 0 deletions solution/ui/regulations/eregs-vite/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export default {
type: String,
default: "/about/",
},
customLoginUrl: {
type: String,
default: "",
},
customUrl: {
type: String,
default: "",
Expand Down Expand Up @@ -54,6 +58,7 @@ export default {
<router-view
:api-url="apiUrl"
:about-url="aboutUrl"
:custom-login-url="customLoginUrl"
:custom-url="customUrl"
:home-url="homeUrl"
:resources-url="resourcesUrl"
Expand Down
Loading

0 comments on commit 55094bb

Please sign in to comment.