From 9261c723249c7a0eca62b0ff09e08e1311509668 Mon Sep 17 00:00:00 2001 From: galta <48960890+galta95@users.noreply.github.com> Date: Mon, 30 Nov 2020 10:33:07 +0200 Subject: [PATCH 1/6] feat(apiv06): new route /api/0.6/changeset/#id/close --- .github/workflows/lint.yml | 1 + .prettierrc.json | 6 + README.md | 1 + package-lock.json | 23 ++-- package.json | 7 +- src/api/v6/index.ts | 93 ++++++++++---- src/index.ts | 4 +- src/lib/endpoints.ts | 4 +- src/lib/error-handler.ts | 43 +++++-- tests/unit/apiv6.test.ts | 203 ++++++++++++++++++++++++------ tests/unit/config/tests-config.ts | 12 +- tests/unit/lib/osm-xml.ts | 18 --- 12 files changed, 301 insertions(+), 114 deletions(-) create mode 100644 .prettierrc.json delete mode 100644 tests/unit/lib/osm-xml.ts diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e45340b..a80e61d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -25,4 +25,5 @@ jobs: github_token: ${{ secrets.github_token }} # Enable linters eslint: true + prettier: true eslint_extensions: ts \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..d1039fb --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 4, + "semi": false, + "singleQuote": true +} \ No newline at end of file diff --git a/README.md b/README.md index f09077f..24509da 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # node-osm-api + easy communication with osm api diff --git a/package-lock.json b/package-lock.json index 8f506a4..a87b4f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -397,7 +397,8 @@ "@types/node": { "version": "14.14.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.9.tgz", - "integrity": "sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw==" + "integrity": "sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw==", + "dev": true }, "@types/normalize-package-data": { "version": "2.4.0", @@ -411,15 +412,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "@types/xml": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/xml/-/xml-1.0.5.tgz", - "integrity": "sha512-h3PVM7waRi2UeoaY2BhpLGvettU/3vfCbsjXMV/9Ex5WjvIy82J8Qfp1xiPxM4kTSOLdFFpjRwQ7YY7XJeKBvg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@typescript-eslint/eslint-plugin": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.8.1.tgz", @@ -2936,6 +2928,11 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -3726,12 +3723,6 @@ "mkdirp": "^0.5.1" } }, - "xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", - "dev": true - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 601e435..40411fd 100644 --- a/package.json +++ b/package.json @@ -35,16 +35,14 @@ "http-status-codes": "^2.1.4" }, "devDependencies": { - "@types/node": "^14.14.9", "@commitlint/config-conventional": "^11.0.0", "@map-colonies/eslint-config": "^1.1.0", "@types/chai": "^4.2.14", "@types/mocha": "^8.0.4", "@types/nock": "^11.1.0", + "@types/node": "^14.14.9", "@typescript-eslint/eslint-plugin": "^4.8.1", "@typescript-eslint/parser": "^4.8.1", - "@types/xml": "^1.0.5", - "typescript": "^4.1.2", "chai": "^4.2.0", "commitlint": "^11.0.0", "eslint": "^7.14.0", @@ -52,6 +50,7 @@ "mocha": "^8.2.1", "nock": "^13.0.5", "ts-node": "^9.0.0", - "xml": "^1.0.1" + "typescript": "^4.1.2", + "prettier": "^2.2.1" } } diff --git a/src/api/v6/index.ts b/src/api/v6/index.ts index 836ae22..c12bae1 100644 --- a/src/api/v6/index.ts +++ b/src/api/v6/index.ts @@ -1,35 +1,82 @@ -import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; -import StatusCodes from 'http-status-codes'; -import { createChangesetEndPoint } from '../../lib/endpoints'; -import { UnauthorizedError, BadXmlError, InternalServerError } from '../../lib/error-handler'; +import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios' +import StatusCodes from 'http-status-codes' +import { + createChangesetEndPoint, + closeChangesetEndPoint, +} from '../../lib/endpoints' +import { + UnauthorizedError, + BadXmlError, + ChangesetNotFoundError, + OwnerMismatchError, + NotAllowedError, + ChangesetAlreadyClosedError, +} from '../../lib/error-handler' class Apiv6 { - private readonly httpClient: AxiosInstance; - - public constructor(private readonly baseUrl: string, username: string, password: string) { - this.httpClient = axios.create({ baseURL: baseUrl, auth: { username, password } }); + private readonly httpClient: AxiosInstance + + public constructor( + private readonly baseUrl: string, + username: string, + password: string + ) { + this.httpClient = axios.create({ + baseURL: baseUrl, + auth: { username, password }, + }) } - + public async createChangeset(data: string): Promise { - let res: AxiosResponse; + let res: AxiosResponse try { - res = await this.httpClient.put(createChangesetEndPoint, data); - } - catch (e) { - const axiosError = e as AxiosError; + res = await this.httpClient.put( + createChangesetEndPoint, + data + ) + } catch (e) { + const axiosError = e as AxiosError if (axiosError.response?.status === StatusCodes.BAD_REQUEST) { - throw new BadXmlError(axiosError); - } else if (axiosError.response?.status === StatusCodes.UNAUTHORIZED) { - throw new UnauthorizedError(axiosError); - } else if (axiosError.response?.status === StatusCodes.INTERNAL_SERVER_ERROR) { - throw new InternalServerError(axiosError); + throw new BadXmlError(axiosError) + } else if ( + axiosError.response?.status === StatusCodes.UNAUTHORIZED + ) { + throw new UnauthorizedError(axiosError) + } else { + throw new Error(e) + } + } + const { data: changeSetId } = res + return changeSetId + } + + public async closeChangeset(id: number): Promise { + try { + await this.httpClient.put(closeChangesetEndPoint(id)) + } catch (e) { + const axiosError = e as AxiosError + + if (axiosError.response?.status === StatusCodes.UNAUTHORIZED) { + throw new UnauthorizedError(axiosError) + } else if ( + axiosError.response?.status === StatusCodes.METHOD_NOT_ALLOWED + ) { + throw new NotAllowedError(axiosError) + } else if (axiosError.response?.status === StatusCodes.NOT_FOUND) { + throw new ChangesetNotFoundError(axiosError) + } else if (axiosError.response?.status === StatusCodes.CONFLICT) { + if ( + axiosError.response.data === + 'The user doesnt own that changeset' + ) { + throw new OwnerMismatchError(axiosError) + } + throw new ChangesetAlreadyClosedError(axiosError) } else { - throw new Error(e); + throw new Error(e) } } - const { data: changeSetId } = res; - return changeSetId; } } -export default Apiv6; \ No newline at end of file +export default Apiv6 diff --git a/src/index.ts b/src/index.ts index 1ccb111..fb0da74 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,3 @@ -import Apiv6 from './api/v6'; +import Apiv6 from './api/v6' -export default Apiv6; \ No newline at end of file +export default Apiv6 diff --git a/src/lib/endpoints.ts b/src/lib/endpoints.ts index d1a8f26..db85369 100644 --- a/src/lib/endpoints.ts +++ b/src/lib/endpoints.ts @@ -1 +1,3 @@ -export const createChangesetEndPoint = '/api/0.6/changeset/create'; \ No newline at end of file +export const createChangesetEndPoint = '/api/0.6/changeset/create' +export const closeChangesetEndPoint = (id: number): string => + `/api/0.6/changeset/${id}/close` diff --git a/src/lib/error-handler.ts b/src/lib/error-handler.ts index 3722169..efab248 100644 --- a/src/lib/error-handler.ts +++ b/src/lib/error-handler.ts @@ -1,29 +1,50 @@ -import { AxiosError } from "axios"; +import { AxiosError } from 'axios' class HttpErrorHandler extends Error { public constructor(error: AxiosError) { - super(error.response?.data); - Object.setPrototypeOf(this, HttpErrorHandler.prototype); + super(error.response?.data) + Object.setPrototypeOf(this, HttpErrorHandler.prototype) } } export class UnauthorizedError extends HttpErrorHandler { public constructor(error: AxiosError) { - super(error); - Object.setPrototypeOf(this, UnauthorizedError.prototype); + super(error) + Object.setPrototypeOf(this, UnauthorizedError.prototype) } } export class BadXmlError extends HttpErrorHandler { public constructor(error: AxiosError) { - super(error); - Object.setPrototypeOf(this, BadXmlError.prototype); + super(error) + Object.setPrototypeOf(this, BadXmlError.prototype) } } -export class InternalServerError extends HttpErrorHandler { +export class ChangesetNotFoundError extends HttpErrorHandler { public constructor(error: AxiosError) { - super(error); - Object.setPrototypeOf(this, InternalServerError.prototype); + super(error) + Object.setPrototypeOf(this, ChangesetNotFoundError.prototype) } -} \ No newline at end of file +} + +export class ChangesetAlreadyClosedError extends HttpErrorHandler { + public constructor(error: AxiosError) { + super(error) + Object.setPrototypeOf(this, ChangesetAlreadyClosedError.prototype) + } +} + +export class OwnerMismatchError extends HttpErrorHandler { + public constructor(error: AxiosError) { + super(error) + Object.setPrototypeOf(this, OwnerMismatchError.prototype) + } +} + +export class NotAllowedError extends HttpErrorHandler { + public constructor(error: AxiosError) { + super(error) + Object.setPrototypeOf(this, NotAllowedError.prototype) + } +} diff --git a/tests/unit/apiv6.test.ts b/tests/unit/apiv6.test.ts index e3208ac..9039e59 100644 --- a/tests/unit/apiv6.test.ts +++ b/tests/unit/apiv6.test.ts @@ -1,46 +1,177 @@ -import { expect } from 'chai'; -import nock = require('nock'); +import { expect } from 'chai' +import nock = require('nock') -import Apiv6 from '../../src/index'; -import { createChangesetEndPoint } from '../../src/lib/endpoints'; -import { testConf } from './config/tests-config'; -import { createChangesetXml } from './lib/osm-xml'; - -const { baseUrl, username, password } = testConf; +import Apiv6 from '../../src/index' +import { + createChangesetEndPoint, + closeChangesetEndPoint, +} from '../../src/lib/endpoints' +import { + UnauthorizedError, + BadXmlError, + ChangesetNotFoundError, + ChangesetAlreadyClosedError, + OwnerMismatchError, +} from '../../src/lib/error-handler' +import { testConf } from './config/tests-config' +const { baseUrl, username, password, changeSetNumber } = testConf describe('apiv6', function () { - describe('happy flow', function () { - describe('/changeset/create', function () { + describe('/changeset/create', function () { + describe('happy flow', function () { describe('with register user', function () { - it('should return 200 and changset number', async function () { - const apiv6 = new Apiv6(baseUrl, username, password); - - nock(baseUrl).put(createChangesetEndPoint).reply(200, '12'); - - const xmlData = createChangesetXml("test-generator", "test-user"); - const res = await apiv6.createChangeset(xmlData); - - expect(res).to.be.equal(12); - }); - }); + it('should return changset number', async function () { + const apiv6 = new Apiv6(baseUrl, username, password) + + nock(baseUrl).put(createChangesetEndPoint).reply(200, '12') + + const xmlData = ` + + + + ` + const res = await apiv6.createChangeset(xmlData) + + expect(res).to.be.equal(12) + }) + }) + }) + describe('sad flow', function () { describe('with unregisterd user', function () { - it('should return error', async function () { - const apiv6 = new Apiv6(baseUrl, 'not-registerd', '123456'); + it('should return UnauthorizedError', async function () { + const apiv6 = new Apiv6(baseUrl, 'not-registerd', '123456') + + nock(baseUrl) + .put(createChangesetEndPoint) + .reply(401, "Couldn't authenticate you") + + const xmlData = ` + + + + ` + try { + await apiv6.createChangeset(xmlData) + } catch (e) { + return expect(e) + .to.be.instanceOf(UnauthorizedError) + .with.property('message') + .and.to.be.equal("Couldn't authenticate you") + } + throw new Error('should have thrown an error') + }) + }) + describe('with bad xml', function () { + it('should return BadXmlError', async function () { + const apiv6 = new Apiv6(baseUrl, 'not-registerd', '123456') + + nock(baseUrl) + .put(createChangesetEndPoint) + .reply( + 400, + 'Cannot parse valid changeset from xml string' + ) + + const xmlData = ` + + + + + + ` + try { + await apiv6.createChangeset(xmlData) + } catch (e) { + return expect(e) + .to.be.instanceOf(BadXmlError) + .with.property('message') + .and.to.be.equal( + 'Cannot parse valid changeset from xml string' + ) + } + throw new Error('should have thrown an error') + }) + }) + }) + }) + describe('/changeset/{id}/close}', function () { + describe('happy flow', function () { + describe('with opened changeset', function () { + it('should close the changset', async function () { + const apiv6 = new Apiv6(baseUrl, username, password) + + nock(baseUrl) + .put(closeChangesetEndPoint(changeSetNumber)) + .reply(200) + const res = await apiv6.closeChangeset(changeSetNumber) + expect(res).to.be.equal(undefined) + }) + }) + }) + describe('sad flow', function () { + describe('with mismatch user', function () { + it('should return OwnerMismatchError', async function () { + const apiv6 = new Apiv6(baseUrl, username, password) + + nock(baseUrl) + .put(closeChangesetEndPoint(changeSetNumber)) + .reply(409, "The user doesn't own that changeset") + + try { + await apiv6.closeChangeset(changeSetNumber) + } catch (e) { + return expect(e) + .to.be.instanceof(OwnerMismatchError) + .with.property('message') + .and.to.be.equal( + "The user doesn't own that changeset" + ) + } + throw new Error('should have thrown an error') + }) + }) + describe('with already closed changeset', function () { + it('should return ChangesetAlreadyClosedError', async function () { + const apiv6 = new Apiv6(baseUrl, username, password) + + nock(baseUrl) + .put(closeChangesetEndPoint(changeSetNumber)) + .reply( + 409, + `changeset ${changeSetNumber} was closed at` + ) + + try { + await apiv6.closeChangeset(changeSetNumber) + } catch (e) { + return expect(e) + .to.be.instanceof(ChangesetAlreadyClosedError) + .with.property('message') + .and.to.be.equal( + `changeset ${changeSetNumber} was closed at` + ) + } + throw new Error('should have thrown an error') + }) + }) + describe('with not exsits changeset', function () { + it('should return ChangesetNotFoundError', async function () { + const apiv6 = new Apiv6(baseUrl, username, password) - nock(baseUrl).put(createChangesetEndPoint).reply(401, 'Couldn\'t authenticate you'); - - const xmlData = createChangesetXml("test-generator", "test-user"); + nock(baseUrl) + .put(closeChangesetEndPoint(changeSetNumber)) + .reply(404) try { - await apiv6.createChangeset(xmlData); + await apiv6.closeChangeset(changeSetNumber) } catch (e) { - console.log(e); - expect(e).to.be.a('Error') - .with.property('message') - .and.to.be.equal('Couldn\'t authenticate you'); + return expect(e).to.be.instanceof( + ChangesetNotFoundError + ) } - }); - }); - }); - }); -}); \ No newline at end of file + throw new Error('should have thrown an error') + }) + }) + }) + }) +}) diff --git a/tests/unit/config/tests-config.ts b/tests/unit/config/tests-config.ts index a93952e..bb79d51 100644 --- a/tests/unit/config/tests-config.ts +++ b/tests/unit/config/tests-config.ts @@ -1,5 +1,11 @@ -export const testConf = { +export const testConf: { + baseUrl: string + username: string + password: string + changeSetNumber: number +} = { baseUrl: 'http://test.com:8080', username: 'USERNAME', - password: 'PASSWORD' -}; \ No newline at end of file + password: 'PASSWORD', + changeSetNumber: 12, +} diff --git a/tests/unit/lib/osm-xml.ts b/tests/unit/lib/osm-xml.ts deleted file mode 100644 index ffc7e3f..0000000 --- a/tests/unit/lib/osm-xml.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -import xml from 'xml'; - -export function createChangesetXml(generator: string, createdBy: string): string { - const data = [{ - osm: [ - { changeset: [ - { _atter: {version: 0.6, generator: generator}}, - { tag: {_attr: {k: "created_by", v: createdBy}}} - ]}] - }]; - return createtXml(data); -} - -function createtXml(file: any): string { - const osmXml = xml(file); - return osmXml; -} \ No newline at end of file From fe11da16f8f4202881c50a7d2596324709cee5ed Mon Sep 17 00:00:00 2001 From: galta <48960890+galta95@users.noreply.github.com> Date: Mon, 30 Nov 2020 13:57:11 +0200 Subject: [PATCH 2/6] style(prettier): format all documents --- .github/workflows/lint.yml | 2 +- .github/workflows/tests.yml | 2 +- .prettierrc.json | 10 +- commitlint.config.js | 2 +- src/api/v6/index.ts | 132 ++++++------- src/index.ts | 4 +- src/lib/endpoints.ts | 4 +- src/lib/error-handler.ts | 58 +++--- tests/unit/apiv6.test.ts | 316 ++++++++++++++---------------- tests/unit/config/tests-config.ts | 18 +- tsconfig.json | 20 +- 11 files changed, 272 insertions(+), 296 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a80e61d..9db2409 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -26,4 +26,4 @@ jobs: # Enable linters eslint: true prettier: true - eslint_extensions: ts \ No newline at end of file + eslint_extensions: ts diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3f0610b..c078ac4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,4 +20,4 @@ jobs: run: npm ci - name: Run tests - run: npm run test \ No newline at end of file + run: npm run test diff --git a/.prettierrc.json b/.prettierrc.json index d1039fb..0a72520 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,6 +1,6 @@ { - "trailingComma": "es5", - "tabWidth": 4, - "semi": false, - "singleQuote": true -} \ No newline at end of file + "trailingComma": "es5", + "tabWidth": 2, + "semi": true, + "singleQuote": true +} diff --git a/commitlint.config.js b/commitlint.config.js index 3d88028..422b194 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1 +1 @@ -module.exports = { extends: ['@commitlint/config-conventional'] }; \ No newline at end of file +module.exports = { extends: ['@commitlint/config-conventional'] }; diff --git a/src/api/v6/index.ts b/src/api/v6/index.ts index c12bae1..91b3a62 100644 --- a/src/api/v6/index.ts +++ b/src/api/v6/index.ts @@ -1,82 +1,76 @@ -import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios' -import StatusCodes from 'http-status-codes' +import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; +import StatusCodes from 'http-status-codes'; import { - createChangesetEndPoint, - closeChangesetEndPoint, -} from '../../lib/endpoints' + createChangesetEndPoint, + closeChangesetEndPoint, +} from '../../lib/endpoints'; import { - UnauthorizedError, - BadXmlError, - ChangesetNotFoundError, - OwnerMismatchError, - NotAllowedError, - ChangesetAlreadyClosedError, -} from '../../lib/error-handler' + UnauthorizedError, + BadXmlError, + ChangesetNotFoundError, + OwnerMismatchError, + NotAllowedError, + ChangesetAlreadyClosedError, +} from '../../lib/error-handler'; class Apiv6 { - private readonly httpClient: AxiosInstance + private readonly httpClient: AxiosInstance; - public constructor( - private readonly baseUrl: string, - username: string, - password: string - ) { - this.httpClient = axios.create({ - baseURL: baseUrl, - auth: { username, password }, - }) - } + public constructor( + private readonly baseUrl: string, + username: string, + password: string + ) { + this.httpClient = axios.create({ + baseURL: baseUrl, + auth: { username, password }, + }); + } - public async createChangeset(data: string): Promise { - let res: AxiosResponse - try { - res = await this.httpClient.put( - createChangesetEndPoint, - data - ) - } catch (e) { - const axiosError = e as AxiosError + public async createChangeset(data: string): Promise { + let res: AxiosResponse; + try { + res = await this.httpClient.put(createChangesetEndPoint, data); + } catch (e) { + const axiosError = e as AxiosError; - if (axiosError.response?.status === StatusCodes.BAD_REQUEST) { - throw new BadXmlError(axiosError) - } else if ( - axiosError.response?.status === StatusCodes.UNAUTHORIZED - ) { - throw new UnauthorizedError(axiosError) - } else { - throw new Error(e) - } - } - const { data: changeSetId } = res - return changeSetId + if (axiosError.response?.status === StatusCodes.BAD_REQUEST) { + throw new BadXmlError(axiosError); + } else if (axiosError.response?.status === StatusCodes.UNAUTHORIZED) { + throw new UnauthorizedError(axiosError); + } else { + throw new Error(e); + } } + const { data: changeSetId } = res; + return changeSetId; + } - public async closeChangeset(id: number): Promise { - try { - await this.httpClient.put(closeChangesetEndPoint(id)) - } catch (e) { - const axiosError = e as AxiosError + public async closeChangeset(id: number): Promise { + try { + await this.httpClient.put(closeChangesetEndPoint(id)); + } catch (e) { + const axiosError = e as AxiosError; - if (axiosError.response?.status === StatusCodes.UNAUTHORIZED) { - throw new UnauthorizedError(axiosError) - } else if ( - axiosError.response?.status === StatusCodes.METHOD_NOT_ALLOWED - ) { - throw new NotAllowedError(axiosError) - } else if (axiosError.response?.status === StatusCodes.NOT_FOUND) { - throw new ChangesetNotFoundError(axiosError) - } else if (axiosError.response?.status === StatusCodes.CONFLICT) { - if ( - axiosError.response.data === - 'The user doesnt own that changeset' - ) { - throw new OwnerMismatchError(axiosError) - } - throw new ChangesetAlreadyClosedError(axiosError) - } else { - throw new Error(e) - } + if (axiosError.response?.status === StatusCodes.UNAUTHORIZED) { + throw new UnauthorizedError(axiosError); + } else if ( + axiosError.response?.status === StatusCodes.METHOD_NOT_ALLOWED + ) { + throw new NotAllowedError(axiosError); + } else if (axiosError.response?.status === StatusCodes.NOT_FOUND) { + throw new ChangesetNotFoundError(axiosError); + } else if (axiosError.response?.status === StatusCodes.CONFLICT) { + if ( + axiosError.response.data === "The user doesn't own that changeset" + ) { + throw new OwnerMismatchError(axiosError); } + throw new ChangesetAlreadyClosedError(axiosError); + } else { + throw new Error(e); + } } + } } -export default Apiv6 +export default Apiv6; diff --git a/src/index.ts b/src/index.ts index fb0da74..8c4bf7f 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,3 @@ -import Apiv6 from './api/v6' +import Apiv6 from './api/v6'; -export default Apiv6 +export default Apiv6; diff --git a/src/lib/endpoints.ts b/src/lib/endpoints.ts index db85369..5afcde5 100644 --- a/src/lib/endpoints.ts +++ b/src/lib/endpoints.ts @@ -1,3 +1,3 @@ -export const createChangesetEndPoint = '/api/0.6/changeset/create' +export const createChangesetEndPoint = '/api/0.6/changeset/create'; export const closeChangesetEndPoint = (id: number): string => - `/api/0.6/changeset/${id}/close` + `/api/0.6/changeset/${id}/close`; diff --git a/src/lib/error-handler.ts b/src/lib/error-handler.ts index efab248..1fe981a 100644 --- a/src/lib/error-handler.ts +++ b/src/lib/error-handler.ts @@ -1,50 +1,50 @@ -import { AxiosError } from 'axios' +import { AxiosError } from 'axios'; class HttpErrorHandler extends Error { - public constructor(error: AxiosError) { - super(error.response?.data) - Object.setPrototypeOf(this, HttpErrorHandler.prototype) - } + public constructor(error: AxiosError) { + super(error.response?.data); + Object.setPrototypeOf(this, HttpErrorHandler.prototype); + } } export class UnauthorizedError extends HttpErrorHandler { - public constructor(error: AxiosError) { - super(error) - Object.setPrototypeOf(this, UnauthorizedError.prototype) - } + public constructor(error: AxiosError) { + super(error); + Object.setPrototypeOf(this, UnauthorizedError.prototype); + } } export class BadXmlError extends HttpErrorHandler { - public constructor(error: AxiosError) { - super(error) - Object.setPrototypeOf(this, BadXmlError.prototype) - } + public constructor(error: AxiosError) { + super(error); + Object.setPrototypeOf(this, BadXmlError.prototype); + } } export class ChangesetNotFoundError extends HttpErrorHandler { - public constructor(error: AxiosError) { - super(error) - Object.setPrototypeOf(this, ChangesetNotFoundError.prototype) - } + public constructor(error: AxiosError) { + super(error); + Object.setPrototypeOf(this, ChangesetNotFoundError.prototype); + } } export class ChangesetAlreadyClosedError extends HttpErrorHandler { - public constructor(error: AxiosError) { - super(error) - Object.setPrototypeOf(this, ChangesetAlreadyClosedError.prototype) - } + public constructor(error: AxiosError) { + super(error); + Object.setPrototypeOf(this, ChangesetAlreadyClosedError.prototype); + } } export class OwnerMismatchError extends HttpErrorHandler { - public constructor(error: AxiosError) { - super(error) - Object.setPrototypeOf(this, OwnerMismatchError.prototype) - } + public constructor(error: AxiosError) { + super(error); + Object.setPrototypeOf(this, OwnerMismatchError.prototype); + } } export class NotAllowedError extends HttpErrorHandler { - public constructor(error: AxiosError) { - super(error) - Object.setPrototypeOf(this, NotAllowedError.prototype) - } + public constructor(error: AxiosError) { + super(error); + Object.setPrototypeOf(this, NotAllowedError.prototype); + } } diff --git a/tests/unit/apiv6.test.ts b/tests/unit/apiv6.test.ts index 9039e59..03e893e 100644 --- a/tests/unit/apiv6.test.ts +++ b/tests/unit/apiv6.test.ts @@ -1,177 +1,159 @@ -import { expect } from 'chai' -import nock = require('nock') +import { expect } from 'chai'; +import nock = require('nock'); -import Apiv6 from '../../src/index' +import Apiv6 from '../../src/index'; import { - createChangesetEndPoint, - closeChangesetEndPoint, -} from '../../src/lib/endpoints' + createChangesetEndPoint, + closeChangesetEndPoint, +} from '../../src/lib/endpoints'; import { - UnauthorizedError, - BadXmlError, - ChangesetNotFoundError, - ChangesetAlreadyClosedError, - OwnerMismatchError, -} from '../../src/lib/error-handler' -import { testConf } from './config/tests-config' -const { baseUrl, username, password, changeSetNumber } = testConf + UnauthorizedError, + BadXmlError, + ChangesetNotFoundError, + ChangesetAlreadyClosedError, + OwnerMismatchError, +} from '../../src/lib/error-handler'; +import { testConf } from './config/tests-config'; +const { baseUrl, username, password, changeSetNumber } = testConf; describe('apiv6', function () { - describe('/changeset/create', function () { - describe('happy flow', function () { - describe('with register user', function () { - it('should return changset number', async function () { - const apiv6 = new Apiv6(baseUrl, username, password) + describe('/changeset/create', function () { + describe('happy flow', function () { + describe('with register user', function () { + it('should return changset number', async function () { + const apiv6 = new Apiv6(baseUrl, username, password); - nock(baseUrl).put(createChangesetEndPoint).reply(200, '12') + nock(baseUrl).put(createChangesetEndPoint).reply(200, '12'); - const xmlData = ` - - + const xmlData = ` + + - ` - const res = await apiv6.createChangeset(xmlData) - - expect(res).to.be.equal(12) - }) - }) - }) - describe('sad flow', function () { - describe('with unregisterd user', function () { - it('should return UnauthorizedError', async function () { - const apiv6 = new Apiv6(baseUrl, 'not-registerd', '123456') - - nock(baseUrl) - .put(createChangesetEndPoint) - .reply(401, "Couldn't authenticate you") - - const xmlData = ` - - + `; + const res = await apiv6.createChangeset(xmlData); + + expect(res).to.be.equal(12); + }); + }); + }); + describe('sad flow', function () { + describe('with unregisterd user', function () { + it('should return UnauthorizedError', async function () { + const apiv6 = new Apiv6(baseUrl, 'not-registerd', '123456'); + + nock(baseUrl) + .put(createChangesetEndPoint) + .reply(401, "Couldn't authenticate you"); + + const xmlData = ` + + - ` - try { - await apiv6.createChangeset(xmlData) - } catch (e) { - return expect(e) - .to.be.instanceOf(UnauthorizedError) - .with.property('message') - .and.to.be.equal("Couldn't authenticate you") - } - throw new Error('should have thrown an error') - }) - }) - describe('with bad xml', function () { - it('should return BadXmlError', async function () { - const apiv6 = new Apiv6(baseUrl, 'not-registerd', '123456') - - nock(baseUrl) - .put(createChangesetEndPoint) - .reply( - 400, - 'Cannot parse valid changeset from xml string' - ) - - const xmlData = ` - - - - + `; + try { + await apiv6.createChangeset(xmlData); + } catch (e) { + return expect(e) + .to.be.instanceOf(UnauthorizedError) + .with.property('message') + .and.to.be.equal("Couldn't authenticate you"); + } + throw new Error('should have thrown an error'); + }); + }); + describe('with bad xml', function () { + it('should return BadXmlError', async function () { + const apiv6 = new Apiv6(baseUrl, 'not-registerd', '123456'); + + nock(baseUrl) + .put(createChangesetEndPoint) + .reply(400, 'Cannot parse valid changeset from xml string'); + + const xmlData = ` + + + + - ` - try { - await apiv6.createChangeset(xmlData) - } catch (e) { - return expect(e) - .to.be.instanceOf(BadXmlError) - .with.property('message') - .and.to.be.equal( - 'Cannot parse valid changeset from xml string' - ) - } - throw new Error('should have thrown an error') - }) - }) - }) - }) - describe('/changeset/{id}/close}', function () { - describe('happy flow', function () { - describe('with opened changeset', function () { - it('should close the changset', async function () { - const apiv6 = new Apiv6(baseUrl, username, password) - - nock(baseUrl) - .put(closeChangesetEndPoint(changeSetNumber)) - .reply(200) - const res = await apiv6.closeChangeset(changeSetNumber) - expect(res).to.be.equal(undefined) - }) - }) - }) - describe('sad flow', function () { - describe('with mismatch user', function () { - it('should return OwnerMismatchError', async function () { - const apiv6 = new Apiv6(baseUrl, username, password) - - nock(baseUrl) - .put(closeChangesetEndPoint(changeSetNumber)) - .reply(409, "The user doesn't own that changeset") - - try { - await apiv6.closeChangeset(changeSetNumber) - } catch (e) { - return expect(e) - .to.be.instanceof(OwnerMismatchError) - .with.property('message') - .and.to.be.equal( - "The user doesn't own that changeset" - ) - } - throw new Error('should have thrown an error') - }) - }) - describe('with already closed changeset', function () { - it('should return ChangesetAlreadyClosedError', async function () { - const apiv6 = new Apiv6(baseUrl, username, password) - - nock(baseUrl) - .put(closeChangesetEndPoint(changeSetNumber)) - .reply( - 409, - `changeset ${changeSetNumber} was closed at` - ) - - try { - await apiv6.closeChangeset(changeSetNumber) - } catch (e) { - return expect(e) - .to.be.instanceof(ChangesetAlreadyClosedError) - .with.property('message') - .and.to.be.equal( - `changeset ${changeSetNumber} was closed at` - ) - } - throw new Error('should have thrown an error') - }) - }) - describe('with not exsits changeset', function () { - it('should return ChangesetNotFoundError', async function () { - const apiv6 = new Apiv6(baseUrl, username, password) - - nock(baseUrl) - .put(closeChangesetEndPoint(changeSetNumber)) - .reply(404) - - try { - await apiv6.closeChangeset(changeSetNumber) - } catch (e) { - return expect(e).to.be.instanceof( - ChangesetNotFoundError - ) - } - throw new Error('should have thrown an error') - }) - }) - }) - }) -}) + `; + try { + await apiv6.createChangeset(xmlData); + } catch (e) { + return expect(e) + .to.be.instanceOf(BadXmlError) + .with.property('message') + .and.to.be.equal('Cannot parse valid changeset from xml string'); + } + throw new Error('should have thrown an error'); + }); + }); + }); + }); + describe('/changeset/{id}/close}', function () { + describe('happy flow', function () { + describe('with opened changeset', function () { + it('should close the changset', async function () { + const apiv6 = new Apiv6(baseUrl, username, password); + + nock(baseUrl).put(closeChangesetEndPoint(changeSetNumber)).reply(200); + const res = await apiv6.closeChangeset(changeSetNumber); + expect(res).to.be.equal(undefined); + }); + }); + }); + describe('sad flow', function () { + describe('with mismatch user', function () { + it('should return OwnerMismatchError', async function () { + const apiv6 = new Apiv6(baseUrl, username, password); + + nock(baseUrl) + .put(closeChangesetEndPoint(changeSetNumber)) + .reply(409, "The user doesn't own that changeset"); + + try { + await apiv6.closeChangeset(changeSetNumber); + } catch (e) { + return expect(e) + .to.be.instanceof(OwnerMismatchError) + .with.property('message') + .and.to.be.equal("The user doesn't own that changeset"); + } + throw new Error('should have thrown an error'); + }); + }); + describe('with already closed changeset', function () { + it('should return ChangesetAlreadyClosedError', async function () { + const apiv6 = new Apiv6(baseUrl, username, password); + + nock(baseUrl) + .put(closeChangesetEndPoint(changeSetNumber)) + .reply(409, `changeset ${changeSetNumber} was closed at`); + + try { + await apiv6.closeChangeset(changeSetNumber); + } catch (e) { + return expect(e) + .to.be.instanceof(ChangesetAlreadyClosedError) + .with.property('message') + .and.to.be.equal(`changeset ${changeSetNumber} was closed at`); + } + throw new Error('should have thrown an error'); + }); + }); + describe('with not exsits changeset', function () { + it('should return ChangesetNotFoundError', async function () { + const apiv6 = new Apiv6(baseUrl, username, password); + + nock(baseUrl).put(closeChangesetEndPoint(changeSetNumber)).reply(404); + + try { + await apiv6.closeChangeset(changeSetNumber); + } catch (e) { + return expect(e).to.be.instanceof(ChangesetNotFoundError); + } + throw new Error('should have thrown an error'); + }); + }); + }); + }); +}); diff --git a/tests/unit/config/tests-config.ts b/tests/unit/config/tests-config.ts index bb79d51..1aab28d 100644 --- a/tests/unit/config/tests-config.ts +++ b/tests/unit/config/tests-config.ts @@ -1,11 +1,11 @@ export const testConf: { - baseUrl: string - username: string - password: string - changeSetNumber: number + baseUrl: string; + username: string; + password: string; + changeSetNumber: number; } = { - baseUrl: 'http://test.com:8080', - username: 'USERNAME', - password: 'PASSWORD', - changeSetNumber: 12, -} + baseUrl: 'http://test.com:8080', + username: 'USERNAME', + password: 'PASSWORD', + changeSetNumber: 12, +}; diff --git a/tsconfig.json b/tsconfig.json index 08a9ed8..f318945 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,21 +4,21 @@ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, "lib": [ "ES2015", "DOM" - ], /* Specify library files to be included in the compilation. */ + ] /* Specify library files to be included in the compilation. */, // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - "sourceMap": true, /* Generates corresponding '.map' file. */ + "sourceMap": true /* Generates corresponding '.map' file. */, // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./build", /* Redirect output structure to the directory. */ - "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "outDir": "./build" /* Redirect output structure to the directory. */, + "rootDir": "./" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ @@ -28,7 +28,7 @@ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ + "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* Enable strict null checks. */ // "strictFunctionTypes": true, /* Enable strict checking of function types. */ @@ -52,7 +52,7 @@ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ @@ -67,7 +67,7 @@ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ - "skipLibCheck": true, /* Skip type checking of declaration files. */ - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + "skipLibCheck": true /* Skip type checking of declaration files. */, + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ } } From 7dd2274114fb7c19f2a2bee1d6a384fc595d1a62 Mon Sep 17 00:00:00 2001 From: galta <48960890+galta95@users.noreply.github.com> Date: Thu, 3 Dec 2020 09:47:30 +0200 Subject: [PATCH 3/6] refactor(apiv06): export api res messages to constants --- src/api/v6/index.ts | 22 ++++++---------------- src/lib/constants.ts | 1 + 2 files changed, 7 insertions(+), 16 deletions(-) create mode 100644 src/lib/constants.ts diff --git a/src/api/v6/index.ts b/src/api/v6/index.ts index 91b3a62..11ce209 100644 --- a/src/api/v6/index.ts +++ b/src/api/v6/index.ts @@ -1,9 +1,6 @@ import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; import StatusCodes from 'http-status-codes'; -import { - createChangesetEndPoint, - closeChangesetEndPoint, -} from '../../lib/endpoints'; +import { createChangesetEndPoint, closeChangesetEndPoint } from '../../lib/endpoints'; import { UnauthorizedError, BadXmlError, @@ -11,15 +8,12 @@ import { OwnerMismatchError, NotAllowedError, ChangesetAlreadyClosedError, -} from '../../lib/error-handler'; +} from '../../lib/error'; +import { ownerMismatch } from '../../lib/constants'; class Apiv6 { private readonly httpClient: AxiosInstance; - public constructor( - private readonly baseUrl: string, - username: string, - password: string - ) { + public constructor(private readonly baseUrl: string, username: string, password: string) { this.httpClient = axios.create({ baseURL: baseUrl, auth: { username, password }, @@ -53,16 +47,12 @@ class Apiv6 { if (axiosError.response?.status === StatusCodes.UNAUTHORIZED) { throw new UnauthorizedError(axiosError); - } else if ( - axiosError.response?.status === StatusCodes.METHOD_NOT_ALLOWED - ) { + } else if (axiosError.response?.status === StatusCodes.METHOD_NOT_ALLOWED) { throw new NotAllowedError(axiosError); } else if (axiosError.response?.status === StatusCodes.NOT_FOUND) { throw new ChangesetNotFoundError(axiosError); } else if (axiosError.response?.status === StatusCodes.CONFLICT) { - if ( - axiosError.response.data === "The user doesn't own that changeset" - ) { + if (axiosError.response.data === ownerMismatch) { throw new OwnerMismatchError(axiosError); } throw new ChangesetAlreadyClosedError(axiosError); diff --git a/src/lib/constants.ts b/src/lib/constants.ts new file mode 100644 index 0000000..af0ca41 --- /dev/null +++ b/src/lib/constants.ts @@ -0,0 +1 @@ +export const ownerMismatch = "The user doesn't own that changeset"; From 16194fad94f31b85972ecc56be69b27b3dbc07e0 Mon Sep 17 00:00:00 2001 From: galta <48960890+galta95@users.noreply.github.com> Date: Thu, 3 Dec 2020 09:48:20 +0200 Subject: [PATCH 4/6] style(prettier): added print width to 150 --- .prettierrc.json | 1 + src/lib/endpoints.ts | 3 +-- tests/unit/apiv6.test.ts | 44 ++++++++-------------------------------- tsconfig.json | 5 +---- 4 files changed, 12 insertions(+), 41 deletions(-) diff --git a/.prettierrc.json b/.prettierrc.json index 0a72520..8e83df9 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,6 +1,7 @@ { "trailingComma": "es5", "tabWidth": 2, + "printWidth": 150, "semi": true, "singleQuote": true } diff --git a/src/lib/endpoints.ts b/src/lib/endpoints.ts index 5afcde5..7e50ff8 100644 --- a/src/lib/endpoints.ts +++ b/src/lib/endpoints.ts @@ -1,3 +1,2 @@ export const createChangesetEndPoint = '/api/0.6/changeset/create'; -export const closeChangesetEndPoint = (id: number): string => - `/api/0.6/changeset/${id}/close`; +export const closeChangesetEndPoint = (id: number): string => `/api/0.6/changeset/${id}/close`; diff --git a/tests/unit/apiv6.test.ts b/tests/unit/apiv6.test.ts index 03e893e..6147656 100644 --- a/tests/unit/apiv6.test.ts +++ b/tests/unit/apiv6.test.ts @@ -2,17 +2,8 @@ import { expect } from 'chai'; import nock = require('nock'); import Apiv6 from '../../src/index'; -import { - createChangesetEndPoint, - closeChangesetEndPoint, -} from '../../src/lib/endpoints'; -import { - UnauthorizedError, - BadXmlError, - ChangesetNotFoundError, - ChangesetAlreadyClosedError, - OwnerMismatchError, -} from '../../src/lib/error-handler'; +import { createChangesetEndPoint, closeChangesetEndPoint } from '../../src/lib/endpoints'; +import { UnauthorizedError, BadXmlError, ChangesetNotFoundError, ChangesetAlreadyClosedError, OwnerMismatchError } from '../../src/lib/error'; import { testConf } from './config/tests-config'; const { baseUrl, username, password, changeSetNumber } = testConf; @@ -41,9 +32,7 @@ describe('apiv6', function () { it('should return UnauthorizedError', async function () { const apiv6 = new Apiv6(baseUrl, 'not-registerd', '123456'); - nock(baseUrl) - .put(createChangesetEndPoint) - .reply(401, "Couldn't authenticate you"); + nock(baseUrl).put(createChangesetEndPoint).reply(401, "Couldn't authenticate you"); const xmlData = ` @@ -53,10 +42,7 @@ describe('apiv6', function () { try { await apiv6.createChangeset(xmlData); } catch (e) { - return expect(e) - .to.be.instanceOf(UnauthorizedError) - .with.property('message') - .and.to.be.equal("Couldn't authenticate you"); + return expect(e).to.be.instanceOf(UnauthorizedError).with.property('message').and.to.be.equal("Couldn't authenticate you"); } throw new Error('should have thrown an error'); }); @@ -65,9 +51,7 @@ describe('apiv6', function () { it('should return BadXmlError', async function () { const apiv6 = new Apiv6(baseUrl, 'not-registerd', '123456'); - nock(baseUrl) - .put(createChangesetEndPoint) - .reply(400, 'Cannot parse valid changeset from xml string'); + nock(baseUrl).put(createChangesetEndPoint).reply(400, 'Cannot parse valid changeset from xml string'); const xmlData = ` @@ -79,10 +63,7 @@ describe('apiv6', function () { try { await apiv6.createChangeset(xmlData); } catch (e) { - return expect(e) - .to.be.instanceOf(BadXmlError) - .with.property('message') - .and.to.be.equal('Cannot parse valid changeset from xml string'); + return expect(e).to.be.instanceOf(BadXmlError).with.property('message').and.to.be.equal('Cannot parse valid changeset from xml string'); } throw new Error('should have thrown an error'); }); @@ -106,17 +87,12 @@ describe('apiv6', function () { it('should return OwnerMismatchError', async function () { const apiv6 = new Apiv6(baseUrl, username, password); - nock(baseUrl) - .put(closeChangesetEndPoint(changeSetNumber)) - .reply(409, "The user doesn't own that changeset"); + nock(baseUrl).put(closeChangesetEndPoint(changeSetNumber)).reply(409, "The user doesn't own that changeset"); try { await apiv6.closeChangeset(changeSetNumber); } catch (e) { - return expect(e) - .to.be.instanceof(OwnerMismatchError) - .with.property('message') - .and.to.be.equal("The user doesn't own that changeset"); + return expect(e).to.be.instanceof(OwnerMismatchError).with.property('message').and.to.be.equal("The user doesn't own that changeset"); } throw new Error('should have thrown an error'); }); @@ -125,9 +101,7 @@ describe('apiv6', function () { it('should return ChangesetAlreadyClosedError', async function () { const apiv6 = new Apiv6(baseUrl, username, password); - nock(baseUrl) - .put(closeChangesetEndPoint(changeSetNumber)) - .reply(409, `changeset ${changeSetNumber} was closed at`); + nock(baseUrl).put(closeChangesetEndPoint(changeSetNumber)).reply(409, `changeset ${changeSetNumber} was closed at`); try { await apiv6.closeChangeset(changeSetNumber); diff --git a/tsconfig.json b/tsconfig.json index f318945..aefb5c7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,10 +6,7 @@ // "incremental": true, /* Enable incremental compilation */ "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": [ - "ES2015", - "DOM" - ] /* Specify library files to be included in the compilation. */, + "lib": ["ES2015", "DOM"] /* Specify library files to be included in the compilation. */, // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ From 10a8f736bcaae6261529a62439c45604e362a9a3 Mon Sep 17 00:00:00 2001 From: galta <48960890+galta95@users.noreply.github.com> Date: Thu, 3 Dec 2020 09:49:16 +0200 Subject: [PATCH 5/6] style(rename-file): error-handler to errors --- src/api/v6/index.ts | 2 +- src/lib/{error-handler.ts => errors.ts} | 0 tests/unit/apiv6.test.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/lib/{error-handler.ts => errors.ts} (100%) diff --git a/src/api/v6/index.ts b/src/api/v6/index.ts index 11ce209..e6b2ca4 100644 --- a/src/api/v6/index.ts +++ b/src/api/v6/index.ts @@ -8,7 +8,7 @@ import { OwnerMismatchError, NotAllowedError, ChangesetAlreadyClosedError, -} from '../../lib/error'; +} from '../../lib/errors'; import { ownerMismatch } from '../../lib/constants'; class Apiv6 { private readonly httpClient: AxiosInstance; diff --git a/src/lib/error-handler.ts b/src/lib/errors.ts similarity index 100% rename from src/lib/error-handler.ts rename to src/lib/errors.ts diff --git a/tests/unit/apiv6.test.ts b/tests/unit/apiv6.test.ts index 6147656..fbbb2dc 100644 --- a/tests/unit/apiv6.test.ts +++ b/tests/unit/apiv6.test.ts @@ -3,7 +3,7 @@ import nock = require('nock'); import Apiv6 from '../../src/index'; import { createChangesetEndPoint, closeChangesetEndPoint } from '../../src/lib/endpoints'; -import { UnauthorizedError, BadXmlError, ChangesetNotFoundError, ChangesetAlreadyClosedError, OwnerMismatchError } from '../../src/lib/error'; +import { UnauthorizedError, BadXmlError, ChangesetNotFoundError, ChangesetAlreadyClosedError, OwnerMismatchError } from '../../src/lib/errors'; import { testConf } from './config/tests-config'; const { baseUrl, username, password, changeSetNumber } = testConf; From 85424fe2196504b101a879cbc6d49a1a304ade41 Mon Sep 17 00:00:00 2001 From: galta <48960890+galta95@users.noreply.github.com> Date: Thu, 3 Dec 2020 10:05:24 +0200 Subject: [PATCH 6/6] style(constants): rename constants --- package-lock.json | 3 ++- src/api/v6/index.ts | 4 ++-- src/lib/constants.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index a87b4f4..ecd50b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2931,7 +2931,8 @@ "prettier": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", - "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==" + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true }, "process-nextick-args": { "version": "2.0.1", diff --git a/src/api/v6/index.ts b/src/api/v6/index.ts index e6b2ca4..6ff3962 100644 --- a/src/api/v6/index.ts +++ b/src/api/v6/index.ts @@ -9,7 +9,7 @@ import { NotAllowedError, ChangesetAlreadyClosedError, } from '../../lib/errors'; -import { ownerMismatch } from '../../lib/constants'; +import { OWNER_MISMATCH } from '../../lib/constants'; class Apiv6 { private readonly httpClient: AxiosInstance; @@ -52,7 +52,7 @@ class Apiv6 { } else if (axiosError.response?.status === StatusCodes.NOT_FOUND) { throw new ChangesetNotFoundError(axiosError); } else if (axiosError.response?.status === StatusCodes.CONFLICT) { - if (axiosError.response.data === ownerMismatch) { + if (axiosError.response.data === OWNER_MISMATCH) { throw new OwnerMismatchError(axiosError); } throw new ChangesetAlreadyClosedError(axiosError); diff --git a/src/lib/constants.ts b/src/lib/constants.ts index af0ca41..f1ee6c0 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -1 +1 @@ -export const ownerMismatch = "The user doesn't own that changeset"; +export const OWNER_MISMATCH = "The user doesn't own that changeset";