code_challenge.test.ts (3144B)
1 import { CodeChallenge } from "#core/domain/code_challenge.ts"; 2 import { assertEquals } from "$std/assert/assert_equals.ts"; 3 import { MINUTE } from "$std/datetime/constants.ts"; 4 import { afterAll, beforeEach, describe, it } from "$std/testing/bdd.ts"; 5 import { FakeTime } from "$std/testing/time.ts"; 6 import { assertInstanceOf } from "$std/assert/assert_instance_of.ts"; 7 import { Code } from "#core/domain/code.ts"; 8 import { nonceCode } from "#core/domain/crypto.ts"; 9 import { assertThrows } from "$std/assert/assert_throws.ts"; 10 import { InvalidCodeChallenge } from "#core/domain/code_challenge.ts"; 11 import { ExceedingLimit } from "#core/domain/limiter.ts"; 12 13 describe("unit code_challenge test", () => { 14 let clock: FakeTime; 15 let challenge: CodeChallenge; 16 17 beforeEach(() => { 18 clock = new FakeTime(); 19 challenge = new CodeChallenge(15 * MINUTE, 2, 3); 20 }); 21 22 afterAll(() => { 23 clock.restore(); 24 }); 25 26 it("shoud be unverified by default", () => { 27 assertEquals(challenge.verified, false); 28 }); 29 30 it("should be requestable", () => { 31 const act = challenge.requestChallenge(); 32 assertInstanceOf(act, Code); 33 }); 34 35 it("random code shouldn't be valid attempt", () => { 36 const act = () => challenge.attemptChallenge(nonceCode()); 37 assertThrows(act, InvalidCodeChallenge); 38 assertEquals(challenge.verified, false); 39 }); 40 41 it("code should be null", () => { 42 assertEquals(challenge.code, null); 43 }); 44 45 it("requested code should be valid attempt", () => { 46 const code = challenge.requestChallenge(); 47 challenge.attemptChallenge(code); 48 assertEquals(challenge.verified, true); 49 }); 50 51 it("random code shouldn't be valid even if code requested", () => { 52 challenge.requestChallenge(); 53 const act = () => challenge.attemptChallenge(nonceCode()); 54 assertThrows(act, InvalidCodeChallenge); 55 assertEquals(challenge.verified, false); 56 }); 57 58 describe("request", () => { 59 beforeEach(() => { 60 challenge.requestChallenge(); 61 }); 62 63 it("should be request 2 times", () => { 64 const code = challenge.requestChallenge(); 65 assertInstanceOf(code, Code); 66 }); 67 68 it("2nd code should be valid attempt", () => { 69 const code = challenge.requestChallenge(); 70 challenge.attemptChallenge(code); 71 assertEquals(challenge.verified, true); 72 }); 73 74 it("3rd code should be requestable", () => { 75 challenge.requestChallenge(); 76 const act = () => challenge.requestChallenge(); 77 assertThrows(act, ExceedingLimit); 78 }); 79 80 it("3rd code should be requestable after delay expiration", () => { 81 challenge.requestChallenge(); 82 clock.tick(15 * MINUTE); 83 const code = challenge.requestChallenge(); 84 assertInstanceOf(code, Code); 85 }); 86 }); 87 88 describe("attempt", () => { 89 let code: Code; 90 beforeEach(() => { 91 code = challenge.requestChallenge(); 92 }); 93 94 it("should be verify after 1 mistake", () => { 95 const act = () => challenge.attemptChallenge(nonceCode()); 96 assertThrows(act, InvalidCodeChallenge); 97 challenge.attemptChallenge(code); 98 assertEquals(challenge.verified, true); 99 }); 100 }); 101 });