Commit Graph

79 Commits

Author SHA1 Message Date
Chris Hill-Scott
98214884d3 Stop posting job metadata to the API
The API is looking at the S3 metadata for this information now, so
there’s no need for us to continue sending it through.
2018-05-01 09:47:04 +01:00
Katie Smith
0e370d511e Update service_api_client to use new endpoints
API now has separate endpoints to archive email reply-to addresses and
SMS senders, so we no longer need to use the endpoints for updating.
2018-05-01 08:38:54 +01:00
Leo Hemsted
2ceea61bb1 Merge pull request #2034 from alphagov/zendesk
send zendesk rather than deskpro tickets
2018-04-27 14:33:31 +01:00
Leo Hemsted
be038e345d define isort first party (app and tests)
we were seeing isort produce different outputs locally and in docker -
this was due to it having different opinions about whether the tests
module (ie all our unit tests) is a first party (local) or third party
(pip installed) import. It's a first party import, so by defining this
in the setup.cfg isort settings, we can force it to be consistent
between environments.

Note: I don't know why it was different in the first place though
2018-04-25 14:12:58 +01:00
Chris Hill-Scott
589dbea971 Make Redis hold onto cached API responses longer
Redis is giving us a big performance boost (it’s roughly halved the
median request time on the admin app).

Once we’re confident that it’s working properly[1] we can eke out a bit
more performance from it by keeping the caches alive for longer. As
far as I can tell we’re still using Redis in a very low-volume way[2],
so increasing the number of things we’re storing shouldn’t start taxing
our Redis server at all. But reducing the number of times we have to
hit the API to refresh the cache _should_ result in some performance
increase.

---

1. ie we’re not seeing instances of stale caches not being invalidated

2. We have 2.5G of available space in Redis. Here is our current usage:
```
used_memory:7728960
used_memory_human:7.37M
used_memory_rss:7728960
used_memory_peak:16563776
used_memory_peak_human:15.79M
used_memory_lua:37888
```
2018-04-23 17:07:41 +01:00
Chris Hill-Scott
222a67959a Add tests for all templates and template versions 2018-04-20 17:32:01 +01:00
Chris Hill-Scott
06de94f1c5 Rewrite cache decorator to use format string
This is easier to read than having to understand the arguments 1…n of
the cache decorator are ‘magic’, and gives us more flexibility about
how the cache keys are formatted, eg being able to add words in the
middle of them.

Also changes the key format for all templates to be
`service-{service_id}-templates` instead of `templates-{service_id}`
because then it’s clearer what the ID represents.
2018-04-20 16:32:02 +01:00
Chris Hill-Scott
cea7a027e3 Add caching of templates in Redis
A lot of the frequently-used pages in the admin app rely on the API to
get templates.

So this commit adds three new caches:
- a single template version (including a key without a version number,
  which is the current version)
- all the templates for a service
- all versions of a template

The first will be the most crucial for performance, but there’s not much
cost to adding the other two.
2018-04-19 13:58:40 +01:00
Chris Hill-Scott
1c91e10d5d Clear user cache when deleting a service
The user JSON has a list of service IDs
2018-04-19 13:25:04 +01:00
Chris Hill-Scott
9a3f9b7273 Delete caches when user accepts invite
Accepting an invite changes:
- the `user_to_service` list of users returned by `GET /service/<id>`
- the `services` list return by `GET /user/<id>`

The latter change is causing the functional tests to fail.
2018-04-19 13:15:52 +01:00
Chris Hill-Scott
eb9aed6d01 Cache GET /user response in Redis
In the same way, and for the same reasons that we’re caching the service
object.

Here’s a sample of the data returned by the API – so we should make sure
that any changes to this data invalidate the cache.

If we ever change a user’s phone number (for example) directly in the
database, then we will need to invalidate this cache manually.

