Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions features/agree_terms_of_use.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@TermsOfUse
Feature: Check if you need an appointment page
Scenario: The page is accessible
Given I am logged in
When I go to "/agree-terms-of-use"
Then there are no accessibility violations

Scenario: Form errors
Given I am logged in
When I go to "/agree-terms-of-use"
And I click "Continue"
Then I am on "/agree-terms-of-use"
And I see a form error "Agree to the terms of use to continue"
And there are no accessibility violations

Scenario: Navigating backwards and forwards
Given I am logged in
When I go to "/agree-terms-of-use"
Then I see a back link to "/start"
When I check "I agree" and submit
Then I am on "/have-you-ever-smoked"
3 changes: 3 additions & 0 deletions features/questionnaire.feature
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Feature: Questionnaire
When I go to "/start"
And I click "Continue"

Then I am on "/agree-terms-of-use"
When I check "I agree" and submit

Then I am on "/have-you-ever-smoked"
When I fill in and submit my smoking status with "Yes, I used to smoke"

Expand Down
23 changes: 22 additions & 1 deletion lung_cancer_screening/core/jinja2/layout.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@

{% block head %}
<link rel="stylesheet" href="{{ static('css/main.css' )}}">
<style>
BODY {
counter-reset: chapter; /* Create a chapter counter scope */
}
.numbered H2:before {
content: counter(chapter) ". ";
counter-increment: chapter; /* Add 1 to chapter */
}
.numbered OL { counter-reset: section }
.numbered OL > LI { display: block }
.numbered OL > LI:before {
content: counter(chapter) "." counter(section) ". ";
counter-increment: section;
font-weight: 600;
}

</style>
<script type="module" src="{{ static('js/bundle.js' )}}"></script>
{% endblock %}

Expand Down Expand Up @@ -63,7 +80,11 @@
{
"href": url("questions:privacy_policy"),
"text": "Privacy policy"
}
},
{
"href": url("questions:terms_of_use"),
"text": "Terms of use"
},
]
}
}) }}
Expand Down
10 changes: 7 additions & 3 deletions lung_cancer_screening/jinja2_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ def environment(**options):
{"singularize": singularize}
)

env.filters.update(
{"singularize": singularize}
)
env.filters['print'] = lambda x: ""
if (settings.DEBUG):
env.filters['print']=debug

return env

def debug(text):
print(text)
return ''
4 changes: 4 additions & 0 deletions lung_cancer_screening/nhsuk_forms/choice_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ def _template_name(widget):
isinstance(widget, type) and issubclass(widget, widgets.Select)
) or isinstance(widget, widgets.Select):
return "select.jinja"
elif (
isinstance(widget, type) and issubclass(widget, widgets.CheckboxInput)
) or isinstance(widget, widgets.CheckboxInput):
return "checkbox.jinja"


class MultipleChoiceField(forms.MultipleChoiceField):
Expand Down
35 changes: 35 additions & 0 deletions lung_cancer_screening/nhsuk_forms/jinja2/checkbox.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{% from 'nhsuk/components/checkboxes/macro.jinja' import checkboxes %}
{% set unbound_field = field.field %}
{% if field.errors %}
{% set error_message = {"text": field.errors | first} %}
{% endif %}
{% set ns = namespace(items=[]) %}
{% for value, text in unbound_field.choices %}
{% set hint_text = field.get_hint_for_choice(value) %}
{% set ns.items = ns.items + [{
"id": field.auto_id ~ '_' ~ loop.index0,
"value": value,
"text": text,
"checked": value == field.value()|string,
"hint": {
"text": hint_text
} if hint_text else undefined
}] %}
{% endfor %}
{{ checkboxes({
"name": field.html_name,
"idPrefix": field.auto_id,
"fieldset": {
"legend": {
"text": field.label,
"classes": unbound_field.label_classes,
"isPageHeading": unbound_field.label_is_page_heading
}
} if field.use_fieldset else none,
"errorMessage": error_message,
"classes": unbound_field.classes if unbound_field.classes,
"hint": {
"html": unbound_field.hint|e
} if unbound_field.hint,
"items": ns.items
}) }}
22 changes: 22 additions & 0 deletions lung_cancer_screening/questions/forms/agree_terms_of_use_form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from django import forms

