Skip to content

Commit 47c65d0

Browse files
committed
PPHA-262: height page
1 parent e18a6d8 commit 47c65d0

File tree

14 files changed

+273
-10
lines changed

14 files changed

+273
-10
lines changed

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
@@ -22,3 +22,10 @@ def fill_in_and_submit_date_of_birth(page, age):
2222
page.get_by_label("Year").fill(str(age.year))
2323

2424
page.click("text=Continue")
25+
26+
def fill_in_and_submit_height(page, height):
27+
expect(page.locator("h1")).to_have_text("What is your height?")
28+
29+
page.get_by_label("Centimeter").fill(str(height))
30+
31+
page.click("text=Continue")

lung_cancer_screening/core/tests/acceptance/test_questionnaire.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from dateutil.relativedelta import relativedelta
66

77
from .helpers.user_interaction_helpers import (
8+
fill_in_and_submit_height,
89
fill_in_and_submit_participant_id,
910
fill_in_and_submit_smoking_elligibility,
1011
fill_in_and_submit_date_of_birth
@@ -31,6 +32,7 @@ def test_full_questionaire_user_journey(self):
3132
participant_id = '123'
3233
smoking_status = 'Yes, I used to smoke regularly'
3334
age = datetime.now() - relativedelta(years=55)
35+
height = "170"
3436

3537
page = self.browser.new_page()
3638
page.goto(f"{self.live_server_url}/start")
@@ -47,12 +49,20 @@ def test_full_questionaire_user_journey(self):
4749

4850
fill_in_and_submit_date_of_birth(page, age)
4951

52+
expect(page).to_have_url(f"{self.live_server_url}/height")
53+
54+
fill_in_and_submit_height(page, height)
55+
5056
expect(page).to_have_url(f"{self.live_server_url}/responses")
5157

52-
expect(page.locator(".responses")).to_contain_text(
53-
age.strftime("Have you ever smoked? Yes, I used to smoke regularly"))
54-
expect(page.locator(".responses")).to_contain_text(age.strftime("What is your date of birth? %Y-%m-%d"))
58+
response = page.locator(".responses")
59+
expect(responses).to_contain_text("Have you ever smoked? Yes, I used to smoke regularly")
60+
expect(responses).to_contain_text(
61+
age.strftime("What is your date of birth? %Y-%m-%d"))
62+
expect(responses).to_contain_text(f"Height: {height}")
5563

5664
page.click("text=Submit")
5765

66+
67+
5868
expect(page).to_have_url(f"{self.live_server_url}/your-results")

lung_cancer_screening/core/tests/unit/__init__.py

Whitespace-only changes.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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/input/macro.jinja' import input %}
5+
{% from 'nhsuk/components/fieldset/macro.jinja' import fieldset %}
6+
7+
{% block beforeContent %}
8+
{{
9+
backLink({
10+
"href": url("questions:date_of_birth"),
11+
"text": "Back"
12+
})
13+
}}
14+
{% endblock beforeContent %}
15+
16+
{% block page_content %}
17+
<div class="nhsuk-grid-row">
18+
<div class="nhsuk-grid-column-two-thirds">
19+
<form action="{{ request.path }}" method="POST">
20+
{{ csrf_input }}
21+
<h1 class="nhsuk-heading-l">What is your height?</h1>
22+
<p>An accurate measurement is important.
23+
24+
<p>You can measure your height at home with a measuring tape. Some pharmacies and gyms have machines to measure your height.
25+
{% call fieldset({
26+
"legend": {
27+
"text": "Enter your height",
28+
"classes": "nhsuk-label--m"
29+
}
30+
}) %}
31+
{{
32+
input({
33+
"id": "height",
34+
"name": "height",
35+
"label": {
36+
"text": "Centimetres",
37+
},
38+
"classes": "nhsuk-input--width-4"
39+
})
40+
}}
41+
{% endcall %}
42+
43+
{{ button({
44+
"text": "Continue"
45+
}) }}
46+
</form>
47+
</div>
48+
</div>
49+
{% endblock %}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.2.6 on 2025-10-06 15:16
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('questions', '0008_remove_responseset_submitted_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='responseset',
15+
name='height',
16+
field=models.PositiveIntegerField(blank=True, null=True),
17+
),
18+
]

