Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
03cac5f
WIP
tnetennba3 May 20, 2026
5abef94
Fix changes in rebase and ruff formatting
252afh Aug 19, 2026
6057762
Update script to only run on dev
252afh Aug 19, 2026
e770eb9
Update comment in prepare_environment.py to reflect code changes
252afh Aug 19, 2026
883394f
Update test
252afh Aug 20, 2026
a49eab1
Update test_generate_dummy_data.py and test_prepare_environment.py
252afh Aug 20, 2026
496724a
Correct test db setup using bypass logic and updated env vars
252afh Aug 21, 2026
a607cc8
Change difference between backend and e2e tests
252afh Aug 21, 2026
a926b39
Fix test users that were created
252afh Aug 21, 2026
c6c89d7
Fix final test that relied on a bucket var being populated, and tried…
252afh Aug 21, 2026
c46dd53
Change email assertion in test_prepare_environment.py
252afh Aug 21, 2026
066d570
Change empty free text in dummy_data.py to None to match existing ing…
252afh Aug 26, 2026
c95cf82
Merge branch 'main' into helenathompson/pro-350-fix-db-migrations-out…
252afh Aug 27, 2026
de9a730
Correct comment to remove preprod from prepare_environment.py
252afh Aug 27, 2026
939e34f
Correct timestamp and csv import in prepare_s3.py
252afh Aug 27, 2026
ff1e738
Organise imports in prepare_s3.py
252afh Aug 27, 2026
e20fb80
Added preprod gate for s3 wipe in prepare_s3.py and preprod environme…
252afh Aug 27, 2026
b831521
Flip gated check so only dev gets wiped to protect against mistyped e…
252afh Aug 27, 2026
e423698
More gate check improvements
252afh Aug 27, 2026
5a72343
Add mock for text embedding in test_prepare_environment.py
252afh Aug 28, 2026
1ed8ee0
Merge branch 'main' into helenathompson/pro-350-fix-db-migrations-out…
252afh Aug 28, 2026
f8a9a17
Add mock aws in test_prepare_environment.py
252afh Aug 28, 2026
510e384
Fix double-write in prepare_s3 and add preprod skip coverage
252afh Aug 28, 2026
9a12bb8
Fix test_skips_on_preprod to exercise preprod guard; patch is_preprod…
252afh Aug 28, 2026
4c441fc
Merge branch 'main' into helenathompson/pro-350-fix-db-migrations-out…
252afh Aug 28, 2026
92d79f0
Split prepare_environment guard into two explicit early returns for c…
252afh Aug 28, 2026
e4f2517
Updated comment and reverted changes so a migration-only exit is done…
252afh Aug 28, 2026
f71a7fd
Updated tests in test_prepare_environment.py to match
252afh Aug 28, 2026
77c192a
Updated comment in prepare_s3.py to specify this only runs on dev
252afh Aug 28, 2026
795567a
Update guard in dummy_data.py to not run against preprod either, and …
252afh Aug 28, 2026
ea4d211
Change the way tests mock and patch in test_prepare_environment.py to…
252afh Aug 28, 2026
5428ce8
Rename candidate theme generation function in prepare_s3.py to match …
252afh Aug 28, 2026
2f5e8b5
Change guard in prepare_s3.py to skip if it's any env except dev
252afh Aug 28, 2026
bb065d9
Change guard in prepare_s3.py to skip if it's any env except dev (cor…
252afh Aug 28, 2026
63f83ab
Move mock and patch settings in test_prepare_s3.py to a separate func…
252afh Aug 28, 2026
caa5bda
Change conditional gate in prepare_environment.py to use HostingEnvir…
252afh Aug 28, 2026
869757d
Merge branch 'main' into helenathompson/pro-350-fix-db-migrations-out…
252afh Aug 28, 2026
6998d13
Replace non-deterministic random calls in dummy_data with themefinder…
252afh Aug 28, 2026
dd7461e
Simplify test mocking to match simplified conditional gates in both t…
252afh Aug 28, 2026
8cfb360
Fix test failures: update patches to is_dev, merge duplicate skip tes…
252afh Aug 28, 2026
d640c7f
Merge branch 'main' into helenathompson/pro-350-fix-db-migrations-out…
252afh Sep 2, 2026
b1f7253
Merge branch 'main' into helenathompson/pro-350-fix-db-migrations-out…
252afh Sep 3, 2026
f4e3e4b
Merge branch 'main' into helenathompson/pro-350-fix-db-migrations-out…
252afh Sep 3, 2026
7de2d5c
Merge branch 'main' into helenathompson/pro-350-fix-db-migrations-out…
252afh Sep 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ FIND_THEMES_BATCH_JOB_QUEUE=i-dot-ai-dev-consult-sign-off-FARGATE-batch-job-queu
FIND_THEMES_BATCH_JOB_DEFINITION=i-dot-ai-dev-consult-sign-off-FARGATE-batch-job-definition
LITELLM_CONSULT_OPENAI_API_KEY=insert-litellm-api-key-here
LLM_GATEWAY_URL=https://llm-gateway.i.ai.gov.uk
ADMIN_USERS=email@example.com
ADMIN_USERS=admin@example.com,policy@example.com
17 changes: 7 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ test-end-to-end: ## Run end-to-end tests with Playwright
# Run the tests, then ALWAYS clean up, then re-raise the tests' exit status so CI
# still fails on failure. Without this wrapper a failure mid-run (e.g. a service
# health-check timeout or a failing test) would skip cleanup and leave
# docker-compose.override.yml behind, silently repointing every later
# `docker compose` command at the E2E database.
# the e2e test database behind or a stale Astro dev.json lock file.
@$(MAKE) _run-e2e-tests; status=$$?; $(MAKE) _clean-e2e; exit $$status

