We'll learn how to Unit Test AdonisJS Model logic using Japa. We'll test a password reset token's validity to show instance-level tests. Then, we'll test its generate and verify methods to show static methods.
Models can have logic within them; sometimes this is a simple getter, and other times it's more complex methods. So, let's take a moment to cover how we can create unit tests to ensure this logic does what we expect.
Within our PasswordResetToken we have a getter, isValid. This is a rather straightforward getter that you might not otherwise have a test for, but for educational purposes, let's test it anyway.
First, let's ensure a future-dated expiry is considered valid. Remember, our factory uses a future-dated expiry by default.
test.group("Models password reset token", () => { test("isValid should be truthy when expiresAt is in the future", async ({ assert, }) => { const token = await PasswordResetTokenFactory.makeStubbed(); assert.isTrue(token.isValid); });});
Copied!
Simple enough, next let's ensure an expiry in the past is considered invalid. For this, we make use of our invalid state in our factory.
test.group("Models password reset token", () => { // ... test("isValid should be falsy when expiresAt is in the past", async ({ assert, }) => { const token = await PasswordResetTokenFactory.apply( "invalid" ).makeStubbed(); assert.isFalse(token.isValid); });});
Copied!
Okay, let's kick it up a notch with our generate method. This returns a random string that's 32 chars long and an encrypted version of that string. So, let's assert both of those.
test("generate should create a value and an encrypted version of that value", ({ assert,}) => { const { value, encryptedValue } = PasswordResetToken.generate(); assert.lengthOf(value, 32); assert.equal(value, encryption.decrypt(encryptedValue));});
Copied!
Great, next we go a step further with our verify method. For this, we'll need a valid token with an associated user.
test("verify should return as valid with a valid token", async ({ assert }) => { // create a token with a user const token = await PasswordResetTokenFactory.with("user").create(); // encrypt the generated token const encryptedValue = encryption.encrypt(token.value); // run our verify method const result = await PasswordResetToken.verify(encryptedValue); assert.isTrue(result.isValid); assert.strictEqual(token.user.id, result.user?.id); assert.strictEqual(token.value, result.token?.value);});
Copied!
Lastly, we need our sad path testing an invalid token.
test("verify should return as invalid with an invalid token", async ({ assert,}) => { const token = await PasswordResetTokenFactory.with("user") .apply("invalid") .create(); const encryptedValue = encryption.encrypt(token.value); const result = await PasswordResetToken.verify(encryptedValue); assert.isFalse(result.isValid); assert.strictEqual(token.user.id, result.user?.id); assert.strictEqual(token.value, result.token?.value);});