```python
{  
   'data':{  
      'organisations':[  
         '4c707b81-4c6d-4d33-9376-17f0de6e0405'
      ],
      'logged_in_at':'2018-04-10T11:41:03.781990Z',
      'id':'2c45486e-177e-40b8-997d-5f4f81a461ca',
      'email_address':'test@example.gov.uk',
      'platform_admin':False,
      'password_changed_at':'2018-01-01 10:10:10.100000',
      'permissions':{  
         '42a9d4f2-1444-4e22-9133-52d9e406213f':[  
            'manage_api_keys',
            'send_letters',
            'manage_users',
            'manage_templates',
            'view_activity',
            'send_texts',
            'send_emails',
            'manage_settings'
         ],
         'a928eef8-0f25-41ca-b480-0447f29b2c20':[  
            'manage_users',
            'manage_templates',
            'manage_settings',
            'send_texts',
            'send_emails',
            'send_letters',
            'manage_api_keys',
            'view_activity'
         ],
      },
      'state':'active',
      'mobile_number':'07700900123',
      'failed_login_count':0,
      'name':'Example',
      'services':[  
         '6078a8c0-52f5-4c4f-b724-d7d1ff2d3884',
         '6afe3c1c-7fda-4d8d-aa8d-769c4bdf7803',
      ],
      'current_session_id':'fea2ade1-db0a-4c90-93e7-c64a877ce83e',
      'auth_type':'sms_auth'
   }
}
```
2018-04-18 13:27:11 +01:00
Chris Hill-Scott
24dbe7b7b1 Add Redis cache between admin and API
Most of the time spent by the admin app to generate a page is spent
waiting for the API. This is slow for three reasons:

1. Talking to the API means going out to the internet, then through
   nginx, the Flask app, SQLAlchemy, down to the database, and then
   serialising the result to JSON and making it into a HTTP response
2. Each call to the API is synchronous, therefore if a page needs 3 API
   calls to render then the second API call won’t be made until the
   first has finished, and the third won’t start until the second has
   finished
3. Every request for a service page in the admin app makes a minimum
   of two requests to the API (`GET /service/…` and `GET /user/…`)

Hitting the database will always be the slowest part of an app like
Notify. But this slowness is exacerbated by 2. and 3. Conversely every
speedup made to 1. is multiplied by 2. and 3.

So this pull request aims to make 1. a _lot_ faster by taking nginx,
Flask, SQLAlchemy and the database out of the equation. It replaces them
with Redis, which as an in-memory key/value store is a lot faster than
Postgres. There is still the overhead of going across the network to
talk to Redis, but the net improvement is vast.

This commit only caches the `GET /service` response, but is written in
such a way that we can easily expand to caching other responses down the
line.

The tradeoff here is that our code is more complex, and we risk
introducing edge cases where a cache becomes stale. The mitigations
against this are:
- invalidating all caches after 24h so a stale cache doesn’t remain
  around indefinitely
- being careful when we add new stuff to the service response

---

Some indicative numbers, based on:
- `GET http://localhost:6012/services/<service_id>/template/<template_id>`
- with the admin app running locally
- talking to Redis running locally
- also talking to the API running locally, itself talking to a local
  Postgres instance
- times measured with Chrome web inspector, average of 10 requests

╲ | No cache | Cache service | Cache service and user | Cache service, user and template
-- | -- | -- | -- | --
**Request time** | 136ms | 97ms | 73ms | 37ms
**Improvement** | 0% | 41% | 88% | 265%

---

Estimates of how much storage this requires:

- Services: 1,942 on production × 2kb = 4Mb
- Users: 4,534 on production × 2kb = 9Mb
- Templates: 7,079 on production × 4kb = 28Mb
2018-04-10 12:58:35 +01:00
Leo Hemsted
3be4b57bbd fix imports 2018-03-06 13:10:37 +00:00
Leo Hemsted
09824078dd remove all instances of db style permissions
lots of renaming of send_texts/emails/letters to send_messages, and
manage_settings/users to manage_service
2018-03-06 13:08:06 +00:00
Leo Hemsted
17061e0d06 map roles and db permissions
in the db, we have several rows for single permissions - we separate
`send_messages` into `send_texts`, `send_emails` and `send_letters`,
and also `manage_service` into `manage_users` and `manage_settings`.

