-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #62 from ministryofjustice/dp-3182-views-and-forms…
…-tests Dp-3182-views-and-forms-tests
- Loading branch information
Showing
14 changed files
with
451 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
name: test | ||
# based on https://jacobian.org/til/github-actions-poetry/ | ||
|
||
on: | ||
pull_request: | ||
types: [opened, edited, reopened, synchronize] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-python@v2 | ||
with: | ||
python-version: 3.11.1 | ||
- name: cache poetry install | ||
uses: actions/cache@v2 | ||
with: | ||
path: ~/.local | ||
key: poetry-1.7.1-0 | ||
- uses: snok/install-poetry@v1 | ||
with: | ||
version: 1.7.1 | ||
virtualenvs-create: true | ||
virtualenvs-in-project: true | ||
- name: cache deps | ||
id: cache-deps | ||
uses: actions/cache@v2 | ||
with: | ||
path: .venv | ||
key: pydeps-${{ hashFiles('**/poetry.lock') }} | ||
- run: poetry install --no-interaction --no-root | ||
if: steps.cache-deps.outputs.cache-hit != 'true' | ||
- run: poetry install --no-interaction | ||
- name: test with coverage | ||
run: poetry run pytest --cov |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
from random import choice | ||
from unittest.mock import MagicMock, patch | ||
|
||
import pytest | ||
from data_platform_catalogue.client import BaseCatalogueClient | ||
from data_platform_catalogue.search_types import (FacetOption, ResultType, | ||
SearchFacets, SearchResponse, | ||
SearchResult) | ||
from django.test import Client | ||
from faker import Faker | ||
|
||
fake = Faker() | ||
|
||
|
||
def generate_page(page_size=20): | ||
""" | ||
Generate a fake search page | ||
""" | ||
results = [] | ||
for _ in range(page_size): | ||
results.append( | ||
SearchResult( | ||
id=fake.unique.name(), | ||
result_type=choice( | ||
(ResultType.DATA_PRODUCT, ResultType.TABLE)), | ||
name=fake.name(), | ||
description=fake.paragraphs(), | ||
) | ||
) | ||
return results | ||
|
||
|
||
def generate_options(num_options=5): | ||
""" | ||
Generate a list of options for the search facets | ||
""" | ||
results = [] | ||
for _ in range(num_options): | ||
results.append( | ||
FacetOption( | ||
value=fake.name(), | ||
label=fake.name(), | ||
count=fake.random_int(min=0, max=100), | ||
) | ||
) | ||
return results | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def client(): | ||
client = Client() | ||
return client | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def mock_catalogue(): | ||
patcher = patch("home.service.base.GenericService._get_catalogue_client") | ||
mock_fn = patcher.start() | ||
mock_catalogue = MagicMock(spec=BaseCatalogueClient) | ||
mock_fn.return_value = mock_catalogue | ||
mock_search_response( | ||
mock_catalogue, page_results=generate_page(), total_results=100) | ||
mock_search_facets_response(mock_catalogue, domains=generate_options()) | ||
|
||
yield mock_catalogue | ||
|
||
patcher.stop() | ||
|
||
|
||
def mock_search_response(mock_catalogue, total_results=0, page_results=()): | ||
search_response = SearchResponse( | ||
total_results=total_results, page_results=page_results) | ||
mock_catalogue.search.return_value = search_response | ||
|
||
|
||
def mock_search_facets_response(mock_catalogue, domains): | ||
mock_catalogue.search_facets.return_value = SearchFacets( | ||
{"domains": domains}) |
Empty file.
Empty file.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from home.forms.search import SearchForm | ||
import pytest | ||
|
||
|
||
@pytest.fixture | ||
def valid_form(): | ||
valid_form = SearchForm( | ||
data={ | ||
"query": "test", | ||
"domains": ["urn:li:domain:HMCTS"], | ||
"sort": "ascending", | ||
"clear_filter": False, | ||
"clear_label": False, | ||
} | ||
) | ||
assert valid_form.is_valid() | ||
|
||
return valid_form | ||
|
||
|
||
class TestSearchForm: | ||
def test_query_field_length(self): | ||
over_100_characters = "a" * 101 | ||
assert not SearchForm(data={"query": over_100_characters}).is_valid() | ||
|
||
def test_domain_is_from_domain_list_false(self): | ||
assert not SearchForm(data={"domains": ["fake"]}).is_valid() | ||
|
||
def test_sort_is_from_sort_list_false(self): | ||
assert not SearchForm(data={"sort": ["fake"]}).is_valid() | ||
|
||
def test_all_fields_nullable(self): | ||
assert SearchForm(data={}).is_valid() | ||
|
||
def test_form_encode_without_filter_for_one_filter(self, valid_form): | ||
assert (valid_form.encode_without_filter("urn:li:domain:HMCTS") == | ||
"?query=test&sort=ascending&clear_filter=False&clear_label=False") | ||
|
||
def test_form_encode_without_filter_for_two_filters(self): | ||
two_filter_form = SearchForm(data={ | ||
"query": "test", | ||
"domains": ["urn:li:domain:HMCTS", "urn:li:domain:HMPPS"] | ||
}) | ||
two_filter_form.is_valid() | ||
|
||
assert (two_filter_form.encode_without_filter("urn:li:domain:HMCTS") == | ||
"?query=test&domains=urn%3Ali%3Adomain%3AHMPPS&sort=&clear_filter=False&clear_label=False") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
|
||
from data_platform_catalogue.search_types import SearchResponse | ||
from django.urls import reverse | ||
|
||
|
||
class TestSearchView: | ||
""" | ||
Test the view renders the correct context depending on query parameters and session | ||
""" | ||
|
||
def test_renders_200(self, client): | ||
response = client.get(reverse("home:search"), data={}) | ||
assert response.status_code == 200 | ||
|
||
def test_exposes_results(self, client): | ||
response = client.get(reverse("home:search"), data={}) | ||
assert response.status_code == 200 | ||
assert len(response.context["results"]) == 20 | ||
|
||
def test_exposes_empty_query(self, client): | ||
response = client.get(reverse("home:search"), data={}) | ||
assert response.status_code == 200 | ||
assert response.context["form"].cleaned_data["query"] == "" | ||
|
||
def test_exposes_query(self, client): | ||
response = client.get(reverse("home:search"), data={"query": "foo"}) | ||
assert response.status_code == 200 | ||
assert response.context["form"].cleaned_data["query"] == "foo" | ||
|
||
def test_bad_form(self, client): | ||
response = client.get(reverse("home:search"), data={"domains": "fake"}) | ||
assert response.status_code == 400 | ||
|
||
|
||
class TestDetailsView: | ||
def test_details(self, client): | ||
response = client.get( | ||
reverse("home:details", kwargs={ | ||
"id": "urn:li:dataProduct:common-platform"}) | ||
) | ||
assert response.status_code == 200 | ||
|
||
def test_details_not_found(self, client, mock_catalogue): | ||
mock_catalogue.search.return_value = SearchResponse( | ||
total_results=0, page_results=[] | ||
) | ||
response = client.get(reverse("home:details", kwargs={"id": "fake"})) | ||
assert response.status_code == 404 |