Merge branch 'master' into remove-stats-from-send
82
.travis.yml
@@ -5,7 +5,7 @@ cache:
|
||||
directories:
|
||||
- node_modules
|
||||
python:
|
||||
- '3.4.3'
|
||||
- 3.4.3
|
||||
env:
|
||||
secure: jT9BIioqBMkOdLZhU+WJNdnRJ+06G7qUx4QqEVldp96dJwmWpPEvA0XbitdnQt/WXYkpMlDbgSApvvGj2ZNvdpowRRe5HFX8D2Udhi2g9+cXgKrQxH6zv0evJyQLOjCINW6KtgMCJ5wkYR3qQ4BQawlDt6ecpmeboKTmvs2W8jZ09aV4IKKvdd7BwFon10QVPF5ny10G83unLtKnKgRMjSSLnaEiA78pE/LSUkekK4mhmtl+yfQf60cIuQGcN9NCYIt5PrdYYyMkbUaht9ykwL2C11sp5JYPClI9k6lrlpGJCdL9wbJwejGhR/pEqwJ4tKK8Zv+mngmkbzE6fd5ehuRMnIUAifG4t3p6WbhKwY5pJsdVyPgWcRSPXOJA7yEcAeTAvWcC++6mCIFBeMxt/yQNw02jkFHeNKRh2twTRvr4xWZHq9FsVxTEVz89OOuue3IkkyDNmVusGJ9+AVRIn9Oa+U/r3bDnrs7jz+meSwb82GZUBzFpUe2pe8qeBE572Ay7yHB73VHUgp/2A1qkZ4SnTjTpMbnS5RdXTgwtMkOs5MLZgteCVxFL3sHcr9e/B3UIUnzKUSPXXOjHyDxBwrABWo81V9Vp2IPV7P9Ofv8zroudjQxK5MOcbmiPQF+eEB9L4DvkUBNsGxtJ/nmPp6tmN0Xjo0xXVdZCEVj29Og=
|
||||
before_install:
|
||||
@@ -26,70 +26,70 @@ notifications:
|
||||
secure: A6n6Gdz3dsE+KQcOd1nWTvdjOF2YbgItT1E40r25poG6p04WHd8qWtC4T2FuZaxPN/TQdKr/dKa/WCkmiEdxT5O0SOwAnAD3u6Fn2nthoI4M5916UrK1ZrqupvnFPSQc8Ivh51PGkcmB4wrb0ylRhMB94RmLcUZcVuXLDx57GO8bPFyLC3E9bgcVVFWaX45sKs74sBSQWi9EBbzHIuduLdjIpW7wX07dA++HlY14W5WgiurmiYohfP11VdAMmMxJs2WdWk16O/qy0HZXaldNIsSnuDBkhAZOMeSrcvp+62yOiN8jK0nSa1IRr3IoUkITdC9YGys3xFJb8gyIQE9T3hUnTYAKCcgsgpVFS6UzsRN42JUAJ8rFTgK9/J299yTk4lqL8uWzcV1QcKXIPNoG0QfqkmlB9B1fKbXuE/KkPEXPCKAcVQpCzEon09FgTCrlVZqJ6HxQonnLcPlIpVzWHAFokLZVHLAFMKYJnGBcZ6zaRK5pdc1babcOXMIPBC8j028G5bhBaCviDvZlimxOsUK1sJTpjzMU0tBQZa8lI+0O5otvMKiX8jPyaedjVvUmsftF2O5FH5nz2ofJC7BThb76/Tac2pNTCn0pWiVz9wi/YXALOMdIzkYgHnyZdEqAjRlpFwZuOrzR6MuvivBebPxjYaRWzCjOeC1uIwz+48E=
|
||||
deploy:
|
||||
- provider: s3
|
||||
access_key_id: AKIAJ5MKF6G3P2JQP4QQ
|
||||
access_key_id: AKIAJLWYN4T4D5WU4APA
|
||||
secret_access_key: &1
|
||||
secure: xfjg4kNBvU0B9xhRETr14mB0bCpVonlAKqGnKL2AoqpnF19yihqGNA8sv/pOGUFpeWZO3cW2GA3anyL2gGG1X0K3f81649mneVJkSHaZ2fiG/S1eKtS0Ws5XblSqLmKTPC7H9ndUxT8r+r2wLg62netBE5g8tAxw2QwN/gVz2fK/68owiyeD/jl6gw/iQ47F+mmGdAY/eFe8sUuGR4Oxj2xNAYARaDQOmHpQF/IG3M69FO5uOJtck8fUWnpd0rWxsyWBOVwwIRQHL6cWOyodeIK7YvLmzviCi1GojBPKQwQbjJu89LHfMJJTW1625drj5CNounuENTFte0Pip8zp90bg090VA8OlTXNWcyFjBQD1vNIE59vyQ/hCh90NK1nlTXdnNOwL0VZTMxQ/zYulXoMqwDLfDozhQbmnkXmexJl6BF4/dz+XmwDu7st5A/PI6U5zCK86ST/6g3MklGSseFi5Rkt6kmJrdlRIhiLnoaab8YgI0FPWjzHBC6B98ZtgIUiUk7Ng5ZTM8Sjq1HCC7mUDrDL0c7aerZA5bq2hQiKGhvjBXFU17iHZ0eEDZ8kO+jumeMwmpW6NbjlS0PuDx+lHywMSG7r+YVmkjxq5gwrTVl3evRxhHe8H/lU18y2dOKpIyX5UEZpXRq9kAWuQruCDBwoDe3Y3QP+Rg7HVGBU=
|
||||
secure: EUiC93M7BI563BTIZV8tR2PvA1iIVKliKIiiFOJ9F8MJDB4Eya0ZfMLC1hsopJ1gZPWv4CjcW04CWqHf62FQJHDDTFtERMXEhJjVGOTgCC+7fkGEKV5pBJCtVdSGlQwd8HjlcfUZ8M7qlnqwLMj2IcTSiMzCVr8RpuSNHM9DF88n3k0EEiF+h83wB1PSmA+4I+CRevFg6xK1ezjSxCZV9N4A9vd1mrX+BSsH0ikbUA66ccAPMGy0yVR3CtzrI9AObutc9mO8qzLXI0SuCYFvyFEHXdXqqcWw4XJ28hYsayHO4gEX1ndYSNzIcCJKXseJRs6idcE0xRpipigYyx83SqvbPtrBlga47MPHXpP8Xl8xTKtVLo9k+Itbx96t1pllrhFqoysHfV8yRrh+otmED2sziB1VTiecPP0IvlVlWGEzUHMepkQhZKfDmFUtcpa7BrJx0Fxzsu9mL9tKx5H7PVA9uMC67Tc6qI3PNSE5XsNfBUjSOzaSY7UFUdKmvINXRk9PIP+NXOsH0kzILl7EzvUoBIbFf8+/1EDmvMc88J5yg4QCmVnIhw5JqnC1uQyDUy41VOsdqgwVUHy7hJuXtKMnUSYuDOltP2fdkArLby0VFgcQgoT+N87I4xcjVzLjEvNgwlZ1nHuBf9v+aB0aD9e/LB03gIt23Nrucu9ON1M=
|
||||
local_dir: dpl_cd_upload
|
||||
skip_cleanup: true
|
||||
region: eu-west-1
|
||||
on: &2
|
||||
repo: alphagov/notifications-admin
|
||||
bucket: notify.works-notifications-admin-codedeploy
|
||||
- provider: codedeploy
|
||||
access_key_id: AKIAJLWYN4T4D5WU4APA
|
||||
secret_access_key: *1
|
||||
bucket: notify.works-notifications-admin-codedeploy
|
||||
key: notifications-admin-$TRAVIS_BRANCH-$TRAVIS_BUILD_NUMBER-$TRAVIS_COMMIT.zip
|
||||
bundle_type: zip
|
||||
application: admin
|
||||
deployment_group: notifications_admin_deployment_group
|
||||
region: eu-west-1
|
||||
on: *2
|
||||
- provider: s3
|
||||
access_key_id: AKIAJCOSRR7IFXS2WJUA
|
||||
secret_access_key: &1
|
||||
secure: LBprDWBFawNvG9M0AVHJkS0txP4IapXG6K8OIzY6T3yDJP8vTnN6M34C++AprkZEqehzug36Vms5PVv9p2gkJOjZkwBKMRFZtjdxGXfRaZnbGQgcBbleMhdXsDWlGJm7RnMS/SX79tiezQ2h6GYyb96vBT0mdfyo/OPr5HJ6IWa/fblUXzZF1a5kCvP2uvR+nXKutsfNnP7lFzrFiH6efyeI1XPD18TU7Nuy6xOZDkDlX2RAvq+Qe5zX0o7VzXFkFdf7NfVT7AswoAEEVZeWNrm84oQJsH88QymDgpdLLzAlwmrWHDTGQtRCOQvXWhK6HvZMgP9n4EcWSIq4WMCjXMcnUqW6mvB+dBjJEe3I+oVgf1TWpdCSAWyffkJ805/xSF/BP92KHg8PAYJKlzrpHWuHaysf05a0QyKsFW09SzzQbpMrs0KLErqOLbG9NKZ5MaUepnsMyuKTr3shysNzlbcC5TghpGQO+D2yj/cJYmKp835Nx9tSU49woDbMDycdgF0rIczfwM8+OrywPw4fY6NAir6uAGx3aYrCx2BNEsGW4tjY7ab8EGCk4pgWpBw1/ERclA6D5sx7ppLI3wnVKsUyPUDvjOFjqdWkBrsONM4xHENRyaJupzQEuzJt/nxtHHGsayyKqYWT24+6ira8p4vJVqnJ+qBM3C7IYVIVXM8=
|
||||
local_dir: dpl_cd_upload
|
||||
skip_cleanup: true
|
||||
region: eu-west-1
|
||||
on: &2
|
||||
repo: alphagov/notifications-admin
|
||||
branch: staging
|
||||
bucket: staging-notifications-admin-codedeploy
|
||||
region: eu-west-1
|
||||
bucket: staging-notify.works-notifications-admin-codedeploy
|
||||
- provider: codedeploy
|
||||
access_key_id: AKIAJ5MKF6G3P2JQP4QQ
|
||||
access_key_id: AKIAJCOSRR7IFXS2WJUA
|
||||
secret_access_key: *1
|
||||
bucket: staging-notifications-admin-codedeploy
|
||||
bucket: staging-notify.works-notifications-admin-codedeploy
|
||||
key: notifications-admin-$TRAVIS_BRANCH-$TRAVIS_BUILD_NUMBER-$TRAVIS_COMMIT.zip
|
||||
bundle_type: zip
|
||||
application: notifications-admin
|
||||
deployment_group: staging_admin_deployment_group
|
||||
application: admin
|
||||
deployment_group: notifications_admin_deployment_group
|
||||
region: eu-west-1
|
||||
on: *2
|
||||
- provider: s3
|
||||
access_key_id: AKIAJ5MKF6G3P2JQP4QQ
|
||||
access_key_id: AKIAIFLN7IJIIQT6S37Q
|
||||
secret_access_key: &1
|
||||
secure: xfjg4kNBvU0B9xhRETr14mB0bCpVonlAKqGnKL2AoqpnF19yihqGNA8sv/pOGUFpeWZO3cW2GA3anyL2gGG1X0K3f81649mneVJkSHaZ2fiG/S1eKtS0Ws5XblSqLmKTPC7H9ndUxT8r+r2wLg62netBE5g8tAxw2QwN/gVz2fK/68owiyeD/jl6gw/iQ47F+mmGdAY/eFe8sUuGR4Oxj2xNAYARaDQOmHpQF/IG3M69FO5uOJtck8fUWnpd0rWxsyWBOVwwIRQHL6cWOyodeIK7YvLmzviCi1GojBPKQwQbjJu89LHfMJJTW1625drj5CNounuENTFte0Pip8zp90bg090VA8OlTXNWcyFjBQD1vNIE59vyQ/hCh90NK1nlTXdnNOwL0VZTMxQ/zYulXoMqwDLfDozhQbmnkXmexJl6BF4/dz+XmwDu7st5A/PI6U5zCK86ST/6g3MklGSseFi5Rkt6kmJrdlRIhiLnoaab8YgI0FPWjzHBC6B98ZtgIUiUk7Ng5ZTM8Sjq1HCC7mUDrDL0c7aerZA5bq2hQiKGhvjBXFU17iHZ0eEDZ8kO+jumeMwmpW6NbjlS0PuDx+lHywMSG7r+YVmkjxq5gwrTVl3evRxhHe8H/lU18y2dOKpIyX5UEZpXRq9kAWuQruCDBwoDe3Y3QP+Rg7HVGBU=
|
||||
secure: Vt558KgvDIAUDWPLviRk24ZOzvNZ993rovMj4rmaZF9Dh1qEHH/tZ/yCkXUTLEMXUVCf5TKek9HfBZAiIrQn+VAe7RTDNHQUuI1EWmpCuqPCZcF6vP6Jz3KyGeCtsF8Ksr394sGbTc4clGxANin0HqWuBqWUV5QGhFJTgBEfCn+Zx1hLQoJisLUSxYaKbc7GGugYa+S3YDhAS7XPlYr4fTnRFp7VT0U2ofecS/skoGLuzb+HMY2MwXAeuBkCb1tIFFl30wbU1PwjLimSu5bWq9cLrRDiH3cDK3fYwAdbjhEM5Wg9i7YfjTcLasOmYNSsLih0FVo1k/G2xTKGU7nsCiSlEX7FpNgwOO3HGdcgb1Pp1X0iIVMh5gw1hlXJNPn/fSDkjLxwISGzI0XmEAilnIo8ovF/jvoEWj5kXrqtOuoH/moQttDCu+0iritfs40A8qBqv/6H3KSamqrDYC5pyRd1VlLo4aR9cH36pedNTnSH88bxm2We3iO/3m60KyEAfgAmJwINvRSuudyi3SeB1FXU0xf7qJ4wg2vWJCzOccFYhpqdk5wh5ZaeH1RdUbz0nNvs2uxDjWTsH/HFbAhgVgt4RtrwjsJUB5i2TWZKl6VykuIMet/y9BHcMbklwEHryPn74fpIs+7ui5zBOMNpEecEWXL5gwnh2fzUPm1+MlA=
|
||||
local_dir: dpl_cd_upload
|
||||
skip_cleanup: true
|
||||
region: eu-west-1
|
||||
on: &2
|
||||
repo: alphagov/notifications-admin
|
||||
branch: live
|
||||
bucket: live-notifications-admin-codedeploy
|
||||
region: eu-west-1
|
||||
bucket: notifications.service.gov.uk-notifications-admin-codedeploy
|
||||
- provider: codedeploy
|
||||
access_key_id: AKIAJ5MKF6G3P2JQP4QQ
|
||||
access_key_id: AKIAIFLN7IJIIQT6S37Q
|
||||
secret_access_key: *1
|
||||
bucket: live-notifications-admin-codedeploy
|
||||
bucket: notifications.service.gov.uk-notifications-admin-codedeploy
|
||||
key: notifications-admin-$TRAVIS_BRANCH-$TRAVIS_BUILD_NUMBER-$TRAVIS_COMMIT.zip
|
||||
bundle_type: zip
|
||||
application: notifications-admin
|
||||
deployment_group: live_admin_deployment_group
|
||||
region: eu-west-1
|
||||
on: *2
|
||||
- provider: s3
|
||||
access_key_id: AKIAJQPPNM6P6V53SWKA
|
||||
secret_access_key: &1
|
||||
secure: 7qVw4gmn7zMCaam9PqIfqwC1z82gXxa+rT/VakoMDY7u62BXA8/fWGFn7yU4qyPSrTWttYdDXmdwrgoEDjGIzLXSpufRqhmXc3xBoRktFSRQAFVom49mWo7WDKgX6gZ3GcuVR8HQ1XpojlkLH/a6cKV9jreDiGHy3sHulBkJRXGIGkTNCiVNVbUsFeiOj/YGaIdZ6ZLjDBSOTwLkLsnzZm7S+xcRd0kxT3VJrV0B3x14igK2Rchv9LteT+fafELURO2asASgLPHy5ny3yGF7vVz6tLBrTpy2N7xxpaDkP/LQi38PRGhZkYPHdqgMfq7fFwN2oJF66zxeQ6kzR9lIwVZnqNYwgAapJAx7TrfX2UaR0zoZgs/TBhFijqJ2CK8fIQ7TKW0wEd84rd5FS8ocHmAsiJSLOSXn665m/nUPrWrUi7mK7/9/85rLiZihw862BhwIn83VQcahK4QEDFkK0PC7JqGvLiH3prjlibsA7ONDbFi8NPtvf3bFaofb6a3NO3qjgSvdftIujw86ZmVBAkQXghyZBlgCPiseOphrxZ4Thl54fo86cbiEqAs8c6DCHtPEiAHZ++sK1aitMtepdGORC1SrLICWO4vFAl6oLptzvY+j9+BhOK28JnRUXpQS7DjkrahqcgE/LbCN55lu1UhWWGY0q20QeKgGnsRuOAU=
|
||||
local_dir: dpl_cd_upload
|
||||
skip_cleanup: true
|
||||
on: &2
|
||||
repo: alphagov/notifications-admin
|
||||
bucket: notifications-admin-codedeploy
|
||||
region: eu-west-1
|
||||
- provider: codedeploy
|
||||
access_key_id: AKIAJQPPNM6P6V53SWKA
|
||||
secret_access_key: *1
|
||||
bucket: notifications-admin-codedeploy
|
||||
key: notifications-admin-$TRAVIS_BRANCH-$TRAVIS_BUILD_NUMBER-$TRAVIS_COMMIT.zip
|
||||
bundle_type: zip
|
||||
application: notifications-admin
|
||||
application: admin
|
||||
deployment_group: notifications_admin_deployment_group
|
||||
region: eu-west-1
|
||||
on: *2
|
||||
before_deploy:
|
||||
- ./scripts/update_version_file.sh
|
||||
- rm -rf node_modules bower_components app/assets
|
||||
- zip -r --exclude=*__pycache__* notifications-admin *
|
||||
- mkdir -p dpl_cd_upload
|
||||
- mv notifications-admin.zip dpl_cd_upload/notifications-admin-$TRAVIS_BRANCH-$TRAVIS_BUILD_NUMBER-$TRAVIS_COMMIT.zip
|
||||
- ./scripts/update_version_file.sh
|
||||
- rm -rf node_modules bower_components app/assets
|
||||
- zip -r --exclude=*__pycache__* notifications-admin *
|
||||
- mkdir -p dpl_cd_upload
|
||||
- mv notifications-admin.zip dpl_cd_upload/notifications-admin-$TRAVIS_BRANCH-$TRAVIS_BUILD_NUMBER-$TRAVIS_COMMIT.zip
|
||||
|
||||
@@ -61,7 +61,7 @@ in a separate terminal from the app
|
||||
|
||||
```
|
||||
echo "
|
||||
export NOTIFY_ADMIN_ENVIRONMENT='config.Development'
|
||||
export NOTIFY_ENVIRONMENT='development'
|
||||
export ADMIN_CLIENT_SECRET='dev-notify-secret-key'
|
||||
export ADMIN_CLIENT_USER_NAME='dev-notify-admin'
|
||||
export API_HOST_NAME='http://localhost:6011'
|
||||
@@ -69,7 +69,6 @@ export DANGEROUS_SALT='dev-notify-salt'
|
||||
export SECRET_KEY='dev-notify-secret-key'
|
||||
export DESKPRO_API_HOST=""
|
||||
export DESKPRO_API_KEY=""
|
||||
export DESKPRO_PERSON_EMAIL=""
|
||||
export DESKPRO_DEPT_ID=""
|
||||
export DESKPRO_ASSIGNED_AGENT_TEAM_ID=""
|
||||
"> environment.sh
|
||||
|
||||
@@ -13,8 +13,8 @@ from flask import (
|
||||
current_app,
|
||||
request,
|
||||
g,
|
||||
url_for
|
||||
)
|
||||
url_for)
|
||||
|
||||
from flask._compat import string_types
|
||||
from flask.globals import _lookup_req_object
|
||||
from flask_login import LoginManager
|
||||
@@ -67,9 +67,11 @@ current_service = LocalProxy(partial(_lookup_req_object, 'service'))
|
||||
|
||||
|
||||
def create_app():
|
||||
from config import configs
|
||||
|
||||
application = Flask(__name__)
|
||||
|
||||
application.config.from_object(os.environ['NOTIFY_ADMIN_ENVIRONMENT'])
|
||||
application.config.from_object(configs[os.environ['NOTIFY_ENVIRONMENT']])
|
||||
|
||||
init_app(application)
|
||||
logging.init_app(application)
|
||||
@@ -241,7 +243,8 @@ def format_notification_status(status, template_type):
|
||||
'temporary-failure': 'Inbox not accepting messages right now',
|
||||
'permanent-failure': 'Email address doesn’t exist',
|
||||
'delivered': 'Delivered',
|
||||
'sending': 'Sending'
|
||||
'sending': 'Sending',
|
||||
'created': 'Sending'
|
||||
},
|
||||
'sms': {
|
||||
'failed': 'Failed',
|
||||
@@ -249,7 +252,8 @@ def format_notification_status(status, template_type):
|
||||
'temporary-failure': 'Phone not accepting messages right now',
|
||||
'permanent-failure': 'Phone number doesn’t exist',
|
||||
'delivered': 'Delivered',
|
||||
'sending': 'Sending'
|
||||
'sending': 'Sending',
|
||||
'created': 'Sending'
|
||||
}
|
||||
}.get(template_type).get(status, status)
|
||||
|
||||
@@ -261,7 +265,8 @@ def format_notification_status_as_field_status(status):
|
||||
'temporary-failure': 'error',
|
||||
'permanent-failure': 'error',
|
||||
'delivered': None,
|
||||
'sending': 'default'
|
||||
'sending': 'default',
|
||||
'created': 'default'
|
||||
}.get(status, 'error')
|
||||
|
||||
|
||||
|
||||
BIN
app/assets/images/email-template/crests/bis_crest_27px_x2.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
app/assets/images/email-template/crests/coastguard_27px_x2.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
app/assets/images/email-template/crests/hmrc_crest_27px_x2.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
app/assets/images/email-template/crests/ho_crest_27px_x2.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
app/assets/images/email-template/crests/mod_crest_27px_x2.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
app/assets/images/email-template/crests/org_crest_27px_x2.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
app/assets/images/email-template/crests/portcullis_27px_x2.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
app/assets/images/email-template/crests/so_crest_27px_x2.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
app/assets/images/email-template/crests/ukaea_crest_27px_x2.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
app/assets/images/email-template/crests/ukho_27px_x2.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
app/assets/images/email-template/crests/wales_crest_27px_x2.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
app/assets/images/email-template/spacer.png
Normal file
|
After Width: | Height: | Size: 95 B |
@@ -31,6 +31,10 @@
|
||||
margin-bottom: $gutter-two-thirds;
|
||||
}
|
||||
|
||||
.bottom-gutter-1-2 {
|
||||
margin-bottom: $gutter-half;
|
||||
}
|
||||
|
||||
.align-with-heading {
|
||||
display: block;
|
||||
text-align: center;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from datetime import datetime, date, timedelta
|
||||
from datetime import datetime, timedelta
|
||||
from collections import namedtuple
|
||||
from itertools import groupby
|
||||
|
||||
import dateutil
|
||||
from flask import (
|
||||
render_template,
|
||||
url_for,
|
||||
@@ -9,13 +10,11 @@ from flask import (
|
||||
jsonify,
|
||||
current_app
|
||||
)
|
||||
|
||||
from flask_login import login_required
|
||||
|
||||
from app.main import main
|
||||
from app import (
|
||||
job_api_client,
|
||||
statistics_api_client,
|
||||
service_api_client,
|
||||
template_statistics_client
|
||||
)
|
||||
@@ -90,20 +89,10 @@ def usage(service_id):
|
||||
@login_required
|
||||
@user_has_permissions('manage_settings', admin_override=True)
|
||||
def weekly(service_id):
|
||||
|
||||
earliest_date = date(2016, 4, 1) # start of tax year
|
||||
while earliest_date.weekday() != 0: # 0 for monday
|
||||
earliest_date -= timedelta(days=1)
|
||||
|
||||
stats = service_api_client.get_weekly_notification_stats(service_id)['data']
|
||||
return render_template(
|
||||
'views/weekly.html',
|
||||
days=(
|
||||
add_rates_to(day) for day in
|
||||
statistics_api_client.get_7_day_aggregate_for_service(
|
||||
service_id,
|
||||
date_from=earliest_date
|
||||
)['data']
|
||||
),
|
||||
days=format_weekly_stats_to_list(stats),
|
||||
now=datetime.utcnow()
|
||||
)
|
||||
|
||||
@@ -199,3 +188,21 @@ def calculate_usage(usage):
|
||||
'sms_chargeable': max(0, sms_sent - sms_free_allowance),
|
||||
'sms_rate': sms_rate
|
||||
}
|
||||
|
||||
|
||||
def format_weekly_stats_to_list(historical_stats):
|
||||
out = []
|
||||
for week, weekly_stats in historical_stats.items():
|
||||
for stats in weekly_stats.values():
|
||||
stats['failure_rate'] = get_formatted_percentage(stats['failed'], stats['requested'])
|
||||
|
||||
week_start = dateutil.parser.parse(week)
|
||||
week_end = week_start + timedelta(days=6)
|
||||
weekly_stats.update({
|
||||
'week_start': week,
|
||||
'week_end': week_end.date().isoformat(),
|
||||
'week_end_datetime': week_end,
|
||||
})
|
||||
out.append(weekly_stats)
|
||||
|
||||
return sorted(out, key=lambda x: x['week_start'], reverse=True)
|
||||
|
||||
@@ -8,17 +8,19 @@ from app.main.forms import Feedback
|
||||
def feedback():
|
||||
form = Feedback()
|
||||
if form.validate_on_submit():
|
||||
user_supplied_email = form.email_address.data != ''
|
||||
feedback_msg = 'Environment: {}\n{}\n{}'.format(
|
||||
url_for('main.index', _external=True),
|
||||
'' if user_supplied_email else '{} (no email address supplied)'.format(form.name.data),
|
||||
form.feedback.data
|
||||
)
|
||||
data = {
|
||||
'person_email': current_app.config.get('DESKPRO_PERSON_EMAIL'),
|
||||
'person_email': form.email_address.data or current_app.config.get('DESKPRO_PERSON_EMAIL'),
|
||||
'person_name': form.name.data or None,
|
||||
'department_id': current_app.config.get('DESKPRO_DEPT_ID'),
|
||||
'agent_team_id': current_app.config.get('DESKPRO_ASSIGNED_AGENT_TEAM_ID'),
|
||||
'subject': 'Notify feedback',
|
||||
'message': 'Environment: {}\n\n{}\n{}\n{}'.format(
|
||||
url_for('main.index', _external=True),
|
||||
form.name.data,
|
||||
form.email_address.data,
|
||||
form.feedback.data
|
||||
)
|
||||
'message': feedback_msg
|
||||
}
|
||||
headers = {
|
||||
"X-DeskPRO-API-Key": current_app.config.get('DESKPRO_API_KEY'),
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import ago
|
||||
import time
|
||||
import dateutil
|
||||
from orderedset import OrderedSet
|
||||
from datetime import datetime, timedelta, timezone
|
||||
import ago
|
||||
from itertools import chain
|
||||
|
||||
from flask import (
|
||||
render_template,
|
||||
@@ -47,15 +49,14 @@ def _parse_filter_args(filter_dict):
|
||||
|
||||
|
||||
def _set_status_filters(filter_args):
|
||||
status_filters = filter_args.get('status', [])
|
||||
all_failure_statuses = ['failed', 'temporary-failure', 'permanent-failure', 'technical-failure']
|
||||
all_statuses = ['sending', 'delivered'] + all_failure_statuses
|
||||
if filter_args.get('status'):
|
||||
if 'processed' in filter_args.get('status') or not filter_args.get('status'):
|
||||
filter_args['status'] = all_statuses
|
||||
elif 'failed' in filter_args.get('status'):
|
||||
filter_args['status'].extend(all_failure_statuses[1:])
|
||||
else:
|
||||
filter_args['status'] = all_statuses
|
||||
all_sending_statuses = ['created', 'sending']
|
||||
return list(OrderedSet(chain(
|
||||
(status_filters or all_sending_statuses + ['delivered'] + all_failure_statuses),
|
||||
all_sending_statuses if 'sending' in status_filters else [],
|
||||
all_failure_statuses if 'failed' in status_filters else []
|
||||
)))
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/jobs")
|
||||
@@ -75,7 +76,7 @@ def view_job(service_id, job_id):
|
||||
|
||||
job = job_api_client.get_job(service_id, job_id)['data']
|
||||
filter_args = _parse_filter_args(request.args)
|
||||
_set_status_filters(filter_args)
|
||||
filter_args['status'] = _set_status_filters(filter_args)
|
||||
|
||||
return render_template(
|
||||
'views/jobs/job.html',
|
||||
@@ -117,7 +118,7 @@ def view_job_csv(service_id, job_id):
|
||||
version=job['template_version']
|
||||
)['data']
|
||||
filter_args = _parse_filter_args(request.args)
|
||||
_set_status_filters(filter_args)
|
||||
filter_args['status'] = _set_status_filters(filter_args)
|
||||
|
||||
return (
|
||||
generate_notifications_csv(
|
||||
@@ -161,7 +162,7 @@ def view_notifications(service_id, message_type):
|
||||
abort(404)
|
||||
|
||||
filter_args = _parse_filter_args(request.args)
|
||||
_set_status_filters(filter_args)
|
||||
filter_args['status'] = _set_status_filters(filter_args)
|
||||
|
||||
notifications = notification_api_client.get_notifications_for_service(
|
||||
service_id=service_id,
|
||||
@@ -210,7 +211,7 @@ def view_notifications(service_id, message_type):
|
||||
page=page,
|
||||
prev_page=prev_page,
|
||||
next_page=next_page,
|
||||
request_args=request.args,
|
||||
status=request.args.get('status'),
|
||||
message_type=message_type,
|
||||
download_link=url_for(
|
||||
'.view_notifications_csv',
|
||||
@@ -250,7 +251,7 @@ def get_status_filters(service, message_type, statistics):
|
||||
|
||||
filters = [
|
||||
# key, label, option
|
||||
('requested', 'processed', 'sending,delivered,failed'),
|
||||
('requested', 'total', 'sending,delivered,failed'),
|
||||
('sending', 'sending', 'sending'),
|
||||
('delivered', 'delivered', 'delivered'),
|
||||
('failed', 'failed', 'failed'),
|
||||
@@ -287,24 +288,22 @@ def _get_job_counts(job, help_argument):
|
||||
count
|
||||
) for label, query_param, count in [
|
||||
[
|
||||
'Processed', '',
|
||||
job.get('notifications_sent', 0)
|
||||
'total', '',
|
||||
job.get('notification_count', 0)
|
||||
],
|
||||
[
|
||||
'Sending', 'sending',
|
||||
(
|
||||
job.get('notifications_sent', 0) -
|
||||
job.get('notifications_delivered', 0) -
|
||||
job.get('notifications_failed', 0)
|
||||
)
|
||||
'sending', 'sending',
|
||||
job.get('notification_count', 0) -
|
||||
job.get('notifications_delivered', 0) -
|
||||
job.get('notifications_failed', 0)
|
||||
],
|
||||
[
|
||||
'Delivered', 'delivered',
|
||||
'delivered', 'delivered',
|
||||
job.get('notifications_delivered', 0)
|
||||
],
|
||||
[
|
||||
'Failed', 'failed',
|
||||
job.get('notifications_failed')
|
||||
'failed', 'failed',
|
||||
job.get('notifications_failed', 0)
|
||||
]
|
||||
]
|
||||
]
|
||||
@@ -312,24 +311,27 @@ def _get_job_counts(job, help_argument):
|
||||
|
||||
def get_job_partials(job):
|
||||
filter_args = _parse_filter_args(request.args)
|
||||
_set_status_filters(filter_args)
|
||||
filter_args['status'] = _set_status_filters(filter_args)
|
||||
notifications = notification_api_client.get_notifications_for_service(
|
||||
job['service'], job['id'], status=filter_args['status']
|
||||
)
|
||||
return {
|
||||
'counts': render_template(
|
||||
'partials/jobs/count.html',
|
||||
job=job,
|
||||
counts=_get_job_counts(job, request.args.get('help', 0)),
|
||||
status=request.args.get('status', '')
|
||||
status=filter_args['status']
|
||||
),
|
||||
'notifications': render_template(
|
||||
'partials/jobs/notifications.html',
|
||||
notifications=notification_api_client.get_notifications_for_service(
|
||||
job['service'], job['id'], status=filter_args.get('status')
|
||||
)['notifications'],
|
||||
notifications=notifications['notifications'],
|
||||
more_than_one_page=bool(notifications.get('links', {}).get('next')),
|
||||
percentage_complete=(job['notifications_sent'] / job['notification_count'] * 100),
|
||||
download_link=url_for(
|
||||
'.view_job_csv',
|
||||
service_id=current_service['id'],
|
||||
job_id=job['id'],
|
||||
status=request.args.get('status', '')
|
||||
status=request.args.get('status')
|
||||
),
|
||||
help=get_help_argument(),
|
||||
time_left=get_time_left(job['created_at'])
|
||||
|
||||
@@ -103,13 +103,12 @@ def service_request_to_go_live(service_id):
|
||||
if form.validate_on_submit():
|
||||
|
||||
data = {
|
||||
'person_email': current_app.config.get('DESKPRO_PERSON_EMAIL'),
|
||||
'person_email': current_user.email_address,
|
||||
'person_name': current_user.name,
|
||||
'department_id': current_app.config.get('DESKPRO_DEPT_ID'),
|
||||
'agent_team_id': current_app.config.get('DESKPRO_ASSIGNED_AGENT_TEAM_ID'),
|
||||
'subject': 'Request to go live',
|
||||
'message': "From {} <{}> on behalf of {} ({})\n\nUsage estimate\n---\n\n{}".format(
|
||||
current_user.name,
|
||||
current_user.email_address,
|
||||
'message': "On behalf of {} ({})\n\nUsage estimate\n---\n\n{}".format(
|
||||
current_service['name'],
|
||||
url_for('main.service_dashboard', service_id=current_service['id'], _external=True),
|
||||
form.usage.data
|
||||
|
||||
@@ -204,6 +204,9 @@ class ServiceAPIClient(NotificationsAPIClient):
|
||||
def get_service_usage(self, service_id):
|
||||
return self.get('/service/{0}/fragment/aggregate_statistics'.format(service_id))
|
||||
|
||||
def get_weekly_notification_stats(self, service_id):
|
||||
return self.get(url='/service/{}/notifications/weekly'.format(service_id))
|
||||
|
||||
|
||||
class ServicesBrowsableItem(BrowsableItem):
|
||||
@property
|
||||
|
||||
@@ -12,16 +12,15 @@ class StatisticsApiClient(BaseAPIClient):
|
||||
self.client_id = app.config['ADMIN_CLIENT_USER_NAME']
|
||||
self.secret = app.config['ADMIN_CLIENT_SECRET']
|
||||
|
||||
def get_7_day_aggregate_for_service(self, service_id, date_from=None, week_count=None):
|
||||
params = {}
|
||||
if date_from is not None:
|
||||
params['date_from'] = date_from
|
||||
if week_count is not None:
|
||||
params['week_count'] = week_count
|
||||
return self.get(
|
||||
url='/service/{}/notifications-statistics/seven_day_aggregate'.format(service_id),
|
||||
params=params
|
||||
)
|
||||
def get_statistics_for_service_for_day(self, service_id, day):
|
||||
url = '/service/{}/notifications-statistics/day/{}'.format(service_id, day)
|
||||
try:
|
||||
return self.get(url=url)['data']
|
||||
except HTTPError as e:
|
||||
if e.status_code == 404:
|
||||
return None
|
||||
else:
|
||||
raise e
|
||||
|
||||
def get_statistics_for_all_services_for_day(self, day):
|
||||
params = {
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
{% if not expanded %}
|
||||
<div class="email-message-body-wrapper">
|
||||
{% endif %}
|
||||
{{ body|nl2br }}
|
||||
{{ body }}
|
||||
{% if not expanded %}
|
||||
</div>
|
||||
<div class='toggle' tabindex='0'>...<span class='visually-hidden'>show full email</span></div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{% if help %}
|
||||
{% call banner_wrapper(type='tour') %}
|
||||
<p class="heading-medium">Try this example</p>
|
||||
<p class="heading-medium">Try sending yourself this example</p>
|
||||
<div class="grid-row bottom-gutter" {% if help != '1' %}style="opacity: 0.6"{% endif %}>
|
||||
<div class="column-one-sixth">
|
||||
<p class="heading-large" style="float: left;">1.</p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% from "components/pill.html" import pill %}
|
||||
|
||||
<div class="bottom-gutter">
|
||||
{{ pill('Status', counts, status) }}
|
||||
{{ pill('Status', counts, request.args.get('status', '')) }}
|
||||
</div>
|
||||
|
||||
@@ -4,12 +4,18 @@
|
||||
<div class="dashboard-table">
|
||||
{% endif %}
|
||||
|
||||
{% if notifications and not help %}
|
||||
<p class="bottom-gutter">
|
||||
<a href="{{ download_link }}" download="download" class="heading-small">Download this report</a>
|
||||
 
|
||||
<span id="time-left">{{ time_left }}</span>
|
||||
</p>
|
||||
{% if not help %}
|
||||
{% if percentage_complete < 100 %}
|
||||
<p class="bottom-gutter-1-2 hint">
|
||||
Report is {{ "{:.0f}%".format(percentage_complete) }} complete…
|
||||
</p>
|
||||
{% elif notifications %}
|
||||
<p class="bottom-gutter-1-2">
|
||||
<a href="{{ download_link }}" download="download" class="heading-small">Download this report</a>
|
||||
 
|
||||
<span id="time-left">{{ time_left }}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% call(item, row_number) list_table(
|
||||
@@ -44,6 +50,12 @@
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
|
||||
{% if more_than_one_page %}
|
||||
<p class="table-show-more-link">
|
||||
Only showing the first 50 rows
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% if notifications %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
<details>
|
||||
<summary class="button tertiary-button">Message length</summary>
|
||||
<div id="guidance-personalisation">
|
||||
<p>
|
||||
If your message is long then it will
|
||||
cost more.
|
||||
</p>
|
||||
<p>
|
||||
See <a href="{{ url_for('.pricing') }}">pricing</a> for details.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
<h2 class="heading-medium">Message length</h2>
|
||||
<p>
|
||||
If your message is long then it will
|
||||
cost more.
|
||||
</p>
|
||||
<p>
|
||||
See <a href="{{ url_for('.pricing') }}">pricing</a> for details.
|
||||
</p>
|
||||
|
||||
27
app/templates/partials/templates/guidance-formatting.html
Normal file
@@ -0,0 +1,27 @@
|
||||
<h2 class="heading-medium">Formatting</h2>
|
||||
<p>
|
||||
To put a title in your template, use a hash:
|
||||
</p>
|
||||
<div class="panel panel-border-wide">
|
||||
<p>
|
||||
# This is a title
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
To make bullet points, use asterisks:
|
||||
</p>
|
||||
<div class="panel panel-border-wide">
|
||||
<p>
|
||||
* point 1<br/>
|
||||
* point 2<br/>
|
||||
* point 3<br/>
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
To add a callout, use a caret:
|
||||
</p>
|
||||
<div class="panel panel-border-wide">
|
||||
<p>
|
||||
^ You must tell us if your circumstances change
|
||||
</p>
|
||||
</div>
|
||||
@@ -1,8 +1,9 @@
|
||||
<details>
|
||||
<summary class="button tertiary-button">Links and URLs</summary>
|
||||
<div id="guidance-personalisation">
|
||||
<p>
|
||||
Always use full URLs, starting with https://
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
<h2 class="heading-medium">Links and URLs</h2>
|
||||
<p>
|
||||
Always use full URLs, starting with https://
|
||||
</p>
|
||||
<div class="panel panel-border-wide">
|
||||
<p>
|
||||
Apply now at https://www.gov.uk/example
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
<details>
|
||||
<summary class="button tertiary-button">Personalisation</summary>
|
||||
<div id="guidance-personalisation">
|
||||
<p>
|
||||
Use double brackets to add personalisation.
|
||||
</p>
|
||||
<p>
|
||||
Correct: ((name))
|
||||
</p>
|
||||
<p>
|
||||
Incorrect: ((Helen))
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
<h2 class="heading-medium">
|
||||
Personalisation
|
||||
</h2>
|
||||
<p>
|
||||
Use double brackets to personalise your message:
|
||||
</p>
|
||||
<div class="panel panel-border-wide">
|
||||
<p>
|
||||
Hello ((first name)), your reference is ((ref number))
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
{% endcall %}
|
||||
{% call field() %}
|
||||
{{ big_number(
|
||||
item.get('notifications_sent', 0) - item.get('notifications_delivered', 0) - item.get('notifications_failed', 0),
|
||||
item.get('notification_count', 0) - item.get('notifications_delivered', 0) - item.get('notifications_failed', 0),
|
||||
smallest=True
|
||||
) }}
|
||||
{% endcall %}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
{% if not templates %}
|
||||
{% include 'views/dashboard/write-first-messages.html' %}
|
||||
{% endif %}
|
||||
{% elif not current_user.has_permissions(['send_texts', 'send_emails', 'send_letters'], any_=True) %}
|
||||
{% elif not current_user.has_permissions(['send_texts', 'send_emails', 'send_letters', 'manage_api_keys'], any_=True) %}
|
||||
{% include 'views/dashboard/no-permissions-banner.html' %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
<form method="post">
|
||||
<div class="grid-row">
|
||||
<div class="column-two-thirds">
|
||||
<div class="column-three-quarters">
|
||||
{{ textbox(form.name, width='1-1', hint='Your recipients won’t see this', rows=10) }}
|
||||
{{ textbox(form.subject, width='1-1', highlight_tags=True, rows=2) }}
|
||||
</div>
|
||||
<div class="column-two-thirds">
|
||||
<div class="column-three-quarters">
|
||||
{{ textbox(form.template_content, highlight_tags=True, width='1-1', rows=8) }}
|
||||
{{ page_footer(
|
||||
'Save',
|
||||
@@ -26,8 +26,8 @@
|
||||
delete_link_text='Delete this template'
|
||||
) }}
|
||||
</div>
|
||||
<aside class="column-one-third">
|
||||
<h2 style="margin: 0 0 5px 0;">Help</h2>
|
||||
<aside class="column-whole">
|
||||
{% include "partials/templates/guidance-formatting.html" %}
|
||||
{% include "partials/templates/guidance-personalisation.html" %}
|
||||
{% include "partials/templates/guidance-links.html" %}
|
||||
</aside>
|
||||
|
||||
@@ -25,8 +25,7 @@
|
||||
delete_link_text='Delete this template'
|
||||
) }}
|
||||
</div>
|
||||
<aside class="column-one-third">
|
||||
<h2 style="margin: 0 0 5px 0;">Help</h2>
|
||||
<aside class="column-whole">
|
||||
{% include "partials/templates/guidance-personalisation.html" %}
|
||||
{% include "partials/templates/guidance-links.html" %}
|
||||
{% include "partials/templates/guidance-character-count.html" %}
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
<h1 class="heading-large">
|
||||
|
||||
<span class="visually-hidden">
|
||||
{%- if request_args.get('status') != 'delivered,failed' -%}
|
||||
{%- if status != 'delivered,failed' -%}
|
||||
{%- for label, option, _, _ in status_filters -%}
|
||||
{%- if request_args.get('status', 'delivered,failed') == option -%}{{label}} {% endif -%}
|
||||
{%- if status == option -%}{{label}} {% endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
</span>
|
||||
@@ -29,15 +29,15 @@
|
||||
{{ pill(
|
||||
'Status',
|
||||
status_filters,
|
||||
request_args.get('status', '')
|
||||
status
|
||||
) }}
|
||||
</div>
|
||||
|
||||
{% if notifications %}
|
||||
<p class="bottom-gutter">
|
||||
<a href="{{ download_link }}" download="download" class="heading-small">Download as a CSV file</a>
|
||||
<p class="bottom-gutter-1-2">
|
||||
<a href="{{ download_link }}" download="download" class="heading-small">Download this report</a>
|
||||
 
|
||||
Delivery information is available for 7 days
|
||||
Data available for 7 days
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{% extends "withnav_template.html" %}
|
||||
|
||||
{% block page_title %}
|
||||
Daily – GOV.UK Notify
|
||||
Previous weeks – GOV.UK Notify
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
@@ -33,16 +33,16 @@
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% call field(align='right') %}
|
||||
{{ item.emails_requested }}
|
||||
{{ item.email.requested }}
|
||||
{% endcall %}
|
||||
{% call field(align='right') %}
|
||||
{{ item.emails_failure_rate }}%
|
||||
{{ item.email.failure_rate }}%
|
||||
{% endcall %}
|
||||
{% call field(align='right') %}
|
||||
{{ item.sms_requested }}
|
||||
{{ item.sms.requested }}
|
||||
{% endcall %}
|
||||
{% call field(align='right') %}
|
||||
{{ item.sms_failure_rate }}%
|
||||
{{ item.sms.failure_rate }}%
|
||||
{% endcall %}
|
||||
{% endcall %}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
__travis_commit__ = "dev"
|
||||
__time__ = "dev"
|
||||
__travis_job_number__ = "dev"
|
||||
__travis_commit__ = ""
|
||||
__time__ = "2016-07-05:14:44:52"
|
||||
__travis_job_number__ = ""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
files:
|
||||
-
|
||||
destination: /home/ubuntu/notifications-admin
|
||||
destination: /home/notify-app/notifications-admin
|
||||
source: /
|
||||
hooks:
|
||||
AfterInstall:
|
||||
|
||||
27
config.py
@@ -3,7 +3,6 @@ from datetime import timedelta
|
||||
|
||||
|
||||
class Config(object):
|
||||
|
||||
DEBUG = False
|
||||
ADMIN_CLIENT_SECRET = os.environ['ADMIN_CLIENT_SECRET']
|
||||
ADMIN_CLIENT_USER_NAME = os.environ['ADMIN_CLIENT_USER_NAME']
|
||||
@@ -36,7 +35,7 @@ class Config(object):
|
||||
CSV_UPLOAD_BUCKET_NAME = 'local-notifications-csv-upload'
|
||||
DESKPRO_API_HOST = os.environ['DESKPRO_API_HOST']
|
||||
DESKPRO_API_KEY = os.environ['DESKPRO_API_KEY']
|
||||
DESKPRO_PERSON_EMAIL = os.environ['DESKPRO_PERSON_EMAIL']
|
||||
DESKPRO_PERSON_EMAIL = 'donotreply@notifications.service.gov.uk'
|
||||
DESKPRO_DEPT_ID = os.environ['DESKPRO_DEPT_ID']
|
||||
DESKPRO_ASSIGNED_AGENT_TEAM_ID = os.environ['DESKPRO_ASSIGNED_AGENT_TEAM_ID']
|
||||
ACTIVITY_STATS_LIMIT_DAYS = 7
|
||||
@@ -78,10 +77,24 @@ class Preview(Config):
|
||||
CSV_UPLOAD_BUCKET_NAME = 'preview-notifications-csv-upload'
|
||||
|
||||
|
||||
class Staging(Config):
|
||||
SHOW_STYLEGUIDE = False
|
||||
HTTP_PROTOCOL = 'https'
|
||||
HEADER_COLOUR = '#F47738' # $orange
|
||||
CSV_UPLOAD_BUCKET_NAME = 'staging-notify-csv-upload'
|
||||
|
||||
|
||||
class Live(Config):
|
||||
SHOW_STYLEGUIDE = False
|
||||
HEADER_COLOUR = '#B10E1E' # $red
|
||||
HTTP_PROTOCOL = 'https'
|
||||
CSV_UPLOAD_BUCKET_NAME = 'live-notifications-csv-upload'
|
||||
|
||||
|
||||
configs = {
|
||||
'development': 'config.Development',
|
||||
'test': 'config.Test',
|
||||
'preview': 'config.Preview',
|
||||
'staging': 'config_staging.Staging',
|
||||
'live': 'config_live.Live'
|
||||
'development': Development,
|
||||
'test': Test,
|
||||
'preview': Preview,
|
||||
'staging': Staging,
|
||||
'live': Live
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import os
|
||||
from config import Config
|
||||
|
||||
|
||||
class Live(Config):
|
||||
SHOW_STYLEGUIDE = False
|
||||
HEADER_COLOUR = '#B10E1E' # $red
|
||||
HTTP_PROTOCOL = 'https'
|
||||
API_HOST_NAME = os.environ['LIVE_API_HOST_NAME']
|
||||
ADMIN_CLIENT_SECRET = os.environ['LIVE_ADMIN_CLIENT_SECRET']
|
||||
SECRET_KEY = os.environ['LIVE_SECRET_KEY']
|
||||
DANGEROUS_SALT = os.environ['LIVE_DANGEROUS_SALT']
|
||||
CSV_UPLOAD_BUCKET_NAME = 'live-notifications-csv-upload'
|
||||
DESKPRO_API_KEY = os.environ['LIVE_DESKPRO_API_KEY']
|
||||
DESKPRO_DEPT_ID = os.environ['LIVE_DESKPRO_DEPT_ID']
|
||||
DESKPRO_ASSIGNED_AGENT_TEAM_ID = os.environ['LIVE_DESKPRO_ASSIGNED_AGENT_TEAM_ID']
|
||||
HEADER_COLOUR = '#B10E1E' # $red
|
||||
@@ -1,16 +0,0 @@
|
||||
import os
|
||||
from config import Config
|
||||
|
||||
|
||||
class Staging(Config):
|
||||
SHOW_STYLEGUIDE = False
|
||||
HTTP_PROTOCOL = 'https'
|
||||
API_HOST_NAME = os.environ['STAGING_API_HOST_NAME']
|
||||
ADMIN_CLIENT_SECRET = os.environ['STAGING_ADMIN_CLIENT_SECRET']
|
||||
SECRET_KEY = os.environ['STAGING_SECRET_KEY']
|
||||
DANGEROUS_SALT = os.environ['STAGING_DANGEROUS_SALT']
|
||||
CSV_UPLOAD_BUCKET_NAME = 'staging-notifications-csv-upload'
|
||||
DESKPRO_API_KEY = os.environ['STAGING_DESKPRO_API_KEY']
|
||||
DESKPRO_DEPT_ID = os.environ['STAGING_DESKPRO_DEPT_ID']
|
||||
DESKPRO_ASSIGNED_AGENT_TEAM_ID = os.environ['STAGING_DESKPRO_ASSIGNED_AGENT_TEAM_ID']
|
||||
HEADER_COLOUR = '#F47738' # $orange
|
||||
@@ -42,7 +42,7 @@ To create JSON Web Tokens you need:
|
||||
* your Service ID – identifies your service
|
||||
* your API key (in JSON Web Token terms this is called the client ID) – used to sign tokens during requests for API resources
|
||||
|
||||
To find your Service ID and create or revoke API keys, click on **API keys** in the [GOV.UK Notify](https://www.notifications.service.gov.uk/) web application.
|
||||
To find your Service ID and create or revoke API keys, click on **API integration** in the [GOV.UK Notify](https://www.notifications.service.gov.uk/) web application.
|
||||
|
||||
<h3 id="JWT_claims">JSON Web Tokens: claims</h3>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export NOTIFY_ADMIN_ENVIRONMENT='config.Test'
|
||||
export NOTIFY_ENVIRONMENT='test'
|
||||
export ADMIN_CLIENT_SECRET='dev-notify-secret-key'
|
||||
export ADMIN_CLIENT_USER_NAME='dev-notify-admin'
|
||||
export API_HOST_NAME=''
|
||||
@@ -6,6 +6,5 @@ export DANGEROUS_SALT='dev-notify-salt'
|
||||
export SECRET_KEY='dev-notify-secret-key'
|
||||
export DESKPRO_API_HOST=""
|
||||
export DESKPRO_API_KEY=""
|
||||
export DESKPRO_PERSON_EMAIL=""
|
||||
export DESKPRO_DEPT_ID=""
|
||||
export DESKPRO_ASSIGNED_AGENT_TEAM_ID=""
|
||||
|
||||
@@ -19,4 +19,4 @@ pytz==2016.4
|
||||
|
||||
git+https://github.com/alphagov/notifications-python-client.git@1.0.0#egg=notifications-python-client==1.0.0
|
||||
|
||||
git+https://github.com/alphagov/notifications-utils.git@8.7.1#egg=notifications-utils==8.7.1
|
||||
git+https://github.com/alphagov/notifications-utils.git@8.7.2#egg=notifications-utils==8.7.2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Chown application to be owned by ubuntu"
|
||||
cd /home/ubuntu/;
|
||||
chown -R ubuntu:ubuntu notifications-admin
|
||||
cd /home/notify-app/;
|
||||
chown -R notify-app:govuk-notify-applications notifications-admin
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Install dependencies"
|
||||
cd /home/ubuntu/notifications-admin;
|
||||
pip3 install -r /home/ubuntu/notifications-admin/requirements.txt
|
||||
cd /home/notify-app/notifications-admin;
|
||||
pip3 install -r /home/notify-app/notifications-admin/requirements.txt
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Starting application"
|
||||
cd ~/notifications-admin/;
|
||||
sudo service notifications-admin start
|
||||
@@ -101,7 +101,7 @@ reset_waiter_timeout() {
|
||||
fi
|
||||
|
||||
# Base register/deregister action may take up to about 30 seconds
|
||||
timeout=$((timeout + 30))
|
||||
timeout=$((timeout + 60))
|
||||
|
||||
WAITER_ATTEMPTS=$((timeout / WAITER_INTERVAL))
|
||||
}
|
||||
@@ -183,7 +183,7 @@ get_instance_health_elb() {
|
||||
;;
|
||||
*)
|
||||
msg "Instance '$instance_id' not part of ELB '$elb_name'"
|
||||
return 1
|
||||
return 0
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -30,8 +30,6 @@ display_result $? 1 "Code style check"
|
||||
npm test
|
||||
display_result $? 2 "Front end code style check"
|
||||
|
||||
export NOTIFY_ADMIN_ENVIRONMENT='config.Test'
|
||||
|
||||
## Code coverage
|
||||
py.test -n2 --cov=app --cov-report=term-missing tests/
|
||||
display_result $? 3 "Code coverage"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from datetime import datetime
|
||||
import copy
|
||||
from flask import url_for
|
||||
|
||||
@@ -5,7 +6,7 @@ import pytest
|
||||
from bs4 import BeautifulSoup
|
||||
from freezegun import freeze_time
|
||||
|
||||
from app.main.views.dashboard import get_dashboard_totals
|
||||
from app.main.views.dashboard import get_dashboard_totals, format_weekly_stats_to_list
|
||||
|
||||
from tests import validate_route_permission
|
||||
from tests.conftest import SERVICE_ONE_ID
|
||||
@@ -65,7 +66,6 @@ def test_get_started(
|
||||
api_user_active,
|
||||
mock_get_service,
|
||||
mock_get_service_templates_when_no_templates_exist,
|
||||
mock_get_aggregate_service_statistics,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email,
|
||||
mock_login,
|
||||
@@ -94,7 +94,6 @@ def test_get_started_is_hidden_once_templates_exist(
|
||||
api_user_active,
|
||||
mock_get_service,
|
||||
mock_get_service_templates,
|
||||
mock_get_aggregate_service_statistics,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email,
|
||||
mock_login,
|
||||
@@ -119,7 +118,6 @@ def test_should_show_recent_templates_on_dashboard(app_,
|
||||
api_user_active,
|
||||
mock_get_service,
|
||||
mock_get_service_templates,
|
||||
mock_get_aggregate_service_statistics,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email,
|
||||
mock_login,
|
||||
@@ -204,7 +202,6 @@ def test_should_show_recent_jobs_on_dashboard(
|
||||
api_user_active,
|
||||
mock_get_service,
|
||||
mock_get_service_templates,
|
||||
mock_get_aggregate_service_statistics,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email,
|
||||
mock_login,
|
||||
@@ -482,3 +479,46 @@ def test_get_dashboard_totals_adds_warning(failures, expected):
|
||||
}
|
||||
}
|
||||
assert get_dashboard_totals(stats)['sms']['show_warning'] == expected
|
||||
|
||||
|
||||
def test_format_weekly_stats_to_list_empty_case():
|
||||
assert format_weekly_stats_to_list({}) == []
|
||||
|
||||
|
||||
def test_format_weekly_stats_to_list_sorts_by_week():
|
||||
stats = {
|
||||
'2016-07-04': {},
|
||||
'2016-07-11': {},
|
||||
'2016-07-18': {},
|
||||
'2016-07-25': {}
|
||||
}
|
||||
resp = format_weekly_stats_to_list(stats)
|
||||
assert resp[0]['week_start'] == '2016-07-25'
|
||||
assert resp[1]['week_start'] == '2016-07-18'
|
||||
assert resp[2]['week_start'] == '2016-07-11'
|
||||
assert resp[3]['week_start'] == '2016-07-04'
|
||||
|
||||
|
||||
def test_format_weekly_stats_to_list_includes_datetime_for_comparison():
|
||||
stats = {
|
||||
'2016-07-25': {}
|
||||
}
|
||||
resp = format_weekly_stats_to_list(stats)
|
||||
assert resp == [{
|
||||
'week_start': '2016-07-25',
|
||||
'week_end': '2016-07-31',
|
||||
'week_end_datetime': datetime(2016, 7, 31, 0, 0, 0)
|
||||
}]
|
||||
|
||||
|
||||
def test_format_weekly_stats_to_list_has_stats_with_failure_rate():
|
||||
stats = {
|
||||
'2016-07-25': {'sms': _stats(3, 1, 2)}
|
||||
}
|
||||
resp = format_weekly_stats_to_list(stats)
|
||||
assert resp[0]['sms']['failure_rate'] == '66.7'
|
||||
assert resp[0]['sms']['requested'] == 3
|
||||
|
||||
|
||||
def _stats(requested, delivered, failed):
|
||||
return {'requested': requested, 'delivered': delivered, 'failed': failed}
|
||||
|
||||
@@ -26,17 +26,27 @@ def test_get_feedback_page(app_):
|
||||
assert resp.status_code == 200
|
||||
|
||||
|
||||
def test_post_feedback_with_no_name_email(app_, mocker):
|
||||
def test_post_feedback_with_name_but_no_email(app_, mocker):
|
||||
mock_post = mocker.patch(
|
||||
'app.main.views.feedback.requests.post',
|
||||
return_value=Mock(status_code=201))
|
||||
with app_.test_request_context():
|
||||
with app_.test_client() as client:
|
||||
resp = client.post(url_for('main.feedback'), data={'feedback': "blah"})
|
||||
resp = client.post(url_for('main.feedback'), data={'feedback': "blah", 'name': 'Fred'})
|
||||
assert resp.status_code == 302
|
||||
mock_post.assert_called_with(
|
||||
ANY,
|
||||
data={
|
||||
'department_id': ANY,
|
||||
'agent_team_id': ANY,
|
||||
'subject': 'Notify feedback',
|
||||
'message': 'Environment: http://localhost/\nFred (no email address supplied)\nblah',
|
||||
'person_email': app_.config['DESKPRO_PERSON_EMAIL'],
|
||||
'person_name': 'Fred'},
|
||||
headers=ANY)
|
||||
|
||||
|
||||
def test_post_feedback_with_no_name_email(app_, mocker):
|
||||
def test_post_feedback_with_no_name_or_email(app_, mocker):
|
||||
mock_post = mocker.patch(
|
||||
'app.main.views.feedback.requests.post',
|
||||
return_value=Mock(status_code=201))
|
||||
@@ -50,8 +60,9 @@ def test_post_feedback_with_no_name_email(app_, mocker):
|
||||
'department_id': ANY,
|
||||
'agent_team_id': ANY,
|
||||
'subject': 'Notify feedback',
|
||||
'message': 'Environment: http://localhost/\n\n\n\nblah',
|
||||
'person_email': ANY},
|
||||
'message': 'Environment: http://localhost/\n (no email address supplied)\nblah',
|
||||
'person_email': app_.config['DESKPRO_PERSON_EMAIL'],
|
||||
'person_name': None},
|
||||
headers=ANY)
|
||||
|
||||
|
||||
@@ -71,8 +82,9 @@ def test_post_feedback_with_name_email(app_, mocker):
|
||||
'subject': 'Notify feedback',
|
||||
'department_id': ANY,
|
||||
'agent_team_id': ANY,
|
||||
'message': 'Environment: http://localhost/\n\nSteve Irwin\nrip@gmail.com\nblah',
|
||||
'person_email': ANY},
|
||||
'message': 'Environment: http://localhost/\n\nblah',
|
||||
'person_name': 'Steve Irwin',
|
||||
'person_email': 'rip@gmail.com'},
|
||||
headers=ANY)
|
||||
|
||||
|
||||
@@ -91,14 +103,6 @@ def test_log_error_on_post(app_, mocker):
|
||||
resp = client.post(
|
||||
url_for('main.feedback'),
|
||||
data={'feedback': "blah", 'name': "Steve Irwin", 'email_address': 'rip@gmail.com'})
|
||||
mock_post.assert_called_with(
|
||||
ANY,
|
||||
data={
|
||||
'subject': 'Notify feedback',
|
||||
'department_id': ANY,
|
||||
'agent_team_id': ANY,
|
||||
'message': 'Environment: http://localhost/\n\nSteve Irwin\nrip@gmail.com\nblah',
|
||||
'person_email': ANY},
|
||||
headers=ANY)
|
||||
assert mock_post.called
|
||||
mock_logger.assert_called_with(
|
||||
"Deskpro create ticket request failed with {} '{}'".format(mock_post().status_code, mock_post().json()))
|
||||
|
||||
@@ -32,15 +32,11 @@ def test_should_return_list_of_all_jobs(app_,
|
||||
"status_argument, expected_api_call", [
|
||||
(
|
||||
'',
|
||||
['sending', 'delivered', 'failed', 'temporary-failure', 'permanent-failure', 'technical-failure']
|
||||
),
|
||||
(
|
||||
'processed',
|
||||
['sending', 'delivered', 'failed', 'temporary-failure', 'permanent-failure', 'technical-failure']
|
||||
['created', 'sending', 'delivered', 'failed', 'temporary-failure', 'permanent-failure', 'technical-failure']
|
||||
),
|
||||
(
|
||||
'sending',
|
||||
['sending']
|
||||
['sending', 'created']
|
||||
),
|
||||
(
|
||||
'delivered',
|
||||
@@ -99,6 +95,7 @@ def test_should_show_page_for_one_job(
|
||||
)
|
||||
assert csv_link.text == 'Download this report'
|
||||
assert page.find('span', {'id': 'time-left'}).text == 'Data available for 7 days'
|
||||
assert page.find('p', {'class': 'table-show-more-link'}).text.strip() == 'Only showing the first 50 rows'
|
||||
mock_get_notifications.assert_called_with(
|
||||
service_one['id'],
|
||||
fake_uuid,
|
||||
@@ -106,6 +103,29 @@ def test_should_show_page_for_one_job(
|
||||
)
|
||||
|
||||
|
||||
def test_should_show_job_in_progress(
|
||||
app_,
|
||||
service_one,
|
||||
active_user_with_permissions,
|
||||
mock_get_service_template,
|
||||
mock_get_job_in_progress,
|
||||
mocker,
|
||||
mock_get_notifications,
|
||||
fake_uuid
|
||||
):
|
||||
with app_.test_request_context(), app_.test_client() as client:
|
||||
client.login(active_user_with_permissions, mocker, service_one)
|
||||
response = client.get(url_for(
|
||||
'main.view_job',
|
||||
service_id=service_one['id'],
|
||||
job_id=fake_uuid
|
||||
))
|
||||
|
||||
assert response.status_code == 200
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.find('p', {'class': 'hint'}).text.strip() == 'Report is 50% complete…'
|
||||
|
||||
|
||||
def test_should_show_not_show_csv_download_in_tour(
|
||||
app_,
|
||||
service_one,
|
||||
@@ -179,12 +199,12 @@ def test_should_show_updates_for_one_job_as_json(
|
||||
@pytest.mark.parametrize(
|
||||
"status_argument, expected_api_call", [
|
||||
(
|
||||
'processed',
|
||||
['sending', 'delivered', 'failed', 'temporary-failure', 'permanent-failure', 'technical-failure']
|
||||
'',
|
||||
['created', 'sending', 'delivered', 'failed', 'temporary-failure', 'permanent-failure', 'technical-failure']
|
||||
),
|
||||
(
|
||||
'sending',
|
||||
['sending']
|
||||
['sending', 'created']
|
||||
),
|
||||
(
|
||||
'delivered',
|
||||
@@ -275,10 +295,21 @@ def test_should_show_notifications_for_a_service_with_next_previous(
|
||||
))
|
||||
assert response.status_code == 200
|
||||
content = response.get_data(as_text=True)
|
||||
assert url_for('main.view_notifications', service_id=service_one['id'], message_type='sms', page=3) in content
|
||||
assert url_for('main.view_notifications', service_id=service_one['id'], message_type='sms', page=1) in content
|
||||
assert 'Previous page' in content
|
||||
assert 'Next page' in content
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
next_page_link = page.find('a', {'rel': 'next'})
|
||||
prev_page_link = page.find('a', {'rel': 'previous'})
|
||||
assert (
|
||||
url_for('main.view_notifications', service_id=service_one['id'], message_type='sms', page=3) in
|
||||
next_page_link['href']
|
||||
)
|
||||
assert 'Next page' in next_page_link.text.strip()
|
||||
assert 'page 3' in next_page_link.text.strip()
|
||||
assert (
|
||||
url_for('main.view_notifications', service_id=service_one['id'], message_type='sms', page=1) in
|
||||
prev_page_link['href']
|
||||
)
|
||||
assert 'Previous page' in prev_page_link.text.strip()
|
||||
assert 'page 1' in prev_page_link.text.strip()
|
||||
|
||||
|
||||
@freeze_time("2016-01-01 11:09:00.061258")
|
||||
@@ -335,7 +366,7 @@ def test_get_status_filters_calculates_stats(app_):
|
||||
ret = get_status_filters({'id': 'foo'}, 'sms', STATISTICS)
|
||||
|
||||
assert {label: count for label, _option, _link, count in ret} == {
|
||||
'processed': 6,
|
||||
'total': 6,
|
||||
'sending': 3,
|
||||
'failed': 2,
|
||||
'delivered': 1
|
||||
@@ -347,7 +378,7 @@ def test_get_status_filters_in_right_order(app_):
|
||||
ret = get_status_filters({'id': 'foo'}, 'sms', STATISTICS)
|
||||
|
||||
assert [label for label, _option, _link, _count in ret] == [
|
||||
'processed', 'sending', 'delivered', 'failed'
|
||||
'total', 'sending', 'delivered', 'failed'
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -241,10 +241,9 @@ def test_should_redirect_after_request_to_go_live(
|
||||
'subject': 'Request to go live',
|
||||
'department_id': ANY,
|
||||
'agent_team_id': ANY,
|
||||
'message': 'From Test User <test@user.gov.uk> on behalf of Test Service (http://localhost/services/6ce466d0-fd6a-11e5-82f5-e0accb9d11a6/dashboard)\n\nUsage estimate\n---\n\nOne million messages', # noqa
|
||||
# noqa
|
||||
# noqa
|
||||
'person_email': ANY
|
||||
'message': 'On behalf of Test Service (http://localhost/services/6ce466d0-fd6a-11e5-82f5-e0accb9d11a6/dashboard)\n\nUsage estimate\n---\n\nOne million messages', # noqa
|
||||
'person_name': api_user_active.name,
|
||||
'person_email': api_user_active.email_address
|
||||
},
|
||||
headers=ANY
|
||||
)
|
||||
|
||||
@@ -217,12 +217,23 @@ def mock_delete_service(mocker, mock_get_service):
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def mock_get_aggregate_service_statistics(mocker):
|
||||
def _create(service_id, limit_days=None):
|
||||
return {'data': [{}]}
|
||||
def mock_get_service_statistics_for_day(mocker):
|
||||
|
||||
stats = {'day': datetime.today().date().strftime('%Y-%m-%d'),
|
||||
'emails_delivered': 0,
|
||||
'sms_requested': 0,
|
||||
'sms_delivered': 0,
|
||||
'sms_failed': 0,
|
||||
'emails_requested': 0,
|
||||
'emails_failed': 0,
|
||||
'service': fake_uuid,
|
||||
'id': fake_uuid}
|
||||
|
||||
def _stats(service_id, day):
|
||||
return {'data': stats}
|
||||
|
||||
return mocker.patch(
|
||||
'app.statistics_api_client.get_7_day_aggregate_for_service', side_effect=_create)
|
||||
'app.statistics_api_client.get_statistics_for_service_for_day', side_effect=_stats)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
@@ -854,6 +865,18 @@ def mock_get_job(mocker, api_user_active):
|
||||
return mocker.patch('app.job_api_client.get_job', side_effect=_get_job)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def mock_get_job_in_progress(mocker, api_user_active):
|
||||
def _get_job(service_id, job_id):
|
||||
return {"data": job_json(
|
||||
service_id, api_user_active, job_id=job_id,
|
||||
notification_count=10,
|
||||
notifications_sent=5
|
||||
)}
|
||||
|
||||
return mocker.patch('app.job_api_client.get_job', side_effect=_get_job)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def mock_get_jobs(mocker, api_user_active):
|
||||
def _get_jobs(service_id, limit_days=None):
|
||||
@@ -894,14 +917,16 @@ def mock_get_notifications(mocker, api_user_active):
|
||||
template={'template_type': set_template_type, 'name': 'name', 'id': 'id', 'version': 1},
|
||||
rows=rows,
|
||||
status=set_status,
|
||||
job=job
|
||||
job=job,
|
||||
with_links=True
|
||||
)
|
||||
else:
|
||||
return notification_json(
|
||||
service_id,
|
||||
rows=rows,
|
||||
status=set_status,
|
||||
job=job
|
||||
job=job,
|
||||
with_links=True
|
||||
)
|
||||
|
||||
return mocker.patch(
|
||||
|
||||
12
wsgi.py
@@ -1,21 +1,9 @@
|
||||
from credstash import getAllSecrets
|
||||
import os
|
||||
|
||||
default_env_file = '/home/ubuntu/environment'
|
||||
environment = 'live'
|
||||
|
||||
if os.path.isfile(default_env_file):
|
||||
with open(default_env_file, 'r') as environment_file:
|
||||
environment = environment_file.readline().strip()
|
||||
|
||||
|
||||
# on aws get secrets and export to env
|
||||
os.environ.update(getAllSecrets(region="eu-west-1"))
|
||||
|
||||
from config import configs # noqa
|
||||
|
||||
os.environ['NOTIFY_ADMIN_ENVIRONMENT'] = configs[environment]
|
||||
|
||||
from app import create_app # noqa
|
||||
|
||||
application = create_app()
|
||||
|
||||