diff --git a/src/jira.js b/src/jira.js index c118ac57..8bc495ef 100644 --- a/src/jira.js +++ b/src/jira.js @@ -101,6 +101,13 @@ export default class JiraApi { * Possible values RSA-SHA1, HMAC-SHA1, PLAINTEXT. Jira Cloud supports only RSA-SHA1. */ + /** + * @typedef {object} UriOptions + * @property {string} pathname - The url after the specific functions path + * @property {object} [query] - An object of all query parameters + * @property {string} [intermediatePath] - Overwrites with specified path + */ + /** * @name makeRequestHeader * @function @@ -226,6 +233,25 @@ export default class JiraApi { return decodeURIComponent(uri); } + /** + * @name makeAgile1Uri + * @function + * Creates a URI object for a given pathname + * @param {UriOptions} object + */ + makeAgileUri(object) { + const intermediateToUse = this.intermediatePath || object.intermediatePath; + const tempPath = intermediateToUse || '/rest/agile/1.0'; + const uri = url.format({ + protocol: this.protocol, + hostname: this.host, + port: this.port, + pathname: `${this.base}${tempPath}${object.pathname}`, + query: object.query, + }); + return decodeURIComponent(uri); + } + /** * @name doRequest * @function @@ -1141,4 +1167,194 @@ export default class JiraApi { }, }))); } + + /** Create sprint + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-createSprint) + * @name createSprint + * @function + * @param {string} body - value to set + */ + createSprint(body) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: '/sprint', + }), { + method: 'POST', + body, + })); + } + + /** Update sprint + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-updateSprint) + * @name updateSprint + * @function + * @param {string} sprintId - Id of sprint + * @param {string} body - value to set + */ + updateSprint(sprintId, body) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}`, + }), { + method: 'PUT', + body, + })); + } + + /** Partially update sprint + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-partiallyUpdateSprint) + * @name partiallyUpdateSprint + * @function + * @param {string} sprintId - Id of sprint + * @param {string} body - value to set + */ + partiallyUpdateSprint(sprintId, body) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}`, + }), { + method: 'POST', + body, + })); + } + + /** Delete sprint + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-deleteSprint) + * @name deleteSprint + * @function + * @param {string} sprintId - Id of sprint + */ + deleteSprint(sprintId) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}`, + }), { + method: 'DELETE', + })); + } + + /** Get sprint + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-getSprint) + * @name getSprint + * @function + * @param {string} sprintId - Id of sprint + */ + getSprint(sprintId) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}`, + }))); + } + + /** Move Issues to Sprint + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-moveIssuesToSprint) + * @name moveIssuesToSprint + * @function + * @param {string} sprintId - Id of sprint + * @param {string} body - value to set + */ + moveIssuesToSprint(sprintId, body) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}/issue`, + }), { + method: 'POST', + body, + })); + } + + /** Get Issues for Sprint + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-getIssuesForSprint) + * @name getIssuesForSprint + * @function + * @param {string} sprintId - Id of sprint + * @param {number} [startAt=0] - The starting index of the returned issues. Base index: 0. + * @param {number} [maxResults=50] - The maximum number of issues to return per page. Default: 50. + * @param {string} [jql] - Filters results using a JQL query. + * @param {boolean} [validateQuery] - Specifies whether to validate the JQL query or not. + * Default: true. + * @param {string} [fields] - The list of fields to return for each issue. + * @param {string} [expand] - A comma-separated list of the parameters to expand. + */ + getIssuesForSprint(sprintId, startAt = 0, maxResults = 50, jql, + validateQuery = true, fields, expand) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}/issue`, + query: { + startAt, + maxResults, + jql, + validateQuery, + fields, + expand, + }, + }))); + } + + /** Swap Sprint + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint-swapSprint) + * @name swapSprint + * @function + * @param {string} sprintId - Id of sprint + * @param {string} body - value to set + */ + swapSprint(sprintId, body) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}/swap`, + }), { + method: 'POST', + body, + })); + } + + /** Get Sprint Properties Keys + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint/{sprintId}/properties-getPropertiesKeys) + * @name getSprintPropertiesKeys + * @function + * @param {string} sprintId - Id of sprint + */ + getSprintPropertiesKeys(sprintId) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}/properties`, + }))); + } + + /** Delete Sprint Property + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint/{sprintId}/properties-deleteProperty) + * @name deleteSprintProperty + * @function + * @param {string} sprintId - Id of sprint + * @param {string} propertyKey - Id of property + */ + deleteSprintProperty(sprintId, propertyKey) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}/properties/${propertyKey}`, + }), { + method: 'DELETE', + })); + } + + /** Set Sprint Property + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint/{sprintId}/properties-setProperty) + * @name setSprintProperty + * @function + * @param {string} sprintId - Id of sprint + * @param {string} propertyKey - Id of property + * @param {string} body - value to set, for objects make sure to stringify first + */ + setSprintProperty(sprintId, propertyKey, body) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}/properties/${propertyKey}`, + }), { + method: 'PUT', + body, + })); + } + + /** Get Sprint Property + * [Jira Doc](https://docs.atlassian.com/jira-software/REST/cloud/#agile/1.0/sprint/{sprintId}/properties-getProperty) + * @name getSprintProperty + * @function + * @param {string} sprintId - Id of sprint + * @param {string} propertyKey - Id of property + */ + getSprintProperty(sprintId, propertyKey) { + return this.doRequest(this.makeRequestHeader(this.makeAgileUri({ + pathname: `/sprint/${sprintId}/properties/${propertyKey}`, + }))); + } } diff --git a/test/jira-tests.js b/test/jira-tests.js index 2adcd91c..783aab33 100644 --- a/test/jira-tests.js +++ b/test/jira-tests.js @@ -726,6 +726,69 @@ describe('Jira API Tests', () => { }); }); + // Agile APIs Suite Tests + describe('Agile APIs Suite Tests', () => { + it('createSprint hits proper url', async () => { + const result = await dummyURLCall('createSprint'); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint'); + }); + + it('updateSprint hits proper url', async () => { + const result = await dummyURLCall('updateSprint', ['someSprintId']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId'); + }); + + it('partiallyUpdateSprint hits proper url', async () => { + const result = await dummyURLCall('partiallyUpdateSprint', ['someSprintId']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId'); + }); + + it('deleteSprint hits proper url', async () => { + const result = await dummyURLCall('deleteSprint', ['someSprintId']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId'); + }); + + it('getSprint hits proper url', async () => { + const result = await dummyURLCall('getSprint', ['someSprintId']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId'); + }); + + it('moveIssuesToSprint hits proper url', async () => { + const result = await dummyURLCall('moveIssuesToSprint', ['someSprintId']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId/issue'); + }); + + it('getIssuesForSprint hits proper url', async () => { + const result = await dummyURLCall('getIssuesForSprint', ['someSprintId']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId/issue?startAt=0&maxResults=50&jql=&validateQuery=true&fields=&expand='); + }); + + it('swapSprint hits proper url', async () => { + const result = await dummyURLCall('swapSprint', ['someSprintId']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId/swap'); + }); + + it('getSprintPropertiesKeys hits proper url', async () => { + const result = await dummyURLCall('getSprintPropertiesKeys', ['someSprintId']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId/properties'); + }); + + it('deleteSprintProperty hits proper url', async () => { + const result = await dummyURLCall('deleteSprintProperty', ['someSprintId', 'somePropertyKey']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId/properties/somePropertyKey'); + }); + + it('setSprintProperty hits proper url', async () => { + const result = await dummyURLCall('setSprintProperty', ['someSprintId', 'somePropertyKey']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId/properties/somePropertyKey'); + }); + + it('getSprintProperty hits proper url', async () => { + const result = await dummyURLCall('getSprintProperty', ['someSprintId', 'somePropertyKey']); + result.should.eql('http://jira.somehost.com:8080/rest/agile/1.0/sprint/someSprintId/properties/somePropertyKey'); + }); + }); + it('issueNotify hits proper url', async () => { const result = await dummyURLCall('issueNotify', ['someIssueId', {}]); result.should.eql('http://jira.somehost.com:8080/rest/api/2.0/issue/someIssueId/notify');