Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: bigchaindb/js-bigchaindb-driver
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 9a73fc147a101451a53e40ac9c4652449776db01
Choose a base ref
..
head repository: bigchaindb/js-bigchaindb-driver
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5c92661cc66c9f91d84df301a614bc8738037210
Choose a head ref
30 changes: 17 additions & 13 deletions src/connection/index.js
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ export default class Connection {
'statuses': 'statuses',
'transactions': 'transactions',
'transactionsDetail': 'transactions/%(transactionId)s',
'searchAssets': 'assets',
'assets': 'assets',
'votes': 'votes'
}[endpoints]
}
@@ -78,17 +78,21 @@ export default class Connection {

/**
* @public
* @param public_key
* @param unspent
* @param publicKey
* @param spent
* @param onlyJsonResponse
*/
// TODO: Use camel case for parameters
listOutputs({ public_key, unspent }, onlyJsonResponse = true) {
listOutputs(publicKey, spent, onlyJsonResponse = true) {
const query = {
public_key: publicKey
}
// NOTE: If `spent` is not defined, it must not be included in the
// query parameters.
if (spent !== undefined) {
query.spent = spent
}
return this._req(this.getApiUrls('outputs'), {
query: {
public_key,
unspent
}
query
}, onlyJsonResponse)
}

@@ -161,12 +165,12 @@ export default class Connection {
/**
* @public
*
* @param query
* @param search
*/
searchAssets(query) {
return this._req(this.getApiUrls('searchAssets'), {
searchAssets(search) {
return this._req(this.getApiUrls('assets'), {
query: {
text_search: query
search
}
})
}
2 changes: 0 additions & 2 deletions src/transaction/makeCreateTransaction.js
Original file line number Diff line number Diff line change
@@ -21,8 +21,6 @@ import makeTransaction from './makeTransaction'
* @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before
* sending it off!
*/
// TODO: `outputs` should throw or include output in array if no array was
// passed
export default function makeCreateTransaction(asset, metadata, outputs, ...issuers) {
const assetDefinition = {
'data': asset || null,
60 changes: 25 additions & 35 deletions src/transaction/makeTransferTransaction.js
Original file line number Diff line number Diff line change
@@ -2,32 +2,6 @@ import makeInputTemplate from './makeInputTemplate'
import makeTransaction from './makeTransaction'


// TODO: Can we remove `export` here somehow, but still be able to import the
// function for tests?
export function _makeTransferTransaction(
unspentTransaction,
metadata,
outputs,
...fulfilledOutputs
) {
const inputs = fulfilledOutputs.map((outputIndex) => {
const fulfilledOutput = unspentTransaction.outputs[outputIndex]
const transactionLink = {
'output': outputIndex,
'transaction_id': unspentTransaction.id,
}

return makeInputTemplate(fulfilledOutput.public_keys, transactionLink)
})

const assetLink = {
'id': unspentTransaction.operation === 'CREATE' ? unspentTransaction.id
: unspentTransaction.asset.id
}

return ['TRANSFER', assetLink, metadata, outputs, inputs]
}

/**
* @public
* Generate a `TRANSFER` transaction holding the `asset`, `metadata`, and `outputs`, that fulfills
@@ -40,20 +14,36 @@ export function _makeTransferTransaction(
* For `TRANSFER` Transactions, this should usually just be a list of
* Outputs wrapping Ed25519 Conditions generated from the public keys of
* the recipients.
* @param {...number} fulfilledOutputs Indices of the Outputs in `unspentTransaction` that this
* @param {...number} OutputIndices Indices of the Outputs in `unspentTransaction` that this
* Transaction fulfills.
* Note that the public keys listed in the fulfilled Outputs
* must be used (and in the same order) to sign the Transaction
* Note that listed public keys listed must be used (and in
* the same order) to sign the Transaction
* (`signTransaction()`).
* @returns {object} Unsigned transaction -- make sure to call signTransaction() on it before
* sending it off!
*/

// TODO:
// - Make `metadata` optional argument
// - Rename `fulfilledOutputs`, e.g. inputs
// TODO: `outputs` should throw or include output in array if no array was
// passed
export default function makeTransferTransaction(...args) {
return makeTransaction(..._makeTransferTransaction(...args))
export default function makeTransferTransaction(
unspentTransaction,
metadata,
outputs,
...outputIndices
) {
const inputs = outputIndices.map((outputIndex) => {
const fulfilledOutput = unspentTransaction.outputs[outputIndex]
const transactionLink = {
'output': outputIndex,
'transaction_id': unspentTransaction.id,
}

return makeInputTemplate(fulfilledOutput.public_keys, transactionLink)
})

const assetLink = {
'id': unspentTransaction.operation === 'CREATE' ? unspentTransaction.id
: unspentTransaction.asset.id
}

return makeTransaction('TRANSFER', assetLink, metadata, outputs, inputs)
}
79 changes: 64 additions & 15 deletions test/connection/test_connection.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import test from 'ava'
import sinon from 'sinon'
import request from '../../src/request'

import * as request from '../../src/request' // eslint-disable-line
import { Connection } from '../../src'

const API_PATH = 'http://localhost:9984/api/v1/'
@@ -15,7 +16,7 @@ test('generate API URLS', t => {
'statuses': 'statuses',
'transactions': 'transactions',
'transactionsDetail': 'transactions/%(transactionId)s',
'searchAssets': 'assets',
'assets': 'assets',
}
Object.keys(endpoints).forEach((endpointName) => {
const url = conn.getApiUrls(endpointName)
@@ -25,20 +26,21 @@ test('generate API URLS', t => {
})


// TODO: Find out how to mock `request`
test.skip('Request with custom headers', t => {
test('Request with custom headers', t => {
const testConn = new Connection(API_PATH, { hello: 'world' })
const additionalHeaders = { custom: 'headers' }
const expectedHeaders = {
hello: 'world',
custom: 'headers'
const expectedOptions = {
headers: {
hello: 'world',
custom: 'headers'
}
}

// request is read only, cannot be mocked?
// request = sinon.spy()
testConn._req(API_PATH, additionalHeaders)
sinon.spy(request, 'default')
testConn._req(API_PATH, { headers: { custom: 'headers' } })

t.truthy(request.calledWith(API_PATH, expectedHeaders))
t.truthy(request.default.calledWith(API_PATH, expectedOptions))
request.default.restore()
})


@@ -108,6 +110,53 @@ test('Get list of blocks for a transaction id', t => {
})


test('Get outputs for a public key and no spent flag', t => {
const expectedPath = 'path'
const publicKey = 'publicKey'

conn._req = sinon.spy()
conn.getApiUrls = sinon.stub().returns(expectedPath)

conn.listOutputs(publicKey)
t.truthy(conn._req.calledWith(
expectedPath,
{ query: { public_key: publicKey } }
))
})


test('Get outputs for a public key and spent=false', t => {
const expectedPath = 'path'
const publicKey = 'publicKey'
const spent = false

conn._req = sinon.spy()
conn.getApiUrls = sinon.stub().returns(expectedPath)

conn.listOutputs(publicKey, spent)
t.truthy(conn._req.calledWith(
expectedPath,
{ query: { public_key: publicKey, spent } }
))
})


test('Get outputs for a public key and spent=true', t => {
const expectedPath = 'path'
const publicKey = 'publicKey'
const spent = true

conn._req = sinon.spy()
conn.getApiUrls = sinon.stub().returns(expectedPath)

conn.listOutputs(publicKey, spent)
t.truthy(conn._req.calledWith(
expectedPath,
{ query: { public_key: publicKey, spent } }
))
})


test('Get votes for a block id', t => {
const expectedPath = 'path'
const blockId = 'abc'
@@ -123,16 +172,16 @@ test('Get votes for a block id', t => {
})


test('Get asset for a text', t => {
test('Get asset for text', t => {
const expectedPath = 'path'
const query = 'abc'
const search = 'abc'

conn._req = sinon.spy()
conn.getApiUrls = sinon.stub().returns(expectedPath)

conn.searchAssets(query)
conn.searchAssets(search)
t.truthy(conn._req.calledWith(
expectedPath,
{ query: { text_search: query } }
{ query: { search } }
))
})
14 changes: 7 additions & 7 deletions test/constants.js
Original file line number Diff line number Diff line change
@@ -2,23 +2,23 @@ import test from 'ava'
import { Transaction, Ed25519Keypair } from '../src'
// TODO: Find out if ava has something like conftest, if so put this there.

// TODO: We're adding `Math.random()` here to never create the same transaction
// twice.
export const assetMessage = { assetMessage: Math.random() }
export const metaDataMessage = { metaDataMessage: 'metaDataMessage' }
// NOTE: We cast `Math.random()` to a string, as sometimes Javascript simply
// yields a slightly different float during runtime, lol
export function asset() { return { message: `${Math.random()}` } }
export const metaData = { message: 'metaDataMessage' }

export const alice = new Ed25519Keypair()
export const aliceCondition = Transaction.makeEd25519Condition(alice.publicKey)
export const aliceOutput = Transaction.makeOutput(aliceCondition)
export const createTx = Transaction.makeCreateTransaction(
assetMessage,
metaDataMessage,
asset,
metaData,
[aliceOutput],
alice.publicKey
)
export const transferTx = Transaction.makeTransferTransaction(
createTx,
metaDataMessage,
metaData,
[aliceOutput],
0
)
Loading