lung_cancer_screening/questions/models/response_set.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.db import models
22
from django.core.exceptions import ValidationError
3+
from django.core.validators import MaxValueValidator, MinValueValidator
34
from dateutil.relativedelta import relativedelta
45
from django.utils import timezone
56

@@ -22,6 +23,13 @@ class ResponseSet(BaseModel):
2223
)
2324
date_of_birth = models.DateField(null=True, blank=True)
2425

26+
height = models.PositiveIntegerField(null=True, blank=True, validators=[
27+
MinValueValidator(1397, message="Height must be between 139.7cm and 243.8 cm"),
28+
MaxValueValidator(2438, message="Height must be between 139.7cm and 243.8 cm"),
29+
])
30+
31+
#height_type
32+
2533
submitted_at = models.DateTimeField(null=True, blank=True)
2634

2735
class Meta:

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

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from ....models.participant import Participant
99
from ....models.response_set import HaveYouEverSmokedValues
1010

11+
1112
class TestResponseSet(TestCase):
1213
def setUp(self):
1314
participant = Participant.objects.create(unique_id="12345")
@@ -31,6 +32,15 @@ def test_has_date_of_birth_as_a_date(self):
3132
date
3233
)
3334

35+
def test_has_height_as_a_int(self):
36+
self.response_set.height = 1700
37+
self.response_set.save()
38+
39+
self.assertIsInstance(
40+
self.response_set.height,
41+
int
42+
)
43+
3444
def test_has_a_participant_as_a_foreign_key(self):
3545
self.assertIsInstance(
3646
self.response_set.participant,
@@ -62,12 +72,12 @@ def test_has_submitted_at_as_a_datetime(self):
6272
datetime
6373
)
6474

65-
def test_is_invalid_if_another_unsubmitted_response_set_exists(self):
75+
def test_is_invalid_if_another_unsubmitted_response_set_exists(self):
6676
participant = Participant.objects.create(unique_id="56789")
67-
participant.responseset_set.create(submitted_at = None)
77+
participant.responseset_set.create(submitted_at=None)
6878

6979
with self.assertRaises(ValidationError) as context:
70-
participant.responseset_set.create(submitted_at = None)
80+
participant.responseset_set.create(submitted_at=None)
7181

