'Jest and Nodejs: get authorization token from a function

I'm writing test cases using Jest for my Node Js express application. For my application, I have to test the execution of each functionality using different roles (3 roles - Admin, Supervisor and Emp). So what I have planned is to write three functions that returns the token after authenticating such as getAdminToken, getSupervisorToken and getEmpToken. But my test case always fail when I try to get the token from a function call. But works when I use the same method in It test function.

The following is the method i have written that I expect a valid token to be returned for Admin Role but this doesn't work

async function getAdminToken() {
    console.log("getAdminToken: Start");
    loginToken = "";
    const response = await 
                        myApp.
                        post('/account/login/').
                        send({
                            "email":AdminTestAccount.GetInstance().Email,
                            "password":AdminTestAccount.GetInstance().Password
                        });

    loginToken = response.body.Data.token;

    console.log("getAdminToken: End");
    return loginToken;
}

The following is the It function

it("test supervisor creation by admin", async (done) => {

        //login as Admin role
        if (loginToken == "") {
            console.log("Before getting token");
            loginToken = await getAdminToken();
            console.log("After getting token: " + loginToken);
        }

        response = await 
                            myApp.                            
                            post('/supervisor').
                            send({
                                "name":supervisor[0]
                            }).
                            set('Authorization', AdminTestAccount.GetBearerToken(loginToken));

        expect(response.status).toBe(200);
        expect(response.body.IsSuccessful).toBe(true);//**<--Test fails here**
        expect(response.body.SuccessMessage).toBe("Supervisor created.");
        expect(response.body.ReasonForFailure).toBe("");
        expect(response.body.AdditionalInfo).toBe("");
        expect(response.body.Data).toBe(supervisor[0]);
        
        done();        
    });

But the above code does not work. Rather if I have the token function as part of It test function, all works as expected. The following is the code that works.

it("test team creation by admin", async (done) => {

        var response = await 
                            myApp.
                            post('/account/login/').
                            send({
                                "email":AdminTestAccount.GetInstance().Email,
                                "password":AdminTestAccount.GetInstance().Password
                            });

        expect(response.status).toBe(200);
        expect(response.body.IsSuccessful).toBe(true);
        expect(response.body.Data._id).not.toBe("");
        expect(response.body.Data.email).toBe(AdminTestAccount.GetInstance().Email);
        expect(response.body.Data.roleId).toBe(AdminTestAccount.GetInstance().RoleId.toString());
        expect(response.body.Data.token).not.toBeUndefined();
        expect(response.body.Data.token).not.toBeNull();
        expect(response.body.Data.token).not.toBe("");

        loginToken = response.body.Data.token;

        response = await 
                            myApp.                            
                            post('/team').
                            send({
                                "name":supervisor[0]
                            }).
                            set('Authorization', AdminTestAccount.GetBearerToken(loginToken));

        expect(response.status).toBe(200);
        expect(response.body.IsSuccessful).toBe(true);
        expect(response.body.SuccessMessage).toBe("supervisor created.");
        expect(response.body.ReasonForFailure).toBe("");
        expect(response.body.AdditionalInfo).toBe("");
        expect(response.body.Data).toBe(supervisor[0]);
        
        done();        
    });

Can you please assist what I'm missing in the code that returns the Token by function call?

Thanks, Hemant.



Solution 1:[1]

since supertest expect cookies inside an array, you have to return the cookie inside the array.

 return [loginToken]

Solution 2:[2]

This did the job for me:

 const res2 = await request
        .get(`/api/v1/post/${postId}`)
        .set('Cookie', [`token=${loginToken}`]);

First i login with a request.post etc and then to get the cookie token and call .set() with 'Cookie' and token in an array like @Yilmaz described. Makes it a little more obvious. This helped too: JEST with Cookie token.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yilmaz
Solution 2 mangrove108