diff --git a/src/core/apiCalls/apiResponseGetter.js b/src/core/apiCalls/apiResponseGetter.js index 4525913..8e50737 100644 --- a/src/core/apiCalls/apiResponseGetter.js +++ b/src/core/apiCalls/apiResponseGetter.js @@ -6,5 +6,6 @@ import { export const getApiResponseOfListing = (loginInfo, entryType, action) => getResponseOfHttpGETFromPaginatedApi(loginInfo, entryType, action); -export const getApiResponseOfCreating = (loginInfo, entryType, body) => - getResponseOfHttpPOST(loginInfo, entryType, body); +export const getApiResponseOfCreating = (loginInfo, entryType, entry) => { + return getResponseOfHttpPOST(loginInfo, entryType, entry); +}; diff --git a/src/core/apiCalls/httpRequests/HttpError.js b/src/core/apiCalls/httpRequests/HttpError.js index 0ce11f7..3c30578 100644 --- a/src/core/apiCalls/httpRequests/HttpError.js +++ b/src/core/apiCalls/httpRequests/HttpError.js @@ -1,6 +1,7 @@ export default class HttpError extends Error { constructor(response = {}) { let message = 'HTTP request failed'; + const responseStatus = response.status; if (responseStatus) { diff --git a/src/core/apiCalls/httpRequests/httpRequestBodyBuilder.js b/src/core/apiCalls/httpRequests/httpRequestBodyBuilder.js index 9b1fda9..bc6653a 100644 --- a/src/core/apiCalls/httpRequests/httpRequestBodyBuilder.js +++ b/src/core/apiCalls/httpRequests/httpRequestBodyBuilder.js @@ -1,27 +1,76 @@ -export const buildHttpRequestBodyForLabels = () => { +export const buildHttpRequestBodyForLabelToBeCreatedOnGithub = (label) => { + const { name, description, color } = label; + const colorWithoutLeadingHex = color.substring(1); + const body = { - name: 'type: feature request', - color: '001122', - description: 'Suggestion to new features', + name, + description, + color: colorWithoutLeadingHex, }; + return body; }; -export const buildHttpRequestBodyForMilestones = () => { +export const buildHttpRequestBodyForLabel = (loginInfo, label) => { + const { domain } = loginInfo; + const { action } = label; + + const funcToBuildHttpRequestBodyForLabelToBe = { + github: { + create: (_label) => buildHttpRequestBodyForLabelToBeCreatedOnGithub(_label), + }, + }; + + const buildHttpRequestBodyForLabelToBe = + funcToBuildHttpRequestBodyForLabelToBe[domain][action]; + + const body = buildHttpRequestBodyForLabelToBe(label); + return body; +}; + +export const buildHttpRequestBodyForMilestoneToBeCreatedOnGithub = (milestone) => { + const { title, state, description, dueOn } = milestone; + const body = { - title: 'Backlog', - state: 'open', - description: 'Work not yet planned for a specific release', - due_on: '2030-04-01T09:00:00Z', + title, + state, + description, + due_on: dueOn, + }; + + return body; +}; + +export const buildHttpRequestBodyForMilestone = (loginInfo, milestone) => { + const { domain } = loginInfo; + const { action } = milestone; + + const funcToBuildHttpRequestBodyForMilestoneToBe = { + github: { + create: (_milestone) => + buildHttpRequestBodyForMilestoneToBeCreatedOnGithub(_milestone), + }, }; + + const buildHttpRequestBodyForMilestoneToBe = + funcToBuildHttpRequestBodyForMilestoneToBe[domain][action]; + + const body = buildHttpRequestBodyForMilestoneToBe(milestone); return body; }; -export const buildHttpRequestBody = (entryType) => { - const httpRequestBodyBuilders = { - labels: buildHttpRequestBodyForLabels(), - milestones: buildHttpRequestBodyForMilestones(), +export const buildHttpRequestBody = (loginInfo, entryType, entry) => { + const funcToBuildHttpRequestBodyForEntryType = { + labels: (_loginInfo, label) => buildHttpRequestBodyForLabel(_loginInfo, label), + milestones: (_loginInfo, milestone) => + buildHttpRequestBodyForMilestone(_loginInfo, milestone), }; - const body = httpRequestBodyBuilders[entryType]; - return JSON.stringify(body); + + const buildHttpRequestBodyForEntryType = + funcToBuildHttpRequestBodyForEntryType[entryType]; + + const body = buildHttpRequestBodyForEntryType(loginInfo, entry); + + // Note: the returned body is not stringified + return body; }; diff --git a/src/core/apiCalls/httpRequests/httpRequestHeaderBuilder.js b/src/core/apiCalls/httpRequests/httpRequestHeaderBuilder.js index 44e54ba..449a788 100644 --- a/src/core/apiCalls/httpRequests/httpRequestHeaderBuilder.js +++ b/src/core/apiCalls/httpRequests/httpRequestHeaderBuilder.js @@ -10,5 +10,6 @@ export const buildHttpRequestHeader = (loginInfo) => { Accept: buildAcceptHeaderForHttpRequest(), Authorization: buildAuthorizationHeaderForHttpRequest(loginInfo), }; + return headers; }; diff --git a/src/core/apiCalls/httpRequests/httpRequestMaker.js b/src/core/apiCalls/httpRequests/httpRequestMaker.js index a44bd05..4291c4a 100644 --- a/src/core/apiCalls/httpRequests/httpRequestMaker.js +++ b/src/core/apiCalls/httpRequests/httpRequestMaker.js @@ -1,11 +1,9 @@ import { buildHttpRequestHeader } from './httpRequestHeaderBuilder'; -export const obtainHttpMethodsThatDoNotHaveBody = () => new Set().add('GET'); - export const returnTrueIfNoNeedToAddHttpRequestBody = (method) => { + const obtainHttpMethodsThatDoNotHaveBody = () => new Set().add('GET').add('DELETE'); const httpMethodsThatDoNotHaveBody = obtainHttpMethodsThatDoNotHaveBody(); const noNeedToAddBody = httpMethodsThatDoNotHaveBody.has(method); - return noNeedToAddBody; }; @@ -17,7 +15,9 @@ export const buildOptionsForFetchApi = (loginInfo, method, body = {}) => { const noNeedToAddBody = returnTrueIfNoNeedToAddHttpRequestBody(method); - if (noNeedToAddBody) return optionsWithoutBody; + if (noNeedToAddBody) { + return optionsWithoutBody; + } const optionsWithBody = { ...optionsWithoutBody, diff --git a/src/core/apiCalls/httpRequests/httpRequestResponseGetter.js b/src/core/apiCalls/httpRequests/httpRequestResponseGetter.js index 2f998c7..c85b9e4 100644 --- a/src/core/apiCalls/httpRequests/httpRequestResponseGetter.js +++ b/src/core/apiCalls/httpRequests/httpRequestResponseGetter.js @@ -1,4 +1,5 @@ import HttpError from './HttpError'; +import { buildHttpRequestBody } from './httpRequestBodyBuilder'; import { makeHttpRequest } from './httpRequestMaker'; import { buildUriForHttpRequestGET, @@ -9,13 +10,18 @@ import { parseLinkHeaderFromHttpResponse } from './linkHeaderParser'; export const getResponseOfHttpRequest = async (loginInfo, method, uri, body = {}) => { const response = await makeHttpRequest(loginInfo, method, uri, body); const httpRequestFailed = !response.ok; - if (httpRequestFailed) throw new HttpError(response); + + if (httpRequestFailed) { + throw new HttpError(response); + } + return response; }; export const getResponseOfHttpGET = async (loginInfo, entryType, action, uri) => { const uriForHttpRequest = uri || buildUriForHttpRequestGET(loginInfo, entryType, action); + const response = await getResponseOfHttpRequest(loginInfo, 'GET', uriForHttpRequest); return response; }; @@ -43,7 +49,9 @@ export const getResponseOfHttpGETFromPaginatedApi = async ( uriOfNextPage, } = await parseResponseOfHttpGETFromPaginatedApi(response); - if (thereIsNoNextPage) return responseBody; + if (thereIsNoNextPage) { + return responseBody; + } const combineResponseBodyWithNextPage = async () => [ ...responseBody, @@ -59,8 +67,9 @@ export const getResponseOfHttpGETFromPaginatedApi = async ( return responseBodyCombinedWithNextPage; }; -export const getResponseOfHttpPOST = async (loginInfo, entryType, body) => { +export const getResponseOfHttpPOST = async (loginInfo, entryType, entry) => { const uri = buildUriForHttpRequestPOST(loginInfo, entryType); + const body = buildHttpRequestBody(loginInfo, entryType, entry); const response = await getResponseOfHttpRequest(loginInfo, 'POST', uri, body); const responseBody = await response.json(); return responseBody; diff --git a/src/core/apiCalls/httpRequests/httpRequestUriBuilder.js b/src/core/apiCalls/httpRequests/httpRequestUriBuilder.js index dadae5b..c2648a0 100644 --- a/src/core/apiCalls/httpRequests/httpRequestUriBuilder.js +++ b/src/core/apiCalls/httpRequests/httpRequestUriBuilder.js @@ -5,6 +5,7 @@ export const getUriBuilderOfListing = (entryType) => { labels: (uri) => uri, milestones: (uri) => `${uri}&state=all`, }; + return uriBuilders[entryType]; }; @@ -13,6 +14,7 @@ export const buildUriToList = (uri, entryType) => { const apiPaginationLimit = 100; return `${uri1}?per_page=${apiPaginationLimit}&page=1`; }; + const uriWithParams = appendPaginationToUri(uri); const buildUri = getUriBuilderOfListing(entryType); return buildUri(uriWithParams); @@ -21,12 +23,13 @@ export const buildUriToList = (uri, entryType) => { export const buildUriToCreate = (uri) => uri; export const getUriBuilderOfAction = (action) => { - const uriBuilderFunctions = { + const funcToBuildUri = { list: (uri, entryType) => buildUriToList(uri, entryType), copy: (uri, entryType) => buildUriToList(uri, entryType), create: (uri) => buildUriToCreate(uri), }; - const buildFunc = uriBuilderFunctions[action]; + + const buildFunc = funcToBuildUri[action]; return buildFunc; }; diff --git a/src/core/apiCalls/httpRequests/linkHeaderParser.js b/src/core/apiCalls/httpRequests/linkHeaderParser.js index 14a4dc3..d2e2925 100644 --- a/src/core/apiCalls/httpRequests/linkHeaderParser.js +++ b/src/core/apiCalls/httpRequests/linkHeaderParser.js @@ -35,6 +35,5 @@ export const parseLinkHeaderFromHttpResponse = (response) => { const { headers } = response; const rawLinkHeader = headers.get('link'); const parsedLinkHeader = parseLinkHeader(rawLinkHeader); - return parsedLinkHeader; }; diff --git a/src/core/communicationsWithApi.js b/src/core/communicationsWithApi.js index 44cae85..3d2a931 100644 --- a/src/core/communicationsWithApi.js +++ b/src/core/communicationsWithApi.js @@ -8,6 +8,14 @@ export const makeApiCallToCopy = async (loginInfo, entryType) => { return getApiResponseOfListing(loginInfo, entryType, 'copy'); }; -export const makeApiCallToCreate = async (loginInfo, entryType, body) => { - return getApiResponseOfCreating(loginInfo, entryType, body); +export const makeApiCallToCreate = async (loginInfo, entryType, entry) => { + return getApiResponseOfCreating(loginInfo, entryType, entry); }; + +// export const commitChangesByMakingApiCalls = (inputFromFrontEnd) => { +// const { loginInfo, labels, milestones } = inputFromFrontEnd; + +// // parse labels for next step +// const processedLabelsForApiCalls = processLabelsForApiCalls(loginInfo, labels); +// const processedMilestonesForApiCalls = processMilestonesForApiCalls(loginInfo, labels); +// }; diff --git a/src/core/defaultEntries/generateUniqueId.js b/src/core/defaultEntries/generateUniqueId.js index c443431..4aeac4c 100644 --- a/src/core/defaultEntries/generateUniqueId.js +++ b/src/core/defaultEntries/generateUniqueId.js @@ -1,7 +1,8 @@ const generateUniqueId = () => { const datetimeStr = Date.now().toString(36); - const randomStr = Math.random().toString(36).substring(2); - const id = `n-${datetimeStr}-${randomStr}`; + const randomStr0 = Math.random().toString(36).substring(2, 12); + const randomStr1 = Math.random().toString(36).substring(2, 12); + const id = `n-${datetimeStr}-${randomStr0}-${randomStr1}`; return id; }; diff --git a/src/core/loginInfo.js b/src/core/loginInfo.js index 7463ff2..ac13c29 100644 --- a/src/core/loginInfo.js +++ b/src/core/loginInfo.js @@ -9,6 +9,7 @@ export const getKeyToLoginInfo = (repoOwnerOrRepoName, homeRepoOrTemplateRepo) = name: 'templateRepoName', }, }; + return keys[homeRepoOrTemplateRepo][repoOwnerOrRepoName]; }; @@ -22,17 +23,9 @@ export const getRepoInfoFromLoginInfo = ( }; export const getRepoOwnerAndRepoName = (loginInfo, action) => { - let homeRepoOrTemplateRepo; - const actionIsToCopyEntriesFromAntemplateRepo = action === 'copy'; - - if (actionIsToCopyEntriesFromAntemplateRepo) { - homeRepoOrTemplateRepo = 'other'; - } else { - homeRepoOrTemplateRepo = 'home'; - } - + const actionIsToCopyEntriesFromTemplateRepo = action === 'copy'; + const homeRepoOrTemplateRepo = actionIsToCopyEntriesFromTemplateRepo ? 'other' : 'home'; const repoOwner = getRepoInfoFromLoginInfo(loginInfo, 'owner', homeRepoOrTemplateRepo); const repoName = getRepoInfoFromLoginInfo(loginInfo, 'name', homeRepoOrTemplateRepo); - return { repoOwner, repoName }; }; diff --git a/src/core/validations/validationMethods/validateOrThrow.js b/src/core/validations/validationMethods/validateOrThrow.js index ecf6753..422f1c9 100644 --- a/src/core/validations/validationMethods/validateOrThrow.js +++ b/src/core/validations/validationMethods/validateOrThrow.js @@ -1,7 +1,11 @@ const validateOrThrow = (item, getValidItems, ErrorClass) => { const validItems = getValidItems(); const givenItemIsInvalid = !validItems.has(item); - if (givenItemIsInvalid) throw new ErrorClass(item); + + if (givenItemIsInvalid) { + throw new ErrorClass(item); + } + return true; }; diff --git a/src/core/validations/validationOfAction.js b/src/core/validations/validationOfAction.js index 220dfa1..1ffbfba 100644 --- a/src/core/validations/validationOfAction.js +++ b/src/core/validations/validationOfAction.js @@ -5,6 +5,5 @@ export const getValidActions = () => new Set(['list', 'copy', 'create', 'update' export const validateActionOrThrow = (action) => { const isValid = validateOrThrow(action, getValidActions, InvalidActionError); - return isValid; }; diff --git a/src/core/validations/validationOfEntryType.js b/src/core/validations/validationOfEntryType.js index f61fd13..1875733 100644 --- a/src/core/validations/validationOfEntryType.js +++ b/src/core/validations/validationOfEntryType.js @@ -5,6 +5,5 @@ export const getValidEntryTypes = () => new Set(['labels', 'milestones']); export const validateEntryTypeOrThrow = (entryType) => { const isValid = validateOrThrow(entryType, getValidEntryTypes, InvalidEntryTypeError); - return isValid; }; diff --git a/src/test/apiCalls/httpRequests/getApiResponseOfCreating.spec.js b/src/test/apiCalls/httpRequests/getApiResponseOfCreating.spec.js index 2abcd28..6b02a7c 100644 --- a/src/test/apiCalls/httpRequests/getApiResponseOfCreating.spec.js +++ b/src/test/apiCalls/httpRequests/getApiResponseOfCreating.spec.js @@ -2,19 +2,22 @@ import { expect } from 'chai'; import { buildAcceptHeaderForHttpRequest } from '../../../core/apiCalls/httpRequests/httpRequestHeaderBuilder'; import { getApiResponseOfCreating } from '../../../core/apiCalls/apiResponseGetter'; -import { getBaseApiUriSlashRepos } from '../../../core/apiCalls/httpRequests/httpRequestUriBuilder'; import { mockHttpServerSetup, mockHttpServerCleanup, mockHttpServerForPOSTOnSuccess, } from '../../mockHttpServer'; +import { getDummyNewLabel } from '../../dummyData/dummyLabel.setup.test'; +import { getDummyLoginInfo } from '../../dummyData/dummyLoginInfo.setup.test'; describe('Test getApiResponseOfCreating', function () { - let uriForHttpPost; + let loginInfo; + let dummyLabel; before(function () { mockHttpServerSetup(); - uriForHttpPost = getBaseApiUriSlashRepos(); + loginInfo = getDummyLoginInfo(); + dummyLabel = getDummyNewLabel(); }); after(function () { @@ -23,13 +26,11 @@ describe('Test getApiResponseOfCreating', function () { describe('with HTTP responses on success', function () { let body; - // let response; describe('the HTTP request sent', function () { beforeEach(async function () { mockHttpServerForPOSTOnSuccess(); - - body = await getApiResponseOfCreating(uriForHttpPost, {}); + body = await getApiResponseOfCreating(loginInfo, 'labels', dummyLabel); }); describe('the HTTP request sent', function () { diff --git a/src/test/apiCalls/httpRequests/httpRequestBodyBuilder/buildHttpRequestBody.spec.js b/src/test/apiCalls/httpRequests/httpRequestBodyBuilder/buildHttpRequestBody.spec.js index f08d2eb..4eeed89 100644 --- a/src/test/apiCalls/httpRequests/httpRequestBodyBuilder/buildHttpRequestBody.spec.js +++ b/src/test/apiCalls/httpRequests/httpRequestBodyBuilder/buildHttpRequestBody.spec.js @@ -1,45 +1,43 @@ import { expect } from 'chai'; import { buildHttpRequestBody } from '../../../../core/apiCalls/httpRequests/httpRequestBodyBuilder'; +import { getDummyLoginInfo } from '../../../dummyData/dummyLoginInfo.setup.test'; +import { getDummyNewLabel } from '../../../dummyData/dummyLabel.setup.test'; +import { getDummyNewMilestone } from '../../../dummyData/dummyMilestone.setup.test'; describe('Test buildHttpRequestBody', function () { - const getParsedBody = (entryType) => { - const stringifiedBody = buildHttpRequestBody(entryType); - return JSON.parse(stringifiedBody); - }; + let loginInfo; - describe("with argument 'labels'", function () { - describe('the return value as a whole', function () { - let body; + before(function () { + loginInfo = getDummyLoginInfo(); + }); - before(function () { - body = buildHttpRequestBody('labels'); - }); + describe("with entryType being 'labels'", function () { + let dummyLabel; + let body; + + before(function () { + dummyLabel = getDummyNewLabel(); + body = buildHttpRequestBody(loginInfo, 'labels', dummyLabel); + }); + describe('the return value', function () { it('should not be null', function () { expect(body).to.not.be.null; }); - it('should be a string', function () { - expect(body).to.be.a('string'); + it('should not be stringified', function () { + expect(body).to.not.be.a('string'); }); }); - describe('the parsed body', function () { - let body; - - before(function () { - body = getParsedBody('labels'); - }); - - describe("a key called 'name' in the request body", function () { - it('should exist', function () { - const keyExists = 'name' in body; - expect(keyExists).to.be.true; - }); + describe("in the key-value pair whose key is 'name'", function () { + it('the key should exist', function () { + const keyExists = 'name' in body; + expect(keyExists).to.be.true; }); - describe("the value of key 'name'", function () { + describe('the value', function () { let nameValue; before(function () { @@ -54,15 +52,15 @@ describe('Test buildHttpRequestBody', function () { expect(nameValue).to.have.lengthOf.above(0); }); }); + }); - describe("a key called 'color' in the request body", function () { - it('should exist', function () { - const keyExists = 'color' in body; - expect(keyExists).to.be.true; - }); + describe("in the key-value pair whose key is 'color'", function () { + it('the key should exist', function () { + const keyExists = 'color' in body; + expect(keyExists).to.be.true; }); - describe("the value of key 'color'", function () { + describe('the value', function () { let hexColorCode; before(function () { @@ -78,55 +76,47 @@ describe('Test buildHttpRequestBody', function () { expect(hexColorCode).to.match(hexColorCodeRegex); }); }); + }); - describe("a key called 'description' in the request body", function () { - it('should exist', function () { - const keyExists = 'description' in body; - expect(keyExists).to.be.true; - }); + describe("in the key-value pair whose key is 'description'", function () { + it('the key should exist', function () { + const keyExists = 'description' in body; + expect(keyExists).to.be.true; }); - describe("the value of key 'description'", function () { - it('should be a string', function () { - const descriptionValue = body.description; - expect(descriptionValue).to.be.a('string'); - }); + it('the value should be a string', function () { + const descriptionValue = body.description; + expect(descriptionValue).to.be.a('string'); }); }); }); describe("with argument 'milestones'", function () { - describe('the return value as a whole', function () { - let body; + let dummyMilestone; + let body; - before(function () { - body = buildHttpRequestBody('milestones'); - }); + before(function () { + dummyMilestone = getDummyNewMilestone(); + body = buildHttpRequestBody(loginInfo, 'milestones', dummyMilestone); + }); + describe('the return value', function () { it('should not be null', function () { expect(body).to.not.be.null; }); - it('should be a string', function () { - expect(body).to.be.a('string'); + it('should not be stringified', function () { + expect(body).to.not.be.a('string'); }); }); - describe('the parsed body', function () { - let body; - - before(function () { - body = getParsedBody('milestones'); + describe("a key-value pair whose key is 'title'", function () { + it('the key should exist', function () { + const keyExists = 'title' in body; + expect(keyExists).to.be.true; }); - describe("a key called 'title' in the request body", function () { - it('should exist', function () { - const keyExists = 'title' in body; - expect(keyExists).to.be.true; - }); - }); - - describe("the value of key 'title'", function () { + describe('the value', function () { let titleValue; before(function () { @@ -141,15 +131,15 @@ describe('Test buildHttpRequestBody', function () { expect(titleValue).to.have.lengthOf.above(0); }); }); + }); - describe("a key called 'state' in the request body", function () { - it('should exist', function () { - const keyExists = 'state' in body; - expect(keyExists).to.be.true; - }); + describe("a key-value pair whose key is 'state'", function () { + it('the key exist', function () { + const keyExists = 'state' in body; + expect(keyExists).to.be.true; }); - describe("the value of key 'state'", function () { + describe('the value', function () { let stateValue; before(function () { @@ -164,29 +154,27 @@ describe('Test buildHttpRequestBody', function () { expect(stateValue).to.match(/^open$|^closed$/); }); }); + }); - describe("a key called 'description' in the request body", function () { - it('should exist', function () { - const keyExists = 'description' in body; - expect(keyExists).to.be.true; - }); + describe("a key-value pair whose key is 'description'", function () { + it('the key should exist', function () { + const keyExists = 'description' in body; + expect(keyExists).to.be.true; }); - describe("the value of key 'description'", function () { - it('should be a string', function () { - const descriptionValue = body.description; - expect(descriptionValue).to.be.a('string'); - }); + it('the value should be a string', function () { + const descriptionValue = body.description; + expect(descriptionValue).to.be.a('string'); }); + }); - describe("a key called 'due_on' in the request body", function () { - it('should exist', function () { - const keyExists = 'due_on' in body; - expect(keyExists).to.be.true; - }); + describe("a key-value pair whose key is 'due_on'", function () { + it('the key should exist', function () { + const keyExists = 'due_on' in body; + expect(keyExists).to.be.true; }); - describe("the value of key 'due_on'", function () { + describe('the value', function () { let dueOnValue; before(function () { diff --git a/src/test/makeApiCallToCopy.spec.js b/src/test/communicationsWithApi/makeApiCallToCopy.spec.js similarity index 81% rename from src/test/makeApiCallToCopy.spec.js rename to src/test/communicationsWithApi/makeApiCallToCopy.spec.js index a833d46..65f4a69 100644 --- a/src/test/makeApiCallToCopy.spec.js +++ b/src/test/communicationsWithApi/makeApiCallToCopy.spec.js @@ -1,13 +1,13 @@ import { expect } from 'chai'; -import { makeApiCallToCopy } from '../core/communicationsWithApi'; -import { dummyResponseBodyAll } from './dummyData/dummyResponseBodyOfListingLabels.setup.test'; +import { makeApiCallToCopy } from '../../core/communicationsWithApi'; +import { dummyResponseBodyAll } from '../dummyData/dummyResponseBodyOfListingLabels.setup.test'; import { mockHttpServerSetup, mockHttpServerCleanup, mockHttpServerForListingOnSuccess, -} from './mockHttpServer'; -import { getDummyLoginInfo } from './dummyData/dummyLoginInfo.setup.test'; +} from '../mockHttpServer'; +import { getDummyLoginInfo } from '../dummyData/dummyLoginInfo.setup.test'; describe('Test makeApiCallToCopy', function () { describe('with a mock HTTP server', function () { diff --git a/src/test/makeApiCallToCreate.spec.js b/src/test/communicationsWithApi/makeApiCallToCreate.spec.js similarity index 55% rename from src/test/makeApiCallToCreate.spec.js rename to src/test/communicationsWithApi/makeApiCallToCreate.spec.js index 2197a5a..133a3e1 100644 --- a/src/test/makeApiCallToCreate.spec.js +++ b/src/test/communicationsWithApi/makeApiCallToCreate.spec.js @@ -1,14 +1,13 @@ import { expect } from 'chai'; -import { makeApiCallToCreate } from '../core/communicationsWithApi'; -import { dummyLabel as dummyRequestBody } from './dummyData/dummyLabel.setup.test'; +import { makeApiCallToCreate } from '../../core/communicationsWithApi'; import { mockHttpServerSetup, mockHttpServerCleanup, mockHttpServerForCreationOnSuccess, - mockHttpServerForCreationOnFailure, -} from './mockHttpServer'; -import { getDummyLoginInfo } from './dummyData/dummyLoginInfo.setup.test'; +} from '../mockHttpServer'; +import { getDummyNewLabel } from '../dummyData/dummyLabel.setup.test'; +import { getDummyLoginInfo } from '../dummyData/dummyLoginInfo.setup.test'; describe('Test makeApiCallToCreate', function () { describe('with a mock HTTP server', function () { @@ -25,80 +24,82 @@ describe('Test makeApiCallToCreate', function () { describe('with HTTP responses on failure', function () { const entryType = 'labels'; - const failureStatusCode = 403; - - beforeEach(function () { - mockHttpServerForCreationOnFailure(); - }); it('should throw an error', async function () { try { - await makeApiCallToCreate(loginInfo, entryType); + await makeApiCallToCreate(loginInfo, entryType, {}); } catch (errorReceived) { expect(errorReceived).to.be.an('error'); } }); - - it(`should throw an error that has a status code of ${failureStatusCode}`, async function () { - try { - await makeApiCallToCreate(loginInfo, entryType); - } catch (errorReceived) { - const errorStatusCode = errorReceived.status; - expect(errorStatusCode).to.deep.equal(failureStatusCode); - } - }); }); describe('with HTTP responses on success', function () { const entryType = 'labels'; let responseBody; + let dummyRequestBody; + + before(function () { + dummyRequestBody = getDummyNewLabel(); + }); beforeEach(async function () { mockHttpServerForCreationOnSuccess(); - responseBody = await makeApiCallToCreate(loginInfo, entryType, dummyRequestBody); }); describe('in the received response', function () { - describe("a key-value pair with key 'name'", function () { + describe("in the key-value pair whose key is 'name'", function () { const key = 'name'; - it('key should exist', function () { + it('the key should exist', function () { const keyExists = key in responseBody; expect(keyExists).to.be.true; }); - it('its value should match the expected value', function () { + it('the value should match the expected value', function () { const receivedValue = responseBody[key]; const answerKey = dummyRequestBody[key]; expect(receivedValue).to.deep.equal(answerKey); }); }); - describe("a key-value pair with key 'color'", function () { + describe("in the key-value pair whose key is 'color'", function () { const key = 'color'; - it('key should exist', function () { + it('the key should exist', function () { const keyExists = key in responseBody; expect(keyExists).to.be.true; }); - it('its value should match the expected value', function () { - const receivedValue = responseBody[key]; - const answerKey = dummyRequestBody[key]; - expect(receivedValue).to.deep.equal(answerKey); + describe('the value', function () { + let receivedValue; + + before(function () { + receivedValue = responseBody[key]; + }); + + it('should be a valid hex color code (without the leading hash)', function () { + const hexColorCodeRegex = /^[0-9a-fA-F]{6}$/; + expect(receivedValue).to.match(hexColorCodeRegex); + }); + + it('should match the expected hex color coode (without the leading hash)', function () { + const answerKey = dummyRequestBody[key].slice(1); + expect(receivedValue).to.deep.equal(answerKey); + }); }); }); - describe("a key-value pair with key 'description'", function () { + describe("in the key-value pair whose key is 'description'", function () { const key = 'description'; - it('key should exist', function () { + it('the key should exist', function () { const keyExists = key in responseBody; expect(keyExists).to.be.true; }); - it('its value should match the expected value', function () { + it('the value should match the expected value', function () { const receivedValue = responseBody[key]; const answerKey = dummyRequestBody[key]; expect(receivedValue).to.deep.equal(answerKey); diff --git a/src/test/makeApiCallToList.spec.js b/src/test/communicationsWithApi/makeApiCallToList.spec.js similarity index 86% rename from src/test/makeApiCallToList.spec.js rename to src/test/communicationsWithApi/makeApiCallToList.spec.js index b7e6e11..49580d6 100644 --- a/src/test/makeApiCallToList.spec.js +++ b/src/test/communicationsWithApi/makeApiCallToList.spec.js @@ -1,13 +1,13 @@ import { expect } from 'chai'; -import { makeApiCallToList } from '../core/communicationsWithApi'; -import { dummyResponseBodyAll } from './dummyData/dummyResponseBodyOfListingLabels.setup.test'; +import { makeApiCallToList } from '../../core/communicationsWithApi'; +import { dummyResponseBodyAll } from '../dummyData/dummyResponseBodyOfListingLabels.setup.test'; import { mockHttpServerSetup, mockHttpServerCleanup, mockHttpServerForListingOnSuccess, -} from './mockHttpServer'; -import { getDummyLoginInfo } from './dummyData/dummyLoginInfo.setup.test'; +} from '../mockHttpServer'; +import { getDummyLoginInfo } from '../dummyData/dummyLoginInfo.setup.test'; describe('Test makeApiCallToList', function () { describe('with a mock HTTP server', function () { diff --git a/src/test/defaultEntries/generateUniqueId.spec.js b/src/test/defaultEntries/generateUniqueId.spec.js index a28240f..d7a00ce 100644 --- a/src/test/defaultEntries/generateUniqueId.spec.js +++ b/src/test/defaultEntries/generateUniqueId.spec.js @@ -3,20 +3,22 @@ import { expect } from 'chai'; import generateUniqueId from '../../core/defaultEntries/generateUniqueId'; describe('Test generateUniqueId', function () { + const numOfTests = 100000; + it('should be a string', function () { const output = generateUniqueId(); expect(output).to.be.a('string'); }); - describe('when 100000 random IDs are generated, each ID...', function () { + describe(`when ${numOfTests} random IDs are generated consecutively, each ID...`, function () { it('should be unique', function () { - const output = new Array(100000).fill().map(() => generateUniqueId()); - const arrayLength = output.length; + const randomIds = new Array(numOfTests).fill().map(() => generateUniqueId()); + const numOfIds = randomIds.length; - const set = new Set(output); - const setSize = set.size; + const set = new Set(randomIds); + const numOfUniqueIds = set.size; - expect(arrayLength).to.deep.equal(setSize); + expect(numOfIds).to.deep.equal(numOfUniqueIds); }); }); }); diff --git a/src/test/dummyData/dummyLabel.setup.test.js b/src/test/dummyData/dummyLabel.setup.test.js index 84feff0..9a00f41 100644 --- a/src/test/dummyData/dummyLabel.setup.test.js +++ b/src/test/dummyData/dummyLabel.setup.test.js @@ -1,15 +1,21 @@ -export const dummyLabel = { +export const getDummyNewLabel = () => ({ + id: 123456789, name: 'feature request', - color: '001122', - description: 'Indicates new feature requests', -}; + color: '#001122', + description: 'Indicates a new feature request', + originalName: '', + originalDescription: '', + originalColor: '', + action: 'create', + validation: 'valid', +}); -export const dummyLabelCreationSuccessResponse = { +export const getDummyLabelCreationSuccessResponse = () => ({ id: 208045946, node_id: 'MDU6TGFiZWwyMDgwNDU5NDY=', - url: 'https://api.github.com/repos/repo-owner/repo-name/labels/help%20wanted', - name: 'feature request', - description: 'Indicates new feature requests', + url: 'https://api.github.com/repos/octocat/Hello-World/labels/bug', + name: 'bug', + description: "Something isn't working", color: '001122', default: true, -}; +}); diff --git a/src/test/dummyData/dummyLoginInfo.setup.test.js b/src/test/dummyData/dummyLoginInfo.setup.test.js index 6bf5ce0..4e7ac04 100644 --- a/src/test/dummyData/dummyLoginInfo.setup.test.js +++ b/src/test/dummyData/dummyLoginInfo.setup.test.js @@ -27,4 +27,5 @@ export const getDummyLoginInfo = () => ({ templateRepoOwner: loadTemplateRepoOwnerFromDotEnv(), templateRepoName: loadTemplateRepoNameFromDotEnv(), token: loadTokenFromDotEnv(), + domain: 'github', }); diff --git a/src/test/dummyData/dummyMilestone.setup.test.js b/src/test/dummyData/dummyMilestone.setup.test.js new file mode 100644 index 0000000..1326293 --- /dev/null +++ b/src/test/dummyData/dummyMilestone.setup.test.js @@ -0,0 +1,51 @@ +export const getDummyNewMilestone = () => ({ + id: 123456789, + title: 'Default milestone', + description: 'Default description', + state: 'open', + dueOn: '2032-10-09T23:39:01Z', + originalTitle: '', + originalDescription: '', + originalState: '', + originalDueOn: '', + action: 'create', + validation: 'valid', +}); + +export const getDummyMilestoneCreationSuccessResponse = () => ({ + url: 'https://api.github.com/repos/octocat/Hello-World/milestones/1', + html_url: 'https://github.com/octocat/Hello-World/milestones/v1.0', + labels_url: 'https://api.github.com/repos/octocat/Hello-World/milestones/1/labels', + id: 1002604, + node_id: 'MDk6TWlsZXN0b25lMTAwMjYwNA==', + number: 1, + state: 'open', + title: 'v1.0', + description: 'Tracking milestone for version 1.0', + creator: { + login: 'octocat', + id: 1, + node_id: 'MDQ6VXNlcjE=', + avatar_url: 'https://github.com/images/error/octocat_happy.gif', + gravatar_id: '', + url: 'https://api.github.com/users/octocat', + html_url: 'https://github.com/octocat', + followers_url: 'https://api.github.com/users/octocat/followers', + following_url: 'https://api.github.com/users/octocat/following{/other_user}', + gists_url: 'https://api.github.com/users/octocat/gists{/gist_id}', + starred_url: 'https://api.github.com/users/octocat/starred{/owner}{/repo}', + subscriptions_url: 'https://api.github.com/users/octocat/subscriptions', + organizations_url: 'https://api.github.com/users/octocat/orgs', + repos_url: 'https://api.github.com/users/octocat/repos', + events_url: 'https://api.github.com/users/octocat/events{/privacy}', + received_events_url: 'https://api.github.com/users/octocat/received_events', + type: 'User', + site_admin: false, + }, + open_issues: 4, + closed_issues: 8, + created_at: '2011-04-10T20:09:31Z', + updated_at: '2014-03-03T18:58:10Z', + closed_at: '2013-02-12T13:22:01Z', + due_on: '2012-10-09T23:39:01Z', +}); diff --git a/src/test/mockHttpServer/mockHttpServerForCreation.setup.test.js b/src/test/mockHttpServer/mockHttpServerForCreation.setup.test.js index fcfb00e..858b212 100644 --- a/src/test/mockHttpServer/mockHttpServerForCreation.setup.test.js +++ b/src/test/mockHttpServer/mockHttpServerForCreation.setup.test.js @@ -2,14 +2,13 @@ import mockHttpServer from './mockHttpServerInitiation.setup.test'; const getSuccessStatusCode = () => 201; -const getFailureStatusCode = () => 403; - export const buildResponseForPOSTOnSuccess = (uri, requestBody) => { const parsedRequestBody = JSON.parse(requestBody); const { name, color, description } = parsedRequestBody; const id = 123456789; const nodeId = 'RHVtbXkgbm9kZSBpZA=='; const url = 'https://api.github.com/repos'; + const body = { id, node_id: nodeId, @@ -19,6 +18,7 @@ export const buildResponseForPOSTOnSuccess = (uri, requestBody) => { color, default: true, }; + const statusCode = getSuccessStatusCode(); return [statusCode, body]; }; @@ -27,8 +27,3 @@ export const mockHttpServerForCreationOnSuccess = () => mockHttpServer() .post(/.*/) .reply((uri, requestBody) => buildResponseForPOSTOnSuccess(uri, requestBody)); - -export const mockHttpServerForCreationOnFailure = () => { - const statusCode = getFailureStatusCode(); - return mockHttpServer().post(/.*/).reply(statusCode); -}; diff --git a/src/test/mockHttpServer/mockHttpServerForGET.setup.test.js b/src/test/mockHttpServer/mockHttpServerForGET.setup.test.js index 51c463f..95fd555 100644 --- a/src/test/mockHttpServer/mockHttpServerForGET.setup.test.js +++ b/src/test/mockHttpServer/mockHttpServerForGET.setup.test.js @@ -4,6 +4,7 @@ const getSuccessStatusCode = () => 200; const mockHttpServerForGETOnSuccess = () => { const statusCode = getSuccessStatusCode(); + return mockHttpServer() .get(/.*/) .reply(statusCode, function (uri) { diff --git a/src/test/mockHttpServer/mockHttpServerForListing.setup.test.js b/src/test/mockHttpServer/mockHttpServerForListing.setup.test.js index 4b87d50..aa19e79 100644 --- a/src/test/mockHttpServer/mockHttpServerForListing.setup.test.js +++ b/src/test/mockHttpServer/mockHttpServerForListing.setup.test.js @@ -17,12 +17,16 @@ export const buildResponseBodyFromDummyData = (dataSource, uri = '') => { const matched = uri.match(uriRegex); const noMatchesWereFound = matched === null; - if (noMatchesWereFound) return data.outOfRange; + if (noMatchesWereFound) { + return data.outOfRange; + } const { pageNum } = matched.groups; const pageNumIsOutOfRange = pageNum > lastPageNum; - if (pageNumIsOutOfRange) return data.outOfRange; + if (pageNumIsOutOfRange) { + return data.outOfRange; + } return data[pageNum]; };