Jaime Ramírez
2020-06-11 523d18a86155840b6a89af8b7b9f8bb8b9ca2663
fix(adopt-a-pup): Handle denied adoptions (#48)

1 files added
2 files modified
111 ■■■■■ changed files
adopt-a-pup/web-app/src/Services/AdoptionRESTService.test.ts 80 ●●●●● patch | view | raw | blame | history
adopt-a-pup/web-app/src/Services/AdoptionRESTService.ts 27 ●●●●● patch | view | raw | blame | history
adopt-a-pup/web-app/src/Services/RESTService.ts 4 ●●●● patch | view | raw | blame | history
adopt-a-pup/web-app/src/Services/AdoptionRESTService.test.ts
New file
@@ -0,0 +1,80 @@
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");
        }
    });
});
adopt-a-pup/web-app/src/Services/AdoptionRESTService.ts
@@ -4,6 +4,12 @@
import { AdoptionApplication } from "../Models/AdoptionApplication";
interface AdoptionResponse {
    status: "APPROVED" | "DENIED",
    message: string
}
export default class AdoptionRESTService extends RESTService implements AdoptionService {
    constructor(baseUrl: string) {
@@ -24,7 +30,24 @@
    }
    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;
    }
}
adopt-a-pup/web-app/src/Services/RESTService.ts
@@ -23,9 +23,9 @@
        }
    }
    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);