Add GET /api/notifications, /api/notifications/:notification_id

This commit is contained in:
Son NK 2020-05-23 18:53:29 +02:00
parent a2e7de0bab
commit dae357dd6b
4 changed files with 173 additions and 0 deletions

View File

@ -1219,6 +1219,34 @@ If success, 200.
}
```
### Notification endpoints
#### GET /api/notifications
Get notifications
Input:
- `Authentication` in header: the api key
- page in url: the page number, starts at 0
Output:
List of notification, each notification has:
- id
- message: the message in html
- read: whether the user has read the notification
- created_at: when the notification is created
#### POST /api/notifications/:notification_id
Mark a notification as read
Input:
- `Authentication` in header: the api key
- notification_id in url: the page number, starts at 0
Output:
200 if success
### Misc endpoints
#### POST /api/apple/process_payment

View File

@ -8,4 +8,5 @@ from .views import (
alias,
apple,
mailbox,
notification,
)

View File

@ -0,0 +1,81 @@
from time import sleep
from flask import g
from flask import jsonify
from flask import request
from flask_cors import cross_origin
from app.api.base import api_bp, require_api_auth
from app.config import PAGE_LIMIT
from app.extensions import db
from app.models import Notification
@api_bp.route("/notifications", methods=["GET"])
@cross_origin()
@require_api_auth
def get_notifications():
"""
Get notifications
Input:
- page: in url. Starts at 0
Output: list of notifications. Each notification has the following field:
- id
- message
- read
- created_at
"""
user = g.user
try:
page = int(request.args.get("page"))
except (ValueError, TypeError):
return jsonify(error="page must be provided in request query"), 400
notifications = (
Notification.query.filter_by(user_id=user.id)
.order_by(Notification.read, Notification.created_at.desc())
.limit(PAGE_LIMIT)
.offset(page * PAGE_LIMIT)
.all()
)
return (
jsonify(
[
{
"id": notification.id,
"message": notification.message,
"read": notification.read,
"created_at": notification.created_at.humanize(),
}
for notification in notifications
]
),
200,
)
@api_bp.route("/notifications/<notification_id>/read", methods=["POST"])
@cross_origin()
@require_api_auth
def mark_as_read(notification_id):
"""
Mark a notification as read
Input:
notification_id: in url
Output:
200 if updated successfully
"""
user = g.user
notification = Notification.get(notification_id)
if not notification or notification.user_id != user.id:
return jsonify(error="Forbidden"), 403
notification.read = True
db.session.commit()
return jsonify(done=True), 200

View File

@ -0,0 +1,63 @@
from flask import url_for
from app.extensions import db
from app.models import User, ApiKey, Notification
def test_get_notifications(flask_client):
user = User.create(
email="a@b.c", password="password", name="Test User", activated=True
)
db.session.commit()
# create api_key
api_key = ApiKey.create(user.id, "for test")
db.session.commit()
# create some notifications
Notification.create(user_id=user.id, message="Test message 1")
Notification.create(user_id=user.id, message="Test message 2")
db.session.commit()
r = flask_client.get(
url_for("api.get_notifications", page=0),
headers={"Authentication": api_key.code},
)
assert r.status_code == 200
assert len(r.json) == 2
for n in r.json:
assert n["id"] > 0
assert n["message"]
assert n["read"] is False
assert n["created_at"]
# no more post at the next page
r = flask_client.get(
url_for("api.get_notifications", page=1),
headers={"Authentication": api_key.code},
)
assert len(r.json) == 0
def test_mark_notification_as_read(flask_client):
user = User.create(
email="a@b.c", password="password", name="Test User", activated=True
)
db.session.commit()
# create api_key
api_key = ApiKey.create(user.id, "for test")
db.session.commit()
Notification.create(id=1, user_id=user.id, message="Test message 1")
db.session.commit()
r = flask_client.post(
url_for("api.mark_as_read", notification_id=1),
headers={"Authentication": api_key.code},
)
assert r.status_code == 200
notification = Notification.get(1)
assert notification.read