from ...nhsuk_forms.choice_field import ChoiceField

from ..models.terms_of_use_response import TermsOfUseResponse


class TermsOfUseForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["value"] = ChoiceField(
choices=[(True, 'I agree')],
widget=forms.CheckboxInput,
label="I agree",
error_messages={
'required': 'Agree to the terms of use to continue',
'invalid_choice': 'Agree to the terms of use to continue'
}
)
class Meta:
model = TermsOfUseResponse
fields = ['value']
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{% extends 'question_form.jinja' %}

{% block prelude %}
<h1 class="nhsuk-heading-l">Accept terms of use</h1>

<p>To continue, confirm that you have read and agree to the <a href="/terms-of-use" target="_blank">NHS Check if you need a lung scan terms of use (opens in new tab)</a></p>
{% endblock %}
2 changes: 1 addition & 1 deletion lung_cancer_screening/questions/jinja2/start.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

{{ button({
"text": "Continue",
"href": url("questions:have_you_ever_smoked"),
"href": url("questions:agree_terms_of_use"),
"classes": "nhsuk-button--login"
}) }}

Expand Down
170 changes: 170 additions & 0 deletions lung_cancer_screening/questions/jinja2/terms_of_use.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
{% extends 'layout.jinja' %}

{% block content %}
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds numbered">
<h1 class="nhsuk-heading-l">NHS check if you need a lung scan terms of use</h1>


<p>Information:</p>

<p>Version 3, 5 March 2026</p>



<section>
<h2 class="nhsuk-heading-m">Introduction</h2>

<ol>
<li>We (NHS England) have developed a digital service called NHS check if you need a lung scan. This is a digital way to access <a href="https://www.nhs.uk/tests-and-treatments/lung-cancer-screening/" target="_blank" rel="noopener">NHS lung cancer screening</a>. This service is currently in pilot so is only available in certain areas, and if you are invited by your GP to take part.</li>
<br /><br />
<p>This service will not provide you with any results or information in relation to the lung cancer screening, you will need to complete your lung cancer screening by phone to receive a result.</p>

<p>To find out more about who we are and our role, visit the <a href="https://transform.england.nhs.uk/" target="_blank" rel="noopener">NHS England website</a>.</p>
</li>

<li>Contacting us: if you have any questions about the service, <a href="https://www.nhs.uk/contact-us/nhs-app-contact-us/tell-us-what-you-need-help-with" target="_blank" rel="noopener">contact us</a> by email: <a href="mailto:england.digitallungcancerscreening@nhs.net">england.digitallungcancerscreening@nhs.net</a></li>
</ol>
</section>
<section>
<h2 class="nhsuk-heading-m">When these terms apply</h2>

<ol>
<li>Please read these terms of use and our <a href="/privacy-policy" target="_blank" rel="noopener">privacy policy</a>, <a href="/cookies" target="_blank" rel="noopener">cookies policy</a> and <a href="/accessibility-statement" target="_blank" rel="noopener">accessibility statement</a>. By continuing to use the NHS check if you need a lung scan, you agree to be bound by these terms.</li>
<li>We may, at any time and in our sole discretion, amend these terms for any reason. The latest version of our terms will be accessible through the NHS check if you need a lung scan.</li>
</ol>
</section>
<section>
<h2 class="nhsuk-heading-m">How to use the NHS check if you need a lung scan</h2>

<ol>
<li>NHS check if you need a lung scan is free. To use NHS check if you need a lung scan, you must be invited to take part by your GP. Your GP will send you a letter and an SMS with a link to access the NHS check if you need a lung scan pilot service in a web browser.</li>
<li>To use the NHS check if you need a lung scan you need an NHS login account with a medium level of identity verification. If you do not have an account or a medium level of identity verification, you will be able to set this up as part of your application. <a href="https://www.nhs.uk/nhs-services/online-services/nhs-login/" target="_blank" rel="noopener">Find out more about NHS login</a>.</li>
<li>If you access or attempt to access the NHS check if you need a lung scan from outside of England, you are responsible for complying with any local laws that apply to you in the country from which you are using NHS check if you need a lung scan.</li>
<li>The NHS check if you need a lung scan is split into different sections. You must answer all the questions in each section to enable us to process your information. More information on this and how your information is used and processed is in the <a href="/privacy-policy" target="_blank" rel="noopener">privacy policy</a>.</li>
<li>The NHS check if you need a lung scan can only be accessed if you are aged between 55 and 74, registered with a supported GP surgery, and you smoke or used to smoke tobacco.</li>
</ol>
</section>

