-
Notifications
You must be signed in to change notification settings - Fork 0
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
Get list of the public keys by account address on which these keys depend #16
Changes from 10 commits
756d8f1
e41fea5
45c80fd
67514d1
40b7c70
099b556
3cf9c52
1ac5d8e
375919d
73d5a43
3a6a41e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
* [Configuration file](#configuration-file) | ||
* [Service](#service) | ||
* [Account](#account) | ||
* [Public key](#public-key) | ||
* [Development](#development) | ||
* [Requirements](#development-requirements) | ||
* [Docker](#docker) | ||
|
@@ -139,6 +140,26 @@ $ remme account transfer-tokens \ | |
} | ||
``` | ||
|
||
### Public key | ||
|
||
Get list of the public keys by account address — ``remme public-key get-list``: | ||
|
||
| Arguments | Type | Required | Description | | ||
| :-------: | :----: | :------: | ------------------------------------------ | | ||
| address | String | Yes | Address to get list of the public keys by. | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apply the comment above to the argument description. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dmytrostriletskyi, done. |
||
| node-url | String | No | Node URL to apply a command to. | | ||
|
||
```bash | ||
$ remme public-key get-list \ | ||
--address=1120076ecf036e857f42129b58303bcf1e03723764a1702cbe98529802aad8514ee3cf \ | ||
--node-url=node-genesis-testnet.remme.io | ||
[ | ||
"a23be14785e7b073b50e24f72e086675289795b969a895a7f02202404086946e8ddc5b", | ||
"a23be17265e8393dd9ae7a46f1be662f86130c434fd54576a7d92b678e5c30de4f677f", | ||
... | ||
] | ||
``` | ||
|
||
## Development | ||
|
||
<h3 id="development-requirements">Requirements</h4> | ||
|
@@ -174,7 +195,7 @@ $ docker exec -it remme-core-cli bash | |
|
||
And now being in the container, you can develop the project. For instance, run tests and linters: | ||
|
||
```bash | ||
```bashpytest -vv tests/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Revert this change, please. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dmytrostriletskyi, done. |
||
$ pytest -vv tests/ | ||
$ flake8 cli && flake8 tests/ | ||
``` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
""" | ||
Provide implementation of the command line interface's public key commands. | ||
""" | ||
import asyncio | ||
import sys | ||
|
||
import click | ||
from remme import Remme | ||
|
||
from cli.constants import ( | ||
FAILED_EXIT_FROM_COMMAND_CODE, | ||
NODE_URL_ARGUMENT_HELP_MESSAGE, | ||
) | ||
from cli.public_key.forms import GetPublicKeysForm | ||
from cli.public_key.help import ADDRESS_ARGUMENT_HELP_MESSAGE | ||
from cli.public_key.service import PublicKey | ||
from cli.utils import ( | ||
default_node_url, | ||
print_errors, | ||
print_result, | ||
) | ||
|
||
loop = asyncio.get_event_loop() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You do not need it anymore here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dmytrostriletskyi, done. |
||
|
||
|
||
@click.group('public-key', chain=True) | ||
def public_key_commands(): | ||
""" | ||
Provide commands for working with public key. | ||
""" | ||
pass | ||
|
||
|
||
@click.option('--address', type=str, required=True, help=ADDRESS_ARGUMENT_HELP_MESSAGE) | ||
@click.option('--node-url', type=str, required=False, help=NODE_URL_ARGUMENT_HELP_MESSAGE, default=default_node_url()) | ||
@public_key_commands.command('get-list') | ||
def get_public_keys(address, node_url): | ||
""" | ||
Get list of the public keys by account address. | ||
""" | ||
arguments, errors = GetPublicKeysForm().load({ | ||
'address': address, | ||
'node_url': node_url, | ||
}) | ||
|
||
if errors: | ||
print_errors(errors) | ||
sys.exit(FAILED_EXIT_FROM_COMMAND_CODE) | ||
|
||
address = arguments.get('address') | ||
node_url = arguments.get('node_url') | ||
|
||
remme = Remme(network_config={'node_address': str(node_url) + ':8080'}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Follow this style, please. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dmytrostriletskyi, done. |
||
|
||
result, errors = PublicKey(service=remme).get_list(address=address) | ||
|
||
if errors is not None: | ||
print_errors(errors=errors) | ||
sys.exit(FAILED_EXIT_FROM_COMMAND_CODE) | ||
|
||
print_result(result=result) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
""" | ||
Provide forms for command line interface's account commands. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dmytrostriletskyi, done. |
||
""" | ||
from marshmallow import Schema | ||
|
||
from cli.generic.forms.fields import ( | ||
AccountAddressField, | ||
NodeURLField, | ||
) | ||
|
||
|
||
class GetPublicKeysForm(Schema): | ||
""" | ||
Get list of the public keys of the public key form. | ||
""" | ||
|
||
address = AccountAddressField(required=True) | ||
node_url = NodeURLField(allow_none=True, required=False) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
""" | ||
Provide help messages for command line interface's public key commands. | ||
""" | ||
ADDRESS_ARGUMENT_HELP_MESSAGE = 'Account address to get list of the public keys by.' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
""" | ||
Provide implementation of the public key interfaces. | ||
""" | ||
|
||
|
||
class PublicKeyInterface: | ||
""" | ||
Implements public key interface. | ||
""" | ||
|
||
def get_list(self, address): | ||
""" | ||
Get list of the public keys by account address. | ||
""" | ||
pass |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
""" | ||
Provide implementation of the public key. | ||
""" | ||
import asyncio | ||
|
||
from accessify import implements | ||
|
||
from cli.public_key.interfaces import PublicKeyInterface | ||
|
||
loop = asyncio.get_event_loop() | ||
|
||
|
||
@implements(PublicKeyInterface) | ||
class PublicKey: | ||
""" | ||
Implements public key. | ||
""" | ||
|
||
def __init__(self, service): | ||
""" | ||
Constructor. | ||
|
||
Arguments: | ||
service: object to interact with Remme core API. | ||
""" | ||
self.service = service | ||
|
||
def get_list(self, address): | ||
""" | ||
Get list of the public keys by account address. | ||
""" | ||
public_keys = loop.run_until_complete(self.service.public_key_storage.get_account_public_keys(address=address)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remember to handle There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dmytrostriletskyi, done. |
||
|
||
return { | ||
'public_keys': public_keys, | ||
}, None |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
""" | ||
Provide tests for command line interface's public key get public keys commands. | ||
""" | ||
import json | ||
import re | ||
|
||
from click.testing import CliRunner | ||
|
||
from cli.constants import ( | ||
ADDRESS_REGEXP, | ||
FAILED_EXIT_FROM_COMMAND_CODE, | ||
NODE_IP_ADDRESS_FOR_TESTING, | ||
PASSED_EXIT_FROM_COMMAND_CODE, | ||
) | ||
from cli.entrypoint import cli | ||
from cli.utils import dict_to_pretty_json | ||
|
||
ADDRESS_PRESENTED_ON_THE_TEST_NODE = '1120076ecf036e857f42129b58303bcf1e03723764a1702cbe98529802aad8514ee3cf' | ||
|
||
|
||
def test_get_public_keys(): | ||
""" | ||
Case: get a list of the public keys by account address. | ||
Expect: list of public keys, each public key matched regexp checking. | ||
""" | ||
runner = CliRunner() | ||
result = runner.invoke(cli, [ | ||
'public-key', | ||
'get-list', | ||
'--address', | ||
ADDRESS_PRESENTED_ON_THE_TEST_NODE, | ||
'--node-url', | ||
NODE_IP_ADDRESS_FOR_TESTING, | ||
]) | ||
|
||
public_keys = json.loads(result.output).get('result').get('public_keys') | ||
|
||
assert PASSED_EXIT_FROM_COMMAND_CODE == result.exit_code | ||
|
||
for public_key in public_keys: | ||
assert re.match(pattern=ADDRESS_REGEXP, string=public_key) is not None | ||
|
||
|
||
def test_get_public_keys_invalid_address(): | ||
""" | ||
Case: get a list of the public keys by invalid address. | ||
Expect: the following address is not valid error message. | ||
""" | ||
invalid_address = '1120076ecf036e857f42129b58303bcf1e03723764a1702cbe98529802aad8514ee3zz' | ||
|
||
runner = CliRunner() | ||
result = runner.invoke(cli, [ | ||
'public-key', 'get-list', '--address', invalid_address, '--node-url', NODE_IP_ADDRESS_FOR_TESTING, | ||
]) | ||
|
||
expected_error = { | ||
'errors': { | ||
'address': [ | ||
f'The following address `{invalid_address}` 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_keys_without_node_url(mocker): | ||
""" | ||
Case: get a list of the public keys by address without passing node URL. | ||
Expect: list of public keys is returned from node on localhost. | ||
""" | ||
list_of_public_keys = [ | ||
'a23be14785e7b073b50e24f72e086675289795b969a895a7f02202404086946e8ddc5b', | ||
'a23be17265e8393dd9ae7a46f1be662f86130c434fd54576a7d92b678e5c30de4f677f', | ||
] | ||
|
||
mock_public_key_get_public_keys = mocker.patch('cli.public_key.service.loop.run_until_complete') | ||
mock_public_key_get_public_keys.return_value = list_of_public_keys | ||
|
||
runner = CliRunner() | ||
result = runner.invoke(cli, ['public-key', 'get-list', '--address', ADDRESS_PRESENTED_ON_THE_TEST_NODE]) | ||
|
||
expected_result = { | ||
'result': { | ||
'public_keys': list_of_public_keys, | ||
}, | ||
} | ||
|
||
assert PASSED_EXIT_FROM_COMMAND_CODE == result.exit_code | ||
assert expected_result == json.loads(result.output) | ||
|
||
|
||
def test_get_public_keys_invalid_node_url(): | ||
""" | ||
Case: get a list of the public keys by passing invalid node URL. | ||
Expect: the following node URL is invalid error message. | ||
""" | ||
invalid_node_url = 'domainwithoutextention' | ||
|
||
runner = CliRunner() | ||
result = runner.invoke(cli, [ | ||
'public-key', | ||
'get-list', | ||
'--address', | ||
ADDRESS_PRESENTED_ON_THE_TEST_NODE, | ||
'--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_keys_node_url_with_http(): | ||
""" | ||
Case: get a list of the public keys 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, [ | ||
'public-key', | ||
'get-list', | ||
'--address', | ||
ADDRESS_PRESENTED_ON_THE_TEST_NODE, | ||
'--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_keys_node_url_with_https(): | ||
""" | ||
Case: get a list of the public keys 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, [ | ||
'public-key', | ||
'get-list', | ||
'--address', | ||
ADDRESS_PRESENTED_ON_THE_TEST_NODE, | ||
'--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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get list of the public keys ...
>Get a list of the addresses of the public keys...
.Apply the same to the code and tests documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dmytrostriletskyi, done.