.PHONY: _run-e2e-tests
Expand All @@ -89,18 +88,14 @@ _run-e2e-tests:
@docker exec -i $$(docker compose ps -q postgres) psql -U postgres -c "CREATE DATABASE consult_e2e_test;"
@echo "Initializing test data..."
@docker compose run --rm -e DATABASE_URL=$(E2E_DB_URL) backend venv/bin/python manage.py migrate
@docker compose run --rm -e DATABASE_URL=$(E2E_DB_URL) -e ADMIN_USERS=admin@example.com backend venv/bin/python manage.py createadminusers
@docker compose run --rm -e DATABASE_URL=$(E2E_DB_URL) backend venv/bin/python manage.py createadminusers
@docker compose run --rm -e DATABASE_URL=$(E2E_DB_URL) backend venv/bin/python manage.py shell -c \
"from authentication.models import User; from consultations.models import Consultation; \
user = User.objects.get(email='admin@example.com'); \
[c.users.add(user) for c in Consultation.objects.all()]"
@echo "Starting services..."
@echo "services:" > docker-compose.override.yml
@echo " backend:" >> docker-compose.override.yml
@echo " environment:" >> docker-compose.override.yml
@echo " - DATABASE_URL=$(E2E_DB_URL)" >> docker-compose.override.yml
@docker compose down backend 2>/dev/null || true
@docker compose up -d backend frontend
@rm -f frontend/.astro/dev.json
@DATABASE_URL=$(E2E_DB_URL) docker compose up -d backend frontend
@echo "Waiting for services to be ready..."
@timeout 120 sh -c 'until curl -s http://localhost:3000 > /dev/null; do sleep 2; done' || \
(echo "Frontend failed to start" && docker compose logs frontend && exit 1)
Expand All @@ -116,6 +111,7 @@ _clean-e2e: ## Internal: always-run cleanup for test-end-to-end (drop test DB, r
@echo "Cleaning up..."
@docker exec -i $$(docker compose ps -q postgres) psql -U postgres -c "DROP DATABASE IF EXISTS consult_e2e_test;" 2>/dev/null || true
@rm -f docker-compose.override.yml
@rm -f frontend/.astro/dev.json


