1
0
mirror of https://github.com/bigchaindb/bigchaindb.git synced 2024-06-23 17:56:41 +02:00

outputs endpoint with unspent filter parameter

This commit is contained in:
Scott Sadler 2017-01-19 15:49:30 +01:00
parent 4bb64fa0b8
commit 897ffe81bc
7 changed files with 114 additions and 57 deletions

View File

@ -424,11 +424,17 @@ class Bigchain(object):
:obj:`list` of TransactionLink: list of ``txid`` s and ``output`` s
pointing to another transaction's condition
"""
owned = []
for tx_link in self.get_outputs(owner):
if not self.get_spent(tx_link.txid, tx_link.output):
owned.append(tx_link)
return owned
return self.get_outputs_filtered(owner, include_spent=False)
def get_outputs_filtered(self, owner, include_spent=True):
"""
Get a list of output links filtered on some criteria
"""
outputs = self.get_outputs(owner)
if not include_spent:
outputs = [o for o in outputs
if not self.get_spent(o.txid, o.output)]
return outputs
def get_transactions_filtered(self, asset_id, operation=None):
"""

View File

@ -5,7 +5,7 @@ from bigchaindb.web.views import (
info,
statuses,
transactions as tx,
unspents,
outputs,
votes,
)
@ -30,7 +30,7 @@ ROUTES_API_V1 = [
r('statuses/', statuses.StatusApi),
r('transactions/<string:tx_id>', tx.TransactionApi),
r('transactions', tx.TransactionListApi),
r('unspents/', unspents.UnspentListApi),
r('outputs/', outputs.OutputListApi),
r('votes/', votes.VotesApi),
]

View File

@ -0,0 +1,28 @@
from flask import current_app
from flask_restful import reqparse, Resource
from bigchaindb.web.views import parameters
class OutputListApi(Resource):
def get(self):
"""API endpoint to retrieve a list of links to transaction
outputs.
Returns:
A :obj:`list` of :cls:`str` of links to outputs.
"""
parser = reqparse.RequestParser()
parser.add_argument('public_key', type=parameters.valid_ed25519,
required=True)
parser.add_argument('unspent', type=parameters.valid_bool)
args = parser.parse_args()
pool = current_app.config['bigchain_pool']
include_spent = not args['unspent']
with pool() as bigchain:
outputs = bigchain.get_outputs_filtered(args['public_key'],
include_spent)
# NOTE: We pass '..' as a path to create a valid relative URI
return [u.to_uri('..') for u in outputs]

View File

@ -1,23 +0,0 @@
from flask import current_app
from flask_restful import reqparse, Resource
class UnspentListApi(Resource):
def get(self):
"""API endpoint to retrieve a list of links to transactions's
conditions that have not been used in any previous transaction.
Returns:
A :obj:`list` of :cls:`str` of links to unfulfilled conditions.
"""
parser = reqparse.RequestParser()
parser.add_argument('public_key', type=str, location='args',
required=True)
args = parser.parse_args()
pool = current_app.config['bigchain_pool']
with pool() as bigchain:
unspents = bigchain.get_owned_ids(args['public_key'])
# NOTE: We pass '..' as a path to create a valid relative URI
return [u.to_uri('..') for u in unspents]

View File

