diff --git a/package.json b/package.json index 0397eaf8e..c7263ef77 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "ipld-dag-pb": "^0.9.2", "is-ipfs": "^0.2.1", "isstream": "^0.1.2", + "js-base64": "^2.1.9", "lru-cache": "^4.0.2", "multiaddr": "^2.1.1", "multipart-stream": "^2.0.1", @@ -63,7 +64,7 @@ "gulp": "^3.9.1", "hapi": "^16.0.1", "interface-ipfs-core": "^0.22.0", - "ipfsd-ctl": "^0.17.0", + "@haad/ipfsd-ctl": "^0.18.0-beta.5", "pre-commit": "^1.1.3", "socket.io": "^1.7.1", "socket.io-client": "^1.7.1", @@ -115,4 +116,4 @@ "url": "https://github.com/ipfs/js-ipfs-api/issues" }, "homepage": "https://github.com/ipfs/js-ipfs-api" -} \ No newline at end of file +} diff --git a/src/api/add.js b/src/api/add.js index 1379a4296..1b41f7578 100644 --- a/src/api/add.js +++ b/src/api/add.js @@ -1,24 +1,26 @@ 'use strict' const isStream = require('isstream') -const addToDagNodesTransform = require('../add-to-dagnode-transform') const promisify = require('promisify-es6') +const DAGNodeStream = require('../dagnode-stream') module.exports = (send) => { return promisify((files, callback) => { - const good = Buffer.isBuffer(files) || + const ok = Buffer.isBuffer(files) || isStream.isReadable(files) || Array.isArray(files) - if (!good) { - callback(new Error('"files" must be a buffer, readable stream, or array of objects')) + if (!ok) { + return callback(new Error('"files" must be a buffer, readable stream, or array of objects')) } - const sendWithTransform = send.withTransform(addToDagNodesTransform) - - return sendWithTransform({ + const request = { path: 'add', files: files - }, callback) + } + + // Transform the response stream to DAGNode values + const transform = (res, callback) => DAGNodeStream.streamToValue(send, res, callback) + send.andTransform(request, transform, callback) }) } diff --git a/src/api/dht.js b/src/api/dht.js index fe42146ec..dd78e7e0e 100644 --- a/src/api/dht.js +++ b/src/api/dht.js @@ -1,6 +1,7 @@ 'use strict' const promisify = require('promisify-es6') +const streamToValue = require('../stream-to-value') module.exports = (send) => { return { @@ -19,11 +20,13 @@ module.exports = (send) => { opts = {} } - send({ + const request = { path: 'dht/findprovs', args: args, qs: opts - }, callback) + } + + send.andTransform(request, streamToValue, callback) }), get: promisify((key, opts, callback) => { if (typeof opts === 'function' && diff --git a/src/api/get.js b/src/api/get.js index fa7ba1250..9634b7235 100644 --- a/src/api/get.js +++ b/src/api/get.js @@ -1,11 +1,11 @@ 'use strict' -const tarStreamToObjects = require('../tar-stream-to-objects') -const cleanMultihash = require('../clean-multihash') const promisify = require('promisify-es6') +const cleanMultihash = require('../clean-multihash') +const TarStreamToObjects = require('../tar-stream-to-objects') module.exports = (send) => { - return promisify(function get (path, opts, callback) { + return promisify((path, opts, callback) => { if (typeof opts === 'function' && !callback) { callback = opts @@ -26,12 +26,13 @@ module.exports = (send) => { return callback(err) } - var sendWithTransform = send.withTransform(tarStreamToObjects) - - sendWithTransform({ + const request = { path: 'get', args: path, qs: opts - }, callback) + } + + // Convert the response stream to TarStream objects + send.andTransform(request, TarStreamToObjects.from, callback) }) } diff --git a/src/api/ping.js b/src/api/ping.js index 5e7c74f6f..eeaa3125a 100644 --- a/src/api/ping.js +++ b/src/api/ping.js @@ -1,18 +1,36 @@ 'use strict' const promisify = require('promisify-es6') +const streamToValue = require('../stream-to-value') module.exports = (send) => { return promisify((id, callback) => { - send({ + const request = { path: 'ping', args: id, qs: { n: 1 } - }, function (err, res) { - if (err) { - return callback(err, null) - } - callback(null, res[1]) - }) + } + + // Transform the response stream to a value: + // { Success: , Time: , Text: } + const transform = (res, callback) => { + streamToValue(res, (err, res) => { + if (err) { + return callback(err) + } + + // go-ipfs http api currently returns 3 lines for a ping. + // they're a little messed, so take the correct values from each lines. + const pingResult = { + Success: res[1].Success, + Time: res[1].Time, + Text: res[2].Text + } + + callback(null, pingResult) + }) + } + + send.andTransform(request, transform, callback) }) } diff --git a/src/api/pubsub.js b/src/api/pubsub.js new file mode 100644 index 000000000..b64e2970a --- /dev/null +++ b/src/api/pubsub.js @@ -0,0 +1,98 @@ +'use strict' + +const promisify = require('promisify-es6') +const PubsubMessageStream = require('../pubsub-message-stream') +const stringlistToArray = require('../stringlist-to-array') + +/* Internal subscriptions state and functions */ +let subscriptions = {} + +const addSubscription = (topic, request) => { + subscriptions[topic] = { request: request } +} + +const removeSubscription = promisify((topic, callback) => { + if (!subscriptions[topic]) { + return callback(new Error(`Not subscribed to ${topic}`)) + } + + subscriptions[topic].request.abort() + delete subscriptions[topic] + + if (callback) { + callback(null) + } +}) + +/* Public API */ +module.exports = (send) => { + return { + subscribe: promisify((topic, options, callback) => { + const defaultOptions = { + discover: false + } + + if (typeof options === 'function') { + callback = options + options = defaultOptions + } + + if (!options) { + options = defaultOptions + } + + // If we're already subscribed, return an error + if (subscriptions[topic]) { + return callback(new Error(`Already subscribed to '${topic}'`)) + } + + // Request params + const request = { + path: 'pubsub/sub', + args: [topic], + qs: { discover: options.discover } + } + + // Start the request and transform the response stream to Pubsub messages stream + const req = send.andTransform(request, PubsubMessageStream.from, (err, stream) => { + if (err) { + return callback(err) + } + // Add a cancel method to the stream so that the subscription can be cleanly cancelled + stream.cancel = promisify((cb) => removeSubscription(topic, cb)) + // Add the request to the active subscriptions and return the stream + addSubscription(topic, req) + callback(null, stream) + }) + }), + publish: promisify((topic, data, callback) => { + const buf = Buffer.isBuffer(data) ? data : new Buffer(data) + + const request = { + path: 'pubsub/pub', + args: [topic, buf] + } + + send(request, callback) + }), + ls: promisify((callback) => { + const request = { + path: 'pubsub/ls' + } + + send.andTransform(request, stringlistToArray, callback) + }), + peers: promisify((topic, callback) => { + if (!subscriptions[topic]) { + return callback(new Error(`Not subscribed to '${topic}'`)) + } + + const request = { + path: 'pubsub/peers', + args: [topic] + } + + send.andTransform(request, stringlistToArray, callback) + }) + } +} diff --git a/src/api/refs.js b/src/api/refs.js index 318ccb59f..56958ca7f 100644 --- a/src/api/refs.js +++ b/src/api/refs.js @@ -1,6 +1,7 @@ 'use strict' const promisify = require('promisify-es6') +const streamToValue = require('../stream-to-value') module.exports = (send) => { const refs = promisify((args, opts, callback) => { @@ -8,21 +9,28 @@ module.exports = (send) => { callback = opts opts = {} } - return send({ + + const request = { path: 'refs', args: args, qs: opts - }, callback) + } + + send.andTransform(request, streamToValue, callback) }) + refs.local = promisify((opts, callback) => { if (typeof (opts) === 'function') { callback = opts opts = {} } - return send({ + + const request = { path: 'refs', qs: opts - }, callback) + } + + send.andTransform(request, streamToValue, callback) }) return refs diff --git a/src/api/util/fs-add.js b/src/api/util/fs-add.js index c78dda13a..6c63cf1ab 100644 --- a/src/api/util/fs-add.js +++ b/src/api/util/fs-add.js @@ -1,8 +1,8 @@ 'use strict' const isNode = require('detect-node') -const addToDagNodesTransform = require('./../../add-to-dagnode-transform') const promisify = require('promisify-es6') +const DAGNodeStream = require('../../dagnode-stream') module.exports = (send) => { return promisify((path, opts, callback) => { @@ -28,12 +28,14 @@ module.exports = (send) => { return callback(new Error('"path" must be a string')) } - const sendWithTransform = send.withTransform(addToDagNodesTransform) - - sendWithTransform({ + const request = { path: 'add', qs: opts, files: path - }, callback) + } + + // Transform the response stream to DAGNode values + const transform = (res, callback) => DAGNodeStream.streamToValue(send, res, callback) + send.andTransform(request, transform, callback) }) } diff --git a/src/api/util/url-add.js b/src/api/util/url-add.js index 7dc7694b2..7db525ad7 100644 --- a/src/api/util/url-add.js +++ b/src/api/util/url-add.js @@ -3,9 +3,8 @@ const promisify = require('promisify-es6') const once = require('once') const parseUrl = require('url').parse - const request = require('../../request') -const addToDagNodesTransform = require('./../../add-to-dagnode-transform') +const DAGNodeStream = require('../../dagnode-stream') module.exports = (send) => { return promisify((url, opts, callback) => { @@ -28,7 +27,6 @@ module.exports = (send) => { return callback(new Error('"url" param must be an http(s) url')) } - const sendWithTransform = send.withTransform(addToDagNodesTransform) callback = once(callback) request(parseUrl(url).protocol)(url, (res) => { @@ -37,11 +35,15 @@ module.exports = (send) => { return callback(new Error(`Failed to download with ${res.statusCode}`)) } - sendWithTransform({ + const params = { path: 'add', qs: opts, files: res - }, callback) + } + + // Transform the response stream to DAGNode values + const transform = (res, callback) => DAGNodeStream.streamToValue(send, res, callback) + send.andTransform(params, transform, callback) }).end() }) } diff --git a/src/dagnode-stream.js b/src/dagnode-stream.js new file mode 100644 index 000000000..35cb12c44 --- /dev/null +++ b/src/dagnode-stream.js @@ -0,0 +1,55 @@ +'use strict' + +const TransformStream = require('readable-stream').Transform +const streamToValue = require('./stream-to-value') +const getDagNode = require('./get-dagnode') + +/* + Transforms a stream of objects to DAGNodes and outputs them as objects. + + Usage: inputStream.pipe(DAGNodeStream({ send: send })) + + Input object format: + { + Name: '/path/to/file/foo.txt', + Hash: 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP' + } + + Output object format: + { + path: '/path/to/file/foo.txt', + hash: 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', + size: 20 + } +*/ +class DAGNodeStream extends TransformStream { + constructor (options) { + const opts = Object.assign(options || {}, { objectMode: true }) + super(opts) + this._send = opts.send + } + + static streamToValue (send, inputStream, callback) { + const outputStream = inputStream.pipe(new DAGNodeStream({ send: send })) + streamToValue(outputStream, callback) + } + + _transform (obj, enc, callback) { + getDagNode(this._send, obj.Hash, (err, node) => { + if (err) { + return callback(err) + } + + const dag = { + path: obj.Name, + hash: obj.Hash, + size: node.size + } + + this.push(dag) + callback(null) + }) + } +} + +module.exports = DAGNodeStream diff --git a/src/get-dagnode.js b/src/get-dagnode.js index 75cd0886c..d9942d99c 100644 --- a/src/get-dagnode.js +++ b/src/get-dagnode.js @@ -1,8 +1,8 @@ 'use strict' const DAGNode = require('ipld-dag-pb').DAGNode -const bl = require('bl') const parallel = require('async/parallel') +const streamToValue = require('./stream-to-value') module.exports = function (send, hash, callback) { // Retrieve the object and its data in parallel, then produce a DAGNode @@ -36,12 +36,12 @@ module.exports = function (send, hash, callback) { if (Buffer.isBuffer(stream)) { DAGNode.create(stream, object.Links, callback) } else { - stream.pipe(bl(function (err, data) { + streamToValue(stream, (err, data) => { if (err) { return callback(err) } DAGNode.create(data, object.Links, callback) - })) + }) } }) } diff --git a/src/load-commands.js b/src/load-commands.js index b69c197cb..1246ef5ef 100644 --- a/src/load-commands.js +++ b/src/load-commands.js @@ -25,6 +25,7 @@ function requireCommands () { refs: require('./api/refs'), repo: require('./api/repo'), swarm: require('./api/swarm'), + pubsub: require('./api/pubsub'), update: require('./api/update'), version: require('./api/version') } diff --git a/src/pubsub-message-stream.js b/src/pubsub-message-stream.js new file mode 100644 index 000000000..570c87b48 --- /dev/null +++ b/src/pubsub-message-stream.js @@ -0,0 +1,30 @@ +'use strict' + +const TransformStream = require('readable-stream').Transform +const PubsubMessage = require('./pubsub-message-utils') + +class PubsubMessageStream extends TransformStream { + constructor (options) { + const opts = Object.assign(options || {}, { objectMode: true }) + super(opts) + } + + static from (inputStream, callback) { + let outputStream = inputStream.pipe(new PubsubMessageStream()) + inputStream.on('end', () => outputStream.emit('end')) + callback(null, outputStream) + } + + _transform (obj, enc, callback) { + try { + const message = PubsubMessage.deserialize(obj, 'base64') + this.push(message) + } catch (e) { + // Not a valid pubsub message + // go-ipfs returns '{}' as the very first object atm, we skip that + } + callback() + } +} + +module.exports = PubsubMessageStream diff --git a/src/pubsub-message-utils.js b/src/pubsub-message-utils.js new file mode 100644 index 000000000..540165889 --- /dev/null +++ b/src/pubsub-message-utils.js @@ -0,0 +1,47 @@ +'use strict' + +const Base58 = require('bs58') +const Base64 = require('js-base64').Base64 +const PubsubMessage = require('./pubsub-message') + +class PubsubMessageUtils { + static create (senderId, data, seqNo, topics) { + return new PubsubMessage(senderId, data, seqNo, topics) + } + + static deserialize (data, enc = 'json') { + enc = enc ? enc.toLowerCase() : null + + if (enc === 'json') { + return PubsubMessageUtils._deserializeFromJson(data) + } else if (enc === 'base64') { + return PubsubMessageUtils._deserializeFromBase64(data) + } + + throw new Error(`Unsupported encoding: '${enc}'`) + } + + static _deserializeFromJson (data) { + const json = JSON.parse(data) + return PubsubMessageUtils._deserializeFromBase64(json) + } + + static _deserializeFromBase64 (obj) { + if (!PubsubMessageUtils._isPubsubMessage(obj)) { + throw new Error(`Not a pubsub message`) + } + + const senderId = Base58.encode(obj.from) + const payload = Base64.decode(obj.data) + const seqno = Base64.decode(obj.seqno) + const topics = obj.topicIDs + + return PubsubMessageUtils.create(senderId, payload, seqno, topics) + } + + static _isPubsubMessage (obj) { + return obj && obj.from && obj.seqno && obj.data && obj.topicIDs + } +} + +module.exports = PubsubMessageUtils diff --git a/src/pubsub-message.js b/src/pubsub-message.js new file mode 100644 index 000000000..0d209bfa4 --- /dev/null +++ b/src/pubsub-message.js @@ -0,0 +1,28 @@ +'use strict' + +class PubsubMessage { + constructor (senderId, data, seqNo, topics) { + this._senderId = senderId + this._data = data + this._seqNo = seqNo + this._topics = topics + } + + get from () { + return this._senderId + } + + get data () { + return this._data + } + + get seqno () { + return this._seqNo + } + + get topicIDs () { + return this._topics + } +} + +module.exports = PubsubMessage diff --git a/src/request-api.js b/src/request-api.js index 5eb150269..b980bc4ac 100644 --- a/src/request-api.js +++ b/src/request-api.js @@ -1,50 +1,28 @@ 'use strict' const Qs = require('qs') -const ndjson = require('ndjson') const isNode = require('detect-node') +const ndjson = require('ndjson') const once = require('once') -const concat = require('concat-stream') - const getFilesStream = require('./get-files-stream') +const streamToValue = require('./stream-to-value') +const streamToJsonValue = require('./stream-to-json-value') const request = require('./request') // -- Internal -function parseChunkedJson (res, cb) { - res - .pipe(ndjson.parse()) - .once('error', cb) - .pipe(concat((data) => cb(null, data))) -} - -function parseRaw (res, cb) { - res - .once('error', cb) - .pipe(concat((data) => cb(null, data))) -} - -function parseJson (res, cb) { - res - .once('error', cb) - .pipe(concat((data) => { - if (!data || data.length === 0) { - return cb() - } - - if (Buffer.isBuffer(data)) { - data = data.toString() - } - - let res - try { - res = JSON.parse(data) - } catch (err) { - return cb(err) - } - - cb(null, res) - })) +function parseError (res, cb) { + const error = new Error(`Server responded with ${res.statusCode}`) + streamToJsonValue(res, (err, payload) => { + if (err) { + return cb(err) + } + if (payload) { + error.code = payload.Code + error.message = payload.Message || payload.toString() + } + cb(error) + }) } function onRes (buffer, cb) { @@ -55,33 +33,26 @@ function onRes (buffer, cb) { res.headers['content-type'].indexOf('application/json') === 0 if (res.statusCode >= 400 || !res.statusCode) { - const error = new Error(`Server responded with ${res.statusCode}`) - - parseJson(res, (err, payload) => { - if (err) { - return cb(err) - } - if (payload) { - error.code = payload.Code - error.message = payload.Message || payload.toString() - } - cb(error) - }) + return parseError(res, cb) } + // Return the response stream directly if (stream && !buffer) { return cb(null, res) } + // Return a stream of JSON objects if (chunkedObjects && isJson) { - return parseChunkedJson(res, cb) + return cb(null, res.pipe(ndjson.parse())) } + // Return a JSON object if (isJson) { - return parseJson(res, cb) + return streamToJsonValue(res, cb) } - parseRaw(res, cb) + // Return a value + return streamToValue(res, cb) } } @@ -163,7 +134,7 @@ function requestAPI (config, options, callback) { // // -- Module Interface -exports = module.exports = function getRequestAPI (config) { +exports = module.exports = (config) => { /* * options: { * path: // API path (like /add or /config) - type: string @@ -173,7 +144,7 @@ exports = module.exports = function getRequestAPI (config) { * buffer: // buffer the request before sending it - type: bool * } */ - const send = function (options, callback) { + const send = (options, callback) => { if (typeof options !== 'object') { return callback(new Error('no options were passed')) } @@ -181,25 +152,13 @@ exports = module.exports = function getRequestAPI (config) { return requestAPI(config, options, callback) } - // Wraps the 'send' function such that an asynchronous - // transform may be applied to its result before - // passing it on to either its callback or promise. - send.withTransform = function (transform) { - return function (options, callback) { - if (typeof options !== 'object') { - return callback(new Error('no options were passed')) + send.andTransform = (options, transform, callback) => { + return send(options, (err, res) => { + if (err) { + return callback(err) } - - send(options, wrap(callback)) - - function wrap (func) { - if (func) { - return function (err, res) { - transform(err, res, send, func) - } - } - } - } + transform(res, callback) + }) } return send diff --git a/src/stream-to-json-value.js b/src/stream-to-json-value.js new file mode 100644 index 000000000..e42de2fc6 --- /dev/null +++ b/src/stream-to-json-value.js @@ -0,0 +1,34 @@ +'use strict' + +const streamToValue = require('./stream-to-value') + +/* + Converts a stream to a single JSON value +*/ +function streamToJsonValue (res, cb) { + streamToValue(res, (err, data) => { + if (err) { + return cb(err) + } + + if (!data || data.length === 0) { + return cb() + } + + // TODO: check if needed, afaik JSON.parse can parse Buffers + if (Buffer.isBuffer(data)) { + data = data.toString() + } + + let res + try { + res = JSON.parse(data) + } catch (err) { + return cb(err) + } + + cb(null, res) + }) +} + +module.exports = streamToJsonValue diff --git a/src/stream-to-value.js b/src/stream-to-value.js new file mode 100644 index 000000000..66e8e2ad6 --- /dev/null +++ b/src/stream-to-value.js @@ -0,0 +1,12 @@ +'use strict' + +const concat = require('concat-stream') + +/* + Concatenate a stream to a single value. +*/ +function streamToValue (res, callback) { + res.pipe(concat((data) => callback(null, data))) +} + +module.exports = streamToValue diff --git a/src/stringlist-to-array.js b/src/stringlist-to-array.js new file mode 100644 index 000000000..df28ee6df --- /dev/null +++ b/src/stringlist-to-array.js @@ -0,0 +1,9 @@ +'use strict' + +// Converts a go-ipfs "stringList" to an array +// { Strings: ['A', 'B'] } --> ['A', 'B'] +function stringlistToArray (res, cb) { + cb(null, res.Strings || []) +} + +module.exports = stringlistToArray diff --git a/src/tar-stream-to-objects.js b/src/tar-stream-to-objects.js index acab14658..aabea2745 100644 --- a/src/tar-stream-to-objects.js +++ b/src/tar-stream-to-objects.js @@ -1,38 +1,45 @@ 'use strict' const tar = require('tar-stream') -const Readable = require('readable-stream') +const ReadableStream = require('readable-stream').Readable +/* + Transform tar stream into a stream of objects: -// transform tar stream into readable stream of -// { path: 'string', content: Readable } -module.exports = (err, res, send, done) => { - if (err) { - return done(err) + Output format: + { path: 'string', content: Readable } +*/ +class TarStreamToObjects extends ReadableStream { + constructor (options) { + const opts = Object.assign(options || {}, { objectMode: true }) + super(opts) } - const objStream = new Readable({ objectMode: true }) - objStream._read = function noop () {} - - res - .pipe(tar.extract()) - .on('entry', (header, stream, next) => { - stream.on('end', next) - - if (header.type !== 'directory') { - objStream.push({ - path: header.name, - content: stream - }) - } else { - objStream.push({ - path: header.name - }) - stream.resume() - } - }) - .on('finish', () => { - objStream.push(null) - }) - - done(null, objStream) + static from (inputStream, callback) { + let outputStream = new TarStreamToObjects() + + inputStream + .pipe(tar.extract()) + .on('entry', (header, stream, next) => { + stream.on('end', next) + + if (header.type !== 'directory') { + outputStream.push({ + path: header.name, + content: stream + }) + } else { + outputStream.push({ + path: header.name + }) + stream.resume() + } + }) + .on('finish', () => outputStream.push(null)) + + callback(null, outputStream) + } + + _read () {} } + +module.exports = TarStreamToObjects diff --git a/test/factory/daemon-spawner.js b/test/factory/daemon-spawner.js index 86a2d808b..ca2ee4892 100644 --- a/test/factory/daemon-spawner.js +++ b/test/factory/daemon-spawner.js @@ -1,7 +1,7 @@ 'use strict' // const defaultConfig = require('./default-config.json') -const ipfsd = require('ipfsd-ctl') +const ipfsd = require('@haad/ipfsd-ctl') const series = require('async/series') const eachSeries = require('async/eachSeries') const once = require('once') @@ -73,17 +73,19 @@ function spawnEphemeralNode (callback) { (cb) => { const configValues = { Bootstrap: [], - Discovery: {}, - 'HTTPHeaders.Access-Control-Allow-Origin': ['*'], - 'HTTPHeaders.Access-Control-Allow-Credentials': 'true', - 'HTTPHeaders.Access-Control-Allow-Methods': ['PUT', 'POST', 'GET'] + // Discovery: {}, + API: { + 'HTTPHeaders.Access-Control-Allow-Origin': ['*'], + 'HTTPHeaders.Access-Control-Allow-Credentials': 'true', + 'HTTPHeaders.Access-Control-Allow-Methods': ['PUT', 'POST', 'GET'] + } } eachSeries(Object.keys(configValues), (configKey, cb) => { - node.setConfig(`API.${configKey}`, JSON.stringify(configValues[configKey]), cb) + node.setConfig(`${configKey}`, JSON.stringify(configValues[configKey]), cb) }, cb) }, - (cb) => node.startDaemon(cb) + (cb) => node.startDaemon(['--enable-pubsub-experiment'], cb) ], (err) => { if (err) { return callback(err) diff --git a/test/interface-ipfs-core/ping.spec.js b/test/interface-ipfs-core/ping.spec.js index bf4e2e606..a7dbb4a28 100644 --- a/test/interface-ipfs-core/ping.spec.js +++ b/test/interface-ipfs-core/ping.spec.js @@ -12,6 +12,10 @@ describe('.ping', () => { apiClients.a.ping(id.id, (err, res) => { expect(err).to.not.exist expect(res).to.have.a.property('Success') + expect(res).to.have.a.property('Time') + expect(res).to.have.a.property('Text') + expect(res.Text).to.contain('Average latency') + expect(res.Time).to.be.a('number') done() }) }) @@ -25,6 +29,10 @@ describe('.ping', () => { }) .then((res) => { expect(res).to.have.a.property('Success') + expect(res).to.have.a.property('Time') + expect(res).to.have.a.property('Text') + expect(res.Text).to.contain('Average latency') + expect(res.Time).to.be.a('number') }) }) }) diff --git a/test/interface-ipfs-core/refs.spec.js b/test/interface-ipfs-core/refs.spec.js index 5b33662b0..3a38abe1f 100644 --- a/test/interface-ipfs-core/refs.spec.js +++ b/test/interface-ipfs-core/refs.spec.js @@ -65,7 +65,6 @@ describe('.refs', () => { ipfs.refs(folder, {format: ' '}, (err, objs) => { expect(err).to.not.exist expect(objs).to.eql(result) - done() }) }) diff --git a/test/ipfs-api/util.spec.js b/test/ipfs-api/util.spec.js index e2e9dede2..d103844bd 100644 --- a/test/ipfs-api/util.spec.js +++ b/test/ipfs-api/util.spec.js @@ -65,7 +65,6 @@ describe('.util', () => { ipfs.util.addFromFs(filePath, (err, result) => { expect(err).to.not.exist expect(result.length).to.be.above(5) - done() }) }) diff --git a/test/setup/spawn-daemons.js b/test/setup/spawn-daemons.js index 5a2d3b659..89b831780 100644 --- a/test/setup/spawn-daemons.js +++ b/test/setup/spawn-daemons.js @@ -5,7 +5,7 @@ const gulp = require('gulp') const fs = require('fs') const path = require('path') -const ipfsd = require('ipfsd-ctl') +const ipfsd = require('@haad/ipfsd-ctl') const eachSeries = require('async/eachSeries') const parallel = require('async/parallel') @@ -27,20 +27,22 @@ function startDisposableDaemons (callback) { const configValues = { Bootstrap: [], - Discovery: {}, - 'HTTPHeaders.Access-Control-Allow-Origin': ['*'], - 'HTTPHeaders.Access-Control-Allow-Credentials': 'true', - 'HTTPHeaders.Access-Control-Allow-Methods': ['PUT', 'POST', 'GET'] + // Discovery: {}, + API: { + 'HTTPHeaders.Access-Control-Allow-Origin': ['*'], + 'HTTPHeaders.Access-Control-Allow-Credentials': 'true', + 'HTTPHeaders.Access-Control-Allow-Methods': ['PUT', 'POST', 'GET'] + } } eachSeries(Object.keys(configValues), (configKey, cb) => { - nodes[key].setConfig(`API.${configKey}`, JSON.stringify(configValues[configKey]), cb) + nodes[key].setConfig(`${configKey}`, JSON.stringify(configValues[configKey]), cb) }, (err) => { if (err) { return cb(err) } - nodes[key].startDaemon(cb) + nodes[key].startDaemon(['--enable-pubsub-experiment'], cb) }) }) }