fix(adopt-a-pup): Handle denied adoptions (#48)
1 files added
2 files modified
New file |
| | |
| | | import Axios from "axios"; |
| | | import AdoptionRESTService, { AdoptionDeniedError } from "./AdoptionRESTService"; |
| | | import { Residency } from "../Models/Residency"; |
| | | |
| | | jest.mock("axios"); |
| | | |
| | | describe("AdoptionRESTService", () => { |
| | | |
| | | |
| | | let service: AdoptionRESTService; |
| | | |
| | | beforeEach(() => { |
| | | Axios.create = jest.fn().mockReturnValue(Axios); |
| | | service = new AdoptionRESTService("http://adoption-service.example.com"); |
| | | }); |
| | | |
| | | test("adopt sends a POST request", async () => { |
| | | (Axios.post as jest.Mock).mockResolvedValue({ |
| | | status: 200, |
| | | data: { |
| | | status: "APPROVED" |
| | | } |
| | | }); |
| | | |
| | | await service.applyForAdoption({ |
| | | animalId: "fake-animal-id", |
| | | username: "John", |
| | | email: "test@example.com", |
| | | occupation: "Pilot", |
| | | residency: Residency.APARTMENT, |
| | | squareFootageOfHome: 500, |
| | | kidsUnder16: true, |
| | | ownOtherAnimals: false, |
| | | }); |
| | | |
| | | expect(Axios.post).toHaveBeenCalledWith( |
| | | "/adoption/applyForAdoption", |
| | | { |
| | | animalId: "fake-animal-id", |
| | | username: "John", |
| | | email: "test@example.com", |
| | | occupation: "Pilot", |
| | | residency: Residency.APARTMENT, |
| | | squareFootageOfHome: 500, |
| | | kidsUnder16: true, |
| | | ownOtherAnimals: false, |
| | | }, |
| | | { |
| | | timeout: 3000 |
| | | } |
| | | ); |
| | | }); |
| | | |
| | | test("throws error when adoption is not denied", async () => { |
| | | (Axios.post as jest.Mock).mockResolvedValue({ |
| | | status: 200, |
| | | data: { |
| | | status: "DENIED", |
| | | message: "There was a problem with your application" |
| | | } |
| | | }); |
| | | |
| | | expect.assertions(2); |
| | | try { |
| | | await service.applyForAdoption({ |
| | | animalId: "fake-animal-id", |
| | | username: "John", |
| | | email: "test@example.com", |
| | | occupation: "Pilot", |
| | | residency: Residency.APARTMENT, |
| | | squareFootageOfHome: 500, |
| | | kidsUnder16: true, |
| | | ownOtherAnimals: false, |
| | | }); |
| | | } catch (error) { |
| | | expect(error).toBeInstanceOf(AdoptionDeniedError); |
| | | expect(error.message).toContain("There was a problem with your application"); |
| | | } |
| | | }); |
| | | }); |
| | |
| | | import { AdoptionApplication } from "../Models/AdoptionApplication"; |
| | | |
| | | |
| | | interface AdoptionResponse { |
| | | status: "APPROVED" | "DENIED", |
| | | message: string |
| | | } |
| | | |
| | | |
| | | export default class AdoptionRESTService extends RESTService implements AdoptionService { |
| | | |
| | | constructor(baseUrl: string) { |
| | |
| | | } |
| | | |
| | | public async applyForAdoption(adoptionApplication: AdoptionApplication): Promise<void> { |
| | | await this.post("/adoption/applyForAdoption", adoptionApplication); |
| | | const response = await this.post<AdoptionApplication, AdoptionResponse>( |
| | | "/adoption/applyForAdoption", |
| | | adoptionApplication |
| | | ); |
| | | |
| | | if (response.status === "DENIED") { |
| | | throw new AdoptionDeniedError(response.message); |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | export class AdoptionDeniedError extends Error { |
| | | |
| | | constructor(message: string) { |
| | | super(); |
| | | this.name = "Adoption Denied"; |
| | | this.message = message; |
| | | } |
| | | |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | protected async post<T>(url: string, body: T): Promise<any> { |
| | | protected async post<T, R>(url: string, body: T): Promise<R> { |
| | | try { |
| | | const r = await this.axiosInstance.post<T>(url, body, { timeout: this.timeoutMs }); |
| | | const r = await this.axiosInstance.post<R>(url, body, { timeout: this.timeoutMs }); |
| | | return r.data; |
| | | } catch (e) { |
| | | throw new RESTConnectionError(e, this.remoteServiceName, e.response?.status); |