diff --git a/app/__init__.py b/app/__init__.py index 11a7b8f0e..62e45aaa9 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -10,15 +10,9 @@ search_api_client = apiclient.SearchAPIClient() feature_flags = flask_featureflags.FeatureFlag() -questions_loader = ContentLoader( - "app/content/frameworks/g-cloud-6/manifests/search_filters.yml", - "app/content/frameworks/g-cloud-6/questions/services/" -) - -service_questions_loader = ContentLoader( - "app/content/frameworks/g-cloud-6/manifests/display_service.yml", - "app/content/frameworks/g-cloud-6/questions/services/" -) +content_loader = ContentLoader('app/content') +content_loader.load_manifest('g-cloud-6', 'services', 'search_filters') +content_loader.load_manifest('g-cloud-6', 'services', 'display_service') def create_app(config_name): diff --git a/app/helpers/search_helpers.py b/app/helpers/search_helpers.py index 891f453d9..e7e567c72 100644 --- a/app/helpers/search_helpers.py +++ b/app/helpers/search_helpers.py @@ -79,7 +79,7 @@ def clean_request_args(request_args, lot_filters): return clean_args -def group_request_filters(request_filters, content_loader): +def group_request_filters(request_filters, content_builder): """Groups filters using ','/& according to question type. * Questions of type "radios" result in OR filters - there's only one @@ -94,7 +94,7 @@ def group_request_filters(request_filters, content_loader): """ filter_query = {} for key, values in request_filters.lists(): - if content_loader.get_question(key).get("type") == 'radios': + if is_radio_type(content_builder, key): filter_query[key] = ','.join(values) elif len(values) == 1: filter_query[key] = values[-1] @@ -104,6 +104,14 @@ def group_request_filters(request_filters, content_loader): return filter_query +def is_radio_type(content_builer, key): + if key == 'lot': + return True + + question = content_builer.get_question(key) or {} + return question.get('type') == 'radios' + + def replace_g5_search_dots(keywords_query): """Replaces '.' with '-' in G5 service IDs to support old ID search format.""" @@ -114,7 +122,7 @@ def replace_g5_search_dots(keywords_query): ) -def build_search_query(request, lot_filters, content_loader): +def build_search_query(request, lot_filters, content_builder): """Match request args with known filters. Removes any unknown query parameters, and will only keep `page`, `q` @@ -132,7 +140,7 @@ def build_search_query(request, lot_filters, content_loader): if 'q' in query: query['q'] = replace_g5_search_dots(query['q']) - return group_request_filters(query, content_loader) + return group_request_filters(query, content_builder) def query_args_for_pagination(args): diff --git a/app/main/views.py b/app/main/views.py index 5c7c843fd..81eed2910 100644 --- a/app/main/views.py +++ b/app/main/views.py @@ -12,8 +12,6 @@ from dmutils.formats import LOTS from . import main -from .. import questions_loader -from .. import service_questions_loader from ..presenters.search_presenters import ( filters_for_lot, set_filter_states, @@ -29,7 +27,7 @@ ) from ..exceptions import AuthException -from .. import search_api_client, data_api_client +from .. import search_api_client, data_api_client, content_loader @main.route('/') @@ -135,7 +133,7 @@ def get_service_by_id(service_id): service_data = service['services'] service_view_data = Service( service_data, - service_questions_loader.get_builder().filter( + content_loader.get_builder('g-cloud-6', 'display_service').filter( service_data ) ) @@ -175,13 +173,14 @@ def redirect_search(): @main.route('/g-cloud/search') def search(): + content_builder = content_loader.get_builder('g-cloud-6', 'search_filters') filters = filters_for_lot( get_lot_from_request(request), - questions_loader.get_builder() + content_builder ) response = search_api_client.search_services( - **build_search_query(request, filters, questions_loader) + **build_search_query(request, filters, content_builder) ) search_results_obj = SearchResults(response) diff --git a/requirements.txt b/requirements.txt index da090c457..9dc4b54ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ requests==2.5.1 inflection==0.2.1 pyyaml==3.11 git+https://github.com/madzak/python-json-logger.git@v0.1.3#egg=python-json-logger==v0.1.3 -git+https://github.com/alphagov/digitalmarketplace-utils.git@8.3.0#egg=digitalmarketplace-utils==8.3.0 +git+https://github.com/alphagov/digitalmarketplace-utils.git@10.2.0#egg=digitalmarketplace-utils==10.2.0 # Required for SNI to work in requests pyOpenSSL==0.14 diff --git a/tests/fixtures/g6_questions/manifest.yml b/tests/fixtures/content/frameworks/g6/manifests/manifest.yml similarity index 100% rename from tests/fixtures/g6_questions/manifest.yml rename to tests/fixtures/content/frameworks/g6/manifests/manifest.yml diff --git a/tests/fixtures/g6_questions/data/booleanExample1.yml b/tests/fixtures/content/frameworks/g6/questions/data/booleanExample1.yml similarity index 100% rename from tests/fixtures/g6_questions/data/booleanExample1.yml rename to tests/fixtures/content/frameworks/g6/questions/data/booleanExample1.yml diff --git a/tests/fixtures/g6_questions/data/booleanExample2.yml b/tests/fixtures/content/frameworks/g6/questions/data/booleanExample2.yml similarity index 100% rename from tests/fixtures/g6_questions/data/booleanExample2.yml rename to tests/fixtures/content/frameworks/g6/questions/data/booleanExample2.yml diff --git a/tests/fixtures/g6_questions/data/checkboxesExample.yml b/tests/fixtures/content/frameworks/g6/questions/data/checkboxesExample.yml similarity index 100% rename from tests/fixtures/g6_questions/data/checkboxesExample.yml rename to tests/fixtures/content/frameworks/g6/questions/data/checkboxesExample.yml diff --git a/tests/fixtures/g6_questions/data/listExample.yml b/tests/fixtures/content/frameworks/g6/questions/data/listExample.yml similarity index 100% rename from tests/fixtures/g6_questions/data/listExample.yml rename to tests/fixtures/content/frameworks/g6/questions/data/listExample.yml diff --git a/tests/fixtures/g6_questions/data/radiosExample.yml b/tests/fixtures/content/frameworks/g6/questions/data/radiosExample.yml similarity index 100% rename from tests/fixtures/g6_questions/data/radiosExample.yml rename to tests/fixtures/content/frameworks/g6/questions/data/radiosExample.yml diff --git a/tests/unit/test_search_presenters.py b/tests/unit/test_search_presenters.py index 60f6f3ca1..9527fea88 100644 --- a/tests/unit/test_search_presenters.py +++ b/tests/unit/test_search_presenters.py @@ -8,10 +8,9 @@ from app.presenters.search_presenters import filters_for_lot, set_filter_states -questions_builder = ContentLoader( - "tests/fixtures/g6_questions/manifest.yml", - "tests/fixtures/g6_questions/data/" -).get_builder() +content_loader = ContentLoader('tests/fixtures/content') +content_loader.load_manifest('g6', 'data', 'manifest') +questions_builder = content_loader.get_builder('g6', 'manifest') def _get_fixture_data(): diff --git a/tests/unit/test_search_summary.py b/tests/unit/test_search_summary.py index cff97d69e..ce6ca9f64 100644 --- a/tests/unit/test_search_summary.py +++ b/tests/unit/test_search_summary.py @@ -9,15 +9,12 @@ from app.presenters.search_results import SearchResults from app.presenters.search_summary import SearchSummary, \ SummaryRules, SummaryFragment -from dmutils.content_loader import ContentLoader +from app import content_loader filter_groups = filters_for_lot( "saas", - ContentLoader( - "app/content/frameworks/g-cloud-6/manifests/search_filters.yml", - "app/content/frameworks/g-cloud-6/questions/services/" - ).get_builder() + content_loader.get_builder('g-cloud-6', 'search_filters') ) diff --git a/tests/unit/test_service_presenters.py b/tests/unit/test_service_presenters.py index 541f9a31a..5edbce107 100644 --- a/tests/unit/test_service_presenters.py +++ b/tests/unit/test_service_presenters.py @@ -4,7 +4,7 @@ from app.presenters.service_presenters import ( Service, Attribute, Meta, lowercase_first_character_unless_part_of_acronym ) -from app import service_questions_loader +from app import content_loader def _get_fixture_data(): @@ -24,7 +24,7 @@ def setUp(self): self.fixture = _get_fixture_data() self.fixture = self.fixture['services'] self.service = Service( - self.fixture, service_questions_loader.get_builder() + self.fixture, content_loader.get_builder('g-cloud-6', 'display_service') ) def tearDown(self): @@ -42,17 +42,17 @@ def test_lot_attribute_is_set(self): def test_Service_works_if_supplierName_is_not_set(self): del self.fixture['supplierName'] - self.service = Service(self.fixture, service_questions_loader.get_builder()) + self.service = Service(self.fixture, content_loader.get_builder('g-cloud-6', 'display_service')) self.assertFalse(hasattr(self.service, 'supplierName')) def test_Service_works_if_serviceFeatures_is_not_set(self): del self.fixture['serviceFeatures'] - self.service = Service(self.fixture, service_questions_loader.get_builder()) + self.service = Service(self.fixture, content_loader.get_builder('g-cloud-6', 'display_service')) self.assertFalse(hasattr(self.service, 'features')) def test_Service_works_if_serviceBenefits_is_not_set(self): del self.fixture['serviceBenefits'] - self.service = Service(self.fixture, service_questions_loader.get_builder()) + self.service = Service(self.fixture, content_loader.get_builder('g-cloud-6', 'display_service')) self.assertFalse(hasattr(self.service, 'benefits')) def test_features_attributes_are_correctly_set(self): @@ -65,7 +65,7 @@ def test_benefits_attributes_are_correctly_set(self): def test_attributes_are_correctly_set(self): service = Service( - self.fixture, service_questions_loader.get_builder() + self.fixture, content_loader.get_builder('g-cloud-6', 'display_service') ) self.assertEquals( service.attributes[0]['name'], @@ -82,7 +82,7 @@ def test_attributes_are_correctly_set(self): def test_the_support_attribute_group_is_not_there_if_no_attributes(self): del self.fixture['openStandardsSupported'] - service = Service(self.fixture, service_questions_loader.get_builder()) + service = Service(self.fixture, content_loader.get_builder('g-cloud-6', 'display_service')) for group in service.attributes: if group['name'] == 'Open standards': self.fail("Support group should not be found") @@ -90,7 +90,7 @@ def test_the_support_attribute_group_is_not_there_if_no_attributes(self): def test_only_attributes_with_a_valid_type_are_added_to_groups(self): invalidValue = (u'Manuals provided', u'CMS training') self.fixture['onboardingGuidance'] = invalidValue - service = Service(self.fixture, service_questions_loader.get_builder()) + service = Service(self.fixture, content_loader.get_builder('g-cloud-6', 'display_service')) for group in service.attributes: if ( (group['name'] == 'External interface protection') and @@ -99,7 +99,7 @@ def test_only_attributes_with_a_valid_type_are_added_to_groups(self): self.fail("Attribute with tuple value should not be in group") def test_attributes_with_assurance_in_the_fields_add_it_correctly(self): - service = Service(self.fixture, service_questions_loader.get_builder()) + service = Service(self.fixture, content_loader.get_builder('g-cloud-6', 'display_service')) for group in service.attributes: if group['name'] == 'Data-in-transit protection': for row in group['rows']: @@ -119,7 +119,7 @@ def test_attributes_with_assurance_in_the_fields_add_it_correctly(self): ) def test_attributes_with_assurance_for_a_list_value_has_a_caveat(self): - service = Service(self.fixture, service_questions_loader.get_builder()) + service = Service(self.fixture, content_loader.get_builder('g-cloud-6', 'display_service')) for group in service.attributes: if group['name'] == 'Asset protection and resilience': for row in group['rows']: