diff --git a/.gitignore b/.gitignore index 3d91b19..db4dc1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /node_modules -package-lok.json +package-lock.json /.idea yarn.lock /coverage \ No newline at end of file diff --git a/README.md b/README.md index 0d90ed8..4423ac6 100755 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ client.getCoins().then(console.log).catch(console.error); ``` #### getTicker - +(**DEPRECATED**) Get information on all tickers or specifed ticker. @@ -71,6 +71,42 @@ client.getTicker().then(console.log).catch(console.error); client.getTicker({coinId: 'btc-bitcoin'}).then(console.log).catch(console.error); ``` +#### getAllTickers + +Get tickers for all coins + +##### Parameters + +- `params` (optional, default `{}`) + - `coinId` string (optional but *`required` with historical key*) + - `quotes` array of strings (optional) + - `historical` object (optional) + - start: string (required) + - end: string (optional) + - limit: integer (optional) + - quote: string (optional) + - interval: string (optional) + +##### Examples +```javascript +const client = new CoinpaprikaAPI() +client.getAllTickers({ + coinId:'btc-bitcoin', + quotes: ['BTC', 'ETH'] +}).then(console.log).catch(console.error) + +client.getAllTickers({ + coinId:'btc-bitcoin', + historical: { + start: '2018-02-15', + end: '2018-02-16', + limit: 2000, + quote: 'btc', + interval: '30m' + } +}).then(console.log).catch(console.error) +``` + ## License CoinpaprikaAPI is available under the MIT license. See the LICENSE file for more info. diff --git a/index.js b/index.js index d10783e..a99ed48 100755 --- a/index.js +++ b/index.js @@ -45,9 +45,9 @@ class CoinpaprikaAPI { /** * Get information on all tickers or specifed ticker. + * DEPRECATED * * @param {Object=} options Options for the request - * @param {String=} [options.coinId="all"] Type of cryptocurrency to include ("all" | "coins" | "tokens") * * @example * const client = new CoinpaprikaAPI() @@ -55,6 +55,10 @@ class CoinpaprikaAPI { * client.getTicker().then(console.log).catch(console.error) */ getTicker (args = {}) { + if (Object.prototype.toString.call(args) !== '[object Object]') { + throw Error('Please pass object as arg.') + } + let { coinId } = args return createRequest({ fetcher: this.fetcher, @@ -63,6 +67,70 @@ class CoinpaprikaAPI { }) } + /** + * Get tickers for all coins + * @param {Object=} options for the request consistent to https://api.coinpaprika.com/#tag/Tickers + * @param coinId: string + * @param quotes: array of strings + * @param historical: object + * @example + * const client = new CoinpaprikaAPI() + * client.getAllTickers({ + * coinId:'btc-bitcoin', + * quotes: ['BTC', 'ETH'] + * }) + * .then(console.log) + * .catch(console.error) + * + * client.getAllTickers({ + * coinId:'btc-bitcoin', + * historical: { + * start: '2018-02-15', + * end: '2018-02-16', + * limit: 2000, + * quote: 'btc', + * interval: '30m' + * } + * }) + * .then(console.log) + * .catch(console.error) + */ + getAllTickers (params = {}) { + if (Object.prototype.toString.call(params) !== '[object Object]') { + throw Error('Please pass object as arg.') + } + + const { coinId, quotes, historical } = params + + if ((historical && typeof coinId === 'undefined') || (coinId && historical && typeof historical.start === 'undefined')) { + throw Error('required param was not pass, please check CoinpaprikaAPI client usage') + } + + const coinIdParam = coinId ? `/${coinId}` : '' + const quotesParam = quotes ? `?quotes=${quotes.join(',')}` : '' + let historicalParam = '' + if (historical && coinId) { + historicalParam = ((historicalArgs = {}) => { + const { start, end, limit, quote, interval } = historicalArgs + const startParam = `start=${start}` + const endParam = end ? `&end=${end}` : '' + const limitParam = limit ? `&limit=${limit}` : '' + const quoteParam = quote ? `"e=${quote}` : '' + const intervalParam = interval ? `&interval=${interval}` : '' + + return `/historical?${startParam}${endParam}${limitParam}${quoteParam}${intervalParam}` + })(historical) + } + + const query = `${coinIdParam}${historicalParam}${quotesParam}` + + return createRequest({ + fetcher: this.fetcher, + url: `${this.url}/tickers/${query}`, + config: this.config + }) + } + /** * Get a list of all cryptocurrencies available on coinpaprika.com. * diff --git a/package.json b/package.json index f40e078..3872376 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@coinpaprika/api-nodejs-client", - "version": "1.0.2", + "version": "1.1.0", "description": "This library provides convenient way to use Coinpaprika.com API in NodeJS", "license": "MIT", "repository": { @@ -20,16 +20,16 @@ "pretest": "npm run lint" }, "jest": { - "setupTestFrameworkScriptFile": "./test.js" + "verbose": true }, "author": "coinpaprika.com", "devDependencies": { "documentation": "^8.1.2", "dotenv": "^6.0.0", "husky": "^0.14.3", - "jest": "^23.5.0", - "jest-chain": "^1.0.3", - "jest-extended": "^0.8.1", + "jest": "^24.9.0", + "jest-chain": "^1.1.2", + "jest-extended": "^0.11.2", "standard": "^12.0.1" }, "dependencies": { @@ -48,4 +48,4 @@ "bitcoin", "cryptocurrency" ] -} \ No newline at end of file +} diff --git a/test.js b/test.js deleted file mode 100755 index 359ffb8..0000000 --- a/test.js +++ /dev/null @@ -1,64 +0,0 @@ -require('jest-extended') -require('jest-chain') -const CoinpaprikaAPI = require('./') - -require('dotenv').config() - -test('Check CoinpaprikaAPI', () => { - expect(CoinpaprikaAPI).toBeDefined() -}) - -test('Check new CoinpaprikaAPI client', () => { - const client = new CoinpaprikaAPI() - expect(client.getTicker).toBeDefined() - expect(client.getGlobal).toBeDefined() - expect(client.getCoins).toBeDefined() -}) - -test('check getTicker structure and type', async () => { - const client = new CoinpaprikaAPI() - const ticker = await client.getTicker() - expect(ticker).toBeArray() - expect(Array.isArray(ticker)).toBeTruthy() - for (let info of ticker) { - expect(typeof info).toBe('object') - expect(info).toHaveProperty('id') - expect(info).toHaveProperty('name') - expect(info).toHaveProperty('rank') - } -}) - -test('check getGlobal structure and type', async () => { - const client = new CoinpaprikaAPI() - const global = await client.getGlobal() - - expect(typeof global).toBe('object') - expect(global).toHaveProperty('market_cap_usd') - expect(global).toHaveProperty('volume_24h_usd') - expect(global).toHaveProperty('bitcoin_dominance_percentage') - expect(global).toHaveProperty('cryptocurrencies_number') - expect(global).toHaveProperty('last_updated') -}) - -test('check getCoins structure and type', async () => { - const client = new CoinpaprikaAPI() - const coins = await client.getCoins() - expect(coins).toBeArray() - expect(Array.isArray(coins)).toBeTruthy() - for (let info of coins) { - expect(typeof info).toBe('object') - expect(info).toHaveProperty('id') - expect(info).toHaveProperty('name') - expect(info).toHaveProperty('symbol') - } -}) - -test('check single getTicker for Bitcoin data, structure and type', async () => { - const client = new CoinpaprikaAPI() - const ticker = await client.getTicker({ coinId: 'btc-bitcoin' }) - - expect(typeof ticker).toBe('object') - expect(ticker.price_btc).toBe('1') - expect(ticker.name).toMatch('Bitcoin') - expect(ticker.symbol).toMatch('BTC') -}) diff --git a/tests/CoinpaprikaAPI.test.js b/tests/CoinpaprikaAPI.test.js new file mode 100644 index 0000000..1cebd5a --- /dev/null +++ b/tests/CoinpaprikaAPI.test.js @@ -0,0 +1,20 @@ +const CoinpaprikaAPI = require('../index') + +describe('CoinpaprikaAPI class', () => { + let client = null + + beforeEach(() => { + client = new CoinpaprikaAPI() + }) + + it('is defined', () => { + expect(client).toBeDefined() + }) + + it('has defined all endpoints consistent to API documentation', () => { + expect(client.getGlobal).toBeDefined() + expect(client.getCoins).toBeDefined() + expect(client.getAllTickers).toBeDefined() + expect(client.getTicker).toBeDefined() + }) +}) diff --git a/tests/getAllTickers.test.js b/tests/getAllTickers.test.js new file mode 100644 index 0000000..9cc4171 --- /dev/null +++ b/tests/getAllTickers.test.js @@ -0,0 +1,128 @@ +const CoinpaprikaAPI = require('../index') + +const isObject = obj => Object.prototype.toString.call(obj) === '[object Object]' + +describe('getAllTickers', () => { + let client = null + + beforeEach(() => { + client = new CoinpaprikaAPI() + }) + + it('returns Promise if async/await not used', () => { + const response = client.getAllTickers() + expect(response instanceof Promise).toBe(true) + }) + + it('returns array of objects consistent to API documentation', async () => { + const response = await client.getAllTickers() + expect(Array.isArray(response)).toBeTruthy() + const expectedProperties = ['id', 'name', 'rank', 'symbol', 'circulating_supply', 'total_supply', 'max_supply', 'beta_value', 'last_updated', 'quotes'] + + response.forEach(item => { + expect(isObject(item)).toBeTruthy() + expectedProperties.forEach(property => { + expect(item.hasOwnProperty(property)).toBeTruthy() + }) + }) + }) + + it('returns particular coin when called with coinId param', async () => { + const payload = { coinId: 'btc-bitcoin' } + const response = await client.getAllTickers(payload) + + expect(isObject(response)).toBeTruthy() + expect(response.id).toMatch('btc-bitcoin') + expect(response.symbol).toMatch('BTC') + expect(response.name.toLowerCase()).toMatch('bitcoin') + }) + + it('returns quotes object with expected params when called with quotes param', async () => { + const quotes = ['BTC', 'PLN', 'ETH'] + const payload = { quotes } + const response = await client.getAllTickers(payload) + expect(Array.isArray(response)).toBeTruthy() + + response.forEach(({ quotes }) => { + expect(isObject(quotes)) + expect(quotes.hasOwnProperty(quotes[0])) + expect(quotes.hasOwnProperty(quotes[1])) + expect(quotes.hasOwnProperty(quotes[2])) + }) + }) + + it('returns historical coin data when "coinId","historical" and "historical.start" were pass', async () => { + const payload = { + coinId: 'btc-bitcoin', + historical: { + start: '2019-09-22' + } + } + + const response = await client.getAllTickers(payload) + expect(Array.isArray(response)).toBeTruthy() + + response.forEach(item => { + expect(isObject(item)).toBeTruthy() + expect(item.hasOwnProperty('timestamp')).toBeTruthy() + expect(item.hasOwnProperty('price')).toBeTruthy() + expect(item.hasOwnProperty('volume_24h')).toBeTruthy() + expect(item.hasOwnProperty('market_cap')).toBeTruthy() + }) + }) + + it('returns properly response when all of "historical" params are passed', async () => { + const payload = { + coinId: 'btc-bitcoin', + historical: { + start: '2019-09-18', + end: '2019-09-19', + limit: 2000, + interval: '1h', + quote: 'btc' + } + } + + const response = await client.getAllTickers(payload) + expect(Array.isArray(response)).toBeTruthy() + expect(response.length).toEqual(24) + + response.forEach(item => { + expect(isObject(item)).toBeTruthy() + expect(item.price).toBeLessThanOrEqual(1.001) + }) + }) + + it('throws when is historical endpoint call but coinId param was not pass', () => { + const payload = { + historical: { + start: '2019-09-22' + } + } + expect(() => { + client.getAllTickers(payload) + }).toThrowError('required param was not pass, please check CoinpaprikaAPI client usage') + }) + + it('throws when is historical endpoint call but historical.start is not defined', () => { + const payload = { + coinId: 'btc-bitcoin', + historical: { + quote: 'usd', + last: '2019-09-22' + } + } + + expect(() => { + client.getAllTickers(payload) + }).toThrowError('required param was not pass, please check CoinpaprikaAPI client usage') + }) + + it('throws when object is not passed as arg', () => { + const payload = 'something' + + expect(() => { + client.getAllTickers(payload) + }).toThrowError('Please pass object as arg.') + }) +}) diff --git a/tests/getCoins.test.js b/tests/getCoins.test.js new file mode 100644 index 0000000..70f4636 --- /dev/null +++ b/tests/getCoins.test.js @@ -0,0 +1,29 @@ +const CoinpaprikaAPI = require('../index') + +const isObject = obj => Object.prototype.toString.call(obj) === '[object Object]' + +describe('getCoins', () => { + let client = null + beforeEach(() => { + client = new CoinpaprikaAPI() + }) + + it('returns Promise if async/await not used', () => { + const response = client.getAllTickers() + expect(response instanceof Promise).toBe(true) + }) + + it('returns array of objects consistent with API documentation', async () => { + const response = await client.getCoins() + expect(Array.isArray(response)).toBeTruthy() + + const expectedProperties = ['id', 'name', 'symbol', 'rank', 'is_new', 'is_active', 'type'] + + response.forEach(coin => { + expect(isObject(coin)).toBeTruthy() + expectedProperties.forEach(property => { + expect(coin.hasOwnProperty(property)).toBeTruthy() + }) + }) + }) +}) diff --git a/tests/getGobal.test.js b/tests/getGobal.test.js new file mode 100644 index 0000000..db3ff0f --- /dev/null +++ b/tests/getGobal.test.js @@ -0,0 +1,38 @@ +const CoinpaprikaAPI = require('../index') + +const isObject = obj => Object.prototype.toString.call(obj) === '[object Object]' + +describe('getAllTickers', () => { + let client = null + + beforeEach(() => { + client = new CoinpaprikaAPI() + }) + + it('returns Promise if async/await not used', () => { + const response = client.getGlobal() + expect(response instanceof Promise).toBe(true) + }) + + it('returns object with properties consistent to doc', async () => { + const response = await client.getGlobal() + expect(isObject(response)).toBeTruthy() + const expectedProperties = [ + 'market_cap_usd', + 'volume_24h_usd', + 'bitcoin_dominance_percentage', + 'cryptocurrencies_number', + 'market_cap_ath_value', + 'market_cap_ath_date', + 'volume_24h_ath_value', + 'volume_24h_ath_date', + 'market_cap_change_24h', + 'volume_24h_change_24h', + 'last_updated' + ] + + expectedProperties.forEach(property => { + expect(response.hasOwnProperty(property)).toBeTruthy() + }) + }) +}) diff --git a/tests/getTicker.test.js b/tests/getTicker.test.js new file mode 100644 index 0000000..6c413b4 --- /dev/null +++ b/tests/getTicker.test.js @@ -0,0 +1,61 @@ +const CoinpaprikaAPI = require('../index') + +const isObject = obj => Object.prototype.toString.call(obj) === '[object Object]' + +describe('getAllTickers', () => { + let client = null + + beforeEach(() => { + client = new CoinpaprikaAPI() + }) + + it('returns Promise if async/await not used', () => { + const response = client.getTicker() + expect(response instanceof Promise).toBe(true) + }) + + it('returns array of objects consistent with API documentation', async () => { + const response = await client.getTicker() + expect(Array.isArray(response)).toBeTruthy() + const expectedProperties = [ + 'id', + 'name', + 'rank', + 'symbol', + 'price_usd', + 'price_btc', + 'volume_24h_usd', + 'market_cap_usd', + 'circulating_supply', + 'total_supply', + 'max_supply', + 'percent_change_1h', + 'percent_change_24h', + 'percent_change_7d', + 'last_updated' + ] + + response.forEach(item => { + expect(isObject(item)).toBeTruthy() + expectedProperties.forEach(property => { + expect(item.hasOwnProperty(property)).toBeTruthy() + }) + }) + }) + + it('it returns correct object when called with coinID', async () => { + const payload = { coinId: 'btc-bitcoin' } + + const response = await client.getTicker(payload) + expect(response.id).toMatch('btc-bitcoin') + expect(response.symbol).toMatch('BTC') + expect(response.price_btc).toMatch('1') + }) + + it('throws when object is not passed as arg', () => { + const payload = 'something' + expect(() => { + client.getTicker(payload) + }).toThrowError('Please pass object as arg.') + }) +})