jest testing mongoose unique field creates duplicates

Viewed 457

Trying to test a nodejs backend using jest.
this test is passing 70% of the time but sometimes fails.

my test:
both userInput and copycatUserInput are saved to the database and create a duplicate email.

test("Register with the same email twice shoud throw an error.", async () => {
    const userInput: ICreateUserInput = {
        email: "same-email@gmail.com",
        username: "username",
        password: "tesT$1234",
    };

    const copycatUserInput: ICreateUserInput = {
        email: "same-email@gmail.com",
        username: "differentUsername",
        password: "tesT$1234",
    };

>    await registerUser(userInput);
>    await expect(registerUser(copycatUserInput)).rejects.toThrow(/(Email address is already exists)/);
});

the fail reason:

expect(received).rejects.toThrow()

Received promise resolved instead of rejected
Resolved to value: {"token": "eyJhb...

here is my mongoose schema:
both username and email fields are unique

const schemaOptions: SchemaOptions = { timestamps: true };

const userSchema = new Schema(
    {
        username: {
            type: String,
            required: true,
            unique: true,
        },

        email: {
            type: String,
            required: true,
            unique: true,
            lowercase: true,
        },

        password: {
            type: String,
            required: true,
        },

        status: String,
    },
    schemaOptions,
);

export default model<IUser>("User", userSchema);

and registerUser function:

export default async (registerInput: ICreateUserInput): Promise<ILoginUserResult> => {
    /**
     * validate props.
     */
    if (!isEmail(registerInput.email)) throw new Error("Email address is not valid.");
    if (!isValidUsername(registerInput.username)) throw new Error("Username is not valid.");
    if (!isStrongPassword(registerInput.password)) throw new Error("Password is not valid.");

    /**
     * gnerate hashed password.
     */
    try {
        const hashPassword = await createHashedPassword(registerInput.password);

        /**
         * create new user.
         */
        const doc: ICreateUserInput = {
            email: registerInput.email,
            username: registerInput.username,
            password: hashPassword,
            status: registerInput.status ? registerInput.status : "",
        };

        /**
         * save the user in the database.
         */
        const user = await new User(doc).save();

        return {
            user,
            token: getAuthToken(user),
        };
    } catch (error) {
        /**
         * throws a duplicate email error.
         */
        if (error.message && `${error.message}`.includes("email_1 dup key:")) {
            throw new Error("Email address is already exists");
        }

        /**
         * throws a duplicate username error.
         */
        if (error.message && `${error.message}`.includes("username_1 dup key:")) {
            throw new Error("Username is already exists");
        }

        /**
         * may be that mongoose or bcrypt are throwing..
         */
        Logger.error(`auth.registerUser => ${error}`);
        throw new Error(`Error: Failed to register user: ${error.message}`);
    }

i also got useCreateIndex: true in the connection options
and tried to wait for the indexes to be created:

user.once("index", () => {
    user = await new User(doc).save();
});

Thank you for your help

EDIT:
ended up running tests separately, make a new connection on each testsuit (beforeAll) can knock things out :(

"scripts": {
    "test": "jest --runInBand",
},
0 Answers
Related