server/tags: add tag deleting

This commit is contained in:
rr- 2016-04-16 17:03:28 +02:00
parent e4239a199c
commit 37a86816af
7 changed files with 99 additions and 13 deletions

36
API.md
View File

@ -17,12 +17,12 @@
- [Creating tag](#creating-tag)
- [Updating tag](#updating-tag)
- [Getting tag](#getting-tag)
- [Removing tag](#removing-tag)
- [Deleting tag](#deleting-tag)
- [Listing users](#listing-users)
- [Creating user](#creating-user)
- [Updating user](#updating-user)
- [Getting user](#getting-user)
- [Removing user](#removing-user)
- [Deleting user](#deleting-user)
- [Password reset - step 1: mail request](#password-reset---step-2-confirmation)
- [Password reset - step 2: confirmation](#password-reset---step-2-confirmation)
@ -183,8 +183,26 @@ Not yet implemented.
Not yet implemented.
## Removing tag
Not yet implemented.
## Deleting tag
- **Request**
`DELETE /tag/<name>`
- **Output**
```json5
{}
```
- **Errors**
- the tag does not exist
- the tag is used by some posts
- privileges are too low
- **Description**
Deletes existing tag.
## Listing users
@ -253,6 +271,7 @@ Not yet implemented.
None.
## Creating user
- **Request**
@ -293,7 +312,6 @@ Not yet implemented.
`default_rank` in the server's configuration.
## Updating user
- **Request**
@ -345,7 +363,6 @@ Not yet implemented.
file - see [file uploads](#file-uploads) for details.
## Getting user
- **Request**
@ -370,8 +387,7 @@ Not yet implemented.
Retrieves information about an existing user.
## Removing user
## Deleting user
- **Request**
`DELETE /user/<name>`
@ -392,7 +408,6 @@ Not yet implemented.
Deletes existing user.
## Password reset - step 1: mail request
- **Request**
@ -418,7 +433,6 @@ Not yet implemented.
account.
## Password reset - step 2: confirmation
- **Request**
@ -483,6 +497,8 @@ Not yet implemented.
}
```
# Search
Search queries are built of tokens that are separated by spaces. Each token can

View File

@ -64,5 +64,16 @@ class TagDetailApi(BaseApi):
ctx.session.commit()
return {'tag': _serialize_tag(tag)}
def delete(self, ctx):
raise NotImplementedError()
def delete(self, ctx, tag_name):
tag = tags.get_by_name(ctx.session, tag_name)
if not tag:
raise tags.TagNotFoundError('Tag %r not found.' % tag_name)
if tag.post_count > 0:
raise tags.TagIsInUseError(
'Tag has some usages and cannot be deleted. ' +
'Please untag relevant posts first.')
auth.verify_privilege(ctx.user, 'tags:delete')
ctx.session.delete(tag)
ctx.session.commit()
return {}

View File

@ -0,0 +1,59 @@
import pytest
from datetime import datetime
from szurubooru import api, db, errors
from szurubooru.util import misc, tags
@pytest.fixture
def test_ctx(
session, config_injector, context_factory, tag_factory, user_factory):
config_injector({
'privileges': {
'tags:delete': 'regular_user',
},
'ranks': ['anonymous', 'regular_user'],
})
ret = misc.dotdict()
ret.session = session
ret.context_factory = context_factory
ret.user_factory = user_factory
ret.tag_factory = tag_factory
ret.api = api.TagDetailApi()
return ret
def test_removing_tags(test_ctx):
test_ctx.session.add(test_ctx.tag_factory(names=['tag']))
test_ctx.session.commit()
result = test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
'tag')
assert result == {}
assert test_ctx.session.query(db.Tag).count() == 0
def test_removing_tags_without_privileges(test_ctx):
test_ctx.session.add(test_ctx.tag_factory(names=['tag']))
test_ctx.session.commit()
with pytest.raises(errors.AuthError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='anonymous')),
'tag')
assert test_ctx.session.query(db.Tag).count() == 1
def test_removing_tags_with_usages(test_ctx):
tag = test_ctx.tag_factory(names=['tag'])
tag.post_count = 5
test_ctx.session.add(tag)
test_ctx.session.commit()
with pytest.raises(tags.TagIsInUseError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')),
'tag')
assert test_ctx.session.query(db.Tag).count() == 1
def test_removing_non_existing(test_ctx):
with pytest.raises(tags.TagNotFoundError):
test_ctx.api.delete(
test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'bad')

View File

@ -149,7 +149,6 @@ def test_mods_trying_to_become_admin(test_ctx):
def test_uploading_avatar(test_ctx, tmpdir):
config.config['data_dir'] = str(tmpdir.mkdir('data'))
config.config['data_url'] = 'http://example.com/data/'
user = test_ctx.user_factory(name='u1', rank='mod')
test_ctx.session.add(user)
empty_pixel = \

View File

@ -9,6 +9,7 @@ class TagAlreadyExistsError(errors.ValidationError): pass
class InvalidNameError(errors.ValidationError): pass
class InvalidCategoryError(errors.ValidationError): pass
class RelationError(errors.ValidationError): pass
class TagIsInUseError(errors.ValidationError): pass
def _verify_name_validity(name):
name_regex = config.config['tag_name_regex']