From f6d2ce2f4b7578c4b92cbde040cedff4a534c963 Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Sun, 1 Sep 2019 10:24:11 -0700 Subject: [PATCH 01/14] built support.groups (closes #10) --- src/api/v2/routes/support/groups.js | 79 +++++++++++ src/api/v2/support.js | 5 +- src/api/v2/validators/support/groups.js | 14 ++ .../src/api/v2/routes/support/groups.test.js | 128 ++++++++++++++++++ 4 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 src/api/v2/routes/support/groups.js create mode 100644 src/api/v2/validators/support/groups.js create mode 100644 tests/src/api/v2/routes/support/groups.test.js diff --git a/src/api/v2/routes/support/groups.js b/src/api/v2/routes/support/groups.js new file mode 100644 index 0000000..f5749f0 --- /dev/null +++ b/src/api/v2/routes/support/groups.js @@ -0,0 +1,79 @@ +const validate = require('../../validators/support/groups'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + list: (options = {}) => { + const { error } = validate.list(options); + if (error) throw new Error(error.details[0].message); + + const { user_id } = options; + return { + method: 'GET', + url: `${url}/api/v2${user_id ? `/users/${user_id}` : ''}/groups.json`, + headers + }; + }, + + show_assignable: (options = null) => { + if (options) throw new Error('no options are allowed'); + + return { + method: 'GET', + url: `${url}/api/v2/groups/assignable.json`, + headers + }; + }, + + show: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/groups/${id}.json`, + headers + }; + }, + + create: (options = {}) => { + const { error } = validate.create(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/groups.json`, + headers, + data + }; + }, + + update: (options = {}) => { + const { error } = validate.update(options); + if (error) throw new Error(error.details[0].message); + + const { id, data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/groups/${id}.json`, + headers, + data + }; + }, + + delete: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/groups/${id}.json`, + headers + }; + } + }; +}; diff --git a/src/api/v2/support.js b/src/api/v2/support.js index ca516df..5ee5d86 100644 --- a/src/api/v2/support.js +++ b/src/api/v2/support.js @@ -1,9 +1,10 @@ module.exports = ({ instance, headers }) => ({ + groups: require('./routes/support/groups')({ instance, headers }), search: require('./routes/support/search')({ instance, headers }), + tags: require('./routes/support/tags')({ instance, headers }), tickets: require('./routes/support/tickets')({ instance, headers }), ticket_metrics: require('./routes/support/ticketMetrics')({ instance, headers - }), - tags: require('./routes/support/tags')({ instance, headers }) + }) }); diff --git a/src/api/v2/validators/support/groups.js b/src/api/v2/validators/support/groups.js new file mode 100644 index 0000000..07e5821 --- /dev/null +++ b/src/api/v2/validators/support/groups.js @@ -0,0 +1,14 @@ +const Joi = require('@hapi/joi'); + +const id = Joi.number().min(1); +const user_id = Joi.number().min(1); +const data = Joi.object(); + +module.exports = { + list: options => Joi.validate(options, { user_id }), + show_assignable: null, // no options + show: options => Joi.validate(options, { id: id.required() }), + create: options => Joi.validate(options, { data: data.required() }), + update: options => + Joi.validate(options, { id: id.required(), data: data.required() }) +}; diff --git a/tests/src/api/v2/routes/support/groups.test.js b/tests/src/api/v2/routes/support/groups.test.js new file mode 100644 index 0000000..4856ab5 --- /dev/null +++ b/tests/src/api/v2/routes/support/groups.test.js @@ -0,0 +1,128 @@ +const endpoint = require('../../../../../../src/api/v2/routes/support/groups'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('groups', () => { + let groups; + + beforeEach(() => (groups = endpoint({ instance, headers }))); + afterEach(() => (groups = null)); + + describe('list groups', () => { + it('should process w/ valid input', () => { + expect(groups.list()).toEqual({ + method: 'GET', + url: `${url}/api/v2/groups.json`, + headers + }); + + expect(groups.list({})).toEqual({ + method: 'GET', + url: `${url}/api/v2/groups.json`, + headers + }); + + expect(groups.list({ user_id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/users/123/groups.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => groups.list('invalid')).toThrowError(); + expect(() => groups.list({ invalid: 123 })).toThrowError(); + expect(() => groups.list({ user_id: 'invalid' })).toThrowError(); + }); + }); + + describe('show assignable groups', () => { + it('should process w/ valid input', () => { + expect(groups.show_assignable()).toEqual({ + method: 'GET', + url: `${url}/api/v2/groups/assignable.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => groups.show_assignable('invalid')).toThrowError(); + }); + }); + + describe('show group', () => { + it('should process w/ valid input', () => { + expect(groups.show({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/groups/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => groups.show()).toThrowError(); + expect(() => groups.show({})).toThrowError(); + expect(() => groups.show('invalid')).toThrowError(); + expect(() => groups.show({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('create group', () => { + it('should process w/ valid input', () => { + expect(groups.create({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/groups.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => groups.create()).toThrowError(); + expect(() => groups.create({})).toThrowError(); + expect(() => groups.create('invalid')).toThrowError(); + expect(() => groups.create({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('update group', () => { + it('should process w/ valid input', () => { + expect(groups.update({ id: 123, data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/groups/123.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => groups.update()).toThrowError(); + expect(() => groups.update('invalid')).toThrowError(); + expect(() => groups.update({})).toThrowError(); + expect(() => groups.update({ id: 'invalid' })).toThrowError(); + expect(() => groups.update({ id: 123, data: 'invalid' })).toThrowError(); + }); + }); + + describe('delete group', () => { + it('should process w/ valid input', () => { + expect(groups.delete({ id: 123 })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/groups/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => groups.delete()).toThrowError(); + expect(() => groups.delete({})).toThrowError(); + expect(() => groups.delete('invalid')).toThrowError(); + expect(() => groups.delete({ id: 'invalid' })).toThrowError(); + }); + }); +}); From 874402291d8fa664bc222e8ed5d89c46b3ff75ee Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Sun, 1 Sep 2019 10:36:40 -0700 Subject: [PATCH 02/14] fixed delete validator --- src/api/v2/routes/support/groups.js | 2 +- src/api/v2/validators/support/groups.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/api/v2/routes/support/groups.js b/src/api/v2/routes/support/groups.js index f5749f0..9085e2a 100644 --- a/src/api/v2/routes/support/groups.js +++ b/src/api/v2/routes/support/groups.js @@ -65,7 +65,7 @@ module.exports = ({ instance, headers }) => { }, delete: (options = {}) => { - const { error } = validate.show(options); + const { error } = validate.delete(options); if (error) throw new Error(error.details[0].message); const { id } = options; diff --git a/src/api/v2/validators/support/groups.js b/src/api/v2/validators/support/groups.js index 07e5821..a31305e 100644 --- a/src/api/v2/validators/support/groups.js +++ b/src/api/v2/validators/support/groups.js @@ -10,5 +10,6 @@ module.exports = { show: options => Joi.validate(options, { id: id.required() }), create: options => Joi.validate(options, { data: data.required() }), update: options => - Joi.validate(options, { id: id.required(), data: data.required() }) + Joi.validate(options, { id: id.required(), data: data.required() }), + delete: options => Joi.validate(options, { id: id.required() }) }; From 083c00f34ddfbd10799913b514d6c6ca54607c4e Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Sun, 1 Sep 2019 15:08:01 -0700 Subject: [PATCH 03/14] built support.ticketForms --- src/api/v2/routes/support/ticketForms.js | 104 ++++++++++++ src/api/v2/validators/support/ticketForms.js | 17 ++ .../api/v2/routes/support/ticketForms.test.js | 155 ++++++++++++++++++ 3 files changed, 276 insertions(+) create mode 100644 src/api/v2/routes/support/ticketForms.js create mode 100644 src/api/v2/validators/support/ticketForms.js create mode 100644 tests/src/api/v2/routes/support/ticketForms.test.js diff --git a/src/api/v2/routes/support/ticketForms.js b/src/api/v2/routes/support/ticketForms.js new file mode 100644 index 0000000..0cbdc3c --- /dev/null +++ b/src/api/v2/routes/support/ticketForms.js @@ -0,0 +1,104 @@ +const validate = require('../../validators/support/ticketForms'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + list: (options = null) => { + if (options) throw new Error('no options are allowed'); + + return { + method: 'GET', + url: `${url}/api/v2/ticket_forms.json`, + headers + }; + }, + + create: (options = {}) => { + const { error } = validate.create(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/ticket_forms.json`, + headers, + data + }; + }, + + show: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/ticket_forms/${id}.json`, + headers + }; + }, + + show_many: (options = {}) => { + const { error } = validate.show_many(options); + if (error) throw new Error(error.details[0].message); + + const { ids } = options; + return { + method: 'GET', + url: `${url}/api/v2/ticket_forms/show_many.json?ids=${ids}`, + headers + }; + }, + + update: (options = {}) => { + const { error } = validate.update(options); + if (error) throw new Error(error.details[0].message); + + const { id, data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/ticket_forms/${id}.json`, + headers, + data + }; + }, + + delete: (options = {}) => { + const { error } = validate.delete(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/ticket_forms/${id}.json`, + headers + }; + }, + + reorder: (options = {}) => { + const { error } = validate.reorder(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/ticket_forms/reorder.json`, + headers, + data + }; + }, + + clone: (options = {}) => { + const { error } = validate.clone(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'POST', + url: `${url}/api/v2/ticket_forms/${id}/clone.json`, + headers + }; + } + }; +}; diff --git a/src/api/v2/validators/support/ticketForms.js b/src/api/v2/validators/support/ticketForms.js new file mode 100644 index 0000000..de29f0f --- /dev/null +++ b/src/api/v2/validators/support/ticketForms.js @@ -0,0 +1,17 @@ +const Joi = require('@hapi/joi'); + +const id = Joi.number().min(1); +const ids = Joi.string().min(3); +const data = Joi.object(); + +module.exports = { + list: null, // no options + create: options => Joi.validate(options, { data: data.required() }), + show: options => Joi.validate(options, { id: id.required() }), + show_many: options => Joi.validate(options, { ids: ids.required() }), + update: options => + Joi.validate(options, { id: id.required(), data: data.required() }), + delete: options => Joi.validate(options, { id: id.required() }), + reorder: options => Joi.validate(options, { data: data.required() }), + clone: options => Joi.validate(options, { id: id.required() }) +}; diff --git a/tests/src/api/v2/routes/support/ticketForms.test.js b/tests/src/api/v2/routes/support/ticketForms.test.js new file mode 100644 index 0000000..41642ec --- /dev/null +++ b/tests/src/api/v2/routes/support/ticketForms.test.js @@ -0,0 +1,155 @@ +const endpoint = require('../../../../../../src/api/v2/routes/support/ticketForms'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('ticket forms', () => { + let ticketForms; + + beforeEach(() => (ticketForms = endpoint({ instance, headers }))); + afterEach(() => (ticketForms = null)); + + describe('list ticket forms', () => { + it('should process w/ valid input', () => { + expect(ticketForms.list()).toEqual({ + method: 'GET', + url: `${url}/api/v2/ticket_forms.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketForms.list('invalid')).toThrowError(); + }); + }); + + describe('create ticket forms', () => { + it('should process w/ valid input', () => { + expect(ticketForms.create({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/ticket_forms.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketForms.create()).toThrowError(); + expect(() => ticketForms.create({})).toThrowError(); + expect(() => ticketForms.create('invalid')).toThrowError(); + expect(() => ticketForms.create({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('show ticket form', () => { + it('should process w/ valid input', () => { + expect(ticketForms.show({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/ticket_forms/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketForms.show()).toThrowError(); + expect(() => ticketForms.show({})).toThrowError(); + expect(() => ticketForms.show('invalid')).toThrowError(); + expect(() => ticketForms.show({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('show many ticket forms', () => { + it('should process w/ valid input', () => { + expect(ticketForms.show_many({ ids: '1,2,3' })).toEqual({ + method: 'GET', + url: `${url}/api/v2/ticket_forms/show_many.json?ids=1,2,3`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketForms.show_many()).toThrowError(); + expect(() => ticketForms.show_many({})).toThrowError(); + expect(() => ticketForms.show_many('invalid')).toThrowError(); + expect(() => ticketForms.show_many({ ids: 0 })).toThrowError(); + }); + }); + + describe('update ticket forms', () => { + it('should process w/ valid input', () => { + expect(ticketForms.update({ id: 123, data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/ticket_forms/123.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketForms.update()).toThrowError(); + expect(() => ticketForms.update({})).toThrowError(); + expect(() => ticketForms.update('invalid')).toThrowError(); + expect(() => ticketForms.update({ id: 0 })).toThrowError(); + expect(() => ticketForms.update({ id: 'invalid' })).toThrowError(); + expect(() => + ticketForms.update({ id: 123, data: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('delete ticket form', () => { + it('should process w/ valid input', () => { + expect(ticketForms.delete({ id: 123 })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/ticket_forms/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketForms.delete()).toThrowError(); + expect(() => ticketForms.delete({})).toThrowError(); + expect(() => ticketForms.delete('invalid')).toThrowError(); + expect(() => ticketForms.delete({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('reorder ticket forms', () => { + it('should process w/ valid input', () => { + expect(ticketForms.reorder({ data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/ticket_forms/reorder.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketForms.reorder()).toThrowError(); + expect(() => ticketForms.reorder({})).toThrowError(); + expect(() => ticketForms.reorder('invalid')).toThrowError(); + expect(() => ticketForms.reorder({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('clone an already existing ticket form', () => { + it('should process w/ valid input', () => { + expect(ticketForms.clone({ id: 123 })).toEqual({ + method: 'POST', + url: `${url}/api/v2/ticket_forms/123/clone.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketForms.clone()).toThrowError(); + expect(() => ticketForms.clone({})).toThrowError(); + expect(() => ticketForms.clone('invalid')).toThrowError(); + expect(() => ticketForms.clone({ id: 'invalid' })).toThrowError(); + }); + }); +}); From ce6cce138611b730ea4625a8d14ad05dd6969fd7 Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Sun, 1 Sep 2019 16:31:12 -0700 Subject: [PATCH 04/14] built support.ticketFields --- src/api/v2/routes/support/ticketFields.js | 116 +++++++++++ src/api/v2/validators/support/ticketFields.js | 26 +++ .../v2/routes/support/ticketFields.test.js | 197 ++++++++++++++++++ 3 files changed, 339 insertions(+) create mode 100644 src/api/v2/routes/support/ticketFields.js create mode 100644 src/api/v2/validators/support/ticketFields.js create mode 100644 tests/src/api/v2/routes/support/ticketFields.test.js diff --git a/src/api/v2/routes/support/ticketFields.js b/src/api/v2/routes/support/ticketFields.js new file mode 100644 index 0000000..37fff81 --- /dev/null +++ b/src/api/v2/routes/support/ticketFields.js @@ -0,0 +1,116 @@ +const validate = require('../../validators/support/ticketFields'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + list: (options = null) => { + if (options) throw new Error('no options are allowed'); + + return { + method: 'GET', + url: `${url}/api/v2/ticket_fields.json`, + headers + }; + }, + + show: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/ticket_fields/${id}.json`, + headers + }; + }, + + create: (options = {}) => { + const { error } = validate.create(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/ticket_fields.json`, + headers, + data + }; + }, + + update: (options = {}) => { + const { error } = validate.update(options); + if (error) throw new Error(error.details[0].message); + + const { id, data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/ticket_fields/${id}.json`, + headers, + data + }; + }, + + delete: (options = {}) => { + const { error } = validate.delete(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/ticket_fields/${id}.json`, + headers + }; + }, + + listOptions: (options = {}) => { + const { error } = validate.listOptions(options); + if (error) throw new Error(error.details[0].message); + + const { field_id } = options; + return { + method: 'GET', + url: `${url}/api/v2/ticket_fields/${field_id}/options.json`, + headers + }; + }, + + showOption: (options = {}) => { + const { error } = validate.showOption(options); + if (error) throw new Error(error.details[0].message); + + const { field_id, id } = options; + return { + method: 'GET', + url: `${url}/api/v2/ticket_fields/${field_id}/options/${id}.json`, + headers + }; + }, + + createOrUpdateOption: (options = {}) => { + const { error } = validate.createOrUpdateOption(options); + if (error) throw new Error(error.details[0].message); + + const { field_id, id, data } = options; + return { + method: 'POST', + url: `${url}/api/v2/ticket_fields/${field_id}/options/${id}.json`, + headers, + data + }; + }, + + deleteOption: (options = {}) => { + const { error } = validate.deleteOption(options); + if (error) throw new Error(error.details[0].message); + + const { field_id, id } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/ticket_fields/${field_id}/options/${id}.json`, + headers + }; + } + }; +}; diff --git a/src/api/v2/validators/support/ticketFields.js b/src/api/v2/validators/support/ticketFields.js new file mode 100644 index 0000000..29614d3 --- /dev/null +++ b/src/api/v2/validators/support/ticketFields.js @@ -0,0 +1,26 @@ +const Joi = require('@hapi/joi'); + +const id = Joi.number().min(1); +const field_id = Joi.number().min(1); +const data = Joi.object(); + +module.exports = { + list: null, // no options + show: options => Joi.validate(options, { id: id.required() }), + create: options => Joi.validate(options, { data: data.required() }), + update: options => + Joi.validate(options, { id: id.required(), data: data.required() }), + delete: options => Joi.validate(options, { id: id.required() }), + listOptions: options => + Joi.validate(options, { field_id: field_id.required() }), + showOption: options => + Joi.validate(options, { field_id: field_id.required(), id: id.required() }), + createOrUpdateOption: options => + Joi.validate(options, { + field_id: field_id.required(), + id: id.required(), + data: data.required() + }), + deleteOption: options => + Joi.validate(options, { field_id: field_id.required(), id: id.required() }) +}; diff --git a/tests/src/api/v2/routes/support/ticketFields.test.js b/tests/src/api/v2/routes/support/ticketFields.test.js new file mode 100644 index 0000000..3ace5eb --- /dev/null +++ b/tests/src/api/v2/routes/support/ticketFields.test.js @@ -0,0 +1,197 @@ +const endpoint = require('../../../../../../src/api/v2/routes/support/ticketFields'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('ticket fields', () => { + let ticketFields; + + beforeEach(() => (ticketFields = endpoint({ instance, headers }))); + afterEach(() => (ticketFields = null)); + + describe('list ticket fields', () => { + it('should process w/ valid input', () => { + expect(ticketFields.list()).toEqual({ + method: 'GET', + url: `${url}/api/v2/ticket_fields.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketFields.list('invalid')).toThrowError(); + }); + }); + + describe('show ticket field', () => { + it('should process w/ valid input', () => { + expect(ticketFields.show({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/ticket_fields/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketFields.show()).toThrowError(); + expect(() => ticketFields.show('invalid')).toThrowError(); + expect(() => ticketFields.show({})).toThrowError(); + expect(() => ticketFields.show({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('create ticket field', () => { + it('should process w/ valid input', () => { + expect(ticketFields.create({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/ticket_fields.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketFields.create()).toThrowError(); + expect(() => ticketFields.create('invalid')).toThrowError(); + expect(() => ticketFields.create({})).toThrowError(); + expect(() => ticketFields.create({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('update ticket field', () => { + it('should process w/ valid input', () => { + expect(ticketFields.update({ id: 123, data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/ticket_fields/123.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketFields.update()).toThrowError(); + expect(() => ticketFields.update('invalid')).toThrowError(); + expect(() => ticketFields.update({})).toThrowError(); + expect(() => ticketFields.update({ id: 'invalid' })).toThrowError(); + expect(() => + ticketFields.update({ id: 123, data: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('delete ticket field', () => { + it('should process w/ valid input', () => { + expect(ticketFields.delete({ id: 123 })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/ticket_fields/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketFields.delete()).toThrowError(); + expect(() => ticketFields.delete('invalid')).toThrowError(); + expect(() => ticketFields.delete({})).toThrowError(); + expect(() => ticketFields.delete({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('list ticket field options', () => { + it('should process w/ valid input', () => { + expect(ticketFields.listOptions({ field_id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/ticket_fields/123/options.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketFields.listOptions()).toThrowError(); + expect(() => ticketFields.listOptions('invalid')).toThrowError(); + expect(() => ticketFields.listOptions({})).toThrowError(); + expect(() => + ticketFields.listOptions({ field_id: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('show a ticket field option', () => { + it('should process w/ valid input', () => { + expect(ticketFields.showOption({ field_id: 123, id: 456 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/ticket_fields/123/options/456.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketFields.showOption()).toThrowError(); + expect(() => ticketFields.showOption('invalid')).toThrowError(); + expect(() => ticketFields.showOption({})).toThrowError(); + expect(() => + ticketFields.showOption({ field_id: 'invalid' }) + ).toThrowError(); + expect(() => + ticketFields.showOption({ field_id: 123, id: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('create or update a ticket field option', () => { + it('should process w/ valid input', () => { + expect( + ticketFields.createOrUpdateOption({ field_id: 123, id: 456, data: {} }) + ).toEqual({ + method: 'POST', + url: `${url}/api/v2/ticket_fields/123/options/456.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketFields.createOrUpdateOption()).toThrowError(); + expect(() => ticketFields.createOrUpdateOption('invalid')).toThrowError(); + expect(() => ticketFields.createOrUpdateOption({})).toThrowError(); + expect(() => + ticketFields.createOrUpdateOption({ field_id: 'invalid' }) + ).toThrowError(); + expect(() => + ticketFields.createOrUpdateOption({ field_id: 123, id: 'invalid' }) + ).toThrowError(); + expect(() => + ticketFields.createOrUpdateOption({ + field_id: 123, + id: 456, + data: 'invalid' + }) + ).toThrowError(); + }); + }); + + describe('delete ticket field option', () => { + it('should process w/ valid input', () => { + expect(ticketFields.deleteOption({ field_id: 123, id: 456 })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/ticket_fields/123/options/456.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketFields.deleteOption()).toThrowError(); + expect(() => ticketFields.deleteOption('invalid')).toThrowError(); + expect(() => ticketFields.deleteOption({})).toThrowError(); + expect(() => + ticketFields.deleteOption({ field_id: 'invalid' }) + ).toThrowError(); + expect(() => + ticketFields.deleteOption({ field_id: 123, id: 'invalid' }) + ).toThrowError(); + }); + }); +}); From be50dc0addd9e3682d687cdd5bd8d3d9ccd0c8af Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Sun, 1 Sep 2019 16:42:25 -0700 Subject: [PATCH 05/14] added ticket fields & forms to support import --- src/api/v2/support.js | 9 +++++++-- tests/src/api/v2/support.test.js | 6 ++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/api/v2/support.js b/src/api/v2/support.js index 5ee5d86..9f0ab56 100644 --- a/src/api/v2/support.js +++ b/src/api/v2/support.js @@ -2,9 +2,14 @@ module.exports = ({ instance, headers }) => ({ groups: require('./routes/support/groups')({ instance, headers }), search: require('./routes/support/search')({ instance, headers }), tags: require('./routes/support/tags')({ instance, headers }), - tickets: require('./routes/support/tickets')({ instance, headers }), ticket_metrics: require('./routes/support/ticketMetrics')({ instance, headers - }) + }), + ticket_fields: require('./routes/support/ticketFields')({ + instance, + headers + }), + ticket_forms: require('./routes/support/ticketForms')({ instance, headers }), + tickets: require('./routes/support/tickets')({ instance, headers }) }); diff --git a/tests/src/api/v2/support.test.js b/tests/src/api/v2/support.test.js index f100950..4fbe4f7 100644 --- a/tests/src/api/v2/support.test.js +++ b/tests/src/api/v2/support.test.js @@ -13,8 +13,10 @@ describe('support api', () => { describe('tickets', () => { test('search', () => check(support.search, 'function')); - test('tickets', () => check(support.tickets)); - test('ticket_metrics', () => check(support.ticket_metrics)); test('tags', () => check(support.tags)); + test('ticket_fields', () => check(support.ticket_fields)); + test('ticket_forms', () => check(support.ticket_forms)); + test('ticket_metrics', () => check(support.ticket_metrics)); + test('tickets', () => check(support.tickets)); }); }); From 8a10c51a1df26c7523cef8baee50033f9d8f7cf6 Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Sun, 1 Sep 2019 17:32:58 -0700 Subject: [PATCH 06/14] built support.ticketComments --- src/api/v2/routes/support/ticketComments.js | 57 ++++++++++ src/api/v2/support.js | 6 +- .../v2/validators/support/ticketComments.js | 22 ++++ .../v2/routes/support/ticketComments.test.js | 100 ++++++++++++++++++ tests/src/api/v2/support.test.js | 1 + 5 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/api/v2/routes/support/ticketComments.js create mode 100644 src/api/v2/validators/support/ticketComments.js create mode 100644 tests/src/api/v2/routes/support/ticketComments.test.js diff --git a/src/api/v2/routes/support/ticketComments.js b/src/api/v2/routes/support/ticketComments.js new file mode 100644 index 0000000..eb7c3b7 --- /dev/null +++ b/src/api/v2/routes/support/ticketComments.js @@ -0,0 +1,57 @@ +const validate = require('../../validators/support/ticketComments'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + list: (options = {}) => { + const { error } = validate.list(options); + if (error) throw new Error(error.details[0].message); + + const { ticket_id } = options; + return { + method: 'GET', + url: `${url}/api/v2/tickets/${ticket_id}/comments.json`, + headers + }; + }, + + emailCCs: (options = {}) => { + const { error } = validate.emailCCs(options); + if (error) throw new Error(error.details[0].message); + + const { ticket_id } = options; + return { + method: 'GET', + url: `${url}/api/v2/tickets/${ticket_id}/comments.json?include=users`, + headers + }; + }, + + redact: (options = {}) => { + const { error } = validate.redact(options); + if (error) throw new Error(error.details[0].message); + + const { ticket_id, id, data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/tickets/${ticket_id}/comments/${id}/redact.json`, + headers, + data + }; + }, + + makePrivate: (options = {}) => { + const { error } = validate.makePrivate(options); + if (error) throw new Error(error.details[0].message); + + const { ticket_id, id } = options; + return { + method: 'PUT', + url: `${url}/api/v2/tickets/${ticket_id}/comments/${id}/make_private.json`, + headers, + data: {} + }; + } + }; +}; diff --git a/src/api/v2/support.js b/src/api/v2/support.js index 9f0ab56..a543da8 100644 --- a/src/api/v2/support.js +++ b/src/api/v2/support.js @@ -2,7 +2,7 @@ module.exports = ({ instance, headers }) => ({ groups: require('./routes/support/groups')({ instance, headers }), search: require('./routes/support/search')({ instance, headers }), tags: require('./routes/support/tags')({ instance, headers }), - ticket_metrics: require('./routes/support/ticketMetrics')({ + ticket_comments: require('./routes/support/ticketComments')({ instance, headers }), @@ -11,5 +11,9 @@ module.exports = ({ instance, headers }) => ({ headers }), ticket_forms: require('./routes/support/ticketForms')({ instance, headers }), + ticket_metrics: require('./routes/support/ticketMetrics')({ + instance, + headers + }), tickets: require('./routes/support/tickets')({ instance, headers }) }); diff --git a/src/api/v2/validators/support/ticketComments.js b/src/api/v2/validators/support/ticketComments.js new file mode 100644 index 0000000..cad6483 --- /dev/null +++ b/src/api/v2/validators/support/ticketComments.js @@ -0,0 +1,22 @@ +const Joi = require('@hapi/joi'); + +const id = Joi.number().min(1); +const ticket_id = Joi.number().min(1); +const data = Joi.object(); + +module.exports = { + list: options => Joi.validate(options, { ticket_id: ticket_id.required() }), + emailCCs: options => + Joi.validate(options, { ticket_id: ticket_id.required() }), + redact: options => + Joi.validate(options, { + ticket_id: ticket_id.required(), + id: id.required(), + data: data.required() + }), + makePrivate: options => + Joi.validate(options, { + ticket_id: ticket_id.required(), + id: id.required() + }) +}; diff --git a/tests/src/api/v2/routes/support/ticketComments.test.js b/tests/src/api/v2/routes/support/ticketComments.test.js new file mode 100644 index 0000000..432a114 --- /dev/null +++ b/tests/src/api/v2/routes/support/ticketComments.test.js @@ -0,0 +1,100 @@ +const endpoint = require('../../../../../../src/api/v2/routes/support/ticketComments'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('ticket comments', () => { + let ticketComments; + + beforeEach(() => (ticketComments = endpoint({ instance, headers }))); + afterEach(() => (ticketComments = null)); + + describe('list comments', () => { + it('should process w/ valid input', () => { + expect(ticketComments.list({ ticket_id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/tickets/123/comments.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketComments.list()).toThrowError(); + expect(() => ticketComments.list('invalid')).toThrowError(); + expect(() => + ticketComments.list({ ticket_id: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('list email ccs for a comment', () => { + it('should process w/ valid input', () => { + expect(ticketComments.emailCCs({ ticket_id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/tickets/123/comments.json?include=users`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketComments.emailCCs()).toThrowError(); + expect(() => ticketComments.emailCCs('invalid')).toThrowError(); + expect(() => + ticketComments.emailCCs({ ticket_id: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('redact string in comment', () => { + it('should process w/ valid input', () => { + expect( + ticketComments.redact({ ticket_id: 123, id: 456, data: {} }) + ).toEqual({ + method: 'PUT', + url: `${url}/api/v2/tickets/123/comments/456/redact.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketComments.redact()).toThrowError(); + expect(() => ticketComments.redact('invalid')).toThrowError(); + expect(() => + ticketComments.redact({ ticket_id: 'invalid' }) + ).toThrowError(); + expect(() => + ticketComments.redact({ ticket_id: 123, id: 'invalid' }) + ).toThrowError(); + expect(() => + ticketComments.redact({ ticket_id: 123, id: 456, data: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('make comment private', () => { + it('should process w/ valid input', () => { + expect(ticketComments.makePrivate({ ticket_id: 123, id: 456 })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/tickets/123/comments/456/make_private.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticketComments.makePrivate()).toThrowError(); + expect(() => ticketComments.makePrivate('invalid')).toThrowError(); + expect(() => + ticketComments.makePrivate({ ticket_id: 'invalid' }) + ).toThrowError(); + expect(() => + ticketComments.makePrivate({ ticket_id: 123, id: 'invalid' }) + ).toThrowError(); + }); + }); +}); diff --git a/tests/src/api/v2/support.test.js b/tests/src/api/v2/support.test.js index 4fbe4f7..8431a48 100644 --- a/tests/src/api/v2/support.test.js +++ b/tests/src/api/v2/support.test.js @@ -14,6 +14,7 @@ describe('support api', () => { describe('tickets', () => { test('search', () => check(support.search, 'function')); test('tags', () => check(support.tags)); + test('ticket_comments', () => check(support.ticket_comments)); test('ticket_fields', () => check(support.ticket_fields)); test('ticket_forms', () => check(support.ticket_forms)); test('ticket_metrics', () => check(support.ticket_metrics)); From 8c9736b718e03271028f767edaadf0e042fceffc Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Mon, 2 Sep 2019 12:07:15 -0700 Subject: [PATCH 07/14] folder struct reorg --- src/api/v2/support.js | 19 ------------------- src/v2.js | 3 --- src/v2/index.js | 3 +++ .../groups.js => v2/support/groups/index.js} | 2 +- .../support/groups/validate.js} | 0 src/v2/support/index.js | 11 +++++++++++ .../search.js => v2/support/search/index.js} | 2 +- .../support/search/validate.js} | 0 .../tags.js => v2/support/tags/index.js} | 2 +- .../tags.js => v2/support/tags/validate.js} | 0 .../support/ticket_comments/index.js} | 2 +- .../support/ticket_comments/validate.js} | 0 .../support/ticket_fields/index.js} | 2 +- .../support/ticket_fields/validate.js} | 0 .../support/ticket_forms/index.js} | 2 +- .../support/ticket_forms/validate.js} | 0 .../support/ticket_metrics/index.js} | 2 +- .../support/ticket_metrics/validate.js} | 0 .../support/tickets/index.js} | 2 +- .../support/tickets/validate.js} | 0 .../users.js => v2/support/users/index.js} | 2 +- .../users.js => v2/support/users/validate.js} | 0 tests/src/{api => }/v2.test.js | 11 +++-------- tests/src/{api => }/v2/support.test.js | 2 +- .../v2/routes => v2}/support/groups.test.js | 2 +- .../v2/routes => v2}/support/search.test.js | 2 +- .../v2/routes => v2}/support/tags.test.js | 2 +- .../support/ticket_comments.test.js} | 2 +- .../support/ticket_fields.test.js} | 2 +- .../support/ticket_forms.test.js} | 2 +- .../support/ticket_metrics.test.js} | 2 +- .../v2/routes => v2}/support/tickets.test.js | 2 +- .../v2/routes => v2}/support/users.test.js | 2 +- 33 files changed, 36 insertions(+), 49 deletions(-) delete mode 100644 src/api/v2/support.js delete mode 100644 src/v2.js create mode 100644 src/v2/index.js rename src/{api/v2/routes/support/groups.js => v2/support/groups/index.js} (96%) rename src/{api/v2/validators/support/groups.js => v2/support/groups/validate.js} (100%) create mode 100644 src/v2/support/index.js rename src/{api/v2/routes/support/search.js => v2/support/search/index.js} (86%) rename src/{api/v2/validators/support/search.js => v2/support/search/validate.js} (100%) rename src/{api/v2/routes/support/tags.js => v2/support/tags/index.js} (97%) rename src/{api/v2/validators/support/tags.js => v2/support/tags/validate.js} (100%) rename src/{api/v2/routes/support/ticketComments.js => v2/support/ticket_comments/index.js} (95%) rename src/{api/v2/validators/support/ticketComments.js => v2/support/ticket_comments/validate.js} (100%) rename src/{api/v2/routes/support/ticketFields.js => v2/support/ticket_fields/index.js} (97%) rename src/{api/v2/validators/support/ticketFields.js => v2/support/ticket_fields/validate.js} (100%) rename src/{api/v2/routes/support/ticketForms.js => v2/support/ticket_forms/index.js} (97%) rename src/{api/v2/validators/support/ticketForms.js => v2/support/ticket_forms/validate.js} (100%) rename src/{api/v2/routes/support/ticketMetrics.js => v2/support/ticket_metrics/index.js} (93%) rename src/{api/v2/validators/support/ticketMetrics.js => v2/support/ticket_metrics/validate.js} (100%) rename src/{api/v2/routes/support/tickets.js => v2/support/tickets/index.js} (99%) rename src/{api/v2/validators/support/tickets.js => v2/support/tickets/validate.js} (100%) rename src/{api/v2/routes/support/users.js => v2/support/users/index.js} (99%) rename src/{api/v2/validators/support/users.js => v2/support/users/validate.js} (100%) rename tests/src/{api => }/v2.test.js (50%) rename tests/src/{api => }/v2/support.test.js (92%) rename tests/src/{api/v2/routes => v2}/support/groups.test.js (97%) rename tests/src/{api/v2/routes => v2}/support/search.test.js (92%) rename tests/src/{api/v2/routes => v2}/support/tags.test.js (98%) rename tests/src/{api/v2/routes/support/ticketComments.test.js => v2/support/ticket_comments.test.js} (97%) rename tests/src/{api/v2/routes/support/ticketFields.test.js => v2/support/ticket_fields.test.js} (98%) rename tests/src/{api/v2/routes/support/ticketForms.test.js => v2/support/ticket_forms.test.js} (98%) rename tests/src/{api/v2/routes/support/ticketMetrics.test.js => v2/support/ticket_metrics.test.js} (95%) rename tests/src/{api/v2/routes => v2}/support/tickets.test.js (99%) rename tests/src/{api/v2/routes => v2}/support/users.test.js (99%) diff --git a/src/api/v2/support.js b/src/api/v2/support.js deleted file mode 100644 index a543da8..0000000 --- a/src/api/v2/support.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = ({ instance, headers }) => ({ - groups: require('./routes/support/groups')({ instance, headers }), - search: require('./routes/support/search')({ instance, headers }), - tags: require('./routes/support/tags')({ instance, headers }), - ticket_comments: require('./routes/support/ticketComments')({ - instance, - headers - }), - ticket_fields: require('./routes/support/ticketFields')({ - instance, - headers - }), - ticket_forms: require('./routes/support/ticketForms')({ instance, headers }), - ticket_metrics: require('./routes/support/ticketMetrics')({ - instance, - headers - }), - tickets: require('./routes/support/tickets')({ instance, headers }) -}); diff --git a/src/v2.js b/src/v2.js deleted file mode 100644 index 6e0b6e0..0000000 --- a/src/v2.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = ({ instance, headers }) => ({ - support: require('./api/v2/support')({ instance, headers }) -}); diff --git a/src/v2/index.js b/src/v2/index.js new file mode 100644 index 0000000..23b16dc --- /dev/null +++ b/src/v2/index.js @@ -0,0 +1,3 @@ +module.exports = ({ instance, headers }) => ({ + support: require('./support')({ instance, headers }) +}); diff --git a/src/api/v2/routes/support/groups.js b/src/v2/support/groups/index.js similarity index 96% rename from src/api/v2/routes/support/groups.js rename to src/v2/support/groups/index.js index 9085e2a..5ead783 100644 --- a/src/api/v2/routes/support/groups.js +++ b/src/v2/support/groups/index.js @@ -1,4 +1,4 @@ -const validate = require('../../validators/support/groups'); +const validate = require('./validate'); module.exports = ({ instance, headers }) => { const url = `https://${instance}.zendesk.com`; diff --git a/src/api/v2/validators/support/groups.js b/src/v2/support/groups/validate.js similarity index 100% rename from src/api/v2/validators/support/groups.js rename to src/v2/support/groups/validate.js diff --git a/src/v2/support/index.js b/src/v2/support/index.js new file mode 100644 index 0000000..73d7013 --- /dev/null +++ b/src/v2/support/index.js @@ -0,0 +1,11 @@ +module.exports = ({ instance, headers }) => ({ + groups: require('./groups')({ instance, headers }), + search: require('./search')({ instance, headers }), + tags: require('./tags')({ instance, headers }), + ticket_comments: require('./ticket_comments')({ instance, headers }), + ticket_fields: require('./ticket_fields')({ instance, headers }), + ticket_forms: require('./ticket_forms')({ instance, headers }), + ticket_metrics: require('./ticket_metrics')({ instance, headers }), + tickets: require('./tickets')({ instance, headers }), + users: require('./users')({ instance, headers }) +}); diff --git a/src/api/v2/routes/support/search.js b/src/v2/support/search/index.js similarity index 86% rename from src/api/v2/routes/support/search.js rename to src/v2/support/search/index.js index f80de3f..aee46b7 100644 --- a/src/api/v2/routes/support/search.js +++ b/src/v2/support/search/index.js @@ -1,4 +1,4 @@ -const validate = require('../../validators/support/search'); +const validate = require('./validate'); module.exports = ({ instance, headers }) => { const url = `https://${instance}.zendesk.com`; diff --git a/src/api/v2/validators/support/search.js b/src/v2/support/search/validate.js similarity index 100% rename from src/api/v2/validators/support/search.js rename to src/v2/support/search/validate.js diff --git a/src/api/v2/routes/support/tags.js b/src/v2/support/tags/index.js similarity index 97% rename from src/api/v2/routes/support/tags.js rename to src/v2/support/tags/index.js index 3d4e3bf..6059333 100644 --- a/src/api/v2/routes/support/tags.js +++ b/src/v2/support/tags/index.js @@ -1,4 +1,4 @@ -const validate = require('../../validators/support/tags'); +const validate = require('./validate'); module.exports = ({ instance, headers }) => { const url = `https://${instance}.zendesk.com`; diff --git a/src/api/v2/validators/support/tags.js b/src/v2/support/tags/validate.js similarity index 100% rename from src/api/v2/validators/support/tags.js rename to src/v2/support/tags/validate.js diff --git a/src/api/v2/routes/support/ticketComments.js b/src/v2/support/ticket_comments/index.js similarity index 95% rename from src/api/v2/routes/support/ticketComments.js rename to src/v2/support/ticket_comments/index.js index eb7c3b7..366ed78 100644 --- a/src/api/v2/routes/support/ticketComments.js +++ b/src/v2/support/ticket_comments/index.js @@ -1,4 +1,4 @@ -const validate = require('../../validators/support/ticketComments'); +const validate = require('./validate'); module.exports = ({ instance, headers }) => { const url = `https://${instance}.zendesk.com`; diff --git a/src/api/v2/validators/support/ticketComments.js b/src/v2/support/ticket_comments/validate.js similarity index 100% rename from src/api/v2/validators/support/ticketComments.js rename to src/v2/support/ticket_comments/validate.js diff --git a/src/api/v2/routes/support/ticketFields.js b/src/v2/support/ticket_fields/index.js similarity index 97% rename from src/api/v2/routes/support/ticketFields.js rename to src/v2/support/ticket_fields/index.js index 37fff81..4f29bb6 100644 --- a/src/api/v2/routes/support/ticketFields.js +++ b/src/v2/support/ticket_fields/index.js @@ -1,4 +1,4 @@ -const validate = require('../../validators/support/ticketFields'); +const validate = require('./validate'); module.exports = ({ instance, headers }) => { const url = `https://${instance}.zendesk.com`; diff --git a/src/api/v2/validators/support/ticketFields.js b/src/v2/support/ticket_fields/validate.js similarity index 100% rename from src/api/v2/validators/support/ticketFields.js rename to src/v2/support/ticket_fields/validate.js diff --git a/src/api/v2/routes/support/ticketForms.js b/src/v2/support/ticket_forms/index.js similarity index 97% rename from src/api/v2/routes/support/ticketForms.js rename to src/v2/support/ticket_forms/index.js index 0cbdc3c..3f4366b 100644 --- a/src/api/v2/routes/support/ticketForms.js +++ b/src/v2/support/ticket_forms/index.js @@ -1,4 +1,4 @@ -const validate = require('../../validators/support/ticketForms'); +const validate = require('./validate'); module.exports = ({ instance, headers }) => { const url = `https://${instance}.zendesk.com`; diff --git a/src/api/v2/validators/support/ticketForms.js b/src/v2/support/ticket_forms/validate.js similarity index 100% rename from src/api/v2/validators/support/ticketForms.js rename to src/v2/support/ticket_forms/validate.js diff --git a/src/api/v2/routes/support/ticketMetrics.js b/src/v2/support/ticket_metrics/index.js similarity index 93% rename from src/api/v2/routes/support/ticketMetrics.js rename to src/v2/support/ticket_metrics/index.js index c484970..2a86805 100644 --- a/src/api/v2/routes/support/ticketMetrics.js +++ b/src/v2/support/ticket_metrics/index.js @@ -1,4 +1,4 @@ -const validate = require('../../validators/support/ticketMetrics'); +const validate = require('./validate'); module.exports = ({ instance, headers }) => { const url = `https://${instance}.zendesk.com`; diff --git a/src/api/v2/validators/support/ticketMetrics.js b/src/v2/support/ticket_metrics/validate.js similarity index 100% rename from src/api/v2/validators/support/ticketMetrics.js rename to src/v2/support/ticket_metrics/validate.js diff --git a/src/api/v2/routes/support/tickets.js b/src/v2/support/tickets/index.js similarity index 99% rename from src/api/v2/routes/support/tickets.js rename to src/v2/support/tickets/index.js index e5a729a..89b4177 100644 --- a/src/api/v2/routes/support/tickets.js +++ b/src/v2/support/tickets/index.js @@ -1,4 +1,4 @@ -const validate = require('../../validators/support/tickets'); +const validate = require('./validate'); module.exports = ({ instance, headers }) => { const url = `https://${instance}.zendesk.com`; diff --git a/src/api/v2/validators/support/tickets.js b/src/v2/support/tickets/validate.js similarity index 100% rename from src/api/v2/validators/support/tickets.js rename to src/v2/support/tickets/validate.js diff --git a/src/api/v2/routes/support/users.js b/src/v2/support/users/index.js similarity index 99% rename from src/api/v2/routes/support/users.js rename to src/v2/support/users/index.js index 4603691..3cc57ba 100644 --- a/src/api/v2/routes/support/users.js +++ b/src/v2/support/users/index.js @@ -1,4 +1,4 @@ -const validate = require('../../validators/support/users'); +const validate = require('./validate'); module.exports = ({ instance, headers }) => { const url = `https://${instance}.zendesk.com`; diff --git a/src/api/v2/validators/support/users.js b/src/v2/support/users/validate.js similarity index 100% rename from src/api/v2/validators/support/users.js rename to src/v2/support/users/validate.js diff --git a/tests/src/api/v2.test.js b/tests/src/v2.test.js similarity index 50% rename from tests/src/api/v2.test.js rename to tests/src/v2.test.js index 4913265..213c961 100644 --- a/tests/src/api/v2.test.js +++ b/tests/src/v2.test.js @@ -1,4 +1,4 @@ -const v2 = require('../../../src/v2'); +const v2 = require('../../src/v2'); const instance = ''; const headers = {}; @@ -6,13 +6,8 @@ const headers = {}; describe('zaf v2', () => { let zaf; - beforeEach(() => { - zaf = v2({ instance, headers }); - }); - - afterEach(() => { - zaf = null; - }); + beforeEach(() => (zaf = v2({ instance, headers }))); + afterEach(() => (zaf = null)); test('support api', () => expect(zaf.support).toBeDefined()); }); diff --git a/tests/src/api/v2/support.test.js b/tests/src/v2/support.test.js similarity index 92% rename from tests/src/api/v2/support.test.js rename to tests/src/v2/support.test.js index 8431a48..e7347fa 100644 --- a/tests/src/api/v2/support.test.js +++ b/tests/src/v2/support.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../src/api/v2/support'); +const endpoint = require('../../../src/v2/support'); const instance = 'instance'; const headers = {}; diff --git a/tests/src/api/v2/routes/support/groups.test.js b/tests/src/v2/support/groups.test.js similarity index 97% rename from tests/src/api/v2/routes/support/groups.test.js rename to tests/src/v2/support/groups.test.js index 4856ab5..77695be 100644 --- a/tests/src/api/v2/routes/support/groups.test.js +++ b/tests/src/v2/support/groups.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../../../src/api/v2/routes/support/groups'); +const endpoint = require('../../../../src/v2/support/groups'); const instance = 'instance'; const url = `https://${instance}.zendesk.com`; diff --git a/tests/src/api/v2/routes/support/search.test.js b/tests/src/v2/support/search.test.js similarity index 92% rename from tests/src/api/v2/routes/support/search.test.js rename to tests/src/v2/support/search.test.js index c284c11..aed35af 100644 --- a/tests/src/api/v2/routes/support/search.test.js +++ b/tests/src/v2/support/search.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../../../src/api/v2/routes/support/search'); +const endpoint = require('../../../../src/v2/support/search'); const instance = 'instance'; const url = `https://${instance}.zendesk.com`; diff --git a/tests/src/api/v2/routes/support/tags.test.js b/tests/src/v2/support/tags.test.js similarity index 98% rename from tests/src/api/v2/routes/support/tags.test.js rename to tests/src/v2/support/tags.test.js index 733a580..678a4d9 100644 --- a/tests/src/api/v2/routes/support/tags.test.js +++ b/tests/src/v2/support/tags.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../../../src/api/v2/routes/support/tags'); +const endpoint = require('../../../../src/v2/support/tags'); const instance = 'instance'; const url = `https://${instance}.zendesk.com`; diff --git a/tests/src/api/v2/routes/support/ticketComments.test.js b/tests/src/v2/support/ticket_comments.test.js similarity index 97% rename from tests/src/api/v2/routes/support/ticketComments.test.js rename to tests/src/v2/support/ticket_comments.test.js index 432a114..b56b0d7 100644 --- a/tests/src/api/v2/routes/support/ticketComments.test.js +++ b/tests/src/v2/support/ticket_comments.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../../../src/api/v2/routes/support/ticketComments'); +const endpoint = require('../../../../src/v2/support/ticket_comments'); const instance = 'instance'; const url = `https://${instance}.zendesk.com`; diff --git a/tests/src/api/v2/routes/support/ticketFields.test.js b/tests/src/v2/support/ticket_fields.test.js similarity index 98% rename from tests/src/api/v2/routes/support/ticketFields.test.js rename to tests/src/v2/support/ticket_fields.test.js index 3ace5eb..8a2669e 100644 --- a/tests/src/api/v2/routes/support/ticketFields.test.js +++ b/tests/src/v2/support/ticket_fields.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../../../src/api/v2/routes/support/ticketFields'); +const endpoint = require('../../../../src/v2/support/ticket_fields'); const instance = 'instance'; const url = `https://${instance}.zendesk.com`; diff --git a/tests/src/api/v2/routes/support/ticketForms.test.js b/tests/src/v2/support/ticket_forms.test.js similarity index 98% rename from tests/src/api/v2/routes/support/ticketForms.test.js rename to tests/src/v2/support/ticket_forms.test.js index 41642ec..f898b93 100644 --- a/tests/src/api/v2/routes/support/ticketForms.test.js +++ b/tests/src/v2/support/ticket_forms.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../../../src/api/v2/routes/support/ticketForms'); +const endpoint = require('../../../../src/v2/support/ticket_forms'); const instance = 'instance'; const url = `https://${instance}.zendesk.com`; diff --git a/tests/src/api/v2/routes/support/ticketMetrics.test.js b/tests/src/v2/support/ticket_metrics.test.js similarity index 95% rename from tests/src/api/v2/routes/support/ticketMetrics.test.js rename to tests/src/v2/support/ticket_metrics.test.js index 73cc44a..d2bed25 100644 --- a/tests/src/api/v2/routes/support/ticketMetrics.test.js +++ b/tests/src/v2/support/ticket_metrics.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../../../src/api/v2/routes/support/ticketMetrics'); +const endpoint = require('../../../../src/v2/support/ticket_metrics'); const instance = 'instance'; const url = `https://${instance}.zendesk.com`; diff --git a/tests/src/api/v2/routes/support/tickets.test.js b/tests/src/v2/support/tickets.test.js similarity index 99% rename from tests/src/api/v2/routes/support/tickets.test.js rename to tests/src/v2/support/tickets.test.js index 0943a05..794a72e 100644 --- a/tests/src/api/v2/routes/support/tickets.test.js +++ b/tests/src/v2/support/tickets.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../../../src/api/v2/routes/support/tickets'); +const endpoint = require('../../../../src/v2/support/tickets'); const instance = 'instance'; const url = `https://${instance}.zendesk.com`; diff --git a/tests/src/api/v2/routes/support/users.test.js b/tests/src/v2/support/users.test.js similarity index 99% rename from tests/src/api/v2/routes/support/users.test.js rename to tests/src/v2/support/users.test.js index dcf9eac..bc0d9e4 100644 --- a/tests/src/api/v2/routes/support/users.test.js +++ b/tests/src/v2/support/users.test.js @@ -1,4 +1,4 @@ -const endpoint = require('../../../../../../src/api/v2/routes/support/users'); +const endpoint = require('../../../../src/v2/support/users'); const instance = 'instance'; const url = `https://${instance}.zendesk.com`; From ca6da50baeb0adcc1186192520a17584dead46a8 Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Mon, 2 Sep 2019 14:52:16 -0700 Subject: [PATCH 08/14] built support.organizations --- src/v2/support/index.js | 1 + src/v2/support/organizations/index.js | 190 +++++++++++++ src/v2/support/organizations/validate.js | 28 ++ tests/src/v2/support.test.js | 3 + tests/src/v2/support/organizations.test.js | 306 +++++++++++++++++++++ 5 files changed, 528 insertions(+) create mode 100644 src/v2/support/organizations/index.js create mode 100644 src/v2/support/organizations/validate.js create mode 100644 tests/src/v2/support/organizations.test.js diff --git a/src/v2/support/index.js b/src/v2/support/index.js index 73d7013..4a6d598 100644 --- a/src/v2/support/index.js +++ b/src/v2/support/index.js @@ -1,5 +1,6 @@ module.exports = ({ instance, headers }) => ({ groups: require('./groups')({ instance, headers }), + organizations: require('./organizations')({ instance, headers }), search: require('./search')({ instance, headers }), tags: require('./tags')({ instance, headers }), ticket_comments: require('./ticket_comments')({ instance, headers }), diff --git a/src/v2/support/organizations/index.js b/src/v2/support/organizations/index.js new file mode 100644 index 0000000..d288aef --- /dev/null +++ b/src/v2/support/organizations/index.js @@ -0,0 +1,190 @@ +const validate = require('./validate'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + list: (options = {}) => { + const { error } = validate.list(options); + if (error) throw new Error(error.details[0].message); + + const { user_id = '' } = options; + const part = user_id ? `/users/${user_id}` : ''; + return { + method: 'GET', + url: `${url}/api/v2${part}/organizations.json`, + headers + }; + }, + + autocomplete: (options = {}) => { + const { error } = validate.autocomplete(options); + if (error) throw new Error(error.details[0].message); + + const { name } = options; + return { + method: 'GET', + url: `${url}/api/v2/organizations/autocomplete.json?name=${name}`, + headers + }; + }, + + related: (options = {}) => { + const { error } = validate.related(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/organizations/${id}/related.json`, + headers + }; + }, + + show: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/organizations/${id}.json`, + headers + }; + }, + + show_many: (options = {}) => { + const { error } = validate.show_many(options); + if (error) throw new Error(error.details[0].message); + + const { ids = '', external_ids = '' } = options; + if ((!ids && !external_ids) || (ids && external_ids)) + throw new Error( + 'either "user_ids" or "external_ids" must be set, not both' + ); + + const part = ids ? `?ids=${ids}` : `?external_ids=${external_ids}`; + return { + method: 'GET', + url: `${url}/api/v2/organizations/show_many.json${part}`, + headers + }; + }, + + create: (options = {}) => { + const { error } = validate.create(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/organizations.json`, + headers, + data + }; + }, + + create_many: (options = {}) => { + const { error } = validate.create_many(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/organizations/create_many.json`, + headers, + data + }; + }, + + create_or_update: (options = {}) => { + const { error } = validate.create_or_update(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/organizations/create_or_update.json`, + headers, + data + }; + }, + + update: (options = {}) => { + const { error } = validate.update(options); + if (error) throw new Error(error.details[0].message); + + const { id, data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/organizations/${id}.json`, + headers, + data + }; + }, + + update_many: (options = {}) => { + const { error } = validate.update_many(options); + if (error) throw new Error(error.details[0].message); + + const { ids, external_ids, data } = options; + if (ids && external_ids) + throw new Error('either "ids" or "external_ids" can be set, not both'); + + const part = ids + ? `?ids=${ids}` + : external_ids + ? `?external_ids=${external_ids}` + : ''; + + return { + method: 'PUT', + url: `${url}/api/v2/organizations/update_many.json${part}`, + headers, + data + }; + }, + + delete: (options = {}) => { + const { error } = validate.delete(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/organizations/${id}.json`, + headers + }; + }, + + delete_many: (options = {}) => { + const { error } = validate.delete_many(options); + if (error) throw new Error(error.details[0].message); + + const { ids, external_ids } = options; + if ((!ids && !external_ids) || (ids && external_ids)) + throw new Error( + 'either "user_ids" or "external_ids" must be set, not both' + ); + + const part = ids ? `?ids=${ids}` : `?external_ids=${external_ids}`; + return { + method: 'DELETE', + url: `${url}/api/v2/organizations/destroy_many.json${part}`, + headers + }; + }, + + search: (options = {}) => { + const { error } = validate.search(options); + if (error) throw new Error(error.details[0].message); + + const { external_id } = options; + return { + method: 'GET', + url: `${url}/api/v2/organizations/search.json?external_id=${external_id}`, + headers + }; + } + }; +}; diff --git a/src/v2/support/organizations/validate.js b/src/v2/support/organizations/validate.js new file mode 100644 index 0000000..d9e2365 --- /dev/null +++ b/src/v2/support/organizations/validate.js @@ -0,0 +1,28 @@ +const Joi = require('@hapi/joi'); + +const id = Joi.number().min(1); +const ids = Joi.string().min(3); +const user_id = Joi.number().min(1); +const external_id = Joi.number().min(1); +const external_ids = Joi.string().min(1); +const name = Joi.string().min(1); +const data = Joi.object(); + +module.exports = { + list: options => Joi.validate(options, { user_id }), + autocomplete: options => Joi.validate(options, { name: name.required() }), + related: options => Joi.validate(options, { id: id.required() }), + show: options => Joi.validate(options, { id: id.required() }), + show_many: options => Joi.validate(options, { ids, external_ids }), + create: options => Joi.validate(options, { data: data.required() }), + create_many: options => Joi.validate(options, { data: data.required() }), + create_or_update: options => Joi.validate(options, { data: data.required() }), + update: options => + Joi.validate(options, { id: id.required(), data: data.required() }), + update_many: options => + Joi.validate(options, { ids, external_ids, data: data.required() }), + delete: options => Joi.validate(options, { id: id.required() }), + delete_many: options => Joi.validate(options, { ids, external_ids }), + search: options => + Joi.validate(options, { external_id: external_id.required() }) +}; diff --git a/tests/src/v2/support.test.js b/tests/src/v2/support.test.js index e7347fa..817df4d 100644 --- a/tests/src/v2/support.test.js +++ b/tests/src/v2/support.test.js @@ -12,6 +12,8 @@ describe('support api', () => { afterEach(() => (support = null)); describe('tickets', () => { + test('groups', () => check(support.groups)); + test('organizations', () => check(support.organizations)); test('search', () => check(support.search, 'function')); test('tags', () => check(support.tags)); test('ticket_comments', () => check(support.ticket_comments)); @@ -19,5 +21,6 @@ describe('support api', () => { test('ticket_forms', () => check(support.ticket_forms)); test('ticket_metrics', () => check(support.ticket_metrics)); test('tickets', () => check(support.tickets)); + test('users', () => check(support.users)); }); }); diff --git a/tests/src/v2/support/organizations.test.js b/tests/src/v2/support/organizations.test.js new file mode 100644 index 0000000..6a18edd --- /dev/null +++ b/tests/src/v2/support/organizations.test.js @@ -0,0 +1,306 @@ +const endpoint = require('../../../../src/v2/support/organizations'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('organizations', () => { + let organizations; + + beforeEach(() => (organizations = endpoint({ instance, headers }))); + afterEach(() => (organizations = null)); + + describe('list organizations', () => { + it('should process w/ valid input', () => { + expect(organizations.list()).toEqual({ + method: 'GET', + url: `${url}/api/v2/organizations.json`, + headers + }); + + expect(organizations.list({ user_id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/users/123/organizations.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.list('invalid')).toThrowError(); + expect(() => organizations.list({ user_id: 'invalid' })).toThrowError(); + }); + }); + + describe('autocomplete organizations', () => { + it('should process w/ valid input', () => { + expect(organizations.autocomplete({ name: 'name' })).toEqual({ + method: 'GET', + url: `${url}/api/v2/organizations/autocomplete.json?name=name`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.autocomplete()).toThrowError(); + expect(() => organizations.autocomplete({})).toThrowError(); + expect(() => organizations.autocomplete('invalid')).toThrowError(); + expect(() => organizations.autocomplete({ name: 0 })).toThrowError(); + expect(() => organizations.autocomplete({ name: '' })).toThrowError(); + }); + }); + + describe("show organizations's related information", () => { + it('should process w/ valid input', () => { + expect(organizations.related({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/organizations/123/related.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.related()).toThrowError(); + expect(() => organizations.related({})).toThrowError(); + expect(() => organizations.related('invalid')).toThrowError(); + expect(() => organizations.related({ id: 0 })).toThrowError(); + expect(() => organizations.related({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('show organization', () => { + it('should process w/ valid input', () => { + expect(organizations.show({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/organizations/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.show()).toThrowError(); + expect(() => organizations.show({})).toThrowError(); + expect(() => organizations.show('invalid')).toThrowError(); + expect(() => organizations.show({ id: 0 })).toThrowError(); + expect(() => organizations.show({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('show many organizations', () => { + it('should process w/ valid input', () => { + expect(organizations.show_many({ ids: '1,2,3' })).toEqual({ + method: 'GET', + url: `${url}/api/v2/organizations/show_many.json?ids=1,2,3`, + headers + }); + + expect(organizations.show_many({ external_ids: '4,5,6' })).toEqual({ + method: 'GET', + url: `${url}/api/v2/organizations/show_many.json?external_ids=4,5,6`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.show_many()).toThrowError(); + expect(() => organizations.show_many({})).toThrowError(); + expect(() => organizations.show_many('invalid')).toThrowError(); + expect(() => organizations.show_many({ ids: 0 })).toThrowError(); + expect(() => organizations.show_many({ external_ids: 0 })).toThrowError(); + expect(() => + organizations.show_many({ ids: '1,2,3', external_ids: '4,5,6' }) + ).toThrowError(); + }); + }); + + describe('create organization', () => { + it('should process w/ valid input', () => { + expect(organizations.create({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/organizations.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.create()).toThrowError(); + expect(() => organizations.create({})).toThrowError(); + expect(() => organizations.create('invalid')).toThrowError(); + expect(() => organizations.create({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('create many organizations', () => { + it('should process w/ valid input', () => { + expect(organizations.create_many({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/organizations/create_many.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.create_many()).toThrowError(); + expect(() => organizations.create_many({})).toThrowError(); + expect(() => organizations.create_many('invalid')).toThrowError(); + expect(() => + organizations.create_many({ data: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('create or update organization', () => { + it('should process w/ valid input', () => { + expect(organizations.create_or_update({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/organizations/create_or_update.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.create_or_update()).toThrowError(); + expect(() => organizations.create_or_update({})).toThrowError(); + expect(() => organizations.create_or_update('invalid')).toThrowError(); + expect(() => + organizations.create_or_update({ data: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('update organization', () => { + it('should process w/ valid input', () => { + expect(organizations.update({ id: 123, data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/organizations/123.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.update()).toThrowError(); + expect(() => organizations.update({})).toThrowError(); + expect(() => organizations.update('invalid')).toThrowError(); + expect(() => organizations.update({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('update many organizations', () => { + it('should process w/ valid input', () => { + expect(organizations.update_many({ data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/organizations/update_many.json`, + headers, + data: {} + }); + + expect(organizations.update_many({ ids: '1,2,3', data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/organizations/update_many.json?ids=1,2,3`, + headers, + data: {} + }); + + expect( + organizations.update_many({ external_ids: '4,5,6', data: {} }) + ).toEqual({ + method: 'PUT', + url: `${url}/api/v2/organizations/update_many.json?external_ids=4,5,6`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.update_many()).toThrowError(); + expect(() => organizations.update_many({})).toThrowError(); + expect(() => organizations.update_many('invalid')).toThrowError(); + expect(() => + organizations.update_many({ data: 'invalid' }) + ).toThrowError(); + expect(() => + organizations.update_many({ ids: 0, data: {} }) + ).toThrowError(); + expect(() => + organizations.update_many({ external_ids: 0, data: {} }) + ).toThrowError(); + expect(() => + organizations.update_many({ + ids: '1,2,3', + external_ids: '4,5,6', + data: {} + }) + ).toThrowError(); + }); + }); + + describe('delete organization', () => { + it('should process w/ valid input', () => { + expect(organizations.delete({ id: 123 })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/organizations/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.delete()).toThrowError(); + expect(() => organizations.delete({})).toThrowError(); + expect(() => organizations.delete('invalid')).toThrowError(); + expect(() => organizations.delete({ id: 0 })).toThrowError(); + expect(() => organizations.delete({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('bulk delete organizations', () => { + it('should process w/ valid input', () => { + expect(organizations.delete_many({ ids: '1,2,3' })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/organizations/destroy_many.json?ids=1,2,3`, + headers + }); + + expect(organizations.delete_many({ external_ids: '4,5,6' })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/organizations/destroy_many.json?external_ids=4,5,6`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.delete_many()).toThrowError(); + expect(() => organizations.delete_many({})).toThrowError(); + expect(() => organizations.delete_many('invalid')).toThrowError(); + expect(() => organizations.delete_many({ ids: 0 })).toThrowError(); + expect(() => + organizations.delete_many({ external_ids: 0 }) + ).toThrowError(); + expect(() => + organizations.delete_many({ ids: '1,2,3', external_ids: '4,5,6' }) + ).toThrowError(); + }); + }); + + describe('search organization by external id', () => { + it('should process w/ valid input', () => { + expect(organizations.search({ external_id: '123' })).toEqual({ + method: 'GET', + url: `${url}/api/v2/organizations/search.json?external_id=123`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organizations.search()).toThrowError(); + expect(() => organizations.search({})).toThrowError(); + expect(() => organizations.search('invalid')).toThrowError(); + expect(() => organizations.search({ external_id: 0 })).toThrowError(); + }); + }); +}); From 7667122608ce26700b5e4895c153605c61050dfc Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Mon, 2 Sep 2019 15:26:56 -0700 Subject: [PATCH 09/14] built support.organization_fields --- src/v2/support/index.js | 1 + src/v2/support/organization_fields/index.js | 80 +++++++++++ .../support/organization_fields/validate.js | 14 ++ tests/src/v2/support.test.js | 23 ++-- .../v2/support/organization_fields.test.js | 127 ++++++++++++++++++ 5 files changed, 233 insertions(+), 12 deletions(-) create mode 100644 src/v2/support/organization_fields/index.js create mode 100644 src/v2/support/organization_fields/validate.js create mode 100644 tests/src/v2/support/organization_fields.test.js diff --git a/src/v2/support/index.js b/src/v2/support/index.js index 4a6d598..5a950f4 100644 --- a/src/v2/support/index.js +++ b/src/v2/support/index.js @@ -1,6 +1,7 @@ module.exports = ({ instance, headers }) => ({ groups: require('./groups')({ instance, headers }), organizations: require('./organizations')({ instance, headers }), + organization_fields: require('./organization_fields')({ instance, headers }), search: require('./search')({ instance, headers }), tags: require('./tags')({ instance, headers }), ticket_comments: require('./ticket_comments')({ instance, headers }), diff --git a/src/v2/support/organization_fields/index.js b/src/v2/support/organization_fields/index.js new file mode 100644 index 0000000..86105c1 --- /dev/null +++ b/src/v2/support/organization_fields/index.js @@ -0,0 +1,80 @@ +const validate = require('./validate'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + list: (options = null) => { + if (options) throw new Error('no options are allowed'); + + return { + method: 'GET', + url: `${url}/api/v2/organization_fields.json`, + headers + }; + }, + + show: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/organization_fields/${id}.json`, + headers + }; + }, + + create: (options = {}) => { + const { error } = validate.create(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/organization_fields.json`, + headers, + data + }; + }, + + update: (options = {}) => { + const { error } = validate.update(options); + if (error) throw new Error(error.details[0].message); + + const { id, data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/organization_fields/${id}.json`, + headers, + data + }; + }, + + delete: (options = {}) => { + const { error } = validate.delete(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/organization_fields/${id}.json`, + headers + }; + }, + + reorder: (options = {}) => { + const { error } = validate.reorder(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/organization_fields/reorder.json`, + headers, + data + }; + } + }; +}; diff --git a/src/v2/support/organization_fields/validate.js b/src/v2/support/organization_fields/validate.js new file mode 100644 index 0000000..d82ad53 --- /dev/null +++ b/src/v2/support/organization_fields/validate.js @@ -0,0 +1,14 @@ +const Joi = require('@hapi/joi'); + +const id = Joi.number().min(1); +const data = Joi.object(); + +module.exports = { + list: null, // no options + show: options => Joi.validate(options, { id: id.required() }), + create: options => Joi.validate(options, { data: data.required() }), + update: options => + Joi.validate(options, { id: id.required(), data: data.required() }), + delete: options => Joi.validate(options, { id: id.required() }), + reorder: options => Joi.validate(options, { data: data.required() }) +}; diff --git a/tests/src/v2/support.test.js b/tests/src/v2/support.test.js index 817df4d..5692c44 100644 --- a/tests/src/v2/support.test.js +++ b/tests/src/v2/support.test.js @@ -11,16 +11,15 @@ describe('support api', () => { beforeEach(() => (support = endpoint({ instance, headers }))); afterEach(() => (support = null)); - describe('tickets', () => { - test('groups', () => check(support.groups)); - test('organizations', () => check(support.organizations)); - test('search', () => check(support.search, 'function')); - test('tags', () => check(support.tags)); - test('ticket_comments', () => check(support.ticket_comments)); - test('ticket_fields', () => check(support.ticket_fields)); - test('ticket_forms', () => check(support.ticket_forms)); - test('ticket_metrics', () => check(support.ticket_metrics)); - test('tickets', () => check(support.tickets)); - test('users', () => check(support.users)); - }); + test('groups', () => check(support.groups)); + test('organizations', () => check(support.organizations)); + test('organization_fields', () => check(support.organization_fields)); + test('search', () => check(support.search, 'function')); + test('tags', () => check(support.tags)); + test('ticket_comments', () => check(support.ticket_comments)); + test('ticket_fields', () => check(support.ticket_fields)); + test('ticket_forms', () => check(support.ticket_forms)); + test('ticket_metrics', () => check(support.ticket_metrics)); + test('tickets', () => check(support.tickets)); + test('users', () => check(support.users)); }); diff --git a/tests/src/v2/support/organization_fields.test.js b/tests/src/v2/support/organization_fields.test.js new file mode 100644 index 0000000..4abf2d0 --- /dev/null +++ b/tests/src/v2/support/organization_fields.test.js @@ -0,0 +1,127 @@ +const endpoint = require('../../../../src/v2/support/organization_fields'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('organizations', () => { + let organization_fields; + + beforeEach(() => (organization_fields = endpoint({ instance, headers }))); + afterEach(() => (organization_fields = null)); + + describe('list organization fields', () => { + it('should process w/ valid input', () => { + expect(organization_fields.list()).toEqual({ + method: 'GET', + url: `${url}/api/v2/organization_fields.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organization_fields.list('invalid')).toThrowError(); + }); + }); + + describe('show organization field', () => { + it('should process w/ valid input', () => { + expect(organization_fields.show({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/organization_fields/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organization_fields.show()).toThrowError(); + expect(() => organization_fields.show({})).toThrowError(); + expect(() => organization_fields.show('invalid')).toThrowError(); + expect(() => organization_fields.show({ id: 0 })).toThrowError(); + expect(() => organization_fields.show({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('create organization fields', () => { + it('should process w/ valid input', () => { + expect(organization_fields.create({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/organization_fields.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organization_fields.create()).toThrowError(); + expect(() => organization_fields.create({})).toThrowError(); + expect(() => organization_fields.create('invalid')).toThrowError(); + expect(() => + organization_fields.create({ ids: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('update organization fields', () => { + it('should process w/ valid input', () => { + expect(organization_fields.update({ id: 123, data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/organization_fields/123.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organization_fields.update()).toThrowError(); + expect(() => organization_fields.update({})).toThrowError(); + expect(() => organization_fields.update('invalid')).toThrowError(); + expect(() => + organization_fields.update({ data: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('delete organization fields', () => { + it('should process w/ valid input', () => { + expect(organization_fields.delete({ id: 123 })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/organization_fields/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organization_fields.delete()).toThrowError(); + expect(() => organization_fields.delete({})).toThrowError(); + expect(() => organization_fields.delete('invalid')).toThrowError(); + expect(() => organization_fields.delete({ id: 0 })).toThrowError(); + expect(() => + organization_fields.delete({ id: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('reorder organization field', () => { + it('should process w/ valid input', () => { + expect(organization_fields.reorder({ data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/organization_fields/reorder.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => organization_fields.reorder()).toThrowError(); + expect(() => organization_fields.reorder({})).toThrowError(); + expect(() => organization_fields.reorder('invalid')).toThrowError(); + expect(() => + organization_fields.reorder({ data: 'invalid' }) + ).toThrowError(); + }); + }); +}); From 18aed240cbf384670489c18f7193c4542e741c0f Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Mon, 2 Sep 2019 15:43:04 -0700 Subject: [PATCH 10/14] build support.end_users --- src/v2/support/end_users/index.js | 32 ++++++++++++++++ src/v2/support/end_users/validate.js | 10 +++++ src/v2/support/index.js | 1 + tests/src/v2/support.test.js | 1 + tests/src/v2/support/end_users.test.js | 53 ++++++++++++++++++++++++++ 5 files changed, 97 insertions(+) create mode 100644 src/v2/support/end_users/index.js create mode 100644 src/v2/support/end_users/validate.js create mode 100644 tests/src/v2/support/end_users.test.js diff --git a/src/v2/support/end_users/index.js b/src/v2/support/end_users/index.js new file mode 100644 index 0000000..989aebd --- /dev/null +++ b/src/v2/support/end_users/index.js @@ -0,0 +1,32 @@ +const validate = require('./validate'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + show: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/end_users/${id}.json`, + headers + }; + }, + + update: (options = {}) => { + const { error } = validate.update(options); + if (error) throw new Error(error.details[0].message); + + const { id, data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/end_users/${id}.json`, + headers, + data + }; + } + }; +}; diff --git a/src/v2/support/end_users/validate.js b/src/v2/support/end_users/validate.js new file mode 100644 index 0000000..a9a084b --- /dev/null +++ b/src/v2/support/end_users/validate.js @@ -0,0 +1,10 @@ +const Joi = require('@hapi/joi'); + +const id = Joi.number().min(1); +const data = Joi.object(); + +module.exports = { + show: options => Joi.validate(options, { id: id.required() }), + update: options => + Joi.validate(options, { id: id.required(), data: data.required() }) +}; diff --git a/src/v2/support/index.js b/src/v2/support/index.js index 5a950f4..e111b5b 100644 --- a/src/v2/support/index.js +++ b/src/v2/support/index.js @@ -1,4 +1,5 @@ module.exports = ({ instance, headers }) => ({ + end_users: require('./end_users')({ instance, headers }), groups: require('./groups')({ instance, headers }), organizations: require('./organizations')({ instance, headers }), organization_fields: require('./organization_fields')({ instance, headers }), diff --git a/tests/src/v2/support.test.js b/tests/src/v2/support.test.js index 5692c44..00dfa67 100644 --- a/tests/src/v2/support.test.js +++ b/tests/src/v2/support.test.js @@ -11,6 +11,7 @@ describe('support api', () => { beforeEach(() => (support = endpoint({ instance, headers }))); afterEach(() => (support = null)); + test('end_users', () => check(support.end_users)); test('groups', () => check(support.groups)); test('organizations', () => check(support.organizations)); test('organization_fields', () => check(support.organization_fields)); diff --git a/tests/src/v2/support/end_users.test.js b/tests/src/v2/support/end_users.test.js new file mode 100644 index 0000000..95ff1e0 --- /dev/null +++ b/tests/src/v2/support/end_users.test.js @@ -0,0 +1,53 @@ +const endpoint = require('../../../../src/v2/support/end_users'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('end users', () => { + let end_users; + + beforeEach(() => (end_users = endpoint({ instance, headers }))); + afterEach(() => (end_users = null)); + + describe('show user', () => { + it('should process w/ valid input', () => { + expect(end_users.show({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/end_users/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => end_users.show()).toThrowError(); + expect(() => end_users.show('invalid')).toThrowError(); + expect(() => end_users.show({})).toThrowError(); + expect(() => end_users.show({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('update user', () => { + it('should process w/ valid input', () => { + expect(end_users.update({ id: 123, data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/end_users/123.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => end_users.update()).toThrowError(); + expect(() => end_users.update('invalid')).toThrowError(); + expect(() => end_users.update({})).toThrowError(); + expect(() => end_users.update({ id: 'invalid' })).toThrowError(); + expect(() => + end_users.update({ id: 123, data: 'invalid' }) + ).toThrowError(); + }); + }); +}); From 40473e5fabfad35a403b8289dd3f5ac7ce4574d4 Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Mon, 2 Sep 2019 15:57:13 -0700 Subject: [PATCH 11/14] built support.ticket_activities --- src/v2/support/index.js | 1 + src/v2/support/ticket_activities/index.js | 29 +++++++++++ src/v2/support/ticket_activities/validate.js | 9 ++++ tests/src/v2/support.test.js | 1 + .../src/v2/support/ticket_activities.test.js | 48 +++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 src/v2/support/ticket_activities/index.js create mode 100644 src/v2/support/ticket_activities/validate.js create mode 100644 tests/src/v2/support/ticket_activities.test.js diff --git a/src/v2/support/index.js b/src/v2/support/index.js index e111b5b..df823fa 100644 --- a/src/v2/support/index.js +++ b/src/v2/support/index.js @@ -5,6 +5,7 @@ module.exports = ({ instance, headers }) => ({ organization_fields: require('./organization_fields')({ instance, headers }), search: require('./search')({ instance, headers }), tags: require('./tags')({ instance, headers }), + ticket_activities: require('./ticket_activities')({ instance, headers }), ticket_comments: require('./ticket_comments')({ instance, headers }), ticket_fields: require('./ticket_fields')({ instance, headers }), ticket_forms: require('./ticket_forms')({ instance, headers }), diff --git a/src/v2/support/ticket_activities/index.js b/src/v2/support/ticket_activities/index.js new file mode 100644 index 0000000..646e4d0 --- /dev/null +++ b/src/v2/support/ticket_activities/index.js @@ -0,0 +1,29 @@ +const validate = require('./validate'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + list: (options = null) => { + if (options) throw new Error('no options are allowed'); + + return { + method: 'GET', + url: `${url}/api/v2/activities.json`, + headers + }; + }, + + show: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { activity_id } = options; + return { + method: 'GET', + url: `${url}/api/v2/activities/${activity_id}.json`, + headers + }; + } + }; +}; diff --git a/src/v2/support/ticket_activities/validate.js b/src/v2/support/ticket_activities/validate.js new file mode 100644 index 0000000..bd5f186 --- /dev/null +++ b/src/v2/support/ticket_activities/validate.js @@ -0,0 +1,9 @@ +const Joi = require('@hapi/joi'); + +const activity_id = Joi.number().min(1); + +module.exports = { + list: null, // no options + show: options => + Joi.validate(options, { activity_id: activity_id.required() }) +}; diff --git a/tests/src/v2/support.test.js b/tests/src/v2/support.test.js index 00dfa67..a5d8b7e 100644 --- a/tests/src/v2/support.test.js +++ b/tests/src/v2/support.test.js @@ -17,6 +17,7 @@ describe('support api', () => { test('organization_fields', () => check(support.organization_fields)); test('search', () => check(support.search, 'function')); test('tags', () => check(support.tags)); + test('ticket_activities', () => check(support.ticket_activities)); test('ticket_comments', () => check(support.ticket_comments)); test('ticket_fields', () => check(support.ticket_fields)); test('ticket_forms', () => check(support.ticket_forms)); diff --git a/tests/src/v2/support/ticket_activities.test.js b/tests/src/v2/support/ticket_activities.test.js new file mode 100644 index 0000000..567eec2 --- /dev/null +++ b/tests/src/v2/support/ticket_activities.test.js @@ -0,0 +1,48 @@ +const endpoint = require('../../../../src/v2/support/ticket_activities'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('end users', () => { + let ticket_activities; + + beforeEach(() => (ticket_activities = endpoint({ instance, headers }))); + afterEach(() => (ticket_activities = null)); + + describe('list activities', () => { + it('should process w/ valid input', () => { + expect(ticket_activities.list()).toEqual({ + method: 'GET', + url: `${url}/api/v2/activities.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticket_activities.list('invalid')).toThrowError(); + }); + }); + + describe('show activity', () => { + it('should process w/ valid input', () => { + expect(ticket_activities.show({ activity_id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/activities/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => ticket_activities.show()).toThrowError(); + expect(() => ticket_activities.show('invalid')).toThrowError(); + expect(() => ticket_activities.show({})).toThrowError(); + expect(() => + ticket_activities.show({ activity_id: 'invalid' }) + ).toThrowError(); + }); + }); +}); From 9e476c3167e819075ae20661a8f3c675f0c5d44a Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Mon, 2 Sep 2019 16:39:14 -0700 Subject: [PATCH 12/14] built support.user_fields --- src/v2/support/index.js | 1 + src/v2/support/user_fields/index.js | 129 ++++++++++++++ src/v2/support/user_fields/validate.js | 26 +++ tests/src/v2/support.test.js | 1 + tests/src/v2/support/user_fields.test.js | 208 +++++++++++++++++++++++ 5 files changed, 365 insertions(+) create mode 100644 src/v2/support/user_fields/index.js create mode 100644 src/v2/support/user_fields/validate.js create mode 100644 tests/src/v2/support/user_fields.test.js diff --git a/src/v2/support/index.js b/src/v2/support/index.js index df823fa..4939374 100644 --- a/src/v2/support/index.js +++ b/src/v2/support/index.js @@ -11,5 +11,6 @@ module.exports = ({ instance, headers }) => ({ ticket_forms: require('./ticket_forms')({ instance, headers }), ticket_metrics: require('./ticket_metrics')({ instance, headers }), tickets: require('./tickets')({ instance, headers }), + user_fields: require('./user_fields')({ instance, headers }), users: require('./users')({ instance, headers }) }); diff --git a/src/v2/support/user_fields/index.js b/src/v2/support/user_fields/index.js new file mode 100644 index 0000000..e5b3e7b --- /dev/null +++ b/src/v2/support/user_fields/index.js @@ -0,0 +1,129 @@ +const validate = require('./validate'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + list: (options = null) => { + if (options) throw new Error('no options are allowed'); + + return { + method: 'GET', + url: `${url}/api/v2/user_fields.json`, + headers + }; + }, + + show: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/user_fields/${id}.json`, + headers + }; + }, + + create: (options = {}) => { + const { error } = validate.create(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/user_fields.json`, + headers, + data + }; + }, + + update: (options = {}) => { + const { error } = validate.update(options); + if (error) throw new Error(error.details[0].message); + + const { id, data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/user_fields/${id}.json`, + headers, + data + }; + }, + + delete: (options = {}) => { + const { error } = validate.delete(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/user_fields/${id}.json`, + headers + }; + }, + + reorder: (options = {}) => { + const { error } = validate.reorder(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/user_fields/reorder.json`, + headers, + data + }; + }, + + listOptions: (options = {}) => { + const { error } = validate.listOptions(options); + if (error) throw new Error(error.details[0].message); + + const { field_id } = options; + return { + method: 'GET', + url: `${url}/api/v2/user_fields/${field_id}/options.json`, + headers + }; + }, + + showOption: (options = {}) => { + const { error } = validate.showOption(options); + if (error) throw new Error(error.details[0].message); + + const { field_id, id } = options; + return { + method: 'GET', + url: `${url}/api/v2/ticket_fields/${field_id}/options/${id}.json`, + headers + }; + }, + + createOrUpdateOption: (options = {}) => { + const { error } = validate.createOrUpdateOption(options); + if (error) throw new Error(error.details[0].message); + + const { field_id, data } = options; + return { + method: 'POST', + url: `${url}/api/v2/user_fields/${field_id}/options.json`, + headers, + data + }; + }, + + deleteOption: (options = {}) => { + const { error } = validate.deleteOption(options); + if (error) throw new Error(error.details[0].message); + + const { field_id, id } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/user_fields/${field_id}/options/${id}.json`, + headers + }; + } + }; +}; diff --git a/src/v2/support/user_fields/validate.js b/src/v2/support/user_fields/validate.js new file mode 100644 index 0000000..81a367d --- /dev/null +++ b/src/v2/support/user_fields/validate.js @@ -0,0 +1,26 @@ +const Joi = require('@hapi/joi'); + +const id = Joi.number().min(1); +const field_id = Joi.number().min(1); +const data = Joi.object(); + +module.exports = { + list: null, // no options + show: options => Joi.validate(options, { id: id.required() }), + create: options => Joi.validate(options, { data: data.required() }), + update: options => + Joi.validate(options, { id: id.required(), data: data.required() }), + delete: options => Joi.validate(options, { id: id.required() }), + reorder: options => Joi.validate(options, { data: data.required() }), + listOptions: options => + Joi.validate(options, { field_id: field_id.required() }), + showOption: options => + Joi.validate(options, { field_id: field_id.required(), id: id.required() }), + createOrUpdateOption: options => + Joi.validate(options, { + field_id: field_id.required(), + data: data.required() + }), + deleteOption: options => + Joi.validate(options, { field_id: field_id.required(), id: id.required() }) +}; diff --git a/tests/src/v2/support.test.js b/tests/src/v2/support.test.js index a5d8b7e..4b5c474 100644 --- a/tests/src/v2/support.test.js +++ b/tests/src/v2/support.test.js @@ -23,5 +23,6 @@ describe('support api', () => { test('ticket_forms', () => check(support.ticket_forms)); test('ticket_metrics', () => check(support.ticket_metrics)); test('tickets', () => check(support.tickets)); + test('user_fields', () => check(support.user_fields)); test('users', () => check(support.users)); }); diff --git a/tests/src/v2/support/user_fields.test.js b/tests/src/v2/support/user_fields.test.js new file mode 100644 index 0000000..7761d18 --- /dev/null +++ b/tests/src/v2/support/user_fields.test.js @@ -0,0 +1,208 @@ +const endpoint = require('../../../../src/v2/support/user_fields'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('ticket fields', () => { + let user_fields; + + beforeEach(() => (user_fields = endpoint({ instance, headers }))); + afterEach(() => (user_fields = null)); + + describe('list user fields', () => { + it('should process w/ valid input', () => { + expect(user_fields.list()).toEqual({ + method: 'GET', + url: `${url}/api/v2/user_fields.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.list('invalid')).toThrowError(); + }); + }); + + describe('show user field', () => { + it('should process w/ valid input', () => { + expect(user_fields.show({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/user_fields/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.show()).toThrowError(); + expect(() => user_fields.show('invalid')).toThrowError(); + expect(() => user_fields.show({})).toThrowError(); + expect(() => user_fields.show({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('create user fields', () => { + it('should process w/ valid input', () => { + expect(user_fields.create({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/user_fields.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.create()).toThrowError(); + expect(() => user_fields.create('invalid')).toThrowError(); + expect(() => user_fields.create({})).toThrowError(); + expect(() => user_fields.create({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('update user fields', () => { + it('should process w/ valid input', () => { + expect(user_fields.update({ id: 123, data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/user_fields/123.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.update()).toThrowError(); + expect(() => user_fields.update('invalid')).toThrowError(); + expect(() => user_fields.update({})).toThrowError(); + expect(() => user_fields.update({ id: 'invalid' })).toThrowError(); + expect(() => + user_fields.update({ id: 123, data: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('delete user field', () => { + it('should process w/ valid input', () => { + expect(user_fields.delete({ id: 123 })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/user_fields/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.delete()).toThrowError(); + expect(() => user_fields.delete('invalid')).toThrowError(); + expect(() => user_fields.delete({})).toThrowError(); + expect(() => user_fields.delete({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('reorder user field', () => { + it('should process w/ valid input', () => { + expect(user_fields.reorder({ data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/user_fields/reorder.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.reorder()).toThrowError(); + expect(() => user_fields.reorder('invalid')).toThrowError(); + expect(() => user_fields.reorder({})).toThrowError(); + expect(() => user_fields.reorder({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('list user field options', () => { + it('should process w/ valid input', () => { + expect(user_fields.listOptions({ field_id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/user_fields/123/options.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.listOptions()).toThrowError(); + expect(() => user_fields.listOptions('invalid')).toThrowError(); + expect(() => user_fields.listOptions({})).toThrowError(); + expect(() => + user_fields.listOptions({ field_id: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('show a user field option', () => { + it('should process w/ valid input', () => { + expect(user_fields.showOption({ field_id: 123, id: 456 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/ticket_fields/123/options/456.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.showOption()).toThrowError(); + expect(() => user_fields.showOption('invalid')).toThrowError(); + expect(() => user_fields.showOption({})).toThrowError(); + expect(() => + user_fields.showOption({ field_id: 'invalid' }) + ).toThrowError(); + expect(() => + user_fields.showOption({ field_id: 123, id: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('create or update a user field option', () => { + it('should process w/ valid input', () => { + expect( + user_fields.createOrUpdateOption({ field_id: 123, data: {} }) + ).toEqual({ + method: 'POST', + url: `${url}/api/v2/user_fields/123/options.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.createOrUpdateOption()).toThrowError(); + expect(() => user_fields.createOrUpdateOption('invalid')).toThrowError(); + expect(() => user_fields.createOrUpdateOption({})).toThrowError(); + expect(() => + user_fields.createOrUpdateOption({ field_id: 'invalid' }) + ).toThrowError(); + expect(() => + user_fields.createOrUpdateOption({ field_id: 123, data: 'invalid' }) + ).toThrowError(); + }); + }); + + describe('delete user field option', () => { + it('should process w/ valid input', () => { + expect(user_fields.deleteOption({ field_id: 123, id: 456 })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/user_fields/123/options/456.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => user_fields.deleteOption()).toThrowError(); + expect(() => user_fields.deleteOption('invalid')).toThrowError(); + expect(() => user_fields.deleteOption({})).toThrowError(); + expect(() => + user_fields.deleteOption({ field_id: 'invalid' }) + ).toThrowError(); + expect(() => + user_fields.deleteOption({ field_id: 123, id: 'invalid' }) + ).toThrowError(); + }); + }); +}); From 90fc23fd64aada6108d4addf914564d4f3670337 Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Mon, 2 Sep 2019 18:10:48 -0700 Subject: [PATCH 13/14] built support.views --- src/v2/support/index.js | 3 +- src/v2/support/views/index.js | 215 ++++++++++++++++++++ src/v2/support/views/validate.js | 27 +++ tests/src/v2/support.test.js | 1 + tests/src/v2/support/views.test.js | 308 +++++++++++++++++++++++++++++ 5 files changed, 553 insertions(+), 1 deletion(-) create mode 100644 src/v2/support/views/index.js create mode 100644 src/v2/support/views/validate.js create mode 100644 tests/src/v2/support/views.test.js diff --git a/src/v2/support/index.js b/src/v2/support/index.js index 4939374..fa93d3a 100644 --- a/src/v2/support/index.js +++ b/src/v2/support/index.js @@ -12,5 +12,6 @@ module.exports = ({ instance, headers }) => ({ ticket_metrics: require('./ticket_metrics')({ instance, headers }), tickets: require('./tickets')({ instance, headers }), user_fields: require('./user_fields')({ instance, headers }), - users: require('./users')({ instance, headers }) + users: require('./users')({ instance, headers }), + views: require('./views')({ instance, headers }) }); diff --git a/src/v2/support/views/index.js b/src/v2/support/views/index.js new file mode 100644 index 0000000..d9ae123 --- /dev/null +++ b/src/v2/support/views/index.js @@ -0,0 +1,215 @@ +const validate = require('./validate'); + +module.exports = ({ instance, headers }) => { + const url = `https://${instance}.zendesk.com`; + + return { + list: (options = {}) => { + const { error } = validate.list(options); + if (error) throw new Error(error.details[0].message); + + const { ids = '' } = options; + const part = ids ? `?ids=${ids}` : ''; + + return { + method: 'GET', + url: `${url}/api/v2/views.json${part}`, + headers + }; + }, + + update_many: (options = {}) => { + const { error } = validate.update_many(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/views/update_many.json`, + headers, + data + }; + }, + + active: (options = null) => { + if (options) throw new Error('no options are allowed'); + + return { + method: 'GET', + url: `${url}/api/v2/views/active.json`, + headers + }; + }, + + compact: (options = null) => { + if (options) throw new Error('no options are allowed'); + + return { + method: 'GET', + url: `${url}/api/v2/views/compact.json`, + headers + }; + }, + + show: (options = {}) => { + const { error } = validate.show(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/views/${id}.json`, + headers + }; + }, + + create: (options = {}) => { + const { error } = validate.create(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/views.json`, + headers, + data + }; + }, + + update: (options = {}) => { + const { error } = validate.update(options); + if (error) throw new Error(error.details[0].message); + + const { id, data } = options; + return { + method: 'PUT', + url: `${url}/api/v2/views/${id}.json`, + headers, + data + }; + }, + + delete: (options = {}) => { + const { error } = validate.delete(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/views/${id}.json`, + headers + }; + }, + + delete_many: (options = {}) => { + const { error } = validate.delete_many(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'DELETE', + url: `${url}/api/v2/views/destroy_many.json`, + headers, + data + }; + }, + + execute: (options = {}) => { + const { error } = validate.execute(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/views/${id}/execute.json`, + headers + }; + }, + + tickets: (options = {}) => { + const { error } = validate.tickets(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/views/${id}/tickets.json`, + headers + }; + }, + + count_many: (options = {}) => { + const { error } = validate.count_many(options); + if (error) throw new Error(error.details[0].message); + + const { ids } = options; + return { + method: 'GET', + url: `${url}/api/v2/views/count_many.json?ids=${ids}`, + headers + }; + }, + + count: (options = {}) => { + const { error } = validate.count(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/views/${id}/count.json`, + headers + }; + }, + + export: (options = {}) => { + const { error } = validate.export(options); + if (error) throw new Error(error.details[0].message); + + const { id } = options; + return { + method: 'GET', + url: `${url}/api/v2/views/${id}/export.json`, + headers + }; + }, + + search: (options = {}) => { + const { error } = validate.search(options); + if (error) throw new Error(error.details[0].message); + + const { query } = options; + return { + method: 'GET', + url: `${url}/api/v2/views/search.json?query=${query}`, + headers + }; + }, + + preview: (options = {}) => { + const { error } = validate.preview(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/views/preview.json`, + headers, + data + }; + }, + + preview_count: (options = {}) => { + const { error } = validate.preview_count(options); + if (error) throw new Error(error.details[0].message); + + const { data } = options; + return { + method: 'POST', + url: `${url}/api/v2/views/preview/count.json`, + headers, + data + }; + } + }; +}; diff --git a/src/v2/support/views/validate.js b/src/v2/support/views/validate.js new file mode 100644 index 0000000..b4b6c79 --- /dev/null +++ b/src/v2/support/views/validate.js @@ -0,0 +1,27 @@ +const Joi = require('@hapi/joi'); + +const id = Joi.number().min(1); +const ids = Joi.string().min(3); +const query = Joi.string().min(1); +const data = Joi.object(); + +module.exports = { + list: options => Joi.validate(options, { ids }), + update_many: options => Joi.validate(options, { data: data.required() }), + active: null, // no options + compact: null, // no options + show: options => Joi.validate(options, { id: id.required() }), + create: options => Joi.validate(options, { data: data.required() }), + update: options => + Joi.validate(options, { id: id.required(), data: data.required() }), + delete: options => Joi.validate(options, { id: id.required() }), + delete_many: options => Joi.validate(options, { data: data.required() }), + execute: options => Joi.validate(options, { id: id.required() }), + tickets: options => Joi.validate(options, { id: id.required() }), + count_many: options => Joi.validate(options, { ids: ids.required() }), + count: options => Joi.validate(options, { id: id.required() }), + export: options => Joi.validate(options, { id: id.required() }), + search: options => Joi.validate(options, { query: query.required() }), + preview: options => Joi.validate(options, { data: data.required() }), + preview_count: options => Joi.validate(options, { data: data.required() }) +}; diff --git a/tests/src/v2/support.test.js b/tests/src/v2/support.test.js index 4b5c474..7abe6fd 100644 --- a/tests/src/v2/support.test.js +++ b/tests/src/v2/support.test.js @@ -25,4 +25,5 @@ describe('support api', () => { test('tickets', () => check(support.tickets)); test('user_fields', () => check(support.user_fields)); test('users', () => check(support.users)); + test('views', () => check(support.views)); }); diff --git a/tests/src/v2/support/views.test.js b/tests/src/v2/support/views.test.js new file mode 100644 index 0000000..a12a08e --- /dev/null +++ b/tests/src/v2/support/views.test.js @@ -0,0 +1,308 @@ +const endpoint = require('../../../../src/v2/support/views'); + +const instance = 'instance'; +const url = `https://${instance}.zendesk.com`; +const headers = { + 'Content-Type': 'application/json', + Authorization: 'Basic <64bit_encoded_credentials>' +}; + +describe('views', () => { + let views; + + beforeEach(() => (views = endpoint({ instance, headers }))); + afterEach(() => (views = null)); + + describe('list views', () => { + it('should process w/ valid input', () => { + expect(views.list()).toEqual({ + method: 'GET', + url: `${url}/api/v2/views.json`, + headers + }); + + expect(views.list({ ids: '1,2,3' })).toEqual({ + method: 'GET', + url: `${url}/api/v2/views.json?ids=1,2,3`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.list('invalid')).toThrowError(); + }); + }); + + describe('update many views', () => { + it('should process w/ valid input', () => { + expect(views.update_many({ data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/views/update_many.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.update_many()).toThrowError(); + expect(() => views.update_many({})).toThrowError(); + expect(() => views.update_many('invalid')).toThrowError(); + expect(() => views.update_many({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('list active views', () => { + it('should process w/ valid input', () => { + expect(views.active()).toEqual({ + method: 'GET', + url: `${url}/api/v2/views/active.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.active('invalid')).toThrowError(); + }); + }); + + describe('list views - compact', () => { + it('should process w/ valid input', () => { + expect(views.compact()).toEqual({ + method: 'GET', + url: `${url}/api/v2/views/compact.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.compact('invalid')).toThrowError(); + }); + }); + + describe('show view', () => { + it('should process w/ valid input', () => { + expect(views.show({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/views/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.show()).toThrowError(); + expect(() => views.show({})).toThrowError(); + expect(() => views.show('invalid')).toThrowError(); + expect(() => views.show({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('create view', () => { + it('should process w/ valid input', () => { + expect(views.create({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/views.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.create()).toThrowError(); + expect(() => views.create({})).toThrowError(); + expect(() => views.create('invalid')).toThrowError(); + expect(() => views.create({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('update view', () => { + it('should process w/ valid input', () => { + expect(views.update({ id: 123, data: {} })).toEqual({ + method: 'PUT', + url: `${url}/api/v2/views/123.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.update()).toThrowError(); + expect(() => views.update({})).toThrowError(); + expect(() => views.update('invalid')).toThrowError(); + expect(() => views.update({ id: 'invalid' })).toThrowError(); + expect(() => views.update({ id: 123, data: 'invalid' })).toThrowError(); + }); + }); + + describe('delete view', () => { + it('should process w/ valid input', () => { + expect(views.delete({ id: 123 })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/views/123.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.delete()).toThrowError(); + expect(() => views.delete({})).toThrowError(); + expect(() => views.delete('invalid')).toThrowError(); + expect(() => views.delete({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('delete many views', () => { + it('should process w/ valid input', () => { + expect(views.delete_many({ data: {} })).toEqual({ + method: 'DELETE', + url: `${url}/api/v2/views/destroy_many.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.delete_many()).toThrowError(); + expect(() => views.delete_many({})).toThrowError(); + expect(() => views.delete_many('invalid')).toThrowError(); + expect(() => views.delete_many({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('execute view', () => { + it('should process w/ valid input', () => { + expect(views.execute({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/views/123/execute.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.execute()).toThrowError(); + expect(() => views.execute({})).toThrowError(); + expect(() => views.execute('invalid')).toThrowError(); + expect(() => views.execute({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('list tickets from a view', () => { + it('should process w/ valid input', () => { + expect(views.tickets({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/views/123/tickets.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.tickets()).toThrowError(); + expect(() => views.tickets({})).toThrowError(); + expect(() => views.tickets('invalid')).toThrowError(); + expect(() => views.tickets({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('get view counts', () => { + it('should process w/ valid input', () => { + expect(views.count_many({ ids: '1,2,3' })).toEqual({ + method: 'GET', + url: `${url}/api/v2/views/count_many.json?ids=1,2,3`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.count_many()).toThrowError(); + expect(() => views.count_many({})).toThrowError(); + expect(() => views.count_many('invalid')).toThrowError(); + expect(() => views.count_many({ ids: 0 })).toThrowError(); + }); + }); + + describe('get view count', () => { + it('should process w/ valid input', () => { + expect(views.count({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/views/123/count.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.count()).toThrowError(); + expect(() => views.count({})).toThrowError(); + expect(() => views.count('invalid')).toThrowError(); + expect(() => views.count({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('export view', () => { + it('should process w/ valid input', () => { + expect(views.export({ id: 123 })).toEqual({ + method: 'GET', + url: `${url}/api/v2/views/123/export.json`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.export()).toThrowError(); + expect(() => views.export({})).toThrowError(); + expect(() => views.export('invalid')).toThrowError(); + expect(() => views.export({ id: 'invalid' })).toThrowError(); + }); + }); + + describe('search views', () => { + it('should process w/ valid input', () => { + expect(views.search({ query: 'query' })).toEqual({ + method: 'GET', + url: `${url}/api/v2/views/search.json?query=query`, + headers + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.search()).toThrowError(); + expect(() => views.search({})).toThrowError(); + expect(() => views.search('invalid')).toThrowError(); + expect(() => views.search({ query: '' })).toThrowError(); + }); + }); + + describe('previewing views', () => { + it('should process w/ valid input', () => { + expect(views.preview({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/views/preview.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.preview()).toThrowError(); + expect(() => views.preview({})).toThrowError(); + expect(() => views.preview('invalid')).toThrowError(); + expect(() => views.preview({ data: 'invalid' })).toThrowError(); + }); + }); + + describe('preview count', () => { + it('should process w/ valid input', () => { + expect(views.preview_count({ data: {} })).toEqual({ + method: 'POST', + url: `${url}/api/v2/views/preview/count.json`, + headers, + data: {} + }); + }); + + it('should throw error w/ invalid input', () => { + expect(() => views.preview_count()).toThrowError(); + expect(() => views.preview_count({})).toThrowError(); + expect(() => views.preview_count('invalid')).toThrowError(); + expect(() => views.preview_count({ data: 'invalid' })).toThrowError(); + }); + }); +}); From 772e04bab8aef819589d95e05dcc1dab04536138 Mon Sep 17 00:00:00 2001 From: Andrew Milenic Date: Mon, 2 Sep 2019 18:38:42 -0700 Subject: [PATCH 14/14] updated readme for sprint 2 --- README.md | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index d6f95d6..d3e1cd6 100644 --- a/README.md +++ b/README.md @@ -46,18 +46,23 @@ const instance = ''; // Name of Zendesk instance const email = ''; // Email address of Zendesk user const token = ''; // Generated Zendesk token +const encoded = base64.encode(`${email}/token:${token}`); + const headers = { 'Content-Type': 'application/json', - Authorization: `Basic ${base64.encode(`${email}/token:${token}`)}` + Authorization: `Basic ${encoded}` }; ``` ### Choose framework version ```javascript +const zdApi = require('@androozka/zendesk-api-js'); const zaf_v2 = zdApi.v2({ instance, headers }); ``` +- _**Note**: Only v2, [v1 being deprecated](https://support.zendesk.com/hc/en-us/articles/360002106888-Removal-of-Zendesk-Apps-framework-v1)_ + ### Selecting API endpoints ```javascript @@ -69,44 +74,34 @@ const { support, sunshine } = zaf_v2; ### Add tags to a ticket ```javascript -const data = { tags: ['tag_1', 'tag_2', ... ] } -const req = support.tags.add({ type: 'tickets', id: 123, data }); -const res = await axios(req); +try { + const data = { tags: ['tag_1', 'tag_2', ... ] } + const req = support.tags.add({ type: 'tickets', id: 123, data }); + const res = await axios(req); +} catch (error) { + // ... +} ``` ## API Coverage Status ### Support API -- [x] **Search** -- [x] **Users** -- [x] **Tickets** -- [x] **Ticket Metrics** -- [x] **Tags** +Search, Users, End Users, Groups, Organizations, Tickets, Ticket Comments, Ticket Metrics, Ticket Activities, Tags, Views, Ticket Forms, Ticket Fields, User Fields, Organization Fields #### Under Construction -- [ ] Views -- [ ] Organizations -- [ ] Groups -- [ ] Ticket Forms -- [ ] Ticket Fields -- [ ] User Fields -- [ ] Organization Fields - [ ] Brands - [ ] User Identities - [ ] User Passwords -- [ ] End Users - [ ] Group Memberships - [ ] Custom Agent Roles - [ ] Organization Subscriptions - [ ] Organization Memberships - [ ] Requests - [ ] Ticket Audits -- [ ] Ticket Comments - [ ] Ticket Skips - [ ] Ticket Metric Events -- [ ] Ticket Activities - [ ] Ticket Import - [ ] Attachments - [ ] Satisfaction Ratings