feat: release 1.3.1
This commit is contained in:
commit
c7e6031e50
3 changed files with 197 additions and 23 deletions
18
.github/workflows/bp-devtools-ci.yml
vendored
18
.github/workflows/bp-devtools-ci.yml
vendored
|
|
@ -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 }}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue