cpen321-recipe-roulette / server / test / testReviews.test.js
testReviews.test.js
Raw
var dbFunctions = require("../db/db").Functions;
var app = require("../src/app");
var request = require("supertest");

const mockedDbGetAllRecipesResponse = [
    {
        recipeId: "567446",
        likes: 5,
        userId: "test@ubc.ca",
        recipeName: "Creamy Salmon Pasta",
        recipeImage: "https://spoonacular.com/recipeImages/73420-312x231.jpg",
        recipeSummary: "Lorem Ipsum for first recipe"
    },
    {
        recipeId: "564321",
        likes: 2,
        userId: "test2@ubc.ca",
        recipeName: "Sticky Baked Chicken",
        recipeImage: "https://spoonacular.com/recipeImages/73420-312x231.jpg",
        recipeSummary: "Lorem Ipsum for second recipe"
    }        
]


// Interface GET /reviews
describe("Get all recipes", () => {
    // Input: None
    // Expected status code: 200
    // Expected behavior: Recipes are fetched and sent to frontend
    // Expected output: Empty list of all recipes
    test("No recipes", async () => {
        let expectedResponse = [];
        jest.spyOn(dbFunctions, "dbGetAllReviews").mockReturnValue([]);
        const res = await request(app).get("/reviews");
        expect(res.status).toStrictEqual(200);
        expect(res.body).toEqual(expectedResponse);
    });
    
    // Input: None
    // Expected status code: 200
    // Expected behavior: Recipes are fetched and sent to frontend
    // Expected output: List of all recipes by all users
    test("Small number of recipes", async () => {
        let expectedResponse = [];
        mockedDbGetAllRecipesResponse.forEach(recipe => {
            let review = {
              id: recipe.recipeId,
              rating: recipe.likes,
              author: recipe.userId,
              title: recipe.recipeName,
              image: recipe.recipeImage,
              review: recipe.recipeSummary
            }
            expectedResponse.push(review);
          })
        jest.spyOn(dbFunctions, "dbGetAllReviews").mockReturnValue(mockedDbGetAllRecipesResponse);
        const res = await request(app).get("/reviews");
        expect(res.status).toStrictEqual(200);
        expect(res.body).toEqual(expectedResponse);
    });

    // Input: None
    // Expected status code: 200
    // Expected behavior: Recipes are fetched and sent to frontend
    // Expected output: List of all recipes by all users
    test("Max number of recipes", async () => {
        const maxRecipes = 30;
        let mockedDbGetAllRecipesResponseFull = [];
        let expectedResponse = [];
        let review = {
            id: mockedDbGetAllRecipesResponse[0].recipeId,
            rating: mockedDbGetAllRecipesResponse[0].likes,
            author: mockedDbGetAllRecipesResponse[0].userId,
            title: mockedDbGetAllRecipesResponse[0].recipeName,
            image: mockedDbGetAllRecipesResponse[0].recipeImage,
            review: mockedDbGetAllRecipesResponse[0].recipeSummary
        }
        for (let i = 0; i < maxRecipes; i++) {
            mockedDbGetAllRecipesResponseFull.push(mockedDbGetAllRecipesResponse[0]);
            expectedResponse.push(review);
        }
        jest.spyOn(dbFunctions, "dbGetAllReviews").mockReturnValue(mockedDbGetAllRecipesResponseFull);
        const res = await request(app).get("/reviews");
        expect(res.status).toStrictEqual(200);
        expect(res.body).toEqual(expectedResponse);
    });
})


const mockedDbFindRecordResponse = {
    recipeId: "564321",
    likes: 1,
    userId: "test2@ubc.ca",
    recipeName: "Chicken Curry",
    recipeImage: "https://spoonacular.com/recipeImages/73420-312x231.jpg",
    recipeSummary: "A hearty curry from chicken. Perfect for a winter night"
} 

