Skip to content

Commit 31537c2

Browse files
committed
Weight page starter
1 parent 59e0ef1 commit 31537c2

14 files changed

Lines changed: 278 additions & 8 deletions

File tree

lung_cancer_screening/core/tests/acceptance/helpers/user_interaction_helpers.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,10 @@ def fill_in_and_submit_height_imperial(page, feet, inches):
3737
page.get_by_label("Inches").fill(str(inches))
3838

3939
page.click("text=Continue")
40+
41+
def fill_in_and_submit_weight(page, kilograms):
42+
expect(page.locator("h1")).to_have_text("Enter your weight")
43+
44+
page.get_by_label("Kilograms").fill(str(kilograms))
45+
46+
page.click("text=Continue")

lung_cancer_screening/core/tests/acceptance/test_questionnaire.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
fill_in_and_submit_height_metric,
1010
fill_in_and_submit_participant_id,
1111
fill_in_and_submit_smoking_eligibility,
12-
fill_in_and_submit_date_of_birth
12+
fill_in_and_submit_date_of_birth,
13+
fill_in_and_submit_weight
1314
)
1415

1516
from .helpers.assertion_helpers import expect_back_link_to_have_url
@@ -56,7 +57,7 @@ def test_full_questionnaire_user_journey(self):
5657

5758
fill_in_and_submit_height_metric(page, height)
5859

59-
expect(page).to_have_url(f"{self.live_server_url}/responses")
60+
expect(page).to_have_url(f"{self.live_server_url}/weight")
6061

6162
page.click("text=Back")
6263

@@ -66,6 +67,12 @@ def test_full_questionnaire_user_journey(self):
6667

6768
fill_in_and_submit_height_imperial(page, feet, inches)
6869

70+
expect(page).to_have_url(f"{self.live_server_url}/weight")
71+
72+
fill_in_and_submit_weight(page, "70")
73+
74+
expect(page).to_have_url(f"{self.live_server_url}/responses")
75+
6976
responses = page.locator(".responses")
7077
expect(responses).to_contain_text("Have you ever smoked? Yes, I used to smoke regularly")
7178
expect(responses).to_contain_text(
@@ -74,6 +81,4 @@ def test_full_questionnaire_user_journey(self):
7481

7582
page.click("text=Submit")
7683

77-
78-
7984
expect(page).to_have_url(f"{self.live_server_url}/your-results")
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from django import forms
2+
3+
from lung_cancer_screening.core.form_fields import DecimalField
4+
from ..models.response_set import ResponseSet
5+
6+
class MetricWeightForm(forms.ModelForm):
7+
8+
def __init__(self, *args, **kwargs):
9+
self.participant = kwargs.pop('participant')
10+
super().__init__(*args, **kwargs)
11+
self.instance.participant = self.participant
12+
13+
self.fields["weight_metric"] = DecimalField(
14+
label="Kilograms",
15+
classes="nhsuk-input--width-4",
16+
error_messages={
17+
'required': 'Enter your weight.',
18+
}
19+
)
20+
21+
class Meta:
22+
model = ResponseSet
23+
fields = ['weight_metric']
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{% extends 'layout.jinja' %}
2+
{% from 'nhsuk/components/button/macro.jinja' import button %}
3+
{% from 'nhsuk/components/back-link/macro.jinja' import backLink %}
4+
{% from 'nhsuk/components/fieldset/macro.jinja' import fieldset %}
5+
6+
{% block beforeContent %}
7+
{{
8+
backLink({
9+
"href": url("questions:height"),
10+
"text": "Back"
11+
})
12+
}}
13+
{% endblock beforeContent %}
14+
15+
{% block page_content %}
16+
<div class="nhsuk-grid-row">
17+
<div class="nhsuk-grid-column-two-thirds">
18+
<form action="weight" method="POST" novalidate>
19+
{{ csrf_input }}
20+
<h1 class="nhsuk-heading-l">Enter your weight</h1>
21+
22+
<p>An accurate measurement is important.
23+
24+
<p>If you have digital scales, use these to check your weight. Some pharmacies and gyms have scales where you can check for free.
25+
26+
{% call fieldset({
27+
"legend": {
28+
"text": "What is your weight",
29+
"classes": "nhsuk-label--m"
30+
}
31+
}) %}
32+
33+
{{form.weight_metric.as_field_group()}}
34+
35+
{% endcall %}
36+
37+
{{ button({
38+
"text": "Continue"
39+
}) }}
40+
</form>
41+
</div>
42+
</div>
43+
{% endblock %}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Generated by Django 5.2.7 on 2025-10-21 13:13
2+
3+
import django.core.validators
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('questions', '0010_responseset_height_imperial_alter_responseset_height_and_more'),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name='responseset',
16+
name='weight_metric',
17+
field=models.PositiveIntegerField(blank=True, null=True),
18+
),
19+
migrations.AlterField(
20+
model_name='responseset',
21+
name='height_imperial',
22+
field=models.PositiveIntegerField(blank=True, null=True, validators=[django.core.validators.MinValueValidator(55, message='Height must be between 4 feet 7 inches and 8 feet'), django.core.validators.MaxValueValidator(96, message='Height must be between 4 feet 7 inches and 8 feet')]),
23+
),
24+
]

lung_cancer_screening/questions/models/response_set.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ class ResponseSet(BaseModel):
3939
MAX_HEIGHT_IMPERIAL, message="Height must be between 4 feet 7 inches and 8 feet"),
4040
])
4141

