Skip to content

Commit

Permalink
Add error processing, form validation for public key, create tests
Browse files Browse the repository at this point in the history
  • Loading branch information
anastasiia-bilova committed Apr 25, 2019
1 parent 04d1ede commit 13eab98
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 57 deletions.
30 changes: 17 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,23 @@ $ remme account transfer-tokens \
}
```

### Atomic Swap

Get public key of atomic swap — ``remme atomic-swap get-public-key``:

| Arguments | Type | Required | Description |
| :-------: | :----: | :------: | ------------------------------- |
| node-url | String | No | Node URL to apply a command to. |

```bash
$ remme atomic-swap get-public-key --node-url=node-6-testnet.remme.io
{
"result": {
"public_key": "03738df3f4ac3621ba8e89413d3ff4ad036c3a0a4dbb164b695885aab6aab614ad"
}
}
```

### Node

Get node configurations — ``remme node get-configs``:
Expand Down Expand Up @@ -184,19 +201,6 @@ $ remme public-key get-list \
}
```

### Atomic Swap

Get public key of atomic swap. — ``remme atomic-swap get-public-key``:

| Arguments | Type | Required | Description |
| :-------: | :----: | :------: | --------------------------------------------------- |
| node-url | String | No | Apply the command to the specified node by its URL. |

```bash
$ remme atomic-swap get-public-key --node-url=node-genesis-testnet.remme.io
03738df3f4ac3621ba8e89413d3ff4ad036c3a0a4dbb164b695885aab6aab614ad
```

## Development

<h3 id="development-requirements">Requirements</h4>
Expand Down
37 changes: 28 additions & 9 deletions cli/atomic_swap/cli.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
"""
Provide implementation of the command line interface's atomic swap commands.
"""
import asyncio
import sys

import click
from remme import Remme

from cli.atomic_swap.forms import GetPublicKeyForm
from cli.atomic_swap.service import AtomicSwap
from cli.constants import NODE_URL_ARGUMENT_HELP_MESSAGE

loop = asyncio.get_event_loop()
from cli.constants import (
FAILED_EXIT_FROM_COMMAND_CODE,
NODE_URL_ARGUMENT_HELP_MESSAGE,
)
from cli.utils import (
default_node_url,
print_errors,
print_result,
)


@click.group('atomic-swap', chain=True)
Expand All @@ -19,19 +27,30 @@ def atomic_swap_commands():
pass


@click.option('--node-url', type=str, required=False, help=NODE_URL_ARGUMENT_HELP_MESSAGE)
@click.option('--node-url', type=str, required=False, help=NODE_URL_ARGUMENT_HELP_MESSAGE, default=default_node_url())
@atomic_swap_commands.command('get-public-key')
def get_public_key(node_url):
"""
Get public key of atomic swap.
"""
if node_url is None:
node_url = 'localhost'
arguments, errors = GetPublicKeyForm().load({
'node_url': node_url,
})

if errors:
print_errors(errors=errors)
sys.exit(FAILED_EXIT_FROM_COMMAND_CODE)

node_url = arguments.get('node_url')

remme = Remme(network_config={
'node_address': str(node_url) + ':8080',
})

public_key = loop.run_until_complete(AtomicSwap(service=remme).get())
result, errors = AtomicSwap(service=remme).get_public_key()

if errors is not None:
print_errors(errors=errors)
sys.exit(FAILED_EXIT_FROM_COMMAND_CODE)

click.echo(public_key)
print_result(result=result)
14 changes: 14 additions & 0 deletions cli/atomic_swap/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""
Provide forms for command line interface's atomic swap commands.
"""
from marshmallow import Schema

from cli.generic.forms.fields import NodeURLField


class GetPublicKeyForm(Schema):
"""
Get public key of the atomic swap form.
"""

node_url = NodeURLField(allow_none=True, required=False)
2 changes: 1 addition & 1 deletion cli/atomic_swap/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class AtomicSwapInterface:
Implements atomic swap interface.
"""

async def get(self):
def get_public_key(self):
"""
Get public key of atomic swap.
"""
Expand Down
16 changes: 14 additions & 2 deletions cli/atomic_swap/service.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
"""
Provide implementation of the atomic swap.
"""
import asyncio

from accessify import implements

from cli.atomic_swap.interfaces import AtomicSwapInterface

loop = asyncio.get_event_loop()