But on the front end we don't do anything with this distinction. It's
unhelpful for us to have to think about permissions as groups of things
when we can never split them up at all. So we should combine them. This
commit makes sure:
* when user models are read  (from JSON direct from the API), we
  should transform them from db permissions into roles.
* when permissions are persisted (editing permissions, and creating
  invites), we should send db permissions to the API.

All other interaction with permissions (should just be the endpoint
decorator and checks in html templates generally) should use admin
roles.
2018-03-06 13:08:06 +00:00
Leo Hemsted
7ddad7c99e dont use has_permissions to check for platform admins
platform_admin is a separate concept to permissions, so by removing the
checks for it from the current_user.has_permissions function, we can
simplify things greatly. We already record on the user whether they're
a platform admin anyway.
2018-03-06 13:08:06 +00:00
Alexey Bezhan
acfe8092fc Add route secret key header to the API requests
Currently requests to the API made from the admin app are going from
PaaS admin app to the nginx router ELB, which then routes them back
to the api app on PaaS.

This makes sense for external requests, but for requests made from
the admin app we could skip nginx and go directly to the api PaaS
host, which should reduce load on the nginx instances and
potentially reduce latency of the api requests.

API apps on PaaS are checking the X-Custom-Forwarder header (which
is set by nginx on proxy_pass requests) to only allow requests going
through the proxy.

This adds the custom header to the API client requests, so that they
can pass that header check without going through nginx.
2018-02-28 11:28:46 +00:00
Chris Hill-Scott
f3a0c505bd Enforce order and style of imports
Done using isort[1], with the following command:
```
isort -rc ./app ./tests
```

Adds linting to the `run_tests.sh` script to stop badly-sorted imports
getting re-introduced.

Chosen style is ‘Vertical Hanging Indent’ with trailing commas, because
I think it gives the cleanest diffs, eg:
```
from third_party import (
    lib1,
    lib2,
    lib3,
    lib4,
)
```

1. https://pypi.python.org/pypi/isort
2018-02-27 16:35:13 +00:00
Chris Hill-Scott
96aac519cc Extend user client to count users with permission
One of the things we need to know for a service to go live is whether
they have at least two users with the ‘manage service’ permission.

So this commit adds a method to the client to count how many users have
a given permission. We can do logic on this count later. But having the
counting done in the client feels like a cleaner separation of concerns.

Meant some refactoring of the way `service_id` is extracted from the
request, in order to make it easier to mock.
2018-02-26 08:53:45 +00:00
Chris Hill-Scott
56833b1d10 Add test for existing get users client method
Want to make sure it’s doing what I expect before I build another method
that calls through to it.
2018-02-26 08:53:45 +00:00
Chris Hill-Scott
51f0320aec Add API client method to count templates
When users request to go live we check stuff like:
- if they’ve added templates
- if they have email templates (then we can check their reply to
  address)

This commit adds a method to do this programatically rather than
manually.

We _could_ do this in SQL, but for page that’s used intermittently it
doesn’t feel worth the work/optimisation (and the client method is at
least in place now if we do ever need to lean on this code more
heavily).
2018-02-26 08:53:45 +00:00
Chris Hill-Scott
52241b8f3e Use client from app in tests
Means we don’t have to instantiate it in every test, keeps things
consistent with parent commit.
2018-02-09 15:04:52 +00:00
Chris Hill-Scott
1908e7b091 Tell API what URL to use for email auth links
So that we can keep people on the prototype URL when doing user
research.

Depends on:
- [ ] https://github.com/alphagov/notifications-api/pull/1645
2018-02-09 15:01:20 +00:00
chrisw
9ad4435d94 Change organisations to email branding 2018-02-07 17:41:23 +00:00
Chris Hill-Scott
86d76baa0d Have admin specify host to use for invite links
When we’re doing user research we often:
- start the task by inviting the participant to a service on Notify
- have them use a prototype version of the admin app, hosted on a
  different domain

