Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement block producer deletion by its identifier #124

Merged
merged 3 commits into from
Sep 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,31 @@ $ curl -X POST http://localhost:8000/block-producers/2/ \
| - | General execution | User with specified e-mail address does not exist. | 400 |
| - | General execution | Block producer with specified identifier does not exist. | 400 |

* `DELETE | /block-producers/{block_producer_identifier}/` - delete block producer by its identifier.

##### Request parameters

| Arguments | Type | Required | Description |
| :-----------------------: | :-----: | :------: | ----------------------------- |
| block_producer_identifier | Integer | Yes | Identifier of block producer. |

```bash
$ curl -X DELETE -H "Content-Type: application/json" \
-H "Authorization: JWT eyJ0e....eyJ1c2VyX2....sOx4S9zpC..." \
http://localhost:8000/block-producers/2/ | python -m json.tool
{
"result": "Block producer has been deleted."
}
```

##### Known errors

| Argument | Level | Error message | Status code |
| :-----------------------: | :------------------------: | ---------------------------------------------------------------------- | :---------: |
| block_producer_identifier | Input arguments validation | Block producer with specified identifier does not exist. | 400 |
| username | Input arguments validation | User has no authority to delete this block producer by its identifier. | 400 |


* `GET | /block-producers/search/?phrase=block%20producer%20usa` - search block producers by phrase.

##### Request parameters
Expand Down
25 changes: 25 additions & 0 deletions directory/block_producer/domain/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,28 @@ def do(self):
Get block producers' likes number.
"""
return self.block_producer_like.get_numbers()


class DeleteBlockProducer:
"""
Delete block producer implementation.
"""

def __init__(self, user, block_producer):
"""
Constructor.
"""
self.user = user
self.block_producer = block_producer

def do(self, user_email, block_producer_id):
"""
Delete block producer by its identifier.
"""
if not self.user.does_exist_by_email(email=user_email):
raise UserWithSpecifiedEmailAddressDoesNotExistError

if not self.block_producer.does_exist(identifier=block_producer_id):
raise BlockProducerWithSpecifiedIdentifierDoesNotExistError

return self.block_producer.delete_(identifier=block_producer_id)
7 changes: 7 additions & 0 deletions directory/block_producer/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ def get_last(cls, username):

return BlockProducerDto(**last_block_producer)

@classmethod
def delete_(cls, identifier):
"""
Delete block producer by its identifier.
"""
cls.objects.filter(id=identifier).delete()


class BlockProducerLike(models.Model):
"""
Expand Down
71 changes: 71 additions & 0 deletions directory/block_producer/tests/views/test_block_producer.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,21 @@ def setUp(self):

self.user_token = response.data.get('token')

self.second_user = User.objects.create_user(
id=2,
email='john.cap@gmail.com',
username='john.cap',
password='john.cap.1337',
)

BlockProducer.objects.create(
id=4,
user=self.second_user,
name='Remme',
website_url='https://remmebp.com',
short_description='Founded by a team of serial tech entrepreneurs in Ukraine.',
)

def test_get_block_producer(self):
"""
Case: get block producer.
Expand Down Expand Up @@ -179,6 +194,62 @@ def test_update_block_producer_by_non_exiting_identifier(self):
assert expected_result == response.json()
assert HTTPStatus.NOT_FOUND == response.status_code

def test_delete_block_producer(self):
"""
Case: delete block producer by its identifier.
Expect: block producer deleted from the database.
"""
expected_result = {
'result': 'Block producer has been deleted.',
}

response = self.client.delete(
f'/block-producers/1/',
HTTP_AUTHORIZATION='JWT ' + self.user_token,
content_type='application/json',
)

assert expected_result == response.json()
assert HTTPStatus.OK == response.status_code

def test_delete_block_producer_by_non_exiting_identifier(self):
"""
Case: delete block producer by non-exiting identifier.
Expect: block producer with specified identifier does not exist error message.
"""
expected_result = {
'error': 'Block producer with specified identifier does not exist.',
}

non_existing_block_producer_identifier = 100500

response = self.client.delete(
f'/block-producers/{non_existing_block_producer_identifier}/',
HTTP_AUTHORIZATION='JWT ' + self.user_token,
content_type='application/json',
)

assert expected_result == response.json()
assert HTTPStatus.NOT_FOUND == response.status_code

def test_delete_block_producer_without_deletion_rights(self):
"""
Case: deleting a block producer without deletion rights.
Expect: user has no authority to delete this block producer by its identifier error message.
"""
expected_result = {
'error': 'User has no authority to delete this block producer by its identifier.',
}

response = self.client.delete(
f'/block-producers/4/',
HTTP_AUTHORIZATION='JWT ' + self.user_token,
content_type='application/json',
)

assert expected_result == response.json()
assert HTTPStatus.BAD_REQUEST == response.status_code


class TestBlockProducerCollection(TestCase):
"""
Expand Down
44 changes: 43 additions & 1 deletion directory/block_producer/views/block_producer.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
)
from block_producer.domain.objects import (
CreateBlockProducer,
DeleteBlockProducer,
GetBlockProducer,
GetBlockProducers,
GetUserLastBlockProducer,
Expand All @@ -32,7 +33,10 @@
)
from block_producer.models import BlockProducer
from services.telegram import TelegramBot
from user.domain.errors import UserWithSpecifiedEmailAddressDoesNotExistError
from user.domain.errors import (
UserHasNoAuthorityToDeleteThisBlockProducerError,
UserWithSpecifiedEmailAddressDoesNotExistError,
)
from user.models import User


Expand Down Expand Up @@ -92,6 +96,44 @@ def post(self, request, block_producer_id):

return JsonResponse({'result': 'Block producer has been updated.'}, status=HTTPStatus.OK)

@authentication_classes((JSONWebTokenAuthentication,))
def delete(self, request, block_producer_id):
"""
Delete block producer.
"""
user_email = request.user.email

try:
response = self.get(request=None, block_producer_id=block_producer_id)

json_response = json.loads(response.content)
username = json_response.get('result').get('user').get('username')

except BlockProducerWithSpecifiedIdentifierDoesNotExistError as error:
return JsonResponse({'error': error.message}, status=HTTPStatus.NOT_FOUND)

except AttributeError:
return JsonResponse(
{'error': BlockProducerWithSpecifiedIdentifierDoesNotExistError().message}, status=HTTPStatus.NOT_FOUND,
)

if username != request.user.username:
return JsonResponse(
{'error': UserHasNoAuthorityToDeleteThisBlockProducerError().message}, status=HTTPStatus.BAD_REQUEST,
)

try:
DeleteBlockProducer(user=self.user, block_producer=self.block_producer).do(
user_email=user_email, block_producer_id=block_producer_id,
)
except (
BlockProducerWithSpecifiedIdentifierDoesNotExistError,
UserWithSpecifiedEmailAddressDoesNotExistError,
) as error:
return JsonResponse({'error': error.message}, status=HTTPStatus.NOT_FOUND)

return JsonResponse({'result': 'Block producer has been deleted.'}, status=HTTPStatus.OK)


class BlockProducerCollection(APIView):
"""
Expand Down
12 changes: 12 additions & 0 deletions directory/user/domain/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,15 @@ def __init__(self):
Constructor.
"""
self.message = 'User has no authority to change password for this user by specified username.'


class UserHasNoAuthorityToDeleteThisBlockProducerError(Exception):
"""
User has no authority to delete this block producer by its identifier error.
"""

def __init__(self):
"""
Constructor.
"""
self.message = 'User has no authority to delete this block producer by its identifier.'