.PHONY: build-consultation-template
Expand Down Expand Up @@ -178,7 +174,8 @@ dummy_data: ## Generate dummy consultations. Only works in dev
cd backend && PYTHONPATH=.. uv run python manage.py generate_dummy_data

.PHONY: dev_environment
dev_environment: reset_db migrate dummy_data ## set up the database with dummy data
dev_environment: setup_db ## set up the database with dummy data
cd backend && PYTHONPATH=.. uv run python manage.py prepare_environment

# Docker
AWS_REGION=eu-west-2
Expand Down
6 changes: 2 additions & 4 deletions backend/consultations/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.urls import path, reverse
from simple_history.admin import SimpleHistoryAdmin

from consultations.dummy_data import create_dummy_consultation_from_yaml_job
from consultations.dummy_data import create_dummy_consultation_job
from consultations.models import (
CandidateTheme,
Consultation,
Expand Down Expand Up @@ -55,9 +55,7 @@ def create_dummy_consultation(modeladmin, request, queryset, size=10):
)
return

create_dummy_consultation_from_yaml_job.delay(
number_respondents=size, consultation=consultation
)
create_dummy_consultation_job.delay(number_respondents=size, consultation=consultation)


@admin.action(description="create small dummy consultation")
Expand Down
13 changes: 9 additions & 4 deletions backend/consultations/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ def validate_is_staff(self, value):

# Check if this is an update operation and user is updating themselves
if self.instance and request and request.user == self.instance and value is False:
raise serializers.ValidationError(
"You cannot remove admin privileges from yourself"
)
raise serializers.ValidationError("You cannot remove admin privileges from yourself")

return value

Expand Down Expand Up @@ -150,7 +148,14 @@ class SelectedThemeSerializer(serializers.ModelSerializer):

class Meta:
model = SelectedTheme
fields: ClassVar[list] = ["id", "name", "description", "version", "modified_at", "last_modified_by"]
fields: ClassVar[list] = [
"id",
"name",
"description",
"version",
"modified_at",
"last_modified_by",
]
read_only_fields: ClassVar[list] = ["id", "version", "modified_at", "last_modified_by"]

def get_last_modified_by(self, obj):
Expand Down
4 changes: 1 addition & 3 deletions backend/consultations/api/views/consultation.py
Original file line number Diff line number Diff line change
Expand Up @@ -946,9 +946,7 @@ def evaluation(self, request, pk=None):
SelectedTheme.objects.filter(
question__consultation=consultation,
)
.filter(
Q(name__iexact=NO_REASON_GIVEN_THEME_NAME) | Q(name__iexact=OTHER_THEME_NAME)
)
.filter(Q(name__iexact=NO_REASON_GIVEN_THEME_NAME) | Q(name__iexact=OTHER_THEME_NAME))
.values_list("id", flat=True)
)

Expand Down
4 changes: 1 addition & 3 deletions backend/consultations/api/views/question.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,7 @@ def themes(self, request, pk=None, consultation_pk=None):
)
)
else:
themes = themes.annotate(
count=Count("responseannotation", distinct=True)
)
themes = themes.annotate(count=Count("responseannotation", distinct=True))

serializer = QuestionThemeSerializer(themes, many=True)
return Response({"themes": serializer.data})
Expand Down
6 changes: 1 addition & 5 deletions backend/consultations/api/views/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,7 @@ def mark_read_bulk(self, request, consultation_pk=None, **kwargs):

if len(requested_response_ids) > MAX_BULK_MARK_READ:
return Response(
{
"message": (
f"Too many response IDs provided. Maximum is {MAX_BULK_MARK_READ}."
)
},
{"message": (f"Too many response IDs provided. Maximum is {MAX_BULK_MARK_READ}.")},
status=status.HTTP_400_BAD_REQUEST,
)

Expand Down
Loading
Loading