Skip to content

Commit

Permalink
[test,action][m]: Improve action() function according to comments in #14
Browse files Browse the repository at this point in the history
 PR - #10
  • Loading branch information
kmanaseryan committed Sep 14, 2020
1 parent 573529f commit 0da078d
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 8 deletions.
29 changes: 21 additions & 8 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ const CkanAuthApi = require('./util/ckan-auth-api')
const CkanUploadAPI = require('./util/ckan-upload-api')
const ActionApi = require('./util/action-api')
const Open = require('./file')
const { camelToSnakeCase } = require('./util/general')

/**
* @class Client.
* @param {string} authToken
* @param {string} apiKey
* @param {number} organizationId
* @param {string} datasetId
* @param {string} api
*/
class Client {
constructor(authToken, organizationId, datasetId, api) {
this.authToken = authToken
constructor(apiKey, organizationId, datasetId, api) {
this.apiKey = apiKey
this.organizationId = organizationId
this.datasetId = datasetId
this.api = api
Expand All @@ -29,7 +30,7 @@ class Client {
if (url) {
const response = await CkanAuthApi.getJWTFromCkanAuthz(
url,
this.authToken,
this.apiKey,
scope
)
return response
Expand All @@ -42,17 +43,29 @@ class Client {
* https://docs.ckan.org/en/latest/api/index.html#action-api-reference
* @param {string} actionName - The action name, e.g. site_read, package_show ...
* @param {object} payload - The payload being sent to CKAN
* @param {object} useHttpGet - Optional, if `true` will make `GET` request, otherwise `POST`.
* Note that if the payload is provided during the `GET`, then it will be converted to params,
* where each property will be snake case converted from camel case
*/
async action(actionName, payload) {
async action(actionName, payload, useHttpGet = false) {
const path = `/api/3/action/${actionName}`
const config = {
headers: {
'Content-Type': 'application/json;charset=utf-8',
Authorization: this.authToken,
Authorization: this.apiKey,
},
}
let response
if (!useHttpGet)
response = await axios.post(`${this.api}${path}`, payload, config)
else {
// use the payload as HTTP params
response = await axios.get(`${this.api}${path}`, {
...config,
params: camelToSnakeCase(payload),
})
}

const response = await axios.post(`${this.api}${path}`, payload, config)
if (!response.data.success) {
throw `Action response: ${response.statusText}`
}
Expand All @@ -61,7 +74,7 @@ class Client {
}

put(actionType, data) {
return ActionApi.action(this.api, this.authToken, actionType, data)
return ActionApi.action(this.api, this.apiKey, actionType, data)
}

/**
Expand Down
11 changes: 11 additions & 0 deletions lib/util/general.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports.camelToSnakeCaseStr = (str) =>
str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
module.exports.camelToSnakeCase = (obj) => {
const result = {}
Object.keys(obj).map((key) => {
const snakeCasePropName = module.exports.camelToSnakeCaseStr(key)
result[snakeCasePropName] = obj[key]
})
console.log(result)
return result
}
87 changes: 87 additions & 0 deletions test/action.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const test = require('ava')
const nock = require('nock')
const urlParser = require('url')

const { Client } = require('../lib/index')

const config = {
api: 'http://ckan:5000',
authToken: '5f492394-630d-4759-92f4-000f279dd71b',
organizationId: 'demo-organization',
datasetId: 'my-first-dataset',
}

const client = new Client(
config.authToken,
config.organizationId,
config.datasetId,
config.api
)

test('pass correct action name and payload', async (t) => {
const responseMock = {
success: true,
result: {
foo: 'bar',
bar: 'foo',
},
}

const payload = {
someDataPropString: 'some value',
someDataPropBoolean: true,
}

const actionName = 'some_action_name'

let scope = nock(config.api)
.post(`/api/3/action/${actionName}`, (body) => {
t.deepEqual(body, payload)
return true
})
.reply(200, (url) => {
return responseMock
})

const response = await client.action(actionName, payload)

t.is(scope.isDone(), true)
t.deepEqual(response, responseMock)
})

test('able to force get', async (t) => {
const responseMock = {
success: true,
result: {
foo: 'bar',
bar: 'foo',
},
}

const payload = {
someDataPropString: 'some value',
someDataPropBoolean: true,
foo: 'bar',
}

const actionName = 'some_action_name'

let scope = nock(config.api)
.get(`/api/3/action/${actionName}`)
.query(true)
.reply(200, (url) => {
const queryObject = urlParser.parse(url, true).query
t.is(client.api, config.api)
t.deepEqual(queryObject, {
some_data_prop_string: 'some value',
some_data_prop_boolean: 'true',
foo: 'bar',
})
return responseMock
})

const response = await client.action(actionName, payload, true)

t.is(scope.isDone(), true)
t.deepEqual(response, responseMock)
})

0 comments on commit 0da078d

Please sign in to comment.