diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 15339de8..986b5f82 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -84,6 +84,47 @@ jobs: if: always() && ! cancelled() run: docker compose logs + use-case-tests: + if: | + ! cancelled() && always() && + (needs.check-auto-tagging-will-work.result == 'skipped' || needs.check-auto-tagging-will-work.result == 'success') && + ! startsWith(github.ref, 'refs/tags') + needs: + - check-auto-tagging-will-work + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Use .env.example + run: cp .env.example .env + + - name: Get python Container + run: docker pull python:3.10 + + - name: Install latest Vespa CLI + env: + VESPA_CLI_VERSION: 8.250.43 + run: | + mkdir -p scripts/vespa-cli + curl -fsSL https://github.com/vespa-engine/vespa/releases/download/v${VESPA_CLI_VERSION}/vespa-cli_${VESPA_CLI_VERSION}_linux_amd64.tar.gz | \ + tar -zxf - -C scripts/vespa-cli --strip-component=1 + echo "scripts/vespa-cli/bin" >> $GITHUB_PATH + + - name: Build + run: | + docker compose build + docker images + + - name: Build docker-compose stack & Setup vespa for search + run: make start + + - name: Run backend Use Case tests + run: make test_use_cases + + - name: Log Dump + if: always() && ! cancelled() + run: docker compose logs + search-tests: if: | ! cancelled() && always() && @@ -142,6 +183,7 @@ jobs: ! cancelled() && always() && (needs.code-quality.result == 'success' && needs.non-search-tests.result == 'success' && + needs.use-case-tests.result == 'success' && needs.search-tests.result == 'success' && needs.integration-tests.result == 'success') && ! startsWith(github.ref, 'refs/tags') @@ -149,6 +191,7 @@ jobs: needs: - code-quality - non-search-tests + - use-case-tests - search-tests - integration-tests steps: diff --git a/makefile-docker.defs b/makefile-docker.defs index 276a67f0..48736a86 100644 --- a/makefile-docker.defs +++ b/makefile-docker.defs @@ -113,14 +113,25 @@ test_search: -vvv tests/search \ -m 'search' ${ARGS} -test_cors: +.ONESHELL: +test_use_cases: + docker compose \ + -f docker-compose.yml \ + -f docker-compose.dev.yml \ + run --rm --name search_test \ + -v "${PWD}/data:/data" \ + backend pytest \ + -vvv tests/use-cases \ + -m 'use_case' ${ARGS} + +test_cors: docker compose -f docker-compose.yml -f docker-compose.dev.yml run --rm backend pytest -vvv -m 'cors' ${ARGS} test_unit: docker compose -f docker-compose.yml -f docker-compose.dev.yml run --rm backend pytest -vvv tests/unit ${ARGS} test_non_search: - docker compose -f docker-compose.yml -f docker-compose.dev.yml run --rm backend pytest -vvv -m 'not search' ${ARGS} + docker compose -f docker-compose.yml -f docker-compose.dev.yml run --rm backend pytest -vvv -m 'not search and not use_case' ${ARGS} test: docker compose -f docker-compose.yml -f docker-compose.dev.yml run --rm backend pytest -vvv ${ARGS} diff --git a/tests/use-cases/test_mcf_uc.py b/tests/use-cases/test_mcf_uc.py new file mode 100644 index 00000000..01e33d96 --- /dev/null +++ b/tests/use-cases/test_mcf_uc.py @@ -0,0 +1,58 @@ +from unittest.mock import patch + +import pytest + +from app.api.api_v1.routers import search +from app.repository.lookups import get_country_slug_from_country_code +from tests.search.vespa.setup_search_tests import ( + VESPA_FIXTURE_COUNT, + _make_search_request, + _populate_db_families, +) + + +@pytest.mark.use_case +@patch( + "app.api.api_v1.routers.search.AppTokenFactory.verify_corpora_in_db", + return_value=True, +) +@pytest.mark.parametrize("label,query", [("search", "the"), ("browse", "")]) +def test_keyword_country_filters__geographies( + mock_corpora_exist_in_db, + label, + query, + test_vespa, + data_client, + data_db, + monkeypatch, + valid_token, +): + monkeypatch.setattr(search, "_VESPA_CONNECTION", test_vespa) + _populate_db_families(data_db) + base_params = {"query_string": query} + + # Get all documents and iterate over their country codes to confirm that each are + # the specific one that is returned in the query (as they each have a unique + # country code) + all_body = _make_search_request(data_client, valid_token, params=base_params) + families = [f for f in all_body["families"]] + assert len(families) == VESPA_FIXTURE_COUNT + + for family in families: + for country_code in family["family_geographies"]: + country_slug = get_country_slug_from_country_code(data_db, country_code) + + params = { + **base_params, + **{"keyword_filters": {"countries": [country_slug]}}, + } + body_with_filters = _make_search_request( + data_client, valid_token, params=params + ) + filtered_family_slugs = [ + f["family_slug"] for f in body_with_filters["families"] + ] + assert len(filtered_family_slugs) == 1 + assert family["family_slug"] in filtered_family_slugs + + assert mock_corpora_exist_in_db.assert_called