2

I am in a programming bootcamp and we are currently learning about fullstack JavaScript. We are using the Express framework and I have opted to use a SQLite3 database. This is a basic app for maintaining books at a local community center. I am required to write up to 3 unit tests and the one that I am having difficulty with is the GET / route. This route is intended to pull data from the database and render them to create a list of books currently in the database when you visit the root route.

I want to test whether the bookList variable containing the awaited Book.findAll() Sequelize function is actually sending an array of objects containing row data to the Pug template engine to render the list of books.

When I host locally, this is working as intended. I am just puzzled on how to have that reflected in my unit tests. I've attached the routes/index.js, views/index.pug & the test/readOp_test.js containing all of my tests including the one for the GET / route. Please let me know if I need to share more of the code and will reply with what is needed for anyone willing to help me.


readOp_test.js

let chai = require('chai');
let chaiHTTP = require('chai-http');
let chaiPromised = require('chai-as-promised');
let application = require('../app');
let expect = require('chai').expect;
chai.use(chaiHTTP);
chai.use(chaiPromised);
chai.should();

// Unit Test Suite
describe('Unit Tests for Endpoints to meet Code Louisville Project Requirements', () => {
    //Test Spec for READ ALL operation


    
    /* it('should pull data from all rows in the database', (done) => {
        chai.request(application)
            .get('/')
            .end((err, res) => {
                res.body.should.be.a('object');
                done();
            })
    }); */

    //Test Spec for READ-by-id operation
    it('should pull data from the below id', (done) => {
        const id = 2;
        chai.request(application)
            .get(`/${id}`)
            .end((err, res) => {
                res.body.should.be.a('object');
                done();
            })
    });
    it('should return status 404 when READING the below id which is not in the database', (done) => {
        const id = 12;
        chai.request(application)
            .get(`/${id}`)
            .end((err, res) => {
                res.should.have.status(404);
                done();
            })
    });
    //Test Spec for CREATE operation
    it('shouldnt POST the below book entry since the title value is an empty string.', async() => {
        let res = await chai
        .request(application)
        .post('/')
        .type('form')
        .send({title: '', author: "al-Gibber", genre: "Math", language: "Arabic"})

        expect(res.status).to.equal(500)
    });
    it('should POST the below book entry since all properties contain actual string values.', async() => {
        let res = await chai
        .request(application)
        .post('/')
        .type('form')
        .send({title: 'Gibberish', author: "al-Gibber", genre: "Math", language: "Arabic"})

        expect(res.status).to.equal(200)
    });
});

routes/index.js

// Requiring Express to enable access to the framework's methods, properties, & other tools.
const express = require('express');
// Router handles HTTP requests.
const router = express.Router();
// These two variables are ensuring `routes/index.js` has access to the database & its models.
const db = require('../db');
const { Book } = db.models;



//This is a convenient function that handles async/await.
function asyncHandler(cb){
    return async(req, res, next) => {
        try {
        await cb(req, res, next)
        } catch(error){
        // Forward error to the global error handler
        next(error);
        }
    }
}



//This route handles the initial load of the app, the root route, & will draw data from each row in the database & display it on the homepage.
//This route is a READ operation distinctly a READ ALL operation.
router.get('/', asyncHandler(async (req, res) => {
    const bookList = await Book.findAll();
    //The use of .render() method ensures that the `index.pug` template is rendered when user visits the root directory.
    //{ bookList } is an object containing data from each row in the database to be used in the Pug template.
    res.render('index', {bookList});
}));



//This route handles adding a book to the app's database by rendering the newBook.pug template which contains a form to collect the column data for the database.
//This route is the beginning of the CREATE operation for this app.
router.get('/new', (req, res) => {
    res.render('newBook', { book: {}});
});

//This route handles the data collected by newBook.pug's form. It creates the database entry and posts the data.
//This route is the closure for the CREATE operation for this app.
router.post('/', asyncHandler(async (req, res) => {
    console.log(req.body);
    let book;
    try {
        book = await Book.create(req.body);
        console.log(book);
        res.redirect('/');
    } catch (error) {
        throw error;
    }
}));



//This route handles rendering found data for each book that would be clicked on in the index.pug template.
//This route is another distinct READ operation that is reading an entry's data based on the primary key ID selected on index.pug.
router.get("/:id", asyncHandler(async (req, res) => {
    const book = await Book.findByPk(req.params.id);
    if(book) {
      res.render("bookViewing", { book });  
    } else {
      res.sendStatus(404);
    }
  })); 



//Ensures that all routes written in this folder can be used in the root's `app.js` file.
module.exports = router;

index.pug

doctype html
html(lang="en")
  head
    title Library
    link(rel='stylesheet', href='/static/stylesheets/style.css')
  body
    div#app
      div#container
        h1 Library
        h2 Our Book Selection
        
        each book in bookList
          book
            p
              span= book.title
              | 
              a(href=`/${book.id}`) Learn More

        p This library is open to all in our local community!
        a(href="/new") Add New Book

Screenshot of the correctly rendered index.pug template

Screenshot of rendered PUG template

0 Answers0