@implements(AtomicSwapInterface)
class AtomicSwap:
Expand All @@ -21,8 +25,16 @@ def __init__(self, service):
"""
self.service = service

async def get(self):
def get_public_key(self):
"""
Get public key of atomic swap.
"""
return await self.service.swap.get_public_key()
try:
public_key = loop.run_until_complete(self.service.swap.get_public_key())

except Exception as error:
return None, str(error)

return {
'public_key': public_key,
}, None
1 change: 1 addition & 0 deletions cli/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@

LATEST_RELEASE_NODE_IP_ADDRESS_FOR_TESTING = '165.22.75.163'
RELEASE_0_9_0_ALPHA_NODE_ADDRESS = '165.227.169.119'
NODE_27_IN_TESTNET_ADDRESS = 'node-27-testnet.remme.io'

PRIVATE_KEY_FOR_TESTING = 'b03e31d2f310305eab249133b53b5fb3270090fc1692c9b022b81c6b9bb6029b'
Empty file added tests/atomic_swap/__init__.py
Empty file.
164 changes: 164 additions & 0 deletions tests/atomic_swap/test_get_public_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
"""
Provide tests for command line interface's get public key of the atomic swap commands.
"""
import json
import re

from click.testing import CliRunner

from cli.constants import (
FAILED_EXIT_FROM_COMMAND_CODE,
NODE_27_IN_TESTNET_ADDRESS,
PASSED_EXIT_FROM_COMMAND_CODE,
PUBLIC_KEY_REGEXP,
)
from cli.entrypoint import cli
from cli.utils import dict_to_pretty_json


def test_get_public_key():
"""
Case: get the public key of atomic swap.
Expect: public key is returned.
"""
runner = CliRunner()
result = runner.invoke(cli, [
'atomic-swap',
'get-public-key',
'--node-url',
NODE_27_IN_TESTNET_ADDRESS,
])

public_key = json.loads(result.output).get('result').get('public_key')

assert PASSED_EXIT_FROM_COMMAND_CODE == result.exit_code
assert re.match(pattern=PUBLIC_KEY_REGEXP, string=public_key) is not None


def test_get_public_key_without_node_url(mocker):
"""
Case: get the public key of atomic swap without passing node URL.
Expect: public key is returned from node on localhost.
"""
public_key = '03738df3f4ac3621ba8e89413d3ff4ad036c3a0a4dbb164b695885aab6aab614ad'
mock_swap_get_public_key = mocker.patch('cli.node.service.loop.run_until_complete')
mock_swap_get_public_key.return_value = public_key

runner = CliRunner()
result = runner.invoke(cli, [
'atomic-swap',
'get-public-key',
])

expected_result = {
'result': {
'public_key': public_key,
},
}

assert PASSED_EXIT_FROM_COMMAND_CODE == result.exit_code
assert expected_result == json.loads(result.output)


def test_get_public_key_invalid_node_url():
"""
Case: get the public key of atomic swap by passing invalid node URL.
Expect: the following node URL is invalid error message.
"""
invalid_node_url = 'domainwithoutextention'

runner = CliRunner()
result = runner.invoke(cli, [
'atomic-swap',
'get-public-key',
'--node-url',
invalid_node_url,
])

expected_error = {
'errors': {
'node_url': [
f'The following node URL `{invalid_node_url}` is invalid.',
],
},
}

assert FAILED_EXIT_FROM_COMMAND_CODE == result.exit_code
assert dict_to_pretty_json(expected_error) in result.output


def test_get_public_key_node_url_with_http():
"""
Case: get the public key of atomic swap by passing node URL with explicit HTTP protocol.
Expect: the following node URL contains protocol error message.
"""
node_url_with_http_protocol = 'http://masternode.com'

runner = CliRunner()
result = runner.invoke(cli, [
'atomic-swap',
'get-public-key',
'--node-url',
node_url_with_http_protocol,
])

expected_error = {
'errors': {
'node_url': [
f'Pass the following node URL `{node_url_with_http_protocol}` without protocol (http, https, etc.).',
],
},
}

assert FAILED_EXIT_FROM_COMMAND_CODE == result.exit_code
assert dict_to_pretty_json(expected_error) in result.output


def test_get_public_key_node_url_with_https():
"""
Case: get the public key of atomic swap by passing node URL with explicit HTTPS protocol.
Expect: the following node URL contains protocol error message.
"""
node_url_with_https_protocol = 'https://masternode.com'

runner = CliRunner()
result = runner.invoke(cli, [
'atomic-swap',
'get-public-key',
'--node-url',
node_url_with_https_protocol,
])

expected_error = {
'errors': {
'node_url': [
f'Pass the following node URL `{node_url_with_https_protocol}` without protocol (http, https, etc.).',
],
},
}

assert FAILED_EXIT_FROM_COMMAND_CODE == result.exit_code
assert dict_to_pretty_json(expected_error) in result.output


def test_get_public_key_non_existing_node_url():
"""
Case: get the public key of atomic swap by passing non existing node URL.
Expect: check if node running at URL error message.
"""
non_existing_node_url = 'non-existing-node.com'

runner = CliRunner()
result = runner.invoke(cli, [
'atomic-swap',
'get-public-key',
'--node-url',
non_existing_node_url,
])

expected_error = {
'errors': f'Please check if your node running at http://{non_existing_node_url}:8080.',
}

assert FAILED_EXIT_FROM_COMMAND_CODE == result.exit_code
assert dict_to_pretty_json(expected_error) in result.output
8 changes: 4 additions & 4 deletions tests/node/test_get_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from click.testing import CliRunner

from cli.constants import (
NODE_27_IN_TESTNET_ADDRESS,
FAILED_EXIT_FROM_COMMAND_CODE,
PASSED_EXIT_FROM_COMMAND_CODE,
RELEASE_0_9_0_ALPHA_NODE_ADDRESS,
)
from cli.entrypoint import cli
from cli.utils import dict_to_pretty_json
Expand All @@ -24,14 +24,14 @@ def test_get_node_configs():
'node',
'get-configs',
'--node-url',
RELEASE_0_9_0_ALPHA_NODE_ADDRESS,
NODE_27_IN_TESTNET_ADDRESS,
])

expected_node_configurations = {
'result': {
'configurations': {
'node_address': '116829f18683f6c30146559c9cb8d5d302545019ff00f2ab72500df99bceb7b81a1dad',
'node_public_key': '0350e9cf23966ad404dc56438fd01ec11a913446cfd7c4fb8d95586a58718431e7',
'node_address': '116829d8293c29cbced8aa4dba6ed29d979c2af6784d8aa9b4120d6c141c0153da7733',
'node_public_key': '03d4613540ce29cd1f5f28ea9169a5cb5853bd53dede635903af9383bc9ffaf079',
},
},
}
Expand Down
28 changes: 0 additions & 28 deletions tests/test_atomic_swap.py

This file was deleted.

0 comments on commit 13eab98

Please sign in to comment.