0

I'm working on a small todos app with nodejs and mongodb.

I have the model definition here:

const Todo = new Schema({
    text: {
        type: String,
        require: true,
        minlength: 5,
        trim: true
    },
    completed: {
        type: Boolean
    },
    createdAt: {
        type: {type: Date, default: Date.now}
    }
});

As you can see, the text property is required and it should throw an error if it's missing when it reads the request.

Over here, I'm send the data to my endpoint:

app.post('/todos', (req, res) => {
    let todo = new Todo({
        text: req.body.text,
        completed: req.body.completed
    });

    todo.save()
        .then((document) => {
            res.send(document);
        }, (error) => {
            res.status(400).send(error);
        })
});

And finally, this is my test for the specific scenario where the user sends a empty set of data to the server:

it('Should not create todo document with invalid body data', (done) => {
        request(app)
            .post('/todos')
            .send({})
            .expect(400)
            .end((error, res) => {
                if(error){
                    return done(error);
                }
                Todo.find()
                    .then((todos) => {
                        expect(todos.length).toBe(0);
                        done();
                    }).catch((error) => done(error));
            });
    });

After running the test, for some reason it throws the following:

1) POST /todos
     Should not create todo document with invalid body data:
     Error: expected 400 "Bad Request", got 200 "OK"
      at Test._assertStatus (node_modules\supertest\lib\test.js:266:12)
      at Test._assertFunction (node_modules\supertest\lib\test.js:281:11)
      at Test.assert (node_modules\supertest\lib\test.js:171:18)
      at Server.assert (node_modules\supertest\lib\test.js:131:12)
      at emitCloseNT (net.js:1689:8)
      at process._tickCallback (internal/process/next_tick.js:152:19)

I've been trying to debug this for the past hour and I can't find what's wrong with it. Can anyone give me a hand?

UPDATE

Other test:

it('Should create a new todo', (done) => {
        let text = 'This is a string';

        request(app)
            .post('/todos')
            .send({text})
            .expect(200)
            .expect((res) => {
                let testString = res.body.text;
                expect(testString).toBe(text);
                expect(typeof testString).toBe('string');
                expect(testString.length).not.toBe(0);
            })
            .end((error, res) => {
                if(error) {
                    return done(error);
                }
                Todo.find()
                    .then((todos) => {
                        expect(todos.length).toBe(1);
                        expect(todos[0].text).toBe(text);
                        done();
                    }).catch((error) => done(error));
            });
    });
CodeTrooper
  • 1,890
  • 6
  • 32
  • 54

1 Answers1

2

You should check if text and completed exist before using them:

app.post('/todos', (req, res) => {
    let text = req.body.text;
    let completed = req.body.completed;
    if(!completed) { completed = false; }
    if(!text) {
        res.status(400).send("Request parameters missing");
    } else {
        let todo = new Todo({
            text: req.body.text,
            completed: req.body.completed
        });

        todo.save()
            .then((document) => {
                res.send(document);
            }, (error) => {
                res.status(400).send(error);
            })
    }
});

Also in your Schema it should be "required" instead of "require"

Giannis Mp
  • 1,291
  • 6
  • 13
  • which is the other test? – Giannis Mp Feb 25 '18 at 22:01
  • Updated my question with the other test. – CodeTrooper Feb 25 '18 at 22:03
  • This is a matter of the logic you want to use. I will update my code as an example. – Giannis Mp Feb 25 '18 at 22:04
  • Can you elaborate please? I'm learning and I wish to understand why it wasn't working. – CodeTrooper Feb 25 '18 at 22:06
  • Sure. For start, you want to access the parameters text and completed so you have to check if they exist so you do not pass undefined to your ToDo. What I mean by logic is if for example you require or not the parameter completed to be sent. I assumed that it's not necessary so I set it to false if it is not sent. The reason your test failed before is because in my previous code I assumed that it should sent 400 if the parameter completed is missing and in the test it is missing. – Giannis Mp Feb 25 '18 at 22:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165793/discussion-between-codeninja-and-giannis-mp). – CodeTrooper Feb 25 '18 at 22:11
  • Solved! That `required` was the problem – CodeTrooper Feb 25 '18 at 22:38