Currently we can’t do both of these things together, because the invite
emails always send people to notifications.service.gov.uk (because it’s
the API that sends the emails, and the prototype admin app points at the
production API).

This commit changes the admin app to tell the API which host to use when
creating the invite links.

Depends on:
- [ ] https://github.com/alphagov/notifications-api/pull/1515
2018-01-03 10:37:29 +00:00
Leo Hemsted
292350633f update tests 2017-12-04 17:08:53 +00:00
venusbb
581759931f Merge branch 'master' of https://github.com/alphagov/notifications-admin into vb-free-sms-history 2017-11-14 09:40:05 +00:00
Leo Hemsted
fcefd2a80c pass in data to posts 2017-11-09 15:02:59 +00:00
Leo Hemsted
2f37b00989 use active-endpoint 2017-11-09 14:58:44 +00:00
Leo Hemsted
b9eca67b0d Revert "use new activate endpoint" 2017-11-09 14:55:08 +00:00
Leo Hemsted
7b0fcf8c08 use active-endpoint 2017-11-09 14:37:33 +00:00
venusbb
1ab4681ff5 Use the revise api endpoints without current-year parameter 2017-11-09 13:18:09 +00:00
venusbb
8ea38ba7b6 Use annual_billing tables at backend for getting and updating free_sms_fragment_limit 2017-10-31 11:22:57 +00:00
Chris Hill-Scott
c516760056 Set free SMS limit depending on organisation type
Different parts of government get billed slightly differently, and
there’s differences in how much money we’re allowed to give them.

Think these numbers are right, but should be double checked.
2017-10-23 17:45:26 +01:00
Chris Hill-Scott
9453f301d2 Collect organisation type
So that we can default services to their appropriate text allowance, we
need to find out what sector they're in. So let's start collecting that
from teams as they create new services.

I think Central/Local/NHS are the right options, but these can be easily
changed if not.
2017-10-23 17:45:01 +01:00
Chris Hill-Scott
2cecadfcbc Add flake8 linting to project
The GDS Way™[1] recommends using Flake8 to lint Python projects.

This commit takes the Flake8 config from Digital Marketplace API[2] and
removes the bits we don’t need.

It changes the `max_complexity` setting to 14, which is the most complex
code we have in this repo currently (we shouldn’t be writing code _more_
complex than what we already have).

This commit also fixes the errors found by Flake8, which includes 6(!)
tests which were never getting run because they had the same names as
existing tests.