@ -1159,13 +1159,34 @@ class TestMultipleInputs(object):
assert b.get_spent(unspent.id, 0) is None
def test_get_owned_ids_calls():
def test_get_owned_ids_calls_get_outputs_filtered():
from bigchaindb.core import Bigchain
with patch('bigchaindb.core.Bigchain.get_outputs_filtered') as gof:
b = Bigchain()
res = b.get_owned_ids("abc")
gof.assert_called_once_with("abc", include_spent=False)
assert res == gof()
def test_get_outputs_filtered_only_unspent():
from bigchaindb.common.transaction import TransactionLink as TL
from bigchaindb.core import Bigchain
with patch('bigchaindb.core.Bigchain.get_outputs') as get_outputs:
get_outputs.return_value = [TL('a', 1), TL('b', 2)]
with patch('bigchaindb.core.Bigchain.get_spent') as get_spent:
get_spent.side_effect = [True, False]
out = Bigchain().get_owned_ids('abc')
assert get_outputs.called_once_with('abc')
out = Bigchain().get_outputs_filtered('abc', include_spent=False)
get_outputs.assert_called_once_with('abc')
assert out == [TL('b', 2)]
def test_get_outputs_filtered():
from bigchaindb.common.transaction import TransactionLink as TL
from bigchaindb.core import Bigchain
with patch('bigchaindb.core.Bigchain.get_outputs') as get_outputs:
get_outputs.return_value = [TL('a', 1), TL('b', 2)]
with patch('bigchaindb.core.Bigchain.get_spent') as get_spent:
out = Bigchain().get_outputs_filtered('abc')
get_outputs.assert_called_once_with('abc')
get_spent.assert_not_called()
assert out == get_outputs.return_value

49
tests/web/test_outputs.py Normal file
View File

@ -0,0 +1,49 @@
import pytest
from unittest.mock import MagicMock, patch
pytestmark = [pytest.mark.bdb, pytest.mark.usefixtures('inputs')]
UNSPENTS_ENDPOINT = '/api/v1/outputs/'
def test_get_outputs_endpoint(client, user_pk):
m = MagicMock()
m.to_uri.side_effect = lambda s: s
with patch('bigchaindb.core.Bigchain.get_outputs_filtered') as gof:
gof.return_value = [m, m]
res = client.get(UNSPENTS_ENDPOINT + '?public_key={}'.format(user_pk))
assert res.json == ["..", ".."]
assert res.status_code == 200
gof.assert_called_once_with(user_pk, True)
def test_get_outputs_endpoint_unspent(client, user_pk):
m = MagicMock()
m.to_uri.side_effect = lambda s: s
with patch('bigchaindb.core.Bigchain.get_outputs_filtered') as gof:
gof.return_value = [m]
params = '?unspent=true&public_key={}'.format(user_pk)
res = client.get(UNSPENTS_ENDPOINT + params)
assert res.json == [".."]
assert res.status_code == 200
gof.assert_called_once_with(user_pk, False)
def test_get_outputs_endpoint_without_public_key(client):
res = client.get(UNSPENTS_ENDPOINT)
assert res.status_code == 400
def test_get_outputs_endpoint_with_invalid_public_key(client):
expected = {'message': {'public_key': 'Invalid base58 ed25519 key'}}
res = client.get(UNSPENTS_ENDPOINT + '?public_key=abc')
assert expected == res.json
assert res.status_code == 400
def test_get_outputs_endpoint_with_invalid_unspent(client, user_pk):
expected = {'message': {'unspent': 'Boolean value must be "true" or "false" (lowercase)'}}
params = '?unspent=tru&public_key={}'.format(user_pk)
res = client.get(UNSPENTS_ENDPOINT + params)
assert expected == res.json
assert res.status_code == 400

View File

@ -1,24 +0,0 @@
import pytest
pytestmark = [pytest.mark.bdb, pytest.mark.usefixtures('inputs')]
UNSPENTS_ENDPOINT = '/api/v1/unspents/'
def test_get_unspents_endpoint(b, client, user_pk):
expected = [u.to_uri('..') for u in b.get_owned_ids(user_pk)]
res = client.get(UNSPENTS_ENDPOINT + '?public_key={}'.format(user_pk))
assert expected == res.json
assert res.status_code == 200
def test_get_unspents_endpoint_without_public_key(client):
res = client.get(UNSPENTS_ENDPOINT)
assert res.status_code == 400
def test_get_unspents_endpoint_with_unused_public_key(client):
expected = []
res = client.get(UNSPENTS_ENDPOINT + '?public_key=abc')
assert expected == res.json
assert res.status_code == 200