From 31f673daa5d48a9298848f27e78240ad20bbc704 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sat, 20 Aug 2016 15:07:27 +0100 Subject: [PATCH] feat(http): Refactor inject tests, made them all pass again --- src/http-api/resources/swarm.js | 7 + test/http-api/index.js | 29 +- test/http-api/inject/test-bitswap.js | 48 ++ test/http-api/inject/test-block.js | 170 ++++++ test/http-api/inject/test-bootstrap.js | 79 +++ test/http-api/inject/test-config.js | 215 +++++++ test/http-api/inject/test-files.js | 56 ++ test/http-api/inject/test-id.js | 35 ++ test/http-api/inject/test-object.js | 528 ++++++++++++++++++ test/http-api/inject/test-repo.js | 10 + test/http-api/inject/test-swarm.js | 91 +++ test/http-api/inject/test-version.js | 27 + test/http-api/{ => ipfs-api}/test-bitswap.js | 0 test/http-api/{ => ipfs-api}/test-block.js | 0 .../http-api/{ => ipfs-api}/test-bootstrap.js | 0 test/http-api/{ => ipfs-api}/test-config.js | 0 test/http-api/{ => ipfs-api}/test-files.js | 0 test/http-api/{ => ipfs-api}/test-id.js | 0 test/http-api/{ => ipfs-api}/test-object.js | 0 test/http-api/{ => ipfs-api}/test-repo.js | 0 test/http-api/{ => ipfs-api}/test-swarm.js | 2 +- test/http-api/{ => ipfs-api}/test-version.js | 2 +- 22 files changed, 1289 insertions(+), 10 deletions(-) create mode 100644 test/http-api/inject/test-bitswap.js create mode 100644 test/http-api/inject/test-block.js create mode 100644 test/http-api/inject/test-bootstrap.js create mode 100644 test/http-api/inject/test-config.js create mode 100644 test/http-api/inject/test-files.js create mode 100644 test/http-api/inject/test-id.js create mode 100644 test/http-api/inject/test-object.js create mode 100644 test/http-api/inject/test-repo.js create mode 100644 test/http-api/inject/test-swarm.js create mode 100644 test/http-api/inject/test-version.js rename test/http-api/{ => ipfs-api}/test-bitswap.js (100%) rename test/http-api/{ => ipfs-api}/test-block.js (100%) rename test/http-api/{ => ipfs-api}/test-bootstrap.js (100%) rename test/http-api/{ => ipfs-api}/test-config.js (100%) rename test/http-api/{ => ipfs-api}/test-files.js (100%) rename test/http-api/{ => ipfs-api}/test-id.js (100%) rename test/http-api/{ => ipfs-api}/test-object.js (100%) rename test/http-api/{ => ipfs-api}/test-repo.js (100%) rename test/http-api/{ => ipfs-api}/test-swarm.js (98%) rename test/http-api/{ => ipfs-api}/test-version.js (95%) diff --git a/src/http-api/resources/swarm.js b/src/http-api/resources/swarm.js index deb0182190..004c241e97 100644 --- a/src/http-api/resources/swarm.js +++ b/src/http-api/resources/swarm.js @@ -3,6 +3,7 @@ const debug = require('debug') const log = debug('http-api:block') log.error = debug('http-api:block:error') +const multiaddr = require('multiaddr') exports = module.exports @@ -12,6 +13,12 @@ exports.parseAddrs = (request, reply) => { return reply("Argument 'addr' is required").code(400).takeover() } + try { + multiaddr(request.query.arg) + } catch (err) { + return reply("Argument 'addr' is invalid").code(500).takeover() + } + return reply({ addr: request.query.arg }) diff --git a/test/http-api/index.js b/test/http-api/index.js index 4f0ab45962..e259874a24 100644 --- a/test/http-api/index.js +++ b/test/http-api/index.js @@ -8,17 +8,20 @@ const ncp = require('ncp').ncp const path = require('path') const clean = require('../utils/clean') -describe('http api', () => { +describe('HTTP API', () => { const repoExample = path.join(__dirname, '../go-ipfs-repo') - const repoTests = exports.repoPath = path.join(__dirname, '../repo-tests-run-http') - const api = new Api(repoTests) + const repoTests = path.join(__dirname, '../repo-tests-run-http') + + let http = {} before((done) => { + http.api = new Api(repoTests) + clean(repoTests) ncp(repoExample, repoTests, (err) => { expect(err).to.not.exist - api.start((err) => { + http.api.start((err) => { expect(err).to.not.exist done() }) @@ -26,19 +29,29 @@ describe('http api', () => { }) after((done) => { - api.stop((err) => { + http.api.stop((err) => { expect(err).to.not.exist clean(repoTests) done() }) }) - describe('--all', () => { - var tests = fs.readdirSync(__dirname) + describe('## inject', () => { + const tests = fs.readdirSync(path.join(__dirname, '/inject')) + tests.filter((file) => { return file.match(/test-.*\.js/) }).forEach((file) => { - require('./' + file)(api) + require('./inject/' + file)(http) }) }) + + // it.skip('## ipfs-api + interface-ipfs-core', () => { + // const tests = fs.readdirSync(path.join(__dirname, '/ipfs-api')) + // tests.filter((file) => { + // return file.match(/test-.*\.js/) + // }).forEach((file) => { + // require('./ipfs-api/' + file)(http) + // }) + // }) }) diff --git a/test/http-api/inject/test-bitswap.js b/test/http-api/inject/test-bitswap.js new file mode 100644 index 0000000000..8048a03432 --- /dev/null +++ b/test/http-api/inject/test-bitswap.js @@ -0,0 +1,48 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect + +module.exports = (http) => { + describe('/bitswap', () => { + let api + + before(() => { + api = http.api.server.select('API') + }) + + it('/wantlist', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/bitswap/wantlist' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result).to.have.property('Keys') + // TODO test that there actual values in there + done() + }) + }) + + it('/stat', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/bitswap/stat' + }, (res) => { + expect(res.statusCode).to.equal(200) + + expect(res.result).to.have.keys([ + 'BlocksReceived', + 'Wantlist', + 'Peers', + 'DupBlksReceived', + 'DupDataReceived' + ]) + // TODO test that there actual values in there + done() + }) + }) + + it.skip('/unwant', () => { + }) + }) +} diff --git a/test/http-api/inject/test-block.js b/test/http-api/inject/test-block.js new file mode 100644 index 0000000000..c13d106e3f --- /dev/null +++ b/test/http-api/inject/test-block.js @@ -0,0 +1,170 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect +const fs = require('fs') +const FormData = require('form-data') +const streamToPromise = require('stream-to-promise') + +module.exports = (http) => { + describe('/block', () => { + let api + + before(() => { + api = http.api.server.select('API') + }) + + describe('/block/put', () => { + it('returns 400 if no node is provided', (done) => { + const form = new FormData() + const headers = form.getHeaders() + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/block/put', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(400) + done() + }) + }) + }) + + it('updates value', (done) => { + const form = new FormData() + const filePath = 'test/test-data/hello' + form.append('data', fs.createReadStream(filePath)) + const headers = form.getHeaders() + const expectedResult = { + Key: 'QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp', + Size: 12 + } + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/block/put', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result).to.deep.equal(expectedResult) + done() + }) + }) + }) + }) + + describe('/block/get', () => { + it('returns 400 for request without argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/block/get' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/block/get?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns value', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/block/get?arg=QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result) + .to.equal('hello world\n') + done() + }) + }) + }) + + describe('/block/stat', () => { + it('returns 400 for request without argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/block/stat' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/block/stat?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns value', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/block/stat?arg=QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Key) + .to.equal('QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp') + expect(res.result.Size).to.equal(12) + done() + }) + }) + }) + + describe('/block/del', () => { + it('returns 400 for request without argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/block/del' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/block/del?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns 200', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/block/del?arg=QmZjTnYw2TFhn9Nn7tjmPSoTBoY7YRkwPzwSrSbabY24Kp' + }, (res) => { + expect(res.statusCode).to.equal(200) + done() + }) + }) + }) + }) +} diff --git a/test/http-api/inject/test-bootstrap.js b/test/http-api/inject/test-bootstrap.js new file mode 100644 index 0000000000..bc36c9868e --- /dev/null +++ b/test/http-api/inject/test-bootstrap.js @@ -0,0 +1,79 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect + +module.exports = (http) => { + describe('/bootstrap', () => { + let api + + before(() => { + api = http.api.server.select('API') + }) + + it('/list', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/bootstrap/list' + }, (res) => { + expect(res.result).to.deep.equal(defaultList) + done() + }) + }) + + it('/list alias', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/bootstrap' + }, (res) => { + expect(res.result).to.deep.equal(defaultList) + done() + }) + }) + + it.skip('/add', (done) => { // TODO + api.inject({ + method: 'GET', + url: '/api/v0/bootstrap/add', + payload: { + arg: '/ip4/111.111.111.111/tcp/1001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLUVIT' + } + }, (res) => { + // TODO assess + }) + }) + + it.skip('/rm', (done) => { // TODO + api.inject({ + method: 'GET', + url: '/api/v0/bootstrap/rm', + payload: { + arg: '/ip4/111.111.111.111/tcp/1001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLUVIT' + } + }, (res) => { + // TODO assess + }) + }) + + it.skip('/list confirm it changed', (done) => { // TODO + api.inject({ + method: 'GET', + url: '/api/v0/bootstrap/list' + }, (res) => { + // TODO assess + }) + }) + }) +} + +const defaultList = [ + '/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ', + '/ip4/104.236.176.52/tcp/4001/ipfs/QmSoLnSGccFuZQJzRadHn95W2CrSFmZuTdDWP8HXaHca9z', + '/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM', + '/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm', + '/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu', + '/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64', + '/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd', + '/ip4/178.62.61.185/tcp/4001/ipfs/QmSoLMeWqB7YGVLJN3pNLQpmmEk35v6wYtsMGLzSr5QBU3', + '/ip4/104.236.151.122/tcp/4001/ipfs/QmSoLju6m7xTh3DuokvT3886QRYqxAzb1kShaanJgW36yx' +] diff --git a/test/http-api/inject/test-config.js b/test/http-api/inject/test-config.js new file mode 100644 index 0000000000..e3849d1b28 --- /dev/null +++ b/test/http-api/inject/test-config.js @@ -0,0 +1,215 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect +const fs = require('fs') +const FormData = require('form-data') +const streamToPromise = require('stream-to-promise') +const path = require('path') + +module.exports = (http) => { + describe('/config', () => { + const configPath = path.join(__dirname, '../../repo-tests-run-http/config') + const originalConfigPath = path.join(__dirname, '../../go-ipfs-repo/config') + + let updatedConfig + let api + + before(() => { + updatedConfig = () => JSON.parse(fs.readFileSync(configPath, 'utf8')) + + api = http.api.server.select('API') + }) + + after(() => { + fs.writeFileSync(configPath, fs.readFileSync(originalConfigPath, 'utf8'), 'utf8') + }) + + describe('400 for request with no args', () => { + it('returns 400 for request without arguments', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config' + }, (res) => { + expect(res.statusCode).to.equal(400) + done() + }) + }) + + it('500 for request with invalid args', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config?arg=kitten' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns value for request with valid arg', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config?arg=API.HTTPHeaders' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Key).to.equal('API.HTTPHeaders') + expect(res.result.Value).to.equal(null) + done() + }) + }) + + it('returns value for request as subcommand', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config/API.HTTPHeaders' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Key).to.equal('API.HTTPHeaders') + expect(res.result.Value).to.equal(null) + done() + }) + }) + + it('updates value for request with both args', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config?arg=Datastore.Path&arg=kitten' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Key).to.equal('Datastore.Path') + expect(res.result.Value).to.equal('kitten') + expect(updatedConfig().Datastore.Path).to.equal('kitten') + + done() + }) + }) + + it('returns 500 value for request with both args and JSON flag with invalid JSON argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config?arg=Datastore.Path&arg=kitten&json' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + + done() + }) + }) + + it('updates value for request with both args and JSON flag with valid JSON argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config?arg=Datastore.Path&arg={"kitten": true}&json' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Key).to.equal('Datastore.Path') + expect(res.result.Value).to.deep.equal({ kitten: true }) + expect(updatedConfig().Datastore.Path).to.deep.equal({ kitten: true }) + + done() + }) + }) + + it('updates value for request with both args and bool flag and true argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config?arg=Datastore.Path&arg=true&bool' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Key).to.equal('Datastore.Path') + expect(res.result.Value).to.deep.equal(true) + expect(updatedConfig().Datastore.Path).to.deep.equal(true) + + done() + }) + }) + + it('updates value for request with both args and bool flag and false argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config?arg=Datastore.Path&arg=false&bool' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Key).to.equal('Datastore.Path') + expect(res.result.Value).to.deep.equal(false) + expect(updatedConfig().Datastore.Path).to.deep.equal(false) + + done() + }) + }) + }) + + it('/config/show', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/config/show' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result).to.deep.equal(updatedConfig()) + done() + }) + }) + + describe('/config/replace', () => { + it('returns 400 if no config is provided', (done) => { + const form = new FormData() + const headers = form.getHeaders() + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/config/replace', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(400) + done() + }) + }) + }) + + it('returns 500 if the config is invalid', (done) => { + const form = new FormData() + const filePath = 'test/test-data/badconfig' + form.append('file', fs.createReadStream(filePath)) + const headers = form.getHeaders() + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/config/replace', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(500) + done() + }) + }) + }) + + it('updates value', (done) => { + const form = new FormData() + const filePath = 'test/test-data/otherconfig' + form.append('file', fs.createReadStream(filePath)) + const headers = form.getHeaders() + const expectedConfig = JSON.parse(fs.readFileSync(filePath, 'utf8')) + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/config/replace', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(updatedConfig()).to.deep.equal(expectedConfig) + done() + }) + }) + }) + }) + }) +} diff --git a/test/http-api/inject/test-files.js b/test/http-api/inject/test-files.js new file mode 100644 index 0000000000..e824b2db04 --- /dev/null +++ b/test/http-api/inject/test-files.js @@ -0,0 +1,56 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect + +module.exports = (http) => { + describe('/files', () => { + let api + + before(() => { + api = http.api.server.select('API') + }) + + describe('/add', () => {}) // TODO + + describe('/cat', () => { + it('returns 400 for request without argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/cat' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('500 for request with invalid argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/cat?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('valid hash', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/cat?arg=QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.rawPayload).to.deep.equal(new Buffer('hello world' + '\n')) + expect(res.payload).to.equal('hello world' + '\n') + done() + }) + }) + }) + + describe('/get', () => {}) // TODO + + describe('/ls', () => {}) // TODO + }) +} diff --git a/test/http-api/inject/test-id.js b/test/http-api/inject/test-id.js new file mode 100644 index 0000000000..e06f050a03 --- /dev/null +++ b/test/http-api/inject/test-id.js @@ -0,0 +1,35 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect + +module.exports = (http) => { + describe('/id', () => { + let api + + before(() => { + api = http.api.server.select('API') + }) + + it('get the id', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/id' + }, (res) => { + expect(res.result.ID).to.equal(idResult.ID) + expect(res.result.PublicKey).to.equal(idResult.PublicKey) + expect(res.result.AgentVersion).to.equal(idResult.AgentVersion) + expect(res.result.ProtocolVersion).to.equal(idResult.ProtocolVersion) + done() + }) + }) + }) +} + +const idResult = { + ID: 'QmQ2zigjQikYnyYUSXZydNXrDRhBut2mubwJBaLXobMt3A', + PublicKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2SKo/HMFZeBml1AF3XijzrxrfQXdJzjePBZAbdxqKR1Mc6juRHXij6HXYPjlAk01BhF1S3Ll4Lwi0cAHhggf457sMg55UWyeGKeUv0ucgvCpBwlR5cQ020i0MgzjPWOLWq1rtvSbNcAi2ZEVn6+Q2EcHo3wUvWRtLeKz+DZSZfw2PEDC+DGPJPl7f8g7zl56YymmmzH9liZLNrzg/qidokUv5u1pdGrcpLuPNeTODk0cqKB+OUbuKj9GShYECCEjaybJDl9276oalL9ghBtSeEv20kugatTvYy590wFlJkkvyl+nPxIH0EEYMKK9XRWlu9XYnoSfboiwcv8M3SlsjAgMBAAE=', + Addresses: [ '/ip4/0.0.0.0/tcp/0' ], + AgentVersion: 'js-ipfs', + ProtocolVersion: '9000' +} diff --git a/test/http-api/inject/test-object.js b/test/http-api/inject/test-object.js new file mode 100644 index 0000000000..dba5506cdc --- /dev/null +++ b/test/http-api/inject/test-object.js @@ -0,0 +1,528 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect +const fs = require('fs') +const FormData = require('form-data') +const streamToPromise = require('stream-to-promise') + +module.exports = (http) => { + describe('/object', () => { + let api + + before('api', () => { + api = http.api.server.select('API') + }) + + describe('/new', () => { + it('returns value', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/new' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Hash) + .to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n') + expect(res.result.Links).to.be.eql([]) + done() + }) + }) + }) + + describe('/get', () => { + it('returns 400 for request without argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/get' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/get?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns value', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/get?arg=QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Links).to.be.eql([]) + expect(res.result.Data).to.be.empty + done() + }) + }) + }) + + describe('/put', () => { + it('returns 400 if no node is provided', (done) => { + const form = new FormData() + const headers = form.getHeaders() + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/put', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(400) + done() + }) + }) + }) + + it('returns 500 if the node is invalid', (done) => { + const form = new FormData() + const filePath = 'test/test-data/badnode.json' + form.append('file', fs.createReadStream(filePath)) + const headers = form.getHeaders() + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/put', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(500) + done() + }) + }) + }) + + it('updates value', (done) => { + const form = new FormData() + const filePath = 'test/test-data/node.json' + form.append('data', fs.createReadStream(filePath)) + const headers = form.getHeaders() + const expectedResult = { + Data: new Buffer('another'), + Hash: 'QmZZmY4KCu9r3e7M2Pcn46Fc5qbn6NpzaAGaYb22kbfTqm', + Links: [{ + Name: 'some link', + Hash: 'QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V', + Size: 8 + }], + Size: 68 + } + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/put', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result).to.deep.equal(expectedResult) + done() + }) + }) + }) + }) + + describe('/stat', () => { + it('returns 400 for request without argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/stat' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/stat?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns value', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/stat?arg=QmZZmY4KCu9r3e7M2Pcn46Fc5qbn6NpzaAGaYb22kbfTqm' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Hash).to.equal('QmZZmY4KCu9r3e7M2Pcn46Fc5qbn6NpzaAGaYb22kbfTqm') + expect(res.result.NumLinks).to.equal(1) + expect(res.result.BlockSize).to.equal(60) + expect(res.result.LinksSize).to.equal(60 - 7) + expect(res.result.DataSize).to.equal(7) + expect(res.result.CumulativeSize).to.equal(60 + 8) + done() + }) + }) + }) + + describe('/data', () => { + it('returns 400 for request without argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/data' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/data?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns value', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/data?arg=QmZZmY4KCu9r3e7M2Pcn46Fc5qbn6NpzaAGaYb22kbfTqm' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result).to.equal('another') + done() + }) + }) + }) + + describe('/links', () => { + it('returns 400 for request without argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/links' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/links?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns value', (done) => { + const expectedResult = { + Hash: 'QmZZmY4KCu9r3e7M2Pcn46Fc5qbn6NpzaAGaYb22kbfTqm', + Links: [ + { Name: 'some link', Hash: 'QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V', Size: 8 } + ] + } + + api.inject({ + method: 'POST', + url: '/api/v0/object/links?arg=QmZZmY4KCu9r3e7M2Pcn46Fc5qbn6NpzaAGaYb22kbfTqm' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result).to.deep.equal(expectedResult) + done() + }) + }) + }) + + describe('/patch/append-data', () => { + it('returns 400 for request without key', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/append-data' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 400 if no data is provided', (done) => { + const form = new FormData() + const headers = form.getHeaders() + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/append-data?arg=QmVLUHkjGg3duGb5w3dnwK5w2P9QWuJmtVNuDPLc9ZDjzk', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(400) + done() + }) + }) + }) + + it('returns 500 for request with invalid key', (done) => { + const form = new FormData() + const filePath = 'test/test-data/badconfig' + form.append('file', fs.createReadStream(filePath)) + const headers = form.getHeaders() + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/append-data?arg=invalid', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(500) + done() + }) + }) + }) + + it('updates value', (done) => { + const form = new FormData() + const filePath = 'test/test-data/badconfig' + form.append('data', fs.createReadStream(filePath)) + const headers = form.getHeaders() + const expectedResult = { + Data: fs.readFileSync(filePath), + Hash: 'QmfY37rjbPCZRnhvvJuQ46htW3VCAWziVB991P79h6WSv6', + Links: [], + Size: 19 + } + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/append-data?arg=QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result).to.deep.equal(expectedResult) + done() + }) + }) + }) + }) + + describe('/patch/set-data', () => { + it('returns 400 for request without key', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/set-data' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 400 if no data is provided', (done) => { + const form = new FormData() + const headers = form.getHeaders() + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/set-data?arg=QmVLUHkjGg3duGb5w3dnwK5w2P9QWuJmtVNuDPLc9ZDjzk', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(400) + done() + }) + }) + }) + + it('returns 500 for request with invalid key', (done) => { + const form = new FormData() + const filePath = 'test/test-data/badconfig' + form.append('file', fs.createReadStream(filePath)) + const headers = form.getHeaders() + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/set-data?arg=invalid', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(500) + done() + }) + }) + }) + + it('updates value', (done) => { + const form = new FormData() + const filePath = 'test/test-data/badconfig' + form.append('data', fs.createReadStream(filePath)) + const headers = form.getHeaders() + const expectedResult = { + Hash: 'QmfY37rjbPCZRnhvvJuQ46htW3VCAWziVB991P79h6WSv6', + Links: [] + } + + streamToPromise(form).then((payload) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/set-data?arg=QmfY37rjbPCZRnhvvJuQ46htW3VCAWziVB991P79h6WSv6', + headers: headers, + payload: payload + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result).to.deep.equal(expectedResult) + done() + }) + }) + }) + }) + + describe('/patch/add-link', () => { + it('returns 400 for request without arguments', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/add-link' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 400 for request with only one invalid argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/add-link?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid first argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/add-link?arg=&arg=foo&arg=QmTz3oc4gdpRMKP2sdGUPZTAGRngqjsi99BPoztyP53JMM' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with empty second argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/add-link?arg=QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn&arg=&arg=QmTz3oc4gdpRMKP2sdGUPZTAGRngqjsi99BPoztyP53JMM' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns value', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/add-link?arg=QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n&arg=foo&arg=QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Hash).to.equal('QmdVHE8fUD6FLNLugtNxqDFyhaCgdob372hs6BYEe75VAK') + expect(res.result.Links[0]).to.deep.equal({ + Name: 'foo', + Hash: 'QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn', + Size: 4 + }) + done() + }) + }) + }) + + describe('/patch/rm-link', () => { + it('returns 400 for request without arguments', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/rm-link' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 400 for request with only one invalid argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/rm-link?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid first argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/rm-link?arg=invalid&arg=foo' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns 500 for request with invalid second argument', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/rm-link?arg=QmZKetgwm4o3LhNaoLSHv32wBhTwj9FBwAdSchDMKyFQEx&arg=' + }, (res) => { + expect(res.statusCode).to.equal(500) + expect(res.result.Code).to.equal(0) + expect(res.result.Message).to.be.a('string') + done() + }) + }) + + it('returns value', (done) => { + api.inject({ + method: 'POST', + url: '/api/v0/object/patch/rm-link?arg=QmdVHE8fUD6FLNLugtNxqDFyhaCgdob372hs6BYEe75VAK&arg=foo' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Hash).to.equal('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n') + done() + }) + }) + }) + }) +} diff --git a/test/http-api/inject/test-repo.js b/test/http-api/inject/test-repo.js new file mode 100644 index 0000000000..08a0655049 --- /dev/null +++ b/test/http-api/inject/test-repo.js @@ -0,0 +1,10 @@ +'use strict' + +/* eslint-env mocha */ + +// const expect = require('chai').expect +// const APIctl = require('ipfs-api') + +module.exports = (http) => { + describe('/repo', () => {}) // TODO +} diff --git a/test/http-api/inject/test-swarm.js b/test/http-api/inject/test-swarm.js new file mode 100644 index 0000000000..d15eec161c --- /dev/null +++ b/test/http-api/inject/test-swarm.js @@ -0,0 +1,91 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect +const createTempNode = require('./../../utils/temp-node') + +module.exports = (http) => { + describe('/swarm', function () { + this.timeout(20000) + + var api + var tmpNode // tmp node + var ipfsAddr + + before((done) => { + api = http.api.server.select('API') + + createTempNode(47, (err, _ipfs) => { + expect(err).to.not.exist + tmpNode = _ipfs + tmpNode.goOnline((err) => { + expect(err).to.not.exist + tmpNode.id((err, res) => { + expect(err).to.not.exist + ipfsAddr = `${res.addresses[0]}/ipfs/${res.id}` + done() + }) + }) + }) + }) + + after((done) => { + setTimeout(() => { + tmpNode.goOffline(done) + }, 1000) + }) + + it('/connect returns 400 for request without argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/swarm/connect' + }, (res) => { + expect(res.statusCode).to.equal(400) + expect(res.result).to.be.a('string') + done() + }) + }) + + it('/connect returns 500 for request with invalid argument', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/swarm/connect?arg=invalid' + }, (res) => { + expect(res.statusCode).to.equal(500) + done() + }) + }) + + it('/connect returns value', (done) => { + api.inject({ + method: 'GET', + url: `/api/v0/swarm/connect?arg=${ipfsAddr}` + }, (res) => { + expect(res.statusCode).to.equal(200) + done() + }) + }) + + it('/peers returns value', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/swarm/peers' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Strings).to.have.length.above(0) + done() + }) + }) + + it('/addrs/local returns value', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/swarm/addrs/local' + }, (res) => { + expect(res.statusCode).to.equal(200) + expect(res.result.Strings).to.have.length.above(0) + done() + }) + }) + }) +} diff --git a/test/http-api/inject/test-version.js b/test/http-api/inject/test-version.js new file mode 100644 index 0000000000..569228712b --- /dev/null +++ b/test/http-api/inject/test-version.js @@ -0,0 +1,27 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect +const pkgversion = require('./../../../package.json').version + +module.exports = (http) => { + describe('/version', () => { + let api + + before(() => { + api = http.api.server.select('API') + }) + + it('get the version', (done) => { + api.inject({ + method: 'GET', + url: '/api/v0/version' + }, (res) => { + expect(res.result.version).to.equal(pkgversion) + expect(res.result).to.have.a.property('commit') + expect(res.result).to.have.a.property('repo') + done() + }) + }) + }) +} diff --git a/test/http-api/test-bitswap.js b/test/http-api/ipfs-api/test-bitswap.js similarity index 100% rename from test/http-api/test-bitswap.js rename to test/http-api/ipfs-api/test-bitswap.js diff --git a/test/http-api/test-block.js b/test/http-api/ipfs-api/test-block.js similarity index 100% rename from test/http-api/test-block.js rename to test/http-api/ipfs-api/test-block.js diff --git a/test/http-api/test-bootstrap.js b/test/http-api/ipfs-api/test-bootstrap.js similarity index 100% rename from test/http-api/test-bootstrap.js rename to test/http-api/ipfs-api/test-bootstrap.js diff --git a/test/http-api/test-config.js b/test/http-api/ipfs-api/test-config.js similarity index 100% rename from test/http-api/test-config.js rename to test/http-api/ipfs-api/test-config.js diff --git a/test/http-api/test-files.js b/test/http-api/ipfs-api/test-files.js similarity index 100% rename from test/http-api/test-files.js rename to test/http-api/ipfs-api/test-files.js diff --git a/test/http-api/test-id.js b/test/http-api/ipfs-api/test-id.js similarity index 100% rename from test/http-api/test-id.js rename to test/http-api/ipfs-api/test-id.js diff --git a/test/http-api/test-object.js b/test/http-api/ipfs-api/test-object.js similarity index 100% rename from test/http-api/test-object.js rename to test/http-api/ipfs-api/test-object.js diff --git a/test/http-api/test-repo.js b/test/http-api/ipfs-api/test-repo.js similarity index 100% rename from test/http-api/test-repo.js rename to test/http-api/ipfs-api/test-repo.js diff --git a/test/http-api/test-swarm.js b/test/http-api/ipfs-api/test-swarm.js similarity index 98% rename from test/http-api/test-swarm.js rename to test/http-api/ipfs-api/test-swarm.js index 77919bf5aa..11f2c3816b 100644 --- a/test/http-api/test-swarm.js +++ b/test/http-api/ipfs-api/test-swarm.js @@ -3,7 +3,7 @@ const expect = require('chai').expect const APIctl = require('ipfs-api') -const createTempNode = require('../utils/temp-node') +const createTempNode = require('./../../utils/temp-node') module.exports = (httpAPI) => { describe('swarm', function () { diff --git a/test/http-api/test-version.js b/test/http-api/ipfs-api/test-version.js similarity index 95% rename from test/http-api/test-version.js rename to test/http-api/ipfs-api/test-version.js index 88000bf6d6..fd6269350b 100644 --- a/test/http-api/test-version.js +++ b/test/http-api/ipfs-api/test-version.js @@ -3,7 +3,7 @@ const expect = require('chai').expect const APIctl = require('ipfs-api') -const pkgversion = require('../../package.json').version +const pkgversion = require('./../../../package.json').version module.exports = (httpAPI) => { describe('version', () => {