Skip to content

Commit f99dd9f

Browse files
committed
PPHA-527: Adding currently smoking cigarettes question
1 parent 503e30d commit f99dd9f

17 files changed

+423
-27
lines changed

features/currently_smoking.feature

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
@CurrentlySmokingCigarettes
2+
Feature: Currently smoking page
3+
Scenario: The page is accessible
4+
Given I am logged in
5+
And I have answered questions showing I am eligible
6+
When I go to "/currently-smoking-cigarettes"
7+
Then there are no accessibility violations
8+
9+
Scenario: Form errors
10+
Given I am logged in
11+
And I have answered questions showing I am eligible
12+
When I go to "/currently-smoking-cigarettes"
13+
And I click "Continue"
14+
Then I am on "/currently-smoking-cigarettes"
15+
And I see a form error "Select if you currently smoke cigarettes"
16+
And there are no accessibility violations
17+
18+
Scenario: Navigating backwards and forwards
19+
Given I am logged in
20+
And I have answered questions showing I am eligible
21+
When I go to "/currently-smoking-cigarettes"
22+
Then I see a back link to "/age-when-started-smoking"
23+
When I check "Yes" and submit
24+
Then I am on "/check-your-answers"
25+
26+
Scenario: Checking responses and changing them
27+
Given I am logged in
28+
And I have answered questions showing I am eligible
29+
When I go to "/currently-smoking-cigarettes"
30+
When I check "Yes" and submit
31+
When I go to "/check-your-answers"
32+
Then I see "Yes" as a response to "Do you currently smoke cigarettes?" under "Smoking history"
33+
And I see "/currently-smoking-cigarettes?change=True" as a link to change "Do you currently smoke cigarettes?" under "Smoking history"
34+
When I click the link to change "Do you currently smoke cigarettes?" under "Smoking history"
35+
Then I am on "/currently-smoking-cigarettes?change=True"
36+
And I see "Yes" selected
37+
When I check "No" and submit
38+
Then I am on "/check-your-answers"
39+
And I see "No" as a response to "Do you currently smoke cigarettes?" under "Smoking history"

features/questionnaire.feature

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
@AgeWhenStartedSmoking
21
Feature: Questionnaire
32
Scenario: Cannot change responses once submitted
43
Given I am logged in
@@ -59,8 +58,11 @@ Feature: Questionnaire
5958
Then I am on "/age-when-started-smoking"
6059
When I fill in "How old were you when you started smoking?" as "18" and submit
6160

61+
Then I am on "/currently-smoking-cigarettes"
62+
When I check "Yes" and submit
63+
6264
Then I am on "/check-your-answers"
63-
And I see a back link to "/age-when-started-smoking"
65+
And I see a back link to "/currently-smoking-cigarettes"
6466

6567
And I see "Yes, I used to smoke" as a response to "Have you ever smoked tobacco?" under "Eligibility"
6668
And I see a date 55 years ago as a response to "Date of birth" under "Eligibility"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from django import forms
2+
3+
from ..models.currently_smoking_cigarettes_response import CurrentlySmokingCigarettesResponse
4+
5+
from ...nhsuk_forms.typed_choice_field import TypedChoiceField
6+
7+
class CurrentlySmokingCigarettesForm(forms.ModelForm):
8+
def __init__(self, *args, **kwargs):
9+
super().__init__(*args, **kwargs)
10+
11+
self.fields["value"] = TypedChoiceField(
12+
choices=[(True, 'Yes'), (False, 'No')],
13+
widget=forms.RadioSelect,
14+
label="Do you currently smoke cigarettes?",
15+
label_classes="nhsuk-fieldset__legend--l",
16+
label_is_page_heading=True,
17+
coerce=lambda x: x == 'True',
18+
error_messages={
19+
'required': 'Select if you currently smoke cigarettes',
20+
}
21+
)
22+
23+
class Meta:
24+
model = CurrentlySmokingCigarettesResponse
25+
fields = ['value']
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Generated by Django 5.2.10 on 2026-01-26 16:07
2+
3+
import django.core.validators
4+
import django.db.models.deletion
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('questions', '0043_agewhenstartedsmokingresponse'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='agewhenstartedsmokingresponse',
17+
name='value',
18+
field=models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(1, message='The age you started smoking must be between 1 and your current age')]),
19+
),
20+
migrations.AlterField(
21+
model_name='ethnicityresponse',
22+
name='value',
23+
field=models.CharField(choices=[('A', 'Asian or Asian British'), ('B', 'Black, African, Caribbean or Black British'), ('M', 'Mixed or multiple ethnic groups'), ('W', 'White'), ('O', 'Other ethnic group'), ('N', 'Prefer not to say')], max_length=1),
24+
),
25+
migrations.AlterField(
26+
model_name='sexatbirthresponse',
27+
name='value',
28+
field=models.CharField(choices=[('F', 'Female'), ('M', 'Male'), ('I', 'Intersex')], max_length=1),
29+
),
30+
migrations.CreateModel(
31+
name='CurrentlySmokingCigarettesResponse',
32+
fields=[
33+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
34+
('created_at', models.DateTimeField(auto_now_add=True)),
35+
('updated_at', models.DateTimeField(auto_now=True)),
36+
('value', models.BooleanField()),
37+
('response_set', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='currently_smoking_cigarettes_response', to='questions.responseset')),
38+
],
39+
options={
40+
'abstract': False,
41+
},
42+
),
43+
]

