make sure everything is using the `nl2br` formatter that properly wraps
it in markdown to keep everything sanitised nicely. Also write a couple
of tests
The API response for jobs includes a field called `job_status`. The API
response for uploads doesn’t.
The `Job` mode handles uploads and jobs, so it needs to account for the
possibility of the field not being there.
Jobs have a `scheduled_for` field. Single letter uploads don’t.
At the moment we treat both of them as `Job`s. So the `Job` model needs
to account for when the `scheduled_for` field is missing.
The property doesn’t represent the whole client, but just one method on
it. So this commit renames the property to better describe what it is
designed to store.
This follows the pattern of what we’ve done with services, users and
events.
It gives us a way of neatly instantiating a model for each item in the
list we get back from the API and reduces the complexity of the view
layer code.
Now is a good time to do this because we’re going to be making a bunch
of changes to the jobs pages, and those changes will be easier to code
and understand with a sensible model behind them.
os.environ is an `environ` object, not a dict. by only interacting with
it through builtin functions we can ensure it remains properly
accessible to third party libraries which might interact with it in
different ways.
See https://github.com/alphagov/notifications-api/commit/d2441466 for
more detail
We work out how complete a job’s processing is by looking at how many
notifications have been created.
Later, we deleted all the notifications, according to the data retention
schedule. This makes it look like the job has gone back to 0% processed.
This commit accounts for this by not showing the % complete message once
a finished job has had its notifications deleted.
Instead of using `mock_get_notification` to create a notification then
mock it in the tests, a new function, `create_notification`, can be used
to create a custom notification to be mocked. Using this in the
`test_notifications.py` file makes it Pytest 5 compatible.
This stops most instances of the fixtures which return sms senders,
email reply to addresses or letter contact blocks from being called as
if they were functions in the tests by replacing them with functions
which return the same results.
This change allows a couple of fixtures which are now longer used to be
deleted.
We were using user fixtures in a lot of parameterized tests, but this is
no longer allowed in Pytest 5. To avoid having to split up the parametrized
tests (which would make the test files a lot longer and slightly more
difficult to read) this commit creates functions which return various types
of user json so that we can use these as the test parameters instead.
Stopped fixtures in conftest.py from calling the fixtures which return
user json as if they were functions. Deleted two fixtures that are now no
longer needed as a result of the changes to conftest.py.
Users who have an API integration (and therefore have a way of passing
in a reference for each notification) can now search by that reference
(see https://github.com/alphagov/notifications-api/pull/2682)
This commit changes the label on the search box to tell these users that
this is possible, without changing the label for users without an API
integration, who might get confused by what ‘reference’ means.
It also makes the label consistently say ‘email address or phone number’
(ie email address is first) because this is our content style.
Flake8 Bugbear checks for some extra things that aren’t code style
errors, but are likely to introduce bugs or unexpected behaviour. A
good example is having mutable default function arguments, which get
shared between every call to the function and therefore mutating a value
in one place can unexpectedly cause it to change in another.
This commit enables all the extra warnings provided by Flake8 Bugbear,
except for the line length one (because we already lint for that
separately).
It disables:
- _B003: Assigning to os.environ_ because I don’t really understand this
- _B306: BaseException.message is removed in Python 3_ because I think
our exceptions have a custom structure that means the `.message`
attribute is still present
Events should be sorted reverse-chronologically, no matter what order
they come back from the API in, or which field in the API response
they’ve been extracted from.
This commit introduces a slightly hacky way of putting usernames against
events, given that the API only returns user IDs.
It does so without:
- making changes to the API
- making a pages that could potentially fire off dozens of API calls (ie
one per user)
This comes with the limitation that it can only get names for those team
members who are still in the team. Otherwise it will say ‘Unknown’.
In the future the API should probably return the name and email address
for the user who initiated the event, and whether that user was acting
in a platform admin capacity.
At the moment we have two types of event, ‘service’ events and ‘API key’
events. They are munged together which is useful initially, but could
get noisy.
This commit adds filters (copied from the choose template page) that let
users narrow down the list to one of the two types of event. This might
help users get a clearer picture of what’s going on.
Scanning the page is difficult at the moment because it’s hard to tell
how far apart in time events are, and thereby determine which events
might be related.
Grouping the events by day quickly lets users narrow their focus to
a meaningful subset of the events.
We store our audit history in two ways:
1. A list of versions of a service
2. A list of events to do with API keys
In the future there could be auditing data which we want to display that
is stored in other formats (for example the event table).
This commit adds some objects which wrap around the different types of
auditing data, and expose a consistent interface to them. This
architecture will let us:
- write clean code in the presentation layer to display these events on
a page
- add more types of events in the future by subclassing the `Event` data
type, without having to rewrite anything in the presentation layer
Turns out our tests spent a lot of time recreating the app for each test
case, which is quite intense.
This commit makes the fixture sessions level, so the app is only created
once per test session, not once per test function.
This cuts down the time taken to run the test suite to about 50 seconds.
It also makes the tests more parallelizable. Before this change going
from 4 to 8 processes made the tests slower. Now it cuts them down from
about 50 seconds to about 35 seconds[1]. So this commit also lets Pytest
choose the best number of processes to run, since on my machine it
chooses 8, which is the fastest.
Overall this means the
1. With a 2.2GHz quad-core Intel Core i7 processor on a 2015 MacBook Pro
Users who work in local government can’t have GOV.UK branding on their
emails. And only those working for Companies House (for example) can
request the Companies House branding.
This commit adds:
- new choices of email branding, which offer the name of the branding,
rather than the style
- logic to filter this list to only the applicable options, based on
what we know about the user, service and organisation
This is a change from the previous approach which put the onus on users
to figure out the style of branding they wanted, when we might already
know that a lot of the options weren’t available to them, or would be
inconsistent with the branding of other services in their organisation.
of course it's logged in, it's a platform admin
also, reduce use of the `client` fixture in test_platform_admin
(replace it with platform_admin_client)
Query string ordering is non-deterministic. This can cause tests to fail
in a non helpful way when we’re comparing two URLs. The values in the
query string can match, but the string won’t because the order is
different. This commit adds some code to split up the URL and check that
each part of it matches, rather than checking the thing as a whole.
This makes it consistent that an option which contains more options has
a hint about how many options it contains.
Also adds a formatter to get us ready for 1,000 services 🎉
If you’ve come from a template to add a new letter sender then it’s
because you want those words on that template. This commit adds the
extra API call to make that happen.
Organisation team members will be ultimately interested in the detailed
usage of each service, but shouldn't necessarily have access to the
personal data of that services users.
So we should allow these organisation team members to navigate to live
services usage page from the organisation page. They may need to contact
the team so they should also be able to view the team members page.
So they'll then see just usage and team members pages.
If they are actually a team member of the service they're viewing, then
they'll see the full range of options as usual.
This commit implement the above by adding an extra flag to the
`user.has_permissions` decorator which allows certain pages to be marked
as viewable by an organisation user. The default (for all other existing
pages) is that organisation users don’t have permission.
Added a breadcrumb link to a service's organisation to the
withnav_template. This will only show if a service has an organisation
and the current user is also a member of that org, or the current user
is a platform admin user.
Also removed a couple of unused fixtures from the client_request
fixture.
so that platform admins (us) can view pages as regular users do easily.
Simply adds a flag in the session cookie that overrides the actual
platform admin flag on the user model if set. This way it's safe, since
this only downgrades existing functionality, so if someone managed to
alter it they could only get less permissions, not more.
You can change this value from the user profile page if either:
* you're a platform admin
* the flag is set (to any value) on the cookie.
This slightly weird check means that we don't check the underlying
`user._platform_admin` flag anywhere in the code, even when toggling
the suppression.