server/comments: add comment updating

This commit is contained in:
rr- 2016-04-24 10:13:22 +02:00
parent 612734e9ff
commit 48cb172cc8
4 changed files with 157 additions and 4 deletions

39
API.md
View file

@ -41,7 +41,7 @@
- Comments
- ~~Listing comments~~
- [Creating comment](#creating-comment)
- ~~Updating comment~~
- [Updating comment](#updating-comment)
- ~~Getting comment~~
- ~~Deleting comment~~
- ~~Rating comment~~
@ -698,7 +698,7 @@ data.
- **Errors**
- post does not exist
- the post does not exist
- comment text is empty
- privileges are too low
@ -707,6 +707,39 @@ data.
Creates a new comment under given post.
## Updating comment
- **Request**
`PUT /comment/<id>`
- **Input**
```json5
{
"text": <new-text> // mandatory
}
```
- **Output**
```json5
{
"comment": <comment>
}
```
...where `<comment>` is a [comment resource](#comment).
- **Errors**
- the comment does not exist
- new comment text is empty
- privileges are too low
- **Description**
Updates an existing comment text.
## Listing users
- **Request**
@ -1225,7 +1258,7 @@ A comment under a post.
```json5
{
"id": <comment-id>,
"id": <id>,
"post": <post>,
"user": <author>
"text": <text>,

View file

@ -1,3 +1,4 @@
import datetime
from szurubooru.api.base_api import BaseApi
from szurubooru.func import auth, comments, posts
@ -23,7 +24,23 @@ class CommentDetailApi(BaseApi):
raise NotImplementedError()
def put(self, ctx, comment_id):
raise NotImplementedError()
comment = comments.get_comment_by_id(comment_id)
if not comment:
raise comments.CommentNotFoundError(
'Comment %r not found.' % comment_id)
if ctx.user.user_id == comment.user_id:
infix = 'self'
else:
infix = 'any'
comment.last_edit_time = datetime.datetime.now()
auth.verify_privilege(ctx.user, 'comments:edit:%s' % infix)
text = ctx.get_param_as_string('text', required=True)
comments.update_comment_text(comment, text)
ctx.session.commit()
return {'comment': comments.serialize_comment(comment, ctx.user)}
def delete(self, ctx, comment_id):
raise NotImplementedError()

View file

@ -15,6 +15,12 @@ def serialize_comment(comment, authenticated_user):
'lastEditTime': comment.last_edit_time,
}
def get_comment_by_id(comment_id):
return db.session \
.query(db.Comment) \
.filter(db.Comment.comment_id == comment_id) \
.one_or_none()
def create_comment(user, post, text):
comment = db.Comment()
comment.user = user

View file

@ -0,0 +1,97 @@
import datetime
import pytest
from szurubooru import api, db, errors
from szurubooru.func import util, comments
@pytest.fixture
def test_ctx(config_injector, context_factory, user_factory, comment_factory):
config_injector({
'ranks': ['anonymous', 'regular_user', 'mod'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord', 'mod': 'King'},
'privileges': {
'comments:edit:self': 'regular_user',
'comments:edit:any': 'mod',
},
'thumbnails': {'avatar_width': 200},
})
db.session.flush()
ret = util.dotdict()
ret.context_factory = context_factory
ret.user_factory = user_factory
ret.comment_factory = comment_factory
ret.api = api.CommentDetailApi()
return ret
def test_simple_updating(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user')
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
with fake_datetime('1997-12-01'):
result = test_ctx.api.put(
test_ctx.context_factory(input={'text': 'new text'}, user=user),
comment.comment_id)
assert result['comment']['text'] == 'new text'
comment = db.session.query(db.Comment).one()
assert comment is not None
assert comment.text == 'new text'
assert comment.last_edit_time is not None
@pytest.mark.parametrize('input,expected_exception', [
({'text': None}, comments.EmptyCommentTextError),
({'text': ''}, comments.EmptyCommentTextError),
({'text': []}, comments.EmptyCommentTextError),
({'text': [None]}, errors.ValidationError),
({'text': ['']}, comments.EmptyCommentTextError),
])
def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
user = test_ctx.user_factory()
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
with pytest.raises(expected_exception):
test_ctx.api.put(
test_ctx.context_factory(input=input, user=user),
comment.comment_id)
def test_trying_to_omit_mandatory_field(test_ctx):
user = test_ctx.user_factory()
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
with pytest.raises(errors.ValidationError):
test_ctx.api.put(
test_ctx.context_factory(input={}, user=user),
comment.comment_id)
def test_trying_to_update_non_existing(test_ctx):
with pytest.raises(comments.CommentNotFoundError):
test_ctx.api.put(
test_ctx.context_factory(
input={'text': 'new text'},
user=test_ctx.user_factory(rank='regular_user')),
5)
def test_trying_to_update_someones_comment_without_privileges(test_ctx):
user = test_ctx.user_factory(rank='regular_user')
user2 = test_ctx.user_factory(rank='regular_user')
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
with pytest.raises(errors.AuthError):
test_ctx.api.put(
test_ctx.context_factory(input={'text': 'new text'}, user=user2),
comment.comment_id)
def test_updating_someones_comment_with_privileges(test_ctx):
user = test_ctx.user_factory(rank='regular_user')
user2 = test_ctx.user_factory(rank='mod')
comment = test_ctx.comment_factory(user=user)
db.session.add(comment)
db.session.commit()
try:
test_ctx.api.put(
test_ctx.context_factory(input={'text': 'new text'}, user=user2),
comment.comment_id)
except:
pytest.fail()