lung_cancer_screening/questions/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .asbestos_exposure_response import AsbestosExposureResponse # noqa: F401
77
from .cancer_diagnosis_response import CancerDiagnosisResponse # noqa: F401
88
from .check_need_appointment_response import CheckNeedAppointmentResponse # noqa: F401
9+
from .currently_smoking_cigarettes_response import CurrentlySmokingCigarettesResponse # noqa: F401
910
from .date_of_birth_response import DateOfBirthResponse # noqa: F401
1011
from .ethnicity_response import EthnicityResponse # noqa: F401
1112
from .family_history_lung_cancer_response import FamilyHistoryLungCancerResponse # noqa: F401
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from django.db import models
2+
3+
from .base import BaseModel
4+
from .response_set import ResponseSet
5+
6+
7+
class CurrentlySmokingCigarettesResponse(BaseModel):
8+
response_set = models.OneToOneField(ResponseSet, on_delete=models.CASCADE, related_name='currently_smoking_cigarettes_response')
9+
value = models.BooleanField()

lung_cancer_screening/questions/presenters/response_set_presenter.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ def age_when_started_smoking(self):
117117

118118
return str(self.response_set.age_when_started_smoking_response.value)
119119

120+
@property
121+
def currently_smoking_cigarettes(self):
122+
if not hasattr(self.response_set, 'currently_smoking_cigarettes_response'):
123+
return None
124+
125+
return "Yes" if self.response_set.currently_smoking_cigarettes_response.value else "No"
126+
120127
@property
121128
def respiratory_conditions(self):
122129
if not hasattr(self.response_set, 'respiratory_conditions_response'):
@@ -229,6 +236,11 @@ def smoking_history_responses_items(self):
229236
"Age you started smoking",
230237
self.age_when_started_smoking,
231238
"questions:age_when_started_smoking",
239+
),
240+
self._check_your_answer_item(
241+
"Do you currently smoke cigarettes?",
242+
self.currently_smoking_cigarettes,
243+
"questions:currently_smoking_cigarettes",
232244
)
233245
]
234246

lung_cancer_screening/questions/tests/factories/age_when_started_smoking_response_factory.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,20 @@ class Meta:
1313
response_set = factory.SubFactory(ResponseSetFactory)
1414
value = factory.Faker('pyint', min_value=15, max_value=50)
1515

16-
# Create a DateOfBirthResponse linked to the same response_set
17-
date_of_birth_response = factory.RelatedFactory(
18-
DateOfBirthResponseFactory,
19-
factory_related_name="value",
20-
)
16+
@factory.post_generation
17+
def date_of_birth_response(obj, create, extracted, **kwargs):
18+
"""Create a DateOfBirthResponse linked to the same response_set if one doesn't exist."""
19+
if extracted:
20+
# Use the provided DateOfBirthResponse
21+
return extracted
22+
23+
# Check if response_set already has a date_of_birth_response
24+
if hasattr(obj.response_set, 'date_of_birth_response'):
25+
return obj.response_set.date_of_birth_response
26+
27+
if create:
28+
# Create a DateOfBirthResponse with the same response_set
29+
DateOfBirthResponseFactory.create(response_set=obj.response_set, **kwargs)
30+
else:
31+
# Build a DateOfBirthResponse with the same response_set
32+
DateOfBirthResponseFactory.build(response_set=obj.response_set, **kwargs)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import factory
2+
3+
from ...models.currently_smoking_cigarettes_response import CurrentlySmokingCigarettesResponse
4+
5+
from .response_set_factory import ResponseSetFactory
6+
7+
8+
class CurrentlySmokingCigarettesResponseFactory(factory.django.DjangoModelFactory):
9+
class Meta:
10+
model = CurrentlySmokingCigarettesResponse
11+
12+
response_set = factory.SubFactory(ResponseSetFactory)
13+
value = factory.Faker('boolean')
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from django.test import TestCase, tag
2+
3+
from ....models.currently_smoking_cigarettes_response import CurrentlySmokingCigarettesResponse
4+
5+
from ...factories.response_set_factory import ResponseSetFactory
6+
7+
from ....forms.currently_smoking_cigarettes_form import CurrentlySmokingCigarettesForm
8+
9+
10+
@tag("CurrentlySmokingCigarettes")
11+
class TestCurrentlySmokingCigarettesForm(TestCase):
12+
def setUp(self):
13+
self.response_set = ResponseSetFactory()
14+
self.response = CurrentlySmokingCigarettesResponse.objects.create(
15+
response_set=self.response_set,
16+
value=False
17+
)
18+
19+
20+
def test_is_valid_with_a_valid_value(self):
21+
form = CurrentlySmokingCigarettesForm(
22+
instance=self.response,
23+
data={
24+
"value": False
25+
}
26+
)
27+
self.assertTrue(form.is_valid())
28+
self.assertEqual(
29+
form.cleaned_data["value"],
30+
False
31+
)
32+
33+
def test_is_invalid_with_an_invalid_value(self):
34+
form = CurrentlySmokingCigarettesForm(
35+
instance=self.response,
36+
data={
37+
"value": "invalid"
38+
}
39+
)
40+
self.assertFalse(form.is_valid())
41+
self.assertEqual(
42+
form.errors["value"],
43+
["Select a valid choice. invalid is not one of the available choices."]
44+
)
45+
46+
def test_is_invalid_when_no_option_is_selected(self):
47+
form = CurrentlySmokingCigarettesForm(
48+
instance=self.response,
49+
data={
50+
"value": None
51+
}
52+
)
53+
self.assertFalse(form.is_valid())
54+
self.assertEqual(
55+
form.errors["value"],
56+
["Select if you currently smoke cigarettes"]
57+
)

0 commit comments

Comments
 (0)