Here is a full list of the errors that were found and fixed:
```
./app/__init__.py:2:1: F401 're' imported but unused
./app/__init__.py:4:1: F401 'json' imported but unused
./app/__init__.py:8:1: F401 'dateutil' imported but unused
./app/__init__.py:11:1: F401 'flask.escape' imported but unused
./app/__init__.py:41:1: F401 'app.proxy_fix' imported but unused
./app/__init__.py:129:5: F821 undefined name 'proxy_fix'
./app/__init__.py:221:19: F821 undefined name 'highlight'
./app/__init__.py:221:35: F821 undefined name 'JavascriptLexer'
./app/__init__.py:221:54: F821 undefined name 'HtmlFormatter'
./app/config.py:2:1: F401 'datetime.timedelta' imported but unused
./app/event_handlers.py:2:1: F401 'flask_login.current_user' imported but unused
./app/utils.py:11:1: F401 'dateutil.parser' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.two_factor' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.notifications' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.add_service' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.forgot_password' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.inbound_number' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.styleguide' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.organisations' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.letter_jobs' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.verify' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.conversation' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.api_keys' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.send' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.dashboard' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.jobs' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.manage_users' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.sign_in' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.sign_out' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.code_not_received' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.invites' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.platform_admin' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.providers' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.service_settings' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.index' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.new_password' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.user_profile' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.feedback' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.choose_service' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.templates' imported but unused
./app/main/__init__.py:5:1: F401 'app.main.views.register' imported but unused
./app/main/forms.py:12:1: F401 'wtforms.SelectField' imported but unused
./app/main/views/api_keys.py:37:29: E241 multiple spaces after ':'
./app/main/views/feedback.py:3:1: F401 'flask.flash' imported but unused
./app/main/views/feedback.py:122:17: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/inbound_number.py:1:1: F401 'flask.url_for' imported but unused
./app/main/views/inbound_number.py:1:1: F401 'flask.session' imported but unused
./app/main/views/inbound_number.py:1:1: F401 'flask.redirect' imported but unused
./app/main/views/inbound_number.py:1:1: F401 'flask.request' imported but unused
./app/main/views/inbound_number.py:13:1: F401 'flask.jsonify' imported but unused
./app/main/views/jobs.py:31:1: F401 'app.utils.get_template' imported but unused
./app/main/views/letter_jobs.py:1:1: F401 'datetime' imported but unused
./app/main/views/letter_jobs.py:6:1: F401 'app.format_datetime_24h' imported but unused
./app/main/views/manage_users.py:111:9: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/notifications.py:121:5: F841 local variable 'status_args' is assigned to but never used
./app/main/views/organisations.py:1:1: F401 'flask.request' imported but unused
./app/main/views/service_settings.py:77:9: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/service_settings.py:82:9: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/service_settings.py:420:13: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/sign_in.py:12:1: F401 'flask_login.confirm_login' imported but unused
./app/main/views/sign_in.py:17:1: F401 'app.service_api_client' imported but unused
./app/main/views/sign_in.py:62:13: E123 closing bracket does not match indentation of opening bracket's line
./app/main/views/templates.py:4:1: F401 'flask.json' imported but unused
./app/main/views/templates.py:17:1: F401 'notifications_utils.formatters.escape_html' imported but unused
./app/main/views/templates.py:23:1: F401 'app.utils.get_help_argument' imported but unused
./app/main/views/templates.py:64:13: E123 closing bracket does not match indentation of opening bracket's line
./app/notify_client/service_api_client.py:6:1: F401 '.notification_api_client' imported but unused
./app/notify_client/user_api_client.py:1:1: F401 'uuid' imported but unused
./app/notify_client/user_api_client.py:3:1: F401 'flask.session' imported but unused
./tests/__init__.py:1:1: F401 'csv' imported but unused
./tests/app/main/test_asset_fingerprinter.py:2:1: F401 'os' imported but unused
./tests/app/main/test_asset_fingerprinter.py:4:1: F401 'unittest.mock' imported but unused
./tests/app/main/test_asset_fingerprinter.py:98:9: F841 local variable 'string_with_unicode_character' is assigned to but never used
./tests/app/main/test_errorhandlers.py:2:1: F401 'flask.url_for' imported but unused
./tests/app/main/test_permissions.py:26:13: F841 local variable 'response' is assigned to but never used
./tests/app/main/test_placeholder_form.py:3:1: F401 'wtforms.Label' imported but unused
./tests/app/main/test_placeholder_form.py:11:10: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:10:67: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:23:65: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:37:48: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:51:67: F841 local variable 'req' is assigned to but never used
./tests/app/main/test_two_factor_form.py:65:67: F841 local variable 'req' is assigned to but never used
./tests/app/main/views/test_accept_invite.py:356:5: F841 local variable 'element' is assigned to but never used
./tests/app/main/views/test_activity.py:11:1: F811 redefinition of unused 'mock_get_notifications' from line 11
./tests/app/main/views/test_activity.py:18:1: F401 'datetime.datetime' imported but unused
./tests/app/main/views/test_activity.py:102:5: F841 local variable 'content' is assigned to but never used
./tests/app/main/views/test_activity.py:104:5: F841 local variable 'notification' is assigned to but never used
./tests/app/main/views/test_activity.py:337:5: F841 local variable '_notifications_mock' is assigned to but never used
./tests/app/main/views/test_activity.py:373:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_activity.py:378:9: E121 continuation line under-indented for hanging indent
./tests/app/main/views/test_activity.py:404:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_activity.py:407:9: E121 continuation line under-indented for hanging indent
./tests/app/main/views/test_api_keys.py:354:5: F841 local variable 'response' is assigned to but never used
./tests/app/main/views/test_conversation.py:5:1: F401 'bs4.BeautifulSoup' imported but unused
./tests/app/main/views/test_conversation.py:198:5: F841 local variable 'mock_get_inbound_sms' is assigned to but never used
./tests/app/main/views/test_dashboard.py:53:5: F841 local variable 'mock_template_stats' is assigned to but never used
./tests/app/main/views/test_dashboard.py:72:5: F841 local variable 'mock_template_stats' is assigned to but never used
./tests/app/main/views/test_jobs.py:2:1: F401 'uuid' imported but unused
./tests/app/main/views/test_jobs.py:3:1: F401 'urllib.parse.urlparse' imported but unused
./tests/app/main/views/test_jobs.py:3:1: F401 'urllib.parse.quote' imported but unused
./tests/app/main/views/test_jobs.py:3:1: F401 'urllib.parse.parse_qs' imported but unused
./tests/app/main/views/test_jobs.py:9:1: F401 'app.main.views.jobs.get_status_filters' imported but unused
./tests/app/main/views/test_jobs.py:10:1: F401 'tests.notification_json' imported but unused
./tests/app/main/views/test_letters.py:6:1: F401 'tests.service_json' imported but unused
./tests/app/main/views/test_notifications.py:5:1: F401 'app.utils.REQUESTED_STATUSES' imported but unused
./tests/app/main/views/test_notifications.py:5:1: F401 'app.utils.DELIVERED_STATUSES' imported but unused
./tests/app/main/views/test_notifications.py:5:1: F401 'app.utils.SENDING_STATUSES' imported but unused
./tests/app/main/views/test_notifications.py:5:1: F401 'app.utils.FAILURE_STATUSES' imported but unused
./tests/app/main/views/test_platform_admin.py:242:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_platform_admin.py:247:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_send.py:3:1: F401 'unittest.mock.Mock' imported but unused
./tests/app/main/views/test_send.py:18:1: F811 redefinition of unused 'mock_get_service' from line 18
./tests/app/main/views/test_send.py:18:1: F401 'tests.conftest.multiple_letter_contact_blocks' imported but unused
./tests/app/main/views/test_send.py:18:1: F401 'tests.conftest.no_sms_senders' imported but unused
./tests/app/main/views/test_send.py:18:1: F401 'tests.conftest.multiple_sms_senders' imported but unused
./tests/app/main/views/test_send.py:18:1: F401 'tests.conftest.no_letter_contact_blocks' imported but unused
./tests/app/main/views/test_send.py:102:5: F841 local variable 'response' is assigned to but never used
./tests/app/main/views/test_send.py:870:5: F841 local variable 'response' is assigned to but never used
./tests/app/main/views/test_send.py:1367:5: F841 local variable 'service_id' is assigned to but never used
./tests/app/main/views/test_send.py:1451:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_send.py:1620:80: E226 missing whitespace around arithmetic operator
./tests/app/main/views/test_send.py:1909:13: E126 continuation line over-indented for hanging indent
./tests/app/main/views/test_send.py:1912:9: E121 continuation line under-indented for hanging indent
./tests/app/main/views/test_service_settings.py:13:1: F811 redefinition of unused 'no_reply_to_email_addresses' from line 13
./tests/app/main/views/test_service_settings.py:13:1: F401 'tests.conftest.single_reply_to_email_address' imported but unused
./tests/app/main/views/test_service_settings.py:28:5: E123 closing bracket does not match indentation of opening bracket's line
./tests/app/main/views/test_service_settings.py:104:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:166:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:186:5: F841 local variable 'mocked_get_fn' is assigned to but never used
./tests/app/main/views/test_service_settings.py:217:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:237:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:257:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:307:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:340:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:466:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:555:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:615:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:719:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:874:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:902:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:954:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:986:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:1101:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1121:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1271:1: F811 redefinition of unused 'test_set_letter_contact_block_saves' from line 1189
./tests/app/main/views/test_service_settings.py:1433:5: F841 local variable 'page' is assigned to but never used
./tests/app/main/views/test_service_settings.py:1495:5: F841 local variable 'mocked_get_fn' is assigned to but never used
./tests/app/main/views/test_service_settings.py:1540:5: F841 local variable 'mocked_get_fn' is assigned to but never used
./tests/app/main/views/test_service_settings.py:1570:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1589:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1621:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1641:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1658:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1676:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1697:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1759:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_service_settings.py:1775:1: F811 redefinition of unused 'single_reply_to_email_address' from line 13
./tests/app/main/views/test_templates.py:3:1: F401 'uuid' imported but unused
./tests/app/main/views/test_templates.py:11:1: F401 'tests.conftest.mock_get_user' imported but unused
./tests/app/main/views/test_templates.py:514:1: F811 redefinition of unused 'mock_get_user' from line 11
./tests/app/main/views/test_templates.py:672:1: F811 redefinition of unused 'mock_get_user' from line 11
./tests/app/main/views/test_templates.py:795:1: F811 redefinition of unused 'mock_get_user' from line 11
./tests/app/main/views/test_templates.py:835:1: F811 redefinition of unused 'mock_get_user' from line 11
./tests/app/main/views/test_two_factor.py:67:13: E126 continuation line over-indented for hanging indent
./tests/app/notify_client/test_notification_client.py:79:5: F841 local variable 'mock_post' is assigned to but never used
```

