Issue Tracker Project - Fails FCC delete request test but works for me

Tell us what’s happening:
I’m not really sure why I pass all tests but the last DELETE REQUEST test. It works for me, but FCC says it fails. I’m confused…

You can send a DELETE request to /api/issues/{projectname} with an _id to delete an issue. If no _id is sent, the return value is { error: 'missing _id' }. On success, the return value is { result: 'successfully deleted', '_id': _id }. On failure, the return value is { error: 'could not delete', '_id': _id }

Here’s some of my code and link to my project:

My Issue Tracker project link

api.js file

'use strict';
const mongoose = require('mongoose');
const IssueModel = require("../models").Issue;
const ProjectModel = require("../models").Project;
const ObjectId = mongoose.Types.ObjectId;

module.exports = function (app) {

  app.route("/api/issues/:project")

    .get(function (req, res) {
      let projectName = req.params.project;
      const {
        _id,
        open,
        issue_title,
        issue_text,
        created_by,
        assigned_to,
        status_text,
      } = req.query;

      ProjectModel.aggregate([
        { $match: { name: projectName } },
        { $unwind: "$issues"},
        _id != undefined
          ? { $match: { "issues._id": ObjectId(_id) } }
          : { $match: {} },
        open != undefined
          ? { $match: { "issues.open": open } }
          : { $match: {} },
        issue_title != undefined
          ? { $match: { "issues.issue_title": issue_title } }
          : { $match: {} },
        issue_text != undefined
          ? { $match: { "issues.issue_text": issue_text } }
          : { $match: {} },
        created_by != undefined
          ? { $match: { "issues.created_by": created_by } }
          : { $match: {} },
        assigned_to != undefined
          ? { $match: { "issues.assigned_to": assigned_to } }
          : { $match: {} },
        status_text != undefined
          ? { $match: { "issues.status_text": status_text } }
          : { $match: {} },
        ]).exec((err, data) => {
          if (!data) {
            res.json([]);
        } else {
          let mappedData = data.map((item) => item.issues);
          res.json(mappedData);
        }
      });
    })

    .post(function (req, res) {
      let project = req.params.project;
      const {
        issue_title,
        issue_text,
        created_by,
        assigned_to,
        status_text,
      } = req.body;
      if (!issue_title || !issue_text || !created_by) {
        res.json({ error: "required field(s) missing"});
        return;
      }
      const newIssue = new IssueModel({
        issue_title: issue_title || "",
        issue_text: issue_text || "",
        created_on: new Date(),
        updated_on: new Date(),
        created_by: created_by || "",
        assigned_to: assigned_to || "",
        open: true,
        status_text: status_text || ""
      })

      ProjectModel.findOne({ name: project }, (err, projectdata) => {
        if (!projectdata) {
          const newProject = new ProjectModel({ name: project });
          newProject.issues.push(newIssue);
          newProject.save((err, data) => {
            if (err || !data) {
              res.send("There was an error saving in post");
            } else {
              res.json(newIssue);
            }
          })
        } else {
          projectdata.issues.push(newIssue);
          projectdata.save((err, data) => {
            if (err || !data) {
              res.send("There was an error saving in post");
            } else {
              res.json(newIssue);
            }
          })
        }
      })
    })

    .put(function (req, res) {
      let project = req.params.project;
      const {
        _id,
        issue_title,
        issue_text,
        created_by,
        assigned_to,
        status_text,
        open,
      } = req.body;
      if (!_id) {
        res.json({ error: "missing _id" });
        return;
      }
      if (
        !issue_title &&
        !issue_text &&
        !created_by &&
        !assigned_to &&
        !status_text &&
        !open
      ) {
        res.json({ error: "no update field(s) sent", _id: _id });
        return;
      }
      ProjectModel.findOne({ name: project }, (err, projectdata) => {
        if (err || !projectdata) {
          res.json({ error: "could not update", _id: _id });
        } else {
          const issueData = projectdata.issues.id(_id);
          if (!issueData) {
            res.json({ error: "could not update", _id: _id });
            return;
          }
          issueData.issue_title = issue_title || issueData.issue_title;
          issueData.issue_text = issue_text || issueData.issue_text;
          issueData.created_by = created_by || issueData.created_by;
          issueData.assigned_to = assigned_to || issueData.assigned_to;
          issueData.status_text = issue_title || issueData.status_text;
          issueData.updated_on = new Date();
          issueData.open = open;
          projectdata.save((err, data) => {
            if (err || !data) {
              res.json({ error: "could not update", _id: _id });
            } else {
              res.json({ result: "successfully updated", _id: _id });
            }
          })
        }
      })
    })

    .delete(function (req, res) {
      let project = req.params.project;
      const { _id } = req.body;
      if (!_id) {
        res.json({ error: "missing_id" });
        return;
      }
      ProjectModel.findOne({ name: project }, (err, projectdata) => {
        if (!projectdata || err) {
          res.send({ error: "could not delete", _id: _id });
        } else {
          const issueData = projectdata.issues.id(_id);
          if (!issueData) {
            res.send({ error: "could not delete", _id: _id });
            return;
          }
          issueData.remove();

          projectdata.save((err, data) => {
            if (err || !data) {
              res.json({ error: "could not delete", _id: issueData._id });
            } else {
              res.json({ result: "successfully deleted", _id: issueData._id });
            }
          });
        }
      });
    });
};

