The only impactful change is the major version itself, where I've
fixed the breaking changes due to the upgrade of PyPDF2 [^1] and
checked there are no deprecation warnings when I run the tests.
[^1]: https://github.com/alphagov/notifications-utils/pull/973
If a letters that has been posted via the API has more than 10 pages it would not get a validation-failed status. This also happens for letters in a CSV upload, only the first row has been validated for having too many pages, because you need to created the pdf before getting an accurate page count.
The API has been updated to mark these letters as invalid and move the
letter to the invalid s3 bucket, the meta data is also set with the
error message and page count.
This PR updates the notification page to display the validation error.
https://www.pivotaltracker.com/story/show/169209742
If you’ve come to look at a notification via the uploaded letters page
then the ‘< back’ link should take you back there, not to the usual
activity page.
We had a report that when clicking on the 'Download this letter' link on
the notification page the file was not being downloaded as a PDF file
but was given a `.htm` file extension instead. We should be able to stop
that happening by using Flask's `send_file` function with the right mimetype.
This change updates the `view_letter_notification_as_preview` to use
`send_file` and splits out code to get the file data into a separate
function.
Mocks in the tests have been updated and some unused mocks removed.
The postage covers up some of the letter, so it can hide the problem. It
also implies that the letter has been put in an envelope, which will
never happen if it fails validation.
This matches what we do for uploaded letters.
Sometimes we manually check that a URL parameter is in a required set.
Sometimes we don’t bother.
This commit adds a URL converter to do this so that:
- we don’t have to re-write the same code every time
- it’s easier to apply this check to other endpoints
This means endpoints that previously allowed a `template_type` or
`message_type` of `None` now 404. So I’ve had to add new routes for
with URLs that don’t include such parameters.
So this…:
```
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications/sms.csv
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications/None.csv
```
…becomes:
```
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications/sms.csv
/services/128b91b6-2996-4107-bb65-51b7c24a728d/notifications.csv
```
This matches what we do for the HTML-responding equivalent (see
265931d217/app/main/views/jobs.py (L215-L216))
We mostly rely on the API returning a 404 to generate 404s for trying
to get things with non-UUID IDs. This is fine, except our tests often
mock these API calls. So it could look like everything is working fine,
except the thing your passing in might never be a valid UUID, and thus
would 404 in a non-test environment.
So this commit:
1. uses the `uuid` URL converter everywhere there’s something that looks
like an ID in a URL parameter
2. adds a test which automates checking for 1.
Show valdiation failed messages on letter notifications in red text,
not in the banner like we do on Uploads and Validation checker pages.
This is because it is a different step in the journey: the user
has already sent the notification and styling needs to be in line
with other places where user is checking the notification she already
has sent.
Rather than force us to write the decorators in a specific order let’s
just have one decorator call the other. This should make fewer lines of
code, and fewer annoying test failures. It also means that the same way
of raising a `401` (through the `current_app` method) is used
everywhere.
At the moment we mostly have `user_has_permissions` execute first. It
shouldn’t matter, but it feels right for us to check that a user is
logged in before we check their permissions to a service. Otherwise a
malicious user could (maybe) check if a service ID belongs to a real
service, and go on to do something malicious with that information.
This commit adds some extra test code to enforce that the order is
always the same.
N.B. decorators in Python execute from closest to furthest (from the
line on which the function is defined).
We accidentally miss these sometimes. This code adds a test which
inspects the code to automatically check that any function which:
- handles a route
- accepts a service_id
For each function it checks that each of these routes have the
permissions decorator we’d expect.
Most of the introspection/AST code is adapted from here:
https://mvdwoord.github.io/exploration/2017/08/18/ast_explore.html
Changed this yesterday. Changing it again now because I think it’s
confusing.
There’s really no going ‘back’ once you’ve sent a message – you can’t
undo it. If you want to get back to the template you used, well, that
link is in the page.
This commit changes the back link logic so it only appears when you’ve
navigated to a notification, not when you’ve just sent it.
If the user wants to go back from here they need to be sent back to the
start of entering the placeholders, because we won’t have their previous
personalisation in the session still
I think the back link on this page was introduced by accident. But it’s
good to still have it on this page, because it keeps consistency with
the previous pages.
When looking at a notification you can either be coming from the page
of all notifications, or from a job. Currently the back link always
takes you to the page of all notifications.
This commit makes it a bit more sophisticated so if you’ve come from
looking at a job, you go back to the job.
To avoid the problem of having confusing defaults, the postage is now
set explicitly on every template.
Putting the postage ‘inside’ the letter template makes the interaction
for changing it consistent with how other parts of the template are
added.
Plus everyone loves skeumorphism.
It’s inaccurate to have an estimated delivery date for letters sent
using a test key. We shouldn’t reassure people that:
- the letter won’t be printed
- (in the case of precompiled letters) that the letter has passed
validation
If PDF files have a validation error which means that they can't be
opened by PyPDF2 we would previously show the 500 status error page. We
now catch PyPDF2.utils.PdfReadErrors so that we can display a custom
error message on the notification page instead.
Added a link to cancel letters from the letter notification pages if the
letter is still able to be cancelled. Clicking on this link will show a
confirmation box, and will then cancel the letter if the user confirms.
Data retention lookup by type is only performed to get the number
of days, so we can update the service method to return the number
or the default directly.
Adds caching for service data retention. This removes separate API
client methods to retrieve individual data retention records by id
or type in favor of a single method that fetches and caches all
retention settings configured for the service. This makes it much
easier to invalidate cache when settings change.
Lookup by id or type is provided by helper methods in the service
model.
This commit adds content pages for the notifications pages, particularly
the letter pages, which will make things clearer now that we will soon be allowing
letters to be cancelled.
The main changes are:
* The confirmation banner for letters sent from a CSV file now states when
printing will start.
* We state the CSV file that notifications were sent from on the
notifications page
* The notification page for letters shows when printing starts (today,
tomorrow, or that date that the letter was printed)
We’ve moved away from using the expand/collapse pattern on the page
where you click ‘send’. Instead we’re putting the send button in the
sticky footer.
So it’s a bit jarring to still have the expand/collapse on the page you
see after you’ve sent an email. This commit replaces it with the sticky
footer as well.
This is only relevant for emails because:
1. Text messages are generally short enough to fit on the screen
2. We don’t show the status of letters because they don’t really change
At the moment we are manually cancelling letters for people when they
ask us to. Once’s we’ve done this there is no indication that it’s
happened except for the date going red on the list of letters.
This commit adds some error messaging and styling to show when a letter
is cancelled.
Letting people cancel their own letters will be a future enhancement.