feat: release 1.3.1

This commit is contained in:
Brian Pooe 2023-06-16 12:08:20 +02:00
commit c7e6031e50
3 changed files with 197 additions and 23 deletions

View file

@ -11,7 +11,7 @@ jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: nrwl/nx-set-shas@v3
@ -22,10 +22,24 @@ jobs:
- run: npx nx affected -t test --parallel=3 --configuration=ci
- run: npx nx affected -t build --parallel=3
- name: Release
- name: Publish
if: ${{ success() && (github.event_name != 'pull_request' || github.event.action == 'closed' && github.event.pull_request.merged == true) }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
npx nx run-many --target release --all
create-github-release:
name: Create GitHub Release
runs-on: ubuntu-latest
needs: main
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Create Release
run: gh release create ${{ github.ref }} --generate-notes
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -1,5 +1,167 @@
import { handleResponseAndError } from './handle-response-and-error.util';
import { AxiosError, AxiosResponse } from 'axios';
import { fromPartial } from '@total-typescript/shoehorn';
import { SubscriberSpy, subscribeSpyTo } from '@hirez_io/observer-spy';
import { of, throwError } from 'rxjs';
import { HttpException, HttpStatus } from '@nestjs/common';
import { PsFetchTransactionResponseModel } from '../../models';
describe(handleResponseAndError.name, () => {
test.todo('should handle response and error');
describe('successful response', () => {
it('should return extracted response on success', () => {
// Arrange
const response: AxiosResponse<PsFetchTransactionResponseModel> =
fromPartial({
data: {
status: true,
message: 'Transaction retrieved',
data: fromPartial({
id: 2836566657,
status: 'success',
reference: '203520101',
amount: 2000,
gateway_response: 'Successful'
})
}
});
// Act
const observerSpy = subscribeSpyTo(
of(response).pipe(handleResponseAndError())
);
// Assert
expect(observerSpy.getLastValue()).toEqual(response.data);
});
});
describe('catch error', () => {
it('should throw bad request error', () => {
// Arrange
const response: AxiosError<HttpException> = fromPartial({
response: fromPartial({
status: HttpStatus.BAD_REQUEST,
data: fromPartial({
message: 'bad request error'
})
})
});
//Act
const observerSpy = getThrownError(response);
// Assert
expect(observerSpy.receivedError()).toBeTruthy();
expect(observerSpy.getError().response.statusCode).toEqual(
response.response?.status
);
expect(observerSpy.getError().response.message).toEqual(
response.response?.data?.message
);
});
it('should throw unauthorized error', () => {
// Arrange
const response: AxiosError<HttpException> = fromPartial({
response: fromPartial({
status: HttpStatus.UNAUTHORIZED,
data: fromPartial({
message: 'unauthorized error'
})
})
});
//Act
const observerSpy = getThrownError(response);
// Assert
expect(observerSpy.receivedError()).toBeTruthy();
expect(observerSpy.getError().response.statusCode).toEqual(
response.response?.status
);
expect(observerSpy.getError().response.message).toEqual(
response.response?.data?.message
);
});
it('should throw not found error', () => {
// Arrange
const response: AxiosError<HttpException> = fromPartial({
response: fromPartial({
status: HttpStatus.NOT_FOUND,
data: fromPartial({
message: 'unauthorized error'
})
})
});
//Act
const observerSpy = getThrownError(response);
// Assert
expect(observerSpy.receivedError()).toBeTruthy();
expect(observerSpy.getError().response.statusCode).toEqual(
response.response?.status
);
expect(observerSpy.getError().response.message).toEqual(
response.response?.data?.message
);
});
it('should throw internal server error', () => {
// Arrange
const response: AxiosError<HttpException> = fromPartial({
response: fromPartial({
status: HttpStatus.INTERNAL_SERVER_ERROR,
data: fromPartial({
message: 'internal server error'
})
})
});
//Act
const observerSpy = getThrownError(response);
// Assert
expect(observerSpy.receivedError()).toBeTruthy();
expect(observerSpy.getError().response.statusCode).toEqual(
response.response?.status
);
expect(observerSpy.getError().response.message).toEqual(
response.response?.data?.message
);
});
it('should throw error with custom message if no response data was provided', () => {
// Arrange
const response: AxiosError<HttpException> = fromPartial({
response: fromPartial({
status: HttpStatus.INTERNAL_SERVER_ERROR,
data: undefined
})
});
//Act
const observerSpy = getThrownError(response);
// Assert
expect(observerSpy.receivedError()).toBeTruthy();
expect(observerSpy.getError().response.statusCode).toEqual(
response.response?.status
);
expect(observerSpy.getError().message).toEqual(
'Something went wrong. Please try again later.'
);
});
});
});
const getThrownError = (
response: AxiosError<HttpException>
): SubscriberSpy<unknown> => {
return subscribeSpyTo(
throwError(() => response).pipe(handleResponseAndError()),
{
expectErrors: true
}
);
};

View file

@ -6,7 +6,14 @@ import {
OperatorFunction,
throwError
} from 'rxjs';
import { HttpException, HttpStatus } from '@nestjs/common';
import {
BadRequestException,
HttpException,
HttpStatus,
InternalServerErrorException,
NotFoundException,
UnauthorizedException
} from '@nestjs/common';
export const handleResponseAndError = <
T extends AxiosResponse,
@ -17,30 +24,21 @@ export const handleResponseAndError = <
map(({ data }) => data),
catchError((error: AxiosError<HttpException>) => {
console.error(error);
const errorMessage = error.response?.data || {
status: false,
message: 'Something went wrong. Please try again later.'
};
switch (error.response?.status) {
const errorMessage =
error.response?.data?.message ||
'Something went wrong. Please try again later.';
const httpStatus = error.response?.status;
switch (httpStatus) {
case HttpStatus.BAD_REQUEST:
return throwError(
() => new HttpException(errorMessage, HttpStatus.BAD_REQUEST)
);
return throwError(() => new BadRequestException(errorMessage));
case HttpStatus.UNAUTHORIZED:
return throwError(
() => new HttpException(errorMessage, HttpStatus.UNAUTHORIZED)
);
return throwError(() => new UnauthorizedException(errorMessage));
case HttpStatus.NOT_FOUND:
return throwError(
() => new HttpException(errorMessage, HttpStatus.NOT_FOUND)
);
return throwError(() => new NotFoundException(errorMessage));
default:
return throwError(
() =>
new HttpException(
errorMessage,
HttpStatus.INTERNAL_SERVER_ERROR
)
() => new InternalServerErrorException(errorMessage)
);
}
})