diff --git a/.docker/Dockerfile-template.ckan b/.docker/Dockerfile-template.ckan index c95fb0b..746d582 100644 --- a/.docker/Dockerfile-template.ckan +++ b/.docker/Dockerfile-template.ckan @@ -7,7 +7,6 @@ RUN ORIGINAL_USER=$(id -un) ARG SITE_URL=http://ckan:5000/ ENV PYTHON_VERSION={PYTHON_VERSION} ENV CKAN_VERSION={CKAN_VERSION} -ENV SOLR_VERSION={SOLR_VERSION} ENV CKAN_SITE_URL="${SITE_URL}" ENV PYTHON={PYTHON} @@ -24,11 +23,7 @@ COPY bin/ckan_cli /usr/bin/ RUN chmod +x "${APP_DIR}"/bin/*.sh /usr/bin/ckan_cli RUN which ps || apt-get install -y procps - -# Install setuptools conditionally -RUN if [ "$CKAN_VERSION" = "2.9" ]; then \ - pip install "setuptools>=44.1.0,<71"; \ - fi +RUN pip install uv # Install CKAN. diff --git a/.env b/.env index 4942995..f9604e0 100644 --- a/.env +++ b/.env @@ -27,3 +27,4 @@ ALLOW_BDD_FAIL=0 # Disable amazeeio based health checks DOCTOR_CHECK_WEBSERVER=0 DOCTOR_CHECK_BOOTSTRAP=0 +DOCTOR_CHECK_PYGMY=0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bf5109c..7c26494 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,15 +26,10 @@ jobs: strategy: fail-fast: false matrix: - ckan-version: ['2.10'] - solr-version: ['8'] + ckan-version: ['2.11', '2.10'] experimental: [false] include: - - ckan-version: '2.11' - solr-version: '9' - experimental: false - ckan-version: 'master' - solr-version: '9' experimental: true #master is unstable, good to know if we are compatible or not name: ${{ matrix.experimental && '**Fail_Ignored** ' || '' }} CKAN ${{ matrix.ckan-version }} @@ -42,7 +37,6 @@ jobs: container: drevops/ci-runner:23.12.0 env: CKAN_VERSION: ${{ matrix.ckan-version }} - SOLR_VERSION: ${{ matrix.solr-version }} steps: # Patch https://github.com/actions/runner/issues/863 diff --git a/bin/build.sh b/bin/build.sh index 23f9be0..9ea85df 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -19,11 +19,13 @@ PYTHON_VERSION=py3 CKAN_GIT_VERSION=$CKAN_VERSION CKAN_GIT_ORG=qld-gov-au +SOLR_VERSION=9 if [ "$CKAN_VERSION" = "2.11" ]; then - CKAN_GIT_VERSION=ckan-2.11.1-qgov.2 + CKAN_GIT_VERSION=ckan-2.11.2-qgov.1 elif [ "$CKAN_VERSION" = "2.10" ]; then - CKAN_GIT_VERSION=ckan-2.10.5-qgov.5 + CKAN_GIT_VERSION=ckan-2.10.7-qgov.1 + SOLR_VERSION=8 elif [ "$CKAN_VERSION" = "master" ]; then CKAN_GIT_ORG=ckan fi @@ -35,4 +37,5 @@ sed "s|{CKAN_VERSION}|$CKAN_VERSION|g" .docker/Dockerfile-template.ckan \ | sed "s|{PYTHON}|$PYTHON|g" \ > .docker/Dockerfile.ckan +export SOLR_VERSION ahoy build diff --git a/bin/init-ext.sh b/bin/init-ext.sh index 350aba5..9a72f7e 100755 --- a/bin/init-ext.sh +++ b/bin/init-ext.sh @@ -4,6 +4,14 @@ # set -ex +install_requirements_file () { + if [ "$TOOL" = "uv" ]; then + uv pip install --system -r "$1" + else + pip install -r "$1" + fi +} + install_requirements () { PROJECT_DIR=$1 shift @@ -12,33 +20,30 @@ install_requirements () { for filename_pattern in "$@"; do filename="$PROJECT_DIR/${filename_pattern}-$CKAN_VERSION.txt" if [ -f "$filename" ]; then - pip install -r "$filename" + install_requirements_file "$filename" return 0 fi done for filename_pattern in "$@"; do filename="$PROJECT_DIR/${filename_pattern}-$PYTHON_VERSION.txt" if [ -f "$filename" ]; then - pip install -r "$filename" + install_requirements_file "$filename" return 0 fi done for filename_pattern in "$@"; do filename="$PROJECT_DIR/$filename_pattern.txt" if [ -f "$filename" ]; then - pip install -r "$filename" + install_requirements_file "$filename" return 0 fi done } . "${APP_DIR}"/bin/activate -if [ "$CKAN_VERSION" = "2.9" ]; then - pip install "setuptools>=44.1.0,<71" -fi install_requirements . dev-requirements requirements-dev for extension in . `ls -d $SRC_DIR/ckanext-*`; do - install_requirements $extension requirements pip-requirements + TOOL=uv install_requirements $extension requirements pip-requirements done pip install -e . installed_name=$(grep '^\s*name=' setup.py |sed "s|[^']*'\([-a-zA-Z0-9]*\)'.*|\1|") diff --git a/bin/init.sh b/bin/init.sh index ba172d5..e000532 100755 --- a/bin/init.sh +++ b/bin/init.sh @@ -7,3 +7,4 @@ set -e . "${APP_DIR}"/bin/activate CLICK_ARGS="--yes" ckan_cli db clean ckan_cli db init +ckan_cli db upgrade diff --git a/ckanext/publications_qld_theme/templates/package/group_list.html b/ckanext/publications_qld_theme/templates/package/group_list.html index 583839b..49a5625 100644 --- a/ckanext/publications_qld_theme/templates/package/group_list.html +++ b/ckanext/publications_qld_theme/templates/package/group_list.html @@ -1,31 +1,31 @@ -{% extends "package/read_base.html" %} -{% import 'macros/form.html' as form %} +{% ckan_extends %} + +{# Replace 'group' with 'category' #} + +{% set default_group_type = h.default_group_type('group') %} {% block primary_content_inner %} -
{{ _('There are no categories associated with this dataset') }}
+{{ h.humanize_entity_type('group', default_group_type, 'no associated label') or _('There are no categories associated with this dataset') }}
{% endif %} {% endblock %} diff --git a/test/features/groups.feature b/test/features/groups.feature index 910c3b2..1a6aba7 100644 --- a/test/features/groups.feature +++ b/test/features/groups.feature @@ -39,3 +39,32 @@ Feature: Group APIs When I view the "silly-walks" group API "not including" users Then I should see an element with xpath "//*[contains(string(), '"success": true') and contains(string(), '"name": "silly-walks"')]" + + Scenario: As a sysadmin, when I create a group with a long name, it should be preserved + Given "SysAdmin" as the persona + When I log in + And I go to group page + And I click the link to "/group/new" + And I fill in title with random text starting with "Group name more than 35 characters" + And I set "group_title" to "$last_generated_title" + And I press the element with xpath "//button[contains(@class, 'btn-primary')]" + And I take a debugging screenshot + # Breadcrumb should be truncated but preserve full name in a tooltip + Then I should see an element with xpath "//ol[contains(@class, 'breadcrumb')]//a[contains(string(), 'Group name more') and contains(string(), '...') and @title = '$group_title']" + + # Search facets should be truncated but preserve full name in a tooltip + When I create a dataset and resource with key-value parameters "notes=Testing long group name" and "name=Test" + And I press "Groups" + When I select by text " $group_title" from "group_added" + And I press the element with xpath "//button[contains(@class, 'btn-primary')]" + Then I should see an element with xpath "//form//a[normalize-space() = '$group_title']" + When I press "$group_title" + + Then I should see a search facet for "$group_title" truncated to "Group name more" + When I press the search facet pointing to "$group_title" + Then I should see an active search facet for "$group_title" truncated to "Group name more" + + When I go to dataset page + Then I should see a search facet for "$group_title" truncated to "Group name more" + When I press the search facet pointing to "$group_title" + Then I should see an active search facet for "$group_title" truncated to "Group name more" diff --git a/test/features/organisations.feature b/test/features/organisations.feature index 4cc9b98..299d574 100644 --- a/test/features/organisations.feature +++ b/test/features/organisations.feature @@ -54,3 +54,24 @@ Feature: Organization APIs Then I should see "Test Organisation" And I should see an element with xpath "//a[contains(@href, 'organization/new') and contains(string(), 'Add Organisation')]" + Scenario: As a sysadmin, when I create an organisation with a long name, it should be preserved + Given "SysAdmin" as the persona + When I log in + And I go to organisation page + And I click the link to "/organization/new" + And I fill in title with random text starting with "Org name more than 35 characters" + And I press the element with xpath "//button[contains(@class, 'btn-primary')]" + And I take a debugging screenshot + # Breadcrumb should be truncated but preserve full name in a tooltip + Then I should see an element with xpath "//ol[contains(@class, 'breadcrumb')]//a[contains(string(), 'Org name more than') and contains(string(), '...') and contains(@title, 'Org name more than 35 characters')]" + + # Search facets should be truncated but preserve full name in a tooltip + When I create a dataset and resource with key-value parameters "notes=Testing long org name::owner_org=Org name more than" and "name=Test" + And I press "Org name more than" + Then I should see a search facet for "Org name more than 35 characters" truncated to "Org name more than" + When I press the search facet pointing to "Org name more than 35 characters" + Then I should see an active search facet for "Org name more than 35 characters" truncated to "Org name more than" + When I go to dataset page + Then I should see a search facet for "Org name more than 35 characters" truncated to "Org name more than" + When I press the search facet pointing to "Org name more than 35 characters" + Then I should see an active search facet for "Org name more than 35 characters" truncated to "Org name more than" diff --git a/test/features/steps/steps.py b/test/features/steps/steps.py index b9de8b8..de5d0d3 100644 --- a/test/features/steps/steps.py +++ b/test/features/steps/steps.py @@ -104,6 +104,27 @@ def request_reset(context): """) +@then(u'I should see a search facet for "{title}" truncated to "{truncated_title}"') +def truncated_facet_visible(context, title, truncated_title): + context.execute_steps(u""" + Then I should see an element with xpath "//li[contains(@class, 'nav-item')]//a[contains(string(), '{truncated_title}') and contains(string(), '...') and (contains(@title, '{title}') or contains(@data-bs-title, '{title}'))]" + """.format(title=title, truncated_title=truncated_title)) + + +@then(u'I should see an active search facet for "{title}" truncated to "{truncated_title}"') +def active_truncated_facet_visible(context, title, truncated_title): + context.execute_steps(u""" + Then I should see an element with xpath "//li[contains(@class, 'nav-item') and contains(@class, 'active')]//a[contains(string(), '{truncated_title}') and contains(string(), '...') and (contains(@title, '{title}') or contains(@data-bs-title, '{title}'))]" + """.format(title=title, truncated_title=truncated_title)) + + +@when(u'I press the search facet pointing to "{title}"') +def press_search_facet(context, title): + context.execute_steps(u""" + When I press the element with xpath "//li[contains(@class, 'nav-item')]//a[contains(@title, '{0}') or contains(@data-bs-title, '{0}')]" + """.format(title)) + + @when(u'I fill in "{name}" with "{value}" if present') def fill_in_field_if_present(context, name, value): context.execute_steps(u""" diff --git a/test/features/users.feature b/test/features/users.feature index 3cccb5a..5bef34d 100644 --- a/test/features/users.feature +++ b/test/features/users.feature @@ -118,6 +118,16 @@ Feature: User APIs Then I should see my datasets And I should see "Add Dataset" + Scenario: Dashboard news feed can display organisational changes + Given "SysAdmin" as the persona + When I log in + And I go to organisation page + And I press "Test Organisation" + And I press "Manage" + And I press "Update" + And I visit "/dashboard" + Then I should see an element with xpath "//li[contains(string(), 'updated the organisation')]/a[contains(string(), 'Test Organisation') and contains(@href, '/organization/')]/..//a[contains(string(), 'Administrator') and @href='/user/admin']" + @email Scenario: As a registered user, when I have locked my account with too many failed logins, I can reset my password to unlock it Given "CKANUser" as the persona