2_functional-tests.js file

const chaiHttp = require('chai-http');
const chai = require('chai');
const assert = chai.assert;
const server = require('../server');

chai.use(chaiHttp);

let deleteID;
suite("Functional Tests", function() {
  suite("Routing Tests", fuction() {
    suite("3 Post request Tests", function() {
      test("Create an issue with every field: POST request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .post("/api/issues/projects")
        set("content-type", "application/json")
        .send({
          issue_title: "Issue",
          issue_text: "Functional Test",
          created_by: "jjmason",
          assigned_to: "jjmason",
          status_text: "Not done",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          deleteID = res.body._id;
          assert.equal(res.body.issue_title, "Issue");
          assert.equal(res.body.assigned_to, "jjmason");
          assert.equal(res.body.status_text, "Not done");
          assert.equal(res.body.issue_text, "Functional Test");
          done();
        });
      });
      test("Create an issue with only required fields: POST request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .post("/api/issues/projects")
        .set("content-type", "application/json")
        .send({
          issue_title: "Issue",
          issue_text: "Functional Test",
          created_by: "jjmason",
          assigned_to: "",
          status_text: "",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.issue_title, "Issue");
          assert.equal(res.body.created_by, "jjmason");
          assert.equal(res.body.issue_text, "Functional Test");
          assert.equal(res.body.assigned_to, "");
          assert.equal(res.body.status_text, "");
          done();
        });
      });
      test("Create an issue with missing required fields: POST request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .post("/api/issues/projects")
        .set("content-type", "application/json")
        .send({
          issue_title: "Issue",
          issue_text: "Functional Test",
          created_by: "jjmason",
          assigned_to: "",
          status_text: "",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.error, "required field(s) missing");
          done();
        });
      });
    });
    ///////////////// GET REQUESTS TESTS ////////////////

    suite("3 Get request Tests", function () {
      test("View issues on a project: GET request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .get("/api/issues/projects")
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.length, 4);
          done();
        });
      });
      test("View issues on a project with one filter: GET request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .get("/api/issues/projects")
        .query({
          _id: "60206683aeb79335a895a377",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body[0], {
            issue_title: "Testing",
            issue_text: "Testing 1, 2, 3",
            created_on: "2021-02-07T22:15:31.596+00:00",
            updated_on: "2021-02-07T22:15:31.596+00:00",
            created_by: "jjmason",
            assigned_to: "jjmason",
            open: true,
            status_text: "Open",
          });
          done();
        });
      });
      test("View issues on a project with multiple filters: GET request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .get("/api/issues/projects")
        .query({
          issue_title: "Testing",
          issue_text: "aksfdk",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.deepEqual(res.body[0], {
            _id: "60206725aeb79335a895a37a",
            issue_title: "Testing",
            issue_text: "aksfdk",
            created_on: "2021-02-07T22:18:13.682+00:00",
            updated_on: "2021-02-07T22:18:13.682+00:00",
            created_by: "jjmason",
            assigned_to: "jjmason",
            open: true,
            status_text: "Open",
          });
          done();
        });
      });
    });

    ///////////////////// PUT REQUEST TESTS //////////////////////

    suite("5 Put request Tests", function () {
      test("Update one field on an issue: PUT request to /api/issues/{project}", function (done) {
        chai
          .request(server)
          .put("/api/issues/projects")
          .send({
            _id: "60206803aeb79335a895a37c",
            issue_title: "changed title",
          })
          .end(function (err, res) {
            assert.equal(res.status, 200);
            assert.equal(res.body.result, "successfully updated");
            assert.equal(res.body._id, "60206803aeb79335a895a37c");
            done();
          });
      });
      test("Update multiple fields on an issue: PUT request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .put("/api/issues/projects")
        .send({
          _id: "60206803aeb79335a895a37c",
          issue_title: "Random",
          issue_text: "Random text",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.result, "successfully updated");
          assert.equal(res.body._id, "60206803aeb79335a895a37c");
          done();
        });
      });
      test("Update an issue with missing _id: PUT request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .put("/api/issues/projects")
        .send({
          _id: "60206803aeb79335a895a37c",
          issue_title: "Update",
          issue_text: "update",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.error, "missing _id");
          done();
        };
      });
      test("Update an issue with no fields to update: PUT request to /api/issues/{project}", function (done) {
        chai
        request(server)
        .put("/api/issues/projects")
        .send({
          _id: "60206803aeb79335a895a37c",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.error, "no update field(s) sent");
          done();
        });
      });
      test("Update an issue with an invalid _id: PUT request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .put("/api/issues/projects")
        .send({
          _id: "60206803aeb79335a895a37c",
          issue_title: "Update",
          issue_text: "update",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.error, "could not update");
          done();
        });
      });
    });

    ///////////////// DELETE REQUEST TESTS ///////////////////

    suite("3 DELETE request Tests", function () {
      test("Delete an issue: DELETE request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .delete("/api/issues/projects")
        .send({
          _id: deleteID
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.result, "successfully deleted");
          done();
        });
      });
      test("Delete an issue with an invalid _id: DELETE request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .delete("/api/issues/projects")
        .send({
          _id: "60206843aeb79335a895a37einvalid",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.error, "could not delete");
          done();
        });
      });
      test("Delete an issue with missing _id: DELETE request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .delete("/api/issues/projects")
        .send({})
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.error, "missing _id");
          done();
        });
      });
    });
  });
});

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36.