1. https://gds-way.cloudapps.digital/manuals/programming-languages/python/linting.html#how-to-use-flake8
2. d5ab8afef4/.flake8
2017-10-20 11:02:39 +01:00
chrisw
e149d0eb91 Allow one-off email sending to select the reply-to address 2017-10-17 11:15:26 +01:00
Leo Hemsted
03397f416e move status mapping logic to the api client
also added tests 👼
2017-09-20 16:02:15 +01:00
Imdad Ahad
232912ab3b Call the correct endpoint to retrieve yearly billing usage 2017-08-17 16:02:30 +01:00
Venus Bailey
cbe2df3946 Revert "Job stats table" 2017-08-16 15:25:26 +01:00
venusbb
6a483c14f5 change get-jobs to point to new statistics tables 2017-08-15 15:53:26 +01:00
Ken Tsang
93eab4ca5f Refactored to use kwarg 2017-08-02 11:04:14 +01:00
Chris Hill-Scott
5ddbe80ea9 Fix calls to API client which now takes fewer args
The Notify API client changed in version 4 to take two arguments, not
three (service ID was removed in favour of the combined API key).

This gets a bit gnarly because the API key has to be at least a certain
length so it can be substringed internally.
2017-07-26 11:10:37 +01:00
Leo Hemsted
a31bf0c5ce add tests for new check and send notification endpoints 2017-06-29 12:40:03 +01:00
Leo Hemsted
3966d024d8 add new send_notification api call 2017-06-29 12:40:03 +01:00
Leo Hemsted
20bb34849d add tests for notification status page 2017-06-16 15:29:34 +01:00
Imdad Ahad
7ad56df78b Change user api client to update password with new endpoint 2017-02-07 13:31:46 +00:00
Leo Hemsted
2419f0d8a9 write tests for @minglis 's code 🙁 2016-12-09 16:09:47 +00:00
Leo Hemsted
255ce158b7 block inactive services from making stateful changes
in the NotifyAdminAPIClient, which all api traffic goes through, return
403 for any stateful requests (post, put and delete), if the following
criteria have been met:
* a current_service is set
    (this prevents checks being carried out on non-service related
     updates, eg editing user details)
* the service is not active
* the current user is not a platform admin

so platform admins can still update anything.

Note: Without any specific error handling, the user will see a generic
403 page. This is fine, probably - it's a relatively niche case that
you'll be editing a service you can't get to anyway
2016-12-09 15:44:58 +00:00
Rebecca Law
cebf8e1d65 Removed get_all_notifications method from notification_api_client as it is not longer being used. 2016-11-18 14:39:23 +00:00