42+
weight_metric = models.PositiveIntegerField(null=True, blank=True
43+
# validators=[
44+
# MinValueValidator(MIN_HEIGHT_METRIC, message="Height must be between 139.7cm and 243.8 cm"),
45+
# MaxValueValidator(MAX_HEIGHT_METRIC, message="Height must be between 139.7cm and 243.8 cm"),
46+
# ]
47+
)
48+
4249
submitted_at = models.DateTimeField(null=True, blank=True)
4350

4451
class Meta:
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from django.test import TestCase
2+
3+
from ....models.participant import Participant
4+
from ....forms.metric_weight_form import MetricWeightForm
5+
6+
class TestMetricWeightForm(TestCase):
7+
def setUp(self):
8+
self.participant = Participant.objects.create(unique_id="1234567890")
9+
self.response_set = self.participant.responseset_set.create()
10+
11+
def test_is_valid_with_valid_input(self):
12+
weight = "70.5"
13+
form = MetricWeightForm(
14+
participant=self.participant,
15+
instance=self.response_set,
16+
data={
17+
"weight_metric": weight
18+
}
19+
)
20+
self.assertTrue(form.is_valid())
21+
22+
def test_is_valid_with_invalid_input(self):
23+
weight = "a"
24+
form = MetricWeightForm(
25+
participant=self.participant,
26+
instance=self.response_set,
27+
data={
28+
"weight_metric": weight
29+
}
30+
)
31+
self.assertFalse(form.is_valid())

lung_cancer_screening/questions/tests/unit/models/test_response_set.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ def test_has_an_imperial_height_as_a_int(self):
5151
int
5252
)
5353

54+
def test_has_an_metric_weight_as_a_int(self):
55+
self.response_set.weight_metric = 68
56+
self.response_set.save()
57+
58+
self.assertIsInstance(
59+
self.response_set.weight_metric,
60+
int
61+
)
62+
5463
def test_has_a_participant_as_a_foreign_key(self):
5564
self.assertIsInstance(
5665
self.response_set.participant,

lung_cancer_screening/questions/tests/unit/views/test_height.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ def test_post_stores_a_valid_response_set_for_the_participant(self):
6868
self.assertEqual(response_set.height, self.valid_height*10)
6969
self.assertEqual(response_set.participant, self.participant)
7070

71-
def test_post_redirects_to_responses_path(self):
71+
def test_post_redirects_to_weight_path(self):
7272
response = self.client.post(
7373
reverse("questions:height"),
7474
self.valid_params
7575
)
7676

77-
self.assertRedirects(response, reverse("questions:responses"))
77+
self.assertRedirects(response, reverse("questions:weight"))
7878

7979
def test_post_responds_with_422_if_the_resource_is_invalid(self):
8080
response = self.client.post(
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
from django.test import TestCase
2+
from django.urls import reverse
3+
from requests import session
4+
5+
from ....models.participant import Participant
6+
7+
8+
class TestWeight(TestCase):
9+
def setUp(self):
10+
self.participant = Participant.objects.create(unique_id="12345")
11+
self.participant.responseset_set.create()
12+
13+
self.valid_weight = 70
14+
self.valid_params = {"weight_metric": self.valid_weight}
15+
16+
self.session = self.client.session
17+
self.session['participant_id'] = self.participant.unique_id
18+
19+
self.session.save()
20+
21+
def test_get_redirects_if_the_participant_does_not_exist(self):
22+
self.session['participant_id'] = "somebody none existent participant"
23+
self.session.save()
24+
25+
response = self.client.get(
26+
reverse("questions:weight")
27+
)
28+
29+
self.assertRedirects(response, reverse("questions:start"))
30+
31+
def test_get_redirects_if_the_participant_is_none(self):
32+
self.session.flush()
33+
34+
response = self.client.get(
35+
reverse("questions:weight")
36+
)
37+
38+
self.assertRedirects(response, reverse("questions:start"))
39+
40+
def test_get_responds_successfully(self):
41+
response = self.client.get(reverse("questions:weight"))
42+
43+
self.assertEqual(response.status_code, 200)
44+
45+
def test_get_renders_the_metric_form(self):
46+
response = self.client.get(reverse("questions:weight"))
47+
48+
self.assertContains(response, "Kilograms")
49+
50+
def test_post_redirects_if_the_participant_does_not_exist(self):
51+
self.session['participant_id'] = "somebody none existent participant"
52+
self.session.save()
53+
54+
response = self.client.post(
55+
reverse("questions:weight")
56+
)
57+
58+
self.assertRedirects(response, reverse("questions:start"))
59+
60+
def test_post_redirects_if_the_participant_is_none(self):
61+
self.session.flush()
62+
63+
response = self.client.post(
64+
reverse("questions:weight")
65+
)
66+
67+
self.assertRedirects(response, reverse("questions:start"))
68+
69+
70+
def test_post_redirects_if_the_weight_is_valid(self):
71+
response = self.client.post(
72+
reverse("questions:weight"),
73+
self.valid_params
74+
)
75+
76+
self.assertRedirects(response, reverse("questions:responses"))
77+
78+
def test_post_valid_weight_added_to_response_set(self):
79+
response = self.client.post(
80+
reverse("questions:weight"),
81+
self.valid_params
82+
)
83+
84+
response_set = self.participant.responseset_set.first()
85+
self.assertEqual(response_set.weight_metric, self.valid_weight)
86+
87+
88+
# def test_post_redirects_if_the_weight_is_invalid(self):
89+
# response = self.client.post(
90+
# reverse("questions:weight"),
91+
# {"weight": "not a valid weight"}
92+
# )
93+
94+
# self.assertEqual(response.status_code, 422)

0 commit comments

Comments
 (0)