From 1e5cb34c9cb093310a4c117210c8aa7580b71d00 Mon Sep 17 00:00:00 2001 From: retrofox Date: Fri, 10 Feb 2017 12:41:40 -0300 Subject: [PATCH 1/7] send-request: improve checking query parameters --- lib/util/send-request.js | 41 +++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/lib/util/send-request.js b/lib/util/send-request.js index 85ddcf3..aa70a52 100644 --- a/lib/util/send-request.js +++ b/lib/util/send-request.js @@ -7,6 +7,9 @@ import debugFactory from 'debug'; const debug = debugFactory( 'wpcom:send-request' ); const debug_res = debugFactory( 'wpcom:send-request:res' ); +export const apiVersionPattern = /^(?:(\d+)\.)?(\d+)$/; +export const apiNamespacePattern = /^(?:([a-z]+)\/)?v(\d+)$/; + /** * Request to WordPress REST API * @@ -40,21 +43,33 @@ export default function sendRequest( params, query, body, fn ) { // query could be `null` query = query || {}; - // Handle special query parameters - // - `apiVersion` - if ( query.apiVersion ) { - params.apiVersion = query.apiVersion; - debug( 'apiVersion: %o', params.apiVersion ); - delete query.apiVersion; + const { apiVersion, apiNamespace } = query; + + if ( typeof apiVersion !== 'undefined' && typeof apiNamespace !== 'undefined' ) { + throw new Error( 'apiVersion and apiNamespace cannot be simultaneously defined.' ); + } + + if ( typeof apiVersion === 'undefined' ) { + if ( typeof apiNamespace === 'undefined' ) { + // set apiVersion default value + params.apiVersion = this.apiVersion; + } else { + params.apiNamespace = apiNamespace; + delete query.apiNamespace; + } } else { - params.apiVersion = this.apiVersion; + params.apiVersion = apiVersion; + delete query.apiVersion; + } + + // check apiVersion shape + if ( params.apiVersion && ! apiVersionPattern.test( params.apiVersion ) ) { + throw new Error( `'{ apiVersion: '${ params.apiVersion }' } value is invalid.` ); } - // - `apiNamespace` - if ( query.apiNamespace ) { - params.apiNamespace = query.apiNamespace; - debug( 'apiNamespace: %o', params.apiNamespace ); - delete query.apiNamespace; + // check apiNamespace shape` + if ( params.apiNamespace && ! apiNamespacePattern.test( params.apiNamespace ) ) { + throw new Error( `'{ apiNamespace: '${ params.apiNamespace }' } value is invalid.` ); } // - `proxyOrigin` @@ -91,4 +106,4 @@ export default function sendRequest( params, query, body, fn ) { err ? reject( err ) : resolve( res ); } ); } ); -}; +} From 1588402e4f02967dbb289d282eae0938d0eaabb4 Mon Sep 17 00:00:00 2001 From: retrofox Date: Fri, 10 Feb 2017 12:21:57 -0300 Subject: [PATCH 2/7] pkg: add chai dependency --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 2e34bb1..329735c 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ ], "dependencies": { "babel-runtime": "^6.9.2", + "chai": "^3.5.0", "debug": "^2.2.0", "qs": "^4.0.0", "wpcom-xhr-request": "1.0.0" From fe37eff7b2a1d7d052086829a67af9ebdd6c36ce Mon Sep 17 00:00:00 2001 From: retrofox Date: Fri, 10 Feb 2017 12:42:06 -0300 Subject: [PATCH 3/7] test: add send-request tests --- test/test.util.send-request.js | 85 ++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 test/test.util.send-request.js diff --git a/test/test.util.send-request.js b/test/test.util.send-request.js new file mode 100644 index 0000000..7d11222 --- /dev/null +++ b/test/test.util.send-request.js @@ -0,0 +1,85 @@ +/** + * Module dependencies + */ +import { expect, assert } from 'chai'; + +/** + * Internal dependencies + */ +import wpcomFactory, { + defaultApiVersion +} from '../'; + +import sendRequest, { + apiVersionPattern, + apiNamespacePattern, +} +from '../lib/util/send-request'; + +const wpcom = wpcomFactory(); + +/** + * Testing data + */ +import fixture from './fixture'; + +describe( 'wpcom', () => { + describe( 'wpcom.util.sendRequest', () => { + describe( 'apiVersion shape', () => { + it( 'should not accept `v1` as a valid version value', () => { + expect( apiVersionPattern.test( 'v1' ) ).to.be.false; + } ); + + it( 'should accept `1` as a valid version value', () => { + expect( apiVersionPattern.test( '1' ) ).to.be.true; + } ); + + it( 'should not accept `1.` as a valid version value', () => { + expect( apiVersionPattern.test( '1.' ) ).to.be.false; + } ); + + it( 'should accept `1.3` as a valid version value', () => { + expect( apiVersionPattern.test( '1.3' ) ).to.be.true; + } ); + } ); + + describe( 'apiNamespace shape', () => { + it( 'should not accept `wpcom` as a valid version value', () => { + expect( apiNamespacePattern.test( 'wpcom' ) ).to.be.false; + } ); + + it( 'should accept `wpcom/v1` as a valid version value', () => { + expect( apiNamespacePattern.test( 'wpcom/v1' ) ).to.be.true; + } ); + + it( 'should not accept `wpcom/` as a valid version value', () => { + expect( apiNamespacePattern.test( 'wpcom/' ) ).to.be.false; + } ); + + it( 'should not accept `wpcom/1` as a valid version value', () => { + expect( apiNamespacePattern.test( 'wpcom/1' ) ).to.be.false; + } ); + } ); + + describe( 'parameters parameters', () => { + it( 'should throw Error when `apiVersion` is malformed', () => { + const path = '/endpoint/path'; + const promise = sendRequest.bind( wpcom, path, { apiVersion: 'version1' }, {} ); + assert.throws( promise, Error, '{ apiVersion: \'version1\' } value is invalid.' ); + } ); + + it( 'should throw Error when `apiNamespace` is malformed', () => { + const path = '/endpoint/path'; + const promise = sendRequest.bind( wpcom, path, { apiNamespace: 'wpcom' }, {} ); + assert.throws( promise, Error, '{ apiNamespace: \'wpcom\' } value is invalid.' ); + } ); + + it( 'should throw Error when `apiVersion` and `apiNamespace` are both defined', () => { + const path = '/timezones'; + + const promise = sendRequest.bind( wpcom, path, { apiVersion: 'v1.4', apiNamespace: 'wpcom/v2' }, {} ); + assert.throws( promise, Error, 'apiVersion and apiNamespace cannot be simultaneously defined.' ); + } ); + } ); + } ); +} ); From f43de0e278335a3a1943424aa45ad9baa7d6a385 Mon Sep 17 00:00:00 2001 From: retrofox Date: Fri, 10 Feb 2017 12:51:30 -0300 Subject: [PATCH 4/7] test: remove overriding test command --- circle.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/circle.yml b/circle.yml index 1174d6a..ab84af1 100644 --- a/circle.yml +++ b/circle.yml @@ -7,7 +7,4 @@ dependencies: - npm install -g npm@3.8.6 machine: node: - version: 5.11.1 -test: - override: - - DEBUG=wpcom* make test \ No newline at end of file + version: 5.11.1 \ No newline at end of file From 8d87c847026c30638f760795757d26d540084e3c Mon Sep 17 00:00:00 2001 From: retrofox Date: Wed, 15 Feb 2017 08:16:58 -0300 Subject: [PATCH 5/7] test: remove site.follow tests --- test/test.wpcom.site.follow.js | 54 ---------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 test/test.wpcom.site.follow.js diff --git a/test/test.wpcom.site.follow.js b/test/test.wpcom.site.follow.js deleted file mode 100644 index 59e52ae..0000000 --- a/test/test.wpcom.site.follow.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Module dependencies - */ -var util = require( './util' ); -var assert = require( 'assert' ); - -/** - * site.follow - */ -describe( 'wpcom.site.follow', function() { - // Global instances - var wpcom = util.wpcom(); - var site = wpcom.site( util.site() ); - var follow = site.follow(); - - describe( 'wpcom.site.follow.follow', function() { - it( 'should follow site', done => { - follow.follow() - .then( data => { - assert.ok( data ); - assert.equal( true, data.is_following ); - - done(); - } ) - .catch( done ); - } ); - } ); - - describe( 'wpcom.site.follow.unfollow', function() { - it( 'should unfollow site', done => { - follow.unfollow() - .then( data => { - assert.ok( data ); - assert.equal( false, data.is_following ); - - done(); - } ) - .catch( done ); - } ); - } ); - - describe( 'wpcom.site.follow.mine', function() { - it( 'should get follow status', done => { - follow.mine() - .then( data => { - assert.ok( data ); - assert.equal( false, data.is_following ); - - done(); - } ) - .catch( done ); - } ); - } ); -} ); From 7bafebc259c2c45d47c50e17f62552b075c2e30c Mon Sep 17 00:00:00 2001 From: retrofox Date: Wed, 15 Feb 2017 08:24:54 -0300 Subject: [PATCH 6/7] test: load default config module --- test/util.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/util.js b/test/util.js index 591b08c..53aae5a 100644 --- a/test/util.js +++ b/test/util.js @@ -8,7 +8,7 @@ import fixture from './fixture'; var configFactory; try { - configFactory = require( './config' ); + configFactory = require( './config' ).default; } catch ( ex ) { configFactory = {}; } @@ -27,17 +27,13 @@ const env = isClientSide && ( ? 'production' : 'development'; -console.log( 'environment: %j', env ); - const config = configFactory[ env ] || {}; if ( isClientSide ) { const clientId = config.oauth.client_id; - console.log( 'clientId: %o', clientId ); qryString = qs.parse( document.location.search.replace( /^\?/, '' ) ); reqHandler = qryString.handler || 'wpcom-proxy-request'; - console.log( `reqHandler: %o`, reqHandler ); if ( 'wpcom-xhr-request' === reqHandler || @@ -73,7 +69,6 @@ function wpcom() { reqHandler = qryString.handler || 'wpcom-proxy-request'; if ( 'wpcom-proxy-request' === reqHandler ) { - console.log( 'PROXY request handler' ); let proxy = require( 'wpcom-proxy-request' ); _wpcom = wpcomFactory( proxy ); _wpcom.request( { From 0ea109e2c1ce8d360c61cb9113718a10c9d61712 Mon Sep 17 00:00:00 2001 From: retrofox Date: Wed, 15 Feb 2017 08:35:33 -0300 Subject: [PATCH 7/7] test: remove site.taxonomy.term tests --- test/test.wpcom.site.taxonomy.term.js | 103 -------------------------- 1 file changed, 103 deletions(-) delete mode 100644 test/test.wpcom.site.taxonomy.term.js diff --git a/test/test.wpcom.site.taxonomy.term.js b/test/test.wpcom.site.taxonomy.term.js deleted file mode 100644 index 107284e..0000000 --- a/test/test.wpcom.site.taxonomy.term.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Module dependencies - */ -var util = require( './util' ); -var assert = require( 'assert' ); - -/** - * site.taxonomy.term - */ -describe( 'wpcom.site.taxonomy.term', () => { - // Global instances - const wpcom = util.wpcom(); - const site = wpcom.site( util.site() ); - const taxonomy = site.taxonomy( 'category' ); - const testTermAttributes = { name: 'Chicken and Ribs', description: 'noms' }; - let testTerm; - let testTermTwo; - - // Create a testTerm - before( done => { - taxonomy.term().add( testTermAttributes ) - .then( term => { - testTerm = term; - done(); - } ) - .catch( done ); - } ); - - after( done => { - // delete testTerm - taxonomy.term( testTerm.slug ).delete() - .then( () => done() ) - .catch( done ); - } ); - - describe( 'wpcom.site.taxonomy.term.get', () => { - it( 'should return term details', done => { - taxonomy.term( testTerm.slug ).get() - .then( data => { - assert.ok( data ); - assert.ok( 'string', typeof data.name ); - assert.ok( 'string', typeof data.slug ); - assert.ok( 'string', typeof data.description ); - assert.ok( 'number', typeof data.post_count ); - assert.ok( 'number', typeof data.parent ); - assert.ok( 'number', typeof data.ID ); - assert.equal( testTerm.ID, data.ID ); - assert.equal( testTerm.name, data.name ); - done(); - } ) - .catch( done ); - } ); - - it( 'should not return an error for unknown_taxonomy', done => { - taxonomy.term( 'i-ate-all-the-chicken-and-ribs' ).get() - .catch( data => { - assert.ok( data ); - assert.equal( data.error, 'unknown_taxonomy' ); - done(); - } ); - } ); - } ); - - describe( 'wpcom.site.taxonomy.term.add', () => { - it( 'should create a new term', done => { - taxonomy.term().add( { name: 'chunky bacon', parent: testTerm.ID, description: 'I LOVE BACON MOAR' } ) - .then( data => { - testTermTwo = data; - assert.ok( data ); - assert.equal( data.name, 'chunky bacon' ); - assert.equal( data.parent, testTerm.ID ); - assert.equal( data.description, 'I LOVE BACON MOAR' ); - done(); - } ) - .catch( done ); - } ); - } ); - - describe( 'wpcom.site.taxonomy.term.update', () => { - it( 'should update the term', done => { - taxonomy.term( testTermTwo.slug ).update( { parent: 0, description: 'I LOVE RIBS AND BACON' } ) - .then( data => { - assert.ok( data ); - assert.equal( data.slug, testTermTwo.slug ); - assert.equal( data.description, 'I LOVE RIBS AND BACON' ); - assert.equal( data.parent, 0 ); - done(); - } ) - .catch( done ); - } ); - } ); - - describe( 'wpcom.site.taxonomy.term.delete', () => { - it( 'should update the term', done => { - taxonomy.term( testTermTwo.slug ).delete() - .then( data => { - assert.ok( data ); - done(); - } ) - .catch( done ); - } ); - } ); -} );