From d6dd94195a132bbfd71e96a6fe99872814eb7561 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:09:20 -0600 Subject: [PATCH] fix: update so that pre-commit hook only includes running unit tests as part of test coverage, but when run as part of ci integration tests will be run as part of test coverage --- .github/workflows/lint_format_test.yaml | 2 +- package.json | 3 +- tests/ApiResponseFactory.spec.ts | 207 ++++++++++++++++++++++++ 3 files changed, 210 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint_format_test.yaml b/.github/workflows/lint_format_test.yaml index a842859..4ec3d73 100644 --- a/.github/workflows/lint_format_test.yaml +++ b/.github/workflows/lint_format_test.yaml @@ -80,7 +80,7 @@ jobs: - name: Install dependencies run: npm install - name: Run test coverage and tests - run: npm run test-coverage + run: npm run test-coverage:ci env: API_BASE_URL: ${{ vars.API_BASE_URL }} SANDBOX_API_KEY: ${{ secrets.SANDBOX_API_KEY }} diff --git a/package.json b/package.json index d397674..9e1fd12 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,8 @@ "tests:unit": "mocha -R progress -r ts-node/register ./tests/**/*.spec.ts", "tests:integration": "mocha -R progress -r ts-node/register -r integrationTests/mochaRootHooks.ts ./integrationTests/**/*.spec.ts", "tests": "mocha -R progress -r ts-node/register ./tests/**/*.spec.ts && mocha -R progress -r ts-node/register -r integrationTests/mochaRootHooks.ts ./integrationTests/**/*.spec.ts", - "test-coverage": "nyc npm run tests", + "test-coverage": "nyc npm run tests:unit", + "test-coverage:ci": "nyc npm run tests", "prepare": "husky install" }, "devDependencies": { diff --git a/tests/ApiResponseFactory.spec.ts b/tests/ApiResponseFactory.spec.ts index 7c13612..5b202ea 100644 --- a/tests/ApiResponseFactory.spec.ts +++ b/tests/ApiResponseFactory.spec.ts @@ -1,6 +1,7 @@ import { ApiResponseFactory } from '../src/models/ApiResponseFactory'; import { type AxiosResponse, type InternalAxiosRequestConfig } from 'axios'; import { expect } from 'chai'; +import { Readable } from 'stream'; describe('ApiResponseFactory', function () { it('should be defined', function () { @@ -80,6 +81,69 @@ describe('ApiResponseFactory', function () { expect(apiResponse.data).to.equal(null); }); + it('should return an ApiResponse object without a message value when request is forbidden, the response does contain a message property, and the responseType is stream', async function () { + const stream = new Readable({ + read() { + this.push(null); + }, + }); + + const response: AxiosResponse = { + data: stream, + status: 403, + statusText: 'Forbidden', + headers: {}, + config: { + responseType: 'stream', + } as InternalAxiosRequestConfig, + }; + + const apiResponse = await ApiResponseFactory.getApiResponse(response); + + expect(apiResponse).to.not.be.undefined; + expect(apiResponse).to.have.property('statusCode'); + expect(apiResponse).to.have.property('message'); + expect(apiResponse).to.have.property('data'); + expect(apiResponse.statusCode).to.equal(403); + expect(apiResponse.message).to.equal(undefined); + expect(apiResponse.data).to.equal(null); + }); + + it('should return an ApiResponse object when request is forbidden, the response contains a message property, and the responseType is stream', async function () { + const stream = new Readable({ + read() { + this.push( + JSON.stringify({ + message: 'Does not have permission to access this resource.', + }) + ); + this.push(null); + }, + }); + + const response: AxiosResponse = { + data: stream, + status: 403, + statusText: 'Forbidden', + headers: {}, + config: { + responseType: 'stream', + } as InternalAxiosRequestConfig, + }; + + const apiResponse = await ApiResponseFactory.getApiResponse(response); + + expect(apiResponse).to.not.be.undefined; + expect(apiResponse).to.have.property('statusCode'); + expect(apiResponse).to.have.property('message'); + expect(apiResponse).to.have.property('data'); + expect(apiResponse.statusCode).to.equal(403); + expect(apiResponse.message).to.equal( + 'Does not have permission to access this resource.' + ); + expect(apiResponse.data).to.equal(null); + }); + it('should return an ApiResponse object without a message value when request is not found and the response does not contain a message property', async function () { const response: AxiosResponse = { data: null, @@ -122,6 +186,63 @@ describe('ApiResponseFactory', function () { expect(apiResponse.data).to.equal(null); }); + it('should return an ApiResponse object without a message value when request is not found, the response does not contain a message property, and the responseType is a stream', async function () { + const stream = new Readable({ + read() { + this.push(null); + }, + }); + + const response: AxiosResponse = { + data: stream, + status: 404, + statusText: 'Not Found', + headers: {}, + config: { + responseType: 'stream', + } as InternalAxiosRequestConfig, + }; + + const apiResponse = await ApiResponseFactory.getApiResponse(response); + + expect(apiResponse).to.not.be.undefined; + expect(apiResponse).to.have.property('statusCode'); + expect(apiResponse).to.have.property('message'); + expect(apiResponse).to.have.property('data'); + expect(apiResponse.statusCode).to.equal(404); + expect(apiResponse.message).to.equal(undefined); + expect(apiResponse.data).to.equal(null); + }); + + it('should return an ApiResponse object with a message value when request is not found, the response contains a message property, and the responseType is stream', async function () { + const stream = new Readable({ + read() { + this.push(JSON.stringify({ message: 'Resource not found.' })); + this.push(null); + }, + }); + + const response: AxiosResponse = { + data: stream, + status: 404, + statusText: 'Not Found', + headers: {}, + config: { + responseType: 'stream', + } as InternalAxiosRequestConfig, + }; + + const apiResponse = await ApiResponseFactory.getApiResponse(response); + + expect(apiResponse).to.not.be.undefined; + expect(apiResponse).to.have.property('statusCode'); + expect(apiResponse).to.have.property('message'); + expect(apiResponse).to.have.property('data'); + expect(apiResponse.statusCode).to.equal(404); + expect(apiResponse.message).to.equal('Resource not found.'); + expect(apiResponse.data).to.equal(null); + }); + it('should return an ApiResponse object without a message value when request is unauthorized and the response does not contain a message property', async function () { const response: AxiosResponse = { data: null, @@ -164,6 +285,63 @@ describe('ApiResponseFactory', function () { expect(apiResponse.data).to.equal(null); }); + it('should return an ApiResponse object without a message value when request is unauthorized and the response does not contain a message property, and the responseType is stream', async function () { + const stream = new Readable({ + read() { + this.push(null); + }, + }); + + const response: AxiosResponse = { + data: stream, + status: 401, + statusText: 'Unauthorized', + headers: {}, + config: { + responseType: 'stream', + } as InternalAxiosRequestConfig, + }; + + const apiResponse = await ApiResponseFactory.getApiResponse(response); + + expect(apiResponse).to.not.be.undefined; + expect(apiResponse).to.have.property('statusCode'); + expect(apiResponse).to.have.property('message'); + expect(apiResponse).to.have.property('data'); + expect(apiResponse.statusCode).to.equal(401); + expect(apiResponse.message).to.equal(undefined); + expect(apiResponse.data).to.equal(null); + }); + + it('should return an ApiResponse object with a message when request is unauthorized, the response contains a message property, and the responseType is stream', async function () { + const stream = new Readable({ + read() { + this.push(JSON.stringify({ message: 'Unauthorized.' })); + this.push(null); + }, + }); + + const response: AxiosResponse = { + data: stream, + status: 401, + statusText: 'Unauthorized', + headers: {}, + config: { + responseType: 'stream', + } as InternalAxiosRequestConfig, + }; + + const apiResponse = await ApiResponseFactory.getApiResponse(response); + + expect(apiResponse).to.not.be.undefined; + expect(apiResponse).to.have.property('statusCode'); + expect(apiResponse).to.have.property('message'); + expect(apiResponse).to.have.property('data'); + expect(apiResponse.statusCode).to.equal(401); + expect(apiResponse.message).to.equal('Unauthorized.'); + expect(apiResponse.data).to.equal(null); + }); + it('should return an ApiResponse object with a message when request is a bad request', async function () { const response: AxiosResponse = { data: { @@ -185,5 +363,34 @@ describe('ApiResponseFactory', function () { expect(apiResponse.message).to.equal('{"field":"Invalid input."}'); expect(apiResponse.data).to.equal(null); }); + + it('should return an ApiResponse object with a message when request is a bad request and responseType is stream', async function () { + const stream = new Readable({ + read() { + this.push(JSON.stringify({ field: 'Invalid input.' })); + this.push(null); + }, + }); + + const response: AxiosResponse = { + data: stream, + status: 400, + statusText: 'Bad Request', + headers: {}, + config: { + responseType: 'stream', + } as InternalAxiosRequestConfig, + }; + + const apiResponse = await ApiResponseFactory.getApiResponse(response); + + expect(apiResponse).to.not.be.undefined; + expect(apiResponse).to.have.property('statusCode'); + expect(apiResponse).to.have.property('message'); + expect(apiResponse).to.have.property('data'); + expect(apiResponse.statusCode).to.equal(400); + expect(apiResponse.message).to.equal('{"field":"Invalid input."}'); + expect(apiResponse.data).to.equal(null); + }); }); });