mirror of
https://github.com/simple-login/app.git
synced 2025-02-23 07:13:18 +08:00
Add GET /api/notifications, /api/notifications/:notification_id
This commit is contained in:
parent
a2e7de0bab
commit
dae357dd6b
4 changed files with 173 additions and 0 deletions
28
README.md
28
README.md
|
@ -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
|
||||
|
||||
|
|
|
@ -8,4 +8,5 @@ from .views import (
|
|||
alias,
|
||||
apple,
|
||||
mailbox,
|
||||
notification,
|
||||
)
|
||||
|
|
81
app/api/views/notification.py
Normal file
81
app/api/views/notification.py
Normal 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
|
63
tests/api/test_notification.py
Normal file
63
tests/api/test_notification.py
Normal 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
|
Loading…
Reference in a new issue