Skip to content

Commit

Permalink
Get Atomic Swap public key (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
anastasiia-bilova authored May 2, 2019
1 parent 079d447 commit a0c768f
Show file tree
Hide file tree
Showing 10 changed files with 311 additions and 0 deletions.
17 changes: 17 additions & 0 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
Empty file added cli/atomic_swap/__init__.py
Empty file.
56 changes: 56 additions & 0 deletions cli/atomic_swap/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
Provide implementation of the command line interface's atomic swap commands.
"""
import sys

import click
from remme import Remme

from cli.atomic_swap.forms import GetAtomicSwapPublicKeyForm
from cli.atomic_swap.service import AtomicSwap
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)
def atomic_swap_commands():
"""
Provide commands for working with atomic swap.
"""
pass


@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.
"""
arguments, errors = GetAtomicSwapPublicKeyForm().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',
})

result, errors = AtomicSwap(service=remme).get_public_key()

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

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 GetAtomicSwapPublicKeyForm(Schema):
"""
Get public key of the atomic swap form.
"""

node_url = NodeURLField(allow_none=True, required=False)
3 changes: 3 additions & 0 deletions cli/atomic_swap/help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
Provide help messages for command line interface's atomic swap commands.
"""
15 changes: 15 additions & 0 deletions cli/atomic_swap/interfaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""
Provide implementation of the atomic swap interfaces.
"""


class AtomicSwapInterface:
"""
Implements atomic swap interface.
"""

def get_public_key(self):
"""
Get public key of atomic swap.
"""
pass
40 changes: 40 additions & 0 deletions cli/atomic_swap/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
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:
"""
Implements atomic swap.
"""

def __init__(self, service):
"""
Constructor.
Arguments:
service: object to interact with Remme core API.
"""
self.service = service

def get_public_key(self):
"""
Get public key of atomic swap.
"""
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
2 changes: 2 additions & 0 deletions cli/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import click

from cli.account.cli import account_commands
from cli.atomic_swap.cli import atomic_swap_commands
from cli.node.cli import node_commands
from cli.public_key.cli import public_key_commands

Expand All @@ -19,5 +20,6 @@ def cli():


cli.add_command(account_commands)
cli.add_command(atomic_swap_commands)
cli.add_command(node_commands)
cli.add_command(public_key_commands)
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

0 comments on commit a0c768f

Please sign in to comment.