Challenge: Issue Tracker

Link to the challenge:

Hello there,

When I submit your project, and look in the browser console, I see this error:

Error: expected { error: 'missing_id' } to deeply equal { error: 'missing _id' }

Now, here is the relevant section:

.delete(function (req, res) {
      let project = req.params.project;
      const { _id } = req.body;
      if (!_id) {
        res.json({ error: "missing_id" });
        return;
      }

Also, I notice the functional tests are not passing, because of:

suite("Functional Tests", function() {
  suite("Routing Tests", fuction() {
    suite("3 Post request Tests", function() {
// Line 183
test("Update an issue with missing _id: PUT request to /api/issues/{project}", function (done) {
        chai
        .request(server)
        .put("/api/issues/projects")
        .send({
          _id: "60206803aeb79335a895a37c",
          issue_title: "Update",
          issue_text: "update",
        })
        .end(function (err, res) {
          assert.equal(res.status, 200);
          assert.equal(res.body.error, "missing _id");
          done();
        };
      });
//Line 16
.post("/api/issues/projects")
        set("content-type", "application/json")
        .send({

The syntax highlighting is the hint…

Also, why are you sending objects like this:

if (!projectdata || err) {
          res.send({ error: "could not delete", _id: _id });
        } else {
          const issueData = projectdata.issues.id(_id);
          if (!issueData) {
            res.send({ error: "could not delete", _id: _id });
            return;
          }

Hope this helps

2 Likes

@Sky020
Thank you so much! Yeah I found quite a few typos that I fixed (forgot a space between “missing _ id” in a couple places and misspelled function, lol how embarrassing). I can now pass the delete test. However, I’m still not passing all 14 functional tests for some reason. I keep getting one console log error saying Error: expected { status: 'unavailable' } to be an array at eval. Not sure why I’m getting this error but I’m assuming it has something to do with why all 14 of my functional tests aren’t passing. I don’t see anything obvious that’s wrong, but I guess I’ll keep trying so I can finally pass. However, you addressed the initial tests that failed spot on! Thanks again!

2 Likes