// Interface POST /reviews/like
describe("Liking a recipe", () => {
    // Input: Missing author email
    // Expected status code: 400
    // Expected behavior: Missing email detected and error returned
    // Expected output: "Body parameters must not be empty"
    test("Missing email", async () => {
        let expectedResponse = "Body parameters must not be empty";
        const res = await request(app).post("/reviews/like").send({
            email: "",
            id: mockedDbFindRecordResponse.recipeId
        });
        expect(res.status).toStrictEqual(400);
        expect(res.text).toEqual(expectedResponse);
        expect(res.body).toEqual({});
    });

    // Input: Missing recipe id
    // Expected status code: 400
    // Expected behavior: Missing recipe id detected and error returned
    // Expected output: "Body parameters must not be empty"
    test("Missing recipe ID", async () => {
        let expectedResponse = "Body parameters must not be empty";
        const res = await request(app).post("/reviews/like").send({
            email: mockedDbFindRecordResponse.userId,
            id: ""
        });
        expect(res.status).toStrictEqual(400);
        expect(res.text).toEqual(expectedResponse);
        expect(res.body).toEqual({});
    });

    // Input: combination of email and recipeId does not exist in db
    // Expected status code: 400
    // Expected behavior: No recipe is fetched and error is returned
    // Expected output: "Specified review does not exist"
    test("Non-Existent recipe", async () => {
        let expectedResponse = "Specified review does not exist";
        jest.spyOn(dbFunctions, "dbFindRecord").mockReturnValue(null);
        const res = await request(app).post("/reviews/like").send({
            email: mockedDbFindRecordResponse.userId,
            id: "00000"
        });
        expect(res.status).toStrictEqual(400);
        expect(res.body).toEqual({});
        expect(res.text).toEqual(expectedResponse);
    });

    // Input: combination of email and recipeId exist in db
    // Expected status code: 200
    // Expected behavior: Recipe is fetched and like count incremented
    // Expected output: Liked recipe
    test("Existing recipe", async () => {
        let expectedResponse = mockedDbFindRecordResponse;
        expectedResponse.likes++;
        jest.spyOn(dbFunctions, "dbFindRecord").mockReturnValue(mockedDbFindRecordResponse);
        jest.spyOn(dbFunctions, "dbSaveRecord").mockReturnValue(null);
        const res = await request(app).post("/reviews/like").send({
            email: mockedDbFindRecordResponse.userId,
            id: mockedDbFindRecordResponse.recipeId
        });
        expect(res.status).toStrictEqual(200);
        expect(res.body).toEqual(expectedResponse);
    });
})

// Interface POST /reviews/custom
describe("Posting a custom review/recipe", () => {
    // Input: Missing author email
    // Expected status code: 400
    // Expected behavior: Missing email detected and error returned
    // Expected output: "Body parameters must not be empty"
    test("Missing email", async () => {
        let expectedResponse = "Body parameters must not be empty";
        const res = await request(app).post("/reviews/custom").send({
            recipeName: mockedDbFindRecordResponse.recipeName,
            userId: "",
            recipeSummary: mockedDbFindRecordResponse.recipeSummary
        });
        expect(res.status).toStrictEqual(400);
        expect(res.text).toEqual(expectedResponse);
        expect(res.body).toEqual({});
    });

    // Input: Missing recipe name
    // Expected status code: 400
    // Expected behavior: Missing recipe name detected and error returned
    // Expected output: "Body parameters must not be empty"
    test("Missing recipe name", async () => {
        let expectedResponse = "Body parameters must not be empty";
        const res = await request(app).post("/reviews/custom").send({
            recipeName: "",
            userId: mockedDbFindRecordResponse.userId,
            recipeSummary: mockedDbFindRecordResponse.recipeSummary
        });
        expect(res.status).toStrictEqual(400);
        expect(res.text).toEqual(expectedResponse);
        expect(res.body).toEqual({});
    });

    // Input: Missing recipe summary
    // Expected status code: 400
    // Expected behavior: Missing recipe summary detected and error returned
    // Expected output: "Body parameters must not be empty"
    test("Missing recipe summary", async () => {
        let expectedResponse = "Body parameters must not be empty";
        const res = await request(app).post("/reviews/custom").send({
            recipeName: mockedDbFindRecordResponse.recipeName,
            userId: mockedDbFindRecordResponse.userId,
            recipeSummary: ""
        });
        expect(res.status).toStrictEqual(400);
        expect(res.text).toEqual(expectedResponse);
        expect(res.body).toEqual({});
    });

    // Input: Valid user email, recipe name and summary
    // Expected status code: 200
    // Expected behavior: New recipe is created, saved and returned
    // Expected output: The newly saved recipe/review
    test("Valid input", async () => {
        jest.spyOn(dbFunctions, "dbSaveRecord").mockReturnValue(null);
        const res = await request(app).post("/reviews/custom").send({
            recipeName: mockedDbFindRecordResponse.recipeName,
            userId: mockedDbFindRecordResponse.userId,
            recipeSummary: mockedDbFindRecordResponse.recipeSummary,
        });
        expect(res.status).toStrictEqual(200);
        expect(res.body.recipeId).toBeDefined();
        expect(res.body.userId).toEqual(mockedDbFindRecordResponse.userId);
        expect(res.body.recipeName).toEqual(mockedDbFindRecordResponse.recipeName);
        expect(res.body.recipeSummary).toEqual(mockedDbFindRecordResponse.recipeSummary);
        expect(res.body.recipeImage).toEqual("https://visitors-centre.jrc.ec.europa.eu/sites/default/files/thumbnail/kmffq_additional-illo4video_2019_5_fishplate%5B1%5D.jpg");
        expect(res.body.likes).toEqual(0);
        expect(res.body.numTimes).toEqual(1);
    });
})