7282
self.assertEqual(
7383
context.exception.messages[0],
@@ -88,3 +98,24 @@ def test_is_invalid_if_another_response_set_was_submitted_within_the_last_year(s
8898
"Responses have already been submitted for this participant"
8999
)
90100

101+
def test_is_invalid_if_height_is_below_lower_bound(self):
102+
self.response_set.height = 1396
103+
104+
with self.assertRaises(ValidationError) as context:
105+
self.response_set.full_clean()
106+
107+
self.assertIn(
108+
"Height must be between 139.7cm and 243.8 cm",
109+
context.exception.messages
110+
)
111+
112+
def test_is_invalid_if_height_is_above_upper_bound(self):
113+
self.response_set.height = 2439
114+
115+
with self.assertRaises(ValidationError) as context:
116+
self.response_set.full_clean()
117+
118+
self.assertIn(
119+
"Height must be between 139.7cm and 243.8 cm",
120+
context.exception.messages
121+
)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,13 @@ def test_post_sets_the_participant_id_in_session(self):
7373

7474
self.assertEqual(self.client.session["participant_id"], "12345")
7575

76-
def test_post_redirects_to_responses_path(self):
76+
def test_post_redirects_to_height_path(self):
7777
response = self.client.post(
7878
reverse("questions:date_of_birth"),
7979
self.valid_params
8080
)
8181

82-
self.assertRedirects(response, reverse("questions:responses"))
82+
self.assertRedirects(response, reverse("questions:height"))
8383

8484
def test_post_responds_with_422_if_the_resource_is_invalid(self):
8585
response = self.client.post(
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from django.test import TestCase
2+
from django.urls import reverse
3+
from datetime import date
4+
from dateutil.relativedelta import relativedelta
5+
6+
from ....models.participant import Participant
7+
8+
9+
class TestPostDateOfBirth(TestCase):
10+
def setUp(self):
11+
self.participant = Participant.objects.create(unique_id="12345")
12+
self.participant.responseset_set.create()
13+
14+
self.valid_height = 170
15+
self.valid_params = {"height": self.valid_height}
16+
self.invalid_height = 80000
17+
18+
session = self.client.session
19+
session['participant_id'] = self.participant.unique_id
20+
21+
session.save()
22+
23+
def test_get_redirects_if_the_participant_does_not_exist(self):
24+
session = self.client.session
25+
session['participant_id'] = "somebody none existent participant"
26+
session.save()
27+
28+
response = self.client.get(
29+
reverse("questions:height")
30+
)
31+
32+
self.assertRedirects(response, reverse("questions:start"))
33+
34+
def test_get_responds_successfully(self):
35+
response = self.client.get(reverse("questions:height"))
36+
37+
self.assertEqual(response.status_code, 200)
38+
39+
def test_post_redirects_if_the_participant_does_not_exist(self):
40+
session = self.client.session
41+
session['participant_id'] = "somebody none existent participant"
42+
session.save()
43+
44+
response = self.client.post(
45+
reverse("questions:height"),
46+
self.valid_params
47+
)
48+
49+
self.assertRedirects(response, reverse("questions:start"))
50+
51+
def test_post_stores_a_valid_response_set_for_the_participant(self):
52+
self.client.post(
53+
reverse("questions:height"),
54+
self.valid_params
55+
)
56+
57+
response_set = self.participant.responseset_set.first()
58+
59+
self.assertEqual(response_set.height, self.valid_height*10)
60+
self.assertEqual(response_set.participant, self.participant)
61+
62+
def test_post_redirects_to_responses_path(self):
63+
response = self.client.post(
64+
reverse("questions:height"),
65+
self.valid_params
66+
)
67+
68+
self.assertRedirects(response, reverse("questions:responses"))
69+
70+
def test_post_responds_with_422_if_the_resource_is_invalid(self):
71+
response = self.client.post(
72+
reverse("questions:height"),
73+
{"height": "a"}
74+
)
75+
76+
self.assertEqual(response.status_code, 422)
77+
78+
79+
# If nothing is entered - Enter your height
80+
# User enters a height that is outside the accepted range (cms) - Height must be between 139.7cm and 243.8 cm
81+
# User enters a height that is outside the accepted range (feet and inches) - Height must be between 4 feet 7 inches and 8 feet
82+
# User enters a reading for feet that is outside the accepted range - Feet must be between 4 and 8
83+
# User enters a reading for inches that is outside the accepted range - Inches must be between 0 and 11
84+
# User enters a reading for feet using a decimal point - Feet must be in whole numbers
85+
# User enters a reading for inches using a decimal point - I

lung_cancer_screening/questions/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@
2222
from .views.age_range_exit import age_range_exit
2323
from .views.non_smoker_exit import non_smoker_exit
2424
from .views.your_results import your_results
25+
from .views.height import height
2526

2627
urlpatterns = [
2728
path('start', start, name='start'),
2829
path('have-you-ever-smoked', have_you_ever_smoked, name='have_you_ever_smoked'),
2930
path('date-of-birth', date_of_birth, name='date_of_birth'),
31+
path('height', height, name='height'),
3032
path('responses', responses, name='responses'),
3133
path('age-range-exit', age_range_exit, name='age_range_exit'),
3234
path('non-smoker-exit', non_smoker_exit, name='non_smoker_exit'),

0 commit comments

Comments
 (0)