<section>
<h2 class="nhsuk-heading-m">Accessing the NHS check if you need a lung scan</h2>

<ol>
<li> You are responsible for making all arrangements necessary for you to access the NHS check if you need a lung scan, including but not limited to:</li>
<ul>
<li>a secure internet connection (see <a href="https://www.ncsc.gov.uk/cyberaware/home" target="_blank" rel="noopener">Cyber Aware website</a>)</li>
<li>an appropriate device, operating system and browser</li>
<li>using your own virus protection software (and regularly updating it) when accessing and using the NHS check if you need a lung scan</li>
</ul>
</li>
</ol>
</section>

<section>
<h2 class="nhsuk-heading-m">Details about the NHS check if you need a lung scan</h2>

<ol>
<li>If you download, print or export any of your submitted information, you are responsible for ensuring that this is held securely, and we will not be liable for any associated disclosure of sensitive and personal data.</li>
<li>In order for you to receive the intended benefits of the NHS check if you need a lung scan, you must ensure that all data provided by you is complete and accurate.</li>
<li>Your GP health records are created and kept up to date by your GP and remain under your GP’s control. We do not hold or have access to any GP records and are unable to answer queries about them or provide hard copies.</li>
<li>The NHS check if you need a lung scan:
<ul>
<li>is not a substitute for seeking medical advice - always follow any medical advice given by your healthcare professionals</li>
<li>does not provide medical or clinical diagnostic services</li>
<li>does not arrange or guarantee further healthcare treatment. You remain responsible for booking further healthcare treatment via the phone service as directed by your GP.</li>
</ul>
</li>
<li>We are not responsible for any delay or lack of response by a GP surgery or for the outcome of any decision your GP may make about any follow-on treatment or advice. No information or results will be shared with GPs through NHS check if you need a lung scan, and we do not guarantee it will lead to onward healthcare.</li>
</ol>
</section>

<section>
<h2 class="nhsuk-heading-m">Ending your use of the NHS check if you need a lung scan</h2>
<ol>
<li>You may stop using the NHS check if you need a lung scan at any time. If you fail to complete your NHS check if you need a lung scan within a set period of time your data will automatically be deleted. More information on how long your information is kept is in the <a href="/privacy-policy" target="_blank" rel="noopener">privacy policy</a>.</li>
</ol>
</section>

<section>
<h2 class="nhsuk-heading-m">Your right to use the NHS check if you need a lung scan</h2>
<ol>
<li>We own or have the right to use all intellectual property rights used for the provision of the NHS check if you need a lung scan, including rights in copyright, patents, database rights, trademarks and other intellectual property rights, ("NHS IPR").</li>
<li>7.2. You have permission to use the NHS check if you need a lung scan for the sole purposes described in these terms and must not use it in any other way.</li>
<li>7.3. Unless permitted by law or under these terms, you will:</li>
<ul>
<li>not copy the NHS check if you need a lung scan or any NHS IPR, except where such copying is incidental to normal use</li>
<li>not rent, lease, sub-license, loan, translate, merge, adapt or modify the NHS check if you need a lung scan or any NHS IPR</li>
<li>not combine or incorporate the NHS check if you need a lung scan in any other programmes or services</li>
<li>not disassemble, decompile, reverse-engineer or create derivative works based on the whole or any part of the NHS check if you need a lung scan or other NHS IPR</li>
<li>comply with all technology control or export laws that apply to the technology used by the NHS check if you need a lung scan or any other NHS IPR</li>
</ul>
</li>
</ol>
</section>

<section>
<h2 class="nhsuk-heading-m">Prohibited uses</h2>
<ol>
<li>You may not use the NHS check if you need a lung scan:
<ul>
<li>to collect any data or attempt to decipher any transmissions to or from our servers</li>
<li>in a way that could damage, disable, overburden, impair or compromise our systems or security</li>
<li>to transmit any material that is insulting or offensive</li>
<li>in a way that interferes with other users</li>
<li>in any unlawful manner or for any unlawful purpose</li>
<li>in a manner that is improper use or inconsistent with these terms</li>
<li>to act fraudulently or maliciously by seeking to access or add data to another patient's GP record</li>
<li>to transmit, send or upload any data that contains viruses, Trojan horses, worms, spyware or any other harmful programs designed to adversely affect the operation of computer software or hardware</li>
<li>in connection with any kind of denial of service attack</li>
<li>on any device or operating system that has been modified outside the mobile device or operating system vendor supported or warranted configurations. This includes devices that have been "jail-broken" or "rooted"</li>
<li>with someone else's NHS login account</li>
</ul>
</li>
</ol>
<p>If you do any of the above acts you may also be committing a criminal offence, and we will report any such activity to the relevant law enforcement authorities. We will co-operate with those authorities by disclosing your identity to them.</p>
</section>

<section>
<h2 class="nhsuk-heading-m">Our liability to you</h2>
<ol>
<li>Although we make reasonable efforts to provide, maintain and update the NHS check if you need a lung scan it is provided "as is" and, to the extent permitted by law, we make no representations, warranties or guarantees, whether express or implied (including but not limited to the implied warranties of satisfactory quality and fitness for a particular purpose), that the NHS check if you need a lung scan:
<ul>
<li>is accurate, complete or up-to-date</li>
<li>will meet your particular requirements or needs</li>
<li>will always be available, error free, uninterrupted or free of viruses</li>
</ul>
<li>We are not responsible for external links to or from the NHS check if you need a lung scan and cannot guarantee these will always work.</li>
<li>Nothing in these terms excludes or limits our liability for:</li>
<ul>
<li>death or personal injury arising from our negligence</li>
<li>fraud or fraudulent misrepresentation</li>
<li>any loss or damage to a device or digital content belonging to you, if you can show that a) this was caused by NHS check if you need a lung scan and b) we failed use to use reasonable skill and care to prevent this</li>
<li>any other liability that cannot be excluded or limited under English law</li>
</ul>
</li>
<li>Subject to clause 9.3 of these terms, we will not be liable or responsible to you or any other person for:</li>
<ul>
<li>any harm, loss or damage suffered where this is not caused by i) our negligence or ii) our breach of these terms</li>
<li>any loss or damage arising from an inability to access or use the NHS check if you need a lung scan in whole or in part</li>
<li>any business loss (including but not limited to loss of profits, revenue, contracts, anticipated savings, data, goodwill or wasted expenditure)</li>
<li>any indirect or consequential losses that were not foreseeable to both you and us when you commenced using the NHS check if you need a lung scan (loss or damage is "foreseeable" if it was an obvious consequence of our breach or if it was recognised by you and us at the time we entered into the contract created by your use of the NHS check if you need a lung scan)</li>
</ul>
</li>
<li>This clause 9 does not affect any legal rights you may have as a consumer in relation to defective services or software. Advice about your legal rights is available from your local Citizen's Advice or Trading Standards Office.</li>
</ol>

</section>

<section>
<h2 class="nhsuk-heading-m">General</h2>
<ol>
<li>These terms, any instructions in the service, and any other terms or policies referenced, set out the entire agreement between you and us in respect of your use of the NHS check if you need a lung scan.</li>
<li>These terms do not give any rights to any third party to enforce any of these terms.</li>
<li>Each of the clauses and sub-clauses of these terms operates separately. If any part is determined to be invalid or unenforceable it will be superseded by a valid and enforceable provision that most closely matches the intent of the original and all other terms shall continue in effect.</li>
<li>Even if we delay in enforcing these terms, we can still enforce them later.</li>
<li>The laws of England shall apply exclusively to these terms and all matters relating to use of the NHS check if you need a lung scan, and any dispute shall be subject to the exclusive jurisdiction of the courts of England.</li>
</ol>
</section>
</div>
</div>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 5.2.11 on 2026-03-09 15:16

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('questions', '0006_alter_smokingfrequencyresponse_value'),
]

operations = [
migrations.CreateModel(
name='TermsOfUseResponse',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('value', models.BooleanField()),
('response_set', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='terms_of_use_response', to='questions.responseset')),
],
options={
'abstract': False,
},
),
]
Loading
Loading