/ test / basic.test.ts
basic.test.ts
  1  import { CaptchaJs } from "../src";
  2  
  3  describe("constructor tests", () => {
  4    test('can construct', () => {
  5      const o = new CaptchaJs({ client: "demo", secret: "secret" });
  6      expect(o).toBeDefined();
  7    });
  8  
  9    test("bad client throws", () => {
 10      // Ignore as we're deliberately missing a parameter.
 11      // @ts-ignore
 12      expect(() => new CaptchaJs({ secret: "secret" })).toThrow('No client ID provided');
 13    });
 14  
 15    test("bad secret throws", () => {
 16      // Ignore as we're deliberately missing a parameter.
 17      // @ts-ignore
 18      expect(() => new CaptchaJs({ client: "demo" })).toThrow('No secret provided');
 19    });
 20  
 21    test("bad alphabet throws", () => {
 22      expect(() => new CaptchaJs({ client: "demo", secret: "secret", alphabet: "" }))
 23        .toThrow("Can't use an empty alphabet");
 24    })
 25  
 26    test("bad numberOfLetters throws", () => {
 27      expect(() => new CaptchaJs({ client: "demo", secret: "secret", numberOfLetters: 0 }))
 28        .toThrow("Need at least one letter");
 29    })
 30  });
 31  
 32  describe("image tests", () => {
 33    test("URL is returned", () => {
 34      const o = new CaptchaJs({ client: "demo", secret: "secret" });
 35      const rs = o.getRandomString();
 36      const url = o.getImageUrl({ randomString: rs });
 37      expect(url).toMatch(/https:\/\/image\.captchas\.net\/\?client=demo&random=\w\w\w\w\w\w/);
 38    });
 39  
 40    test("URL reflects client change", () => {
 41      const o = new CaptchaJs({ client: "newclient", secret: "secret" });
 42      const rs = o.getRandomString();
 43      const url = o.getImageUrl({ randomString: rs });
 44      expect(url).toMatch(/client=newclient/);
 45    });
 46  
 47    test("URL reflects base URL change", () => {
 48      const o = new CaptchaJs({ client: "demo", secret: "secret" });
 49      const rs = o.getRandomString()
 50      const url = o.getImageUrl({ randomString: rs, baseURL: "newbaseurl.something.net" });
 51      expect(url).toMatch(/newbaseurl\.something\.net/);
 52    });
 53  
 54    test("URL reflects alphabet change", () => {
 55      const o = new CaptchaJs({ client: "demo", secret: "secret", alphabet: "abcdef" });
 56      const rs = o.getRandomString();
 57      const url = o.getImageUrl({ randomString: rs });
 58      expect(url).toMatch(/alphabet=abcdef/);
 59    });
 60  
 61  
 62    test("URL reflects number of letters change", () => {
 63      const o = new CaptchaJs({ client: "demo", secret: "secret", numberOfLetters: 5 });
 64      const rs = o.getRandomString();
 65      const url = o.getImageUrl({ randomString: rs });
 66      expect(url).toMatch(/letters=5/);
 67    });
 68  
 69    test("URL reflects width change", () => {
 70      const o = new CaptchaJs({ client: "demo", secret: "secret", width: 480 });
 71      const rs = o.getRandomString();
 72      const url = o.getImageUrl({ randomString: rs });
 73      expect(url).toMatch(/width=480/);
 74    });
 75  
 76    test("URL reflects height change", () => {
 77      const o = new CaptchaJs({ client: "demo", secret: "secret", height: 240 });
 78      const rs = o.getRandomString();
 79      const url = o.getImageUrl({ randomString: rs });
 80      expect(url).toMatch(/height=240/);
 81    });
 82  
 83    test("specifying the random string gives the same URL", () => {
 84      const o = new CaptchaJs({ client: "demo", secret: "secret", height: 240 });
 85      const url1 = o.getImageUrl({ randomString: "RandomZufall" });
 86      const url2 = o.getImageUrl({ randomString: "RandomZufall" });
 87      expect(url1).toEqual(url2);
 88    })
 89  });
 90  
 91  describe("audio tests", () => {
 92    test("URL is returned", () => {
 93      const o = new CaptchaJs({ client: "demo", secret: "secret" });
 94      const rs = o.getRandomString()
 95      const url = o.getAudioUrl({ randomString: rs });
 96      expect(url).toMatch(/https:\/\/audio\.captchas\.net\/\?client=demo&random=\w\w\w\w\w\w/);
 97    });
 98  
 99    test("URL reflects base URL change", () => {
100      const o = new CaptchaJs({ client: "demo", secret: "secret" });
101      const rs = o.getRandomString()
102      const url = o.getAudioUrl({ randomString: rs, baseURL: "newbaseurl.something.net" });
103      expect(url).toMatch(/newbaseurl\.something\.net/);
104    });
105  
106    test("URL reflects alphabet change", () => {
107      const o = new CaptchaJs({ client: "demo", secret: "secret", alphabet: "abcdef" });
108      const rs = o.getRandomString()
109      const url = o.getAudioUrl({ randomString: rs });
110      expect(url).toMatch(/alphabet=abcdef/);
111    });
112  
113    test("URL reflects number of letters change", () => {
114      const o = new CaptchaJs({ client: "demo", secret: "secret", numberOfLetters: 5 });
115      const rs = o.getRandomString()
116      const url = o.getAudioUrl({ randomString: rs });
117      expect(url).toMatch(/letters=5/);
118    });
119  
120    test("specifying the random string gives the same URL", () => {
121      const o = new CaptchaJs({ client: "demo", secret: "secret", height: 240 });
122      const url1 = o.getAudioUrl({ randomString: "RandomZufall" });
123      const url2 = o.getAudioUrl({ randomString: "RandomZufall" });
124      expect(url1).toEqual(url2);
125    })
126  });
127  
128  describe("getRandomString", () => {
129    let o: CaptchaJs;
130  
131    beforeEach(() => {
132      o = new CaptchaJs({ client: "demo", secret: "secret" });
133    });
134  
135    test("two calls to random() get different values", () => {
136      const val1 = o.getRandomString();
137      const val2 = o.getRandomString();
138  
139      expect(val1).not.toEqual(val2);
140    });
141  });
142  
143  describe("makePassword", () => {
144    test("returns a password of the right length", () => {
145      let o = new CaptchaJs({ client: "demo", secret: "secret" });
146      expect(o.makePassword("I am a random string")).toHaveLength(6);
147  
148      o = new CaptchaJs({ client: "demo", secret: "secret", numberOfLetters: 3 });
149      expect(o.makePassword("I am a random string")).toHaveLength(3);
150  
151      o = new CaptchaJs({ client: "demo", secret: "secret", numberOfLetters: 8 });
152      expect(o.makePassword("I am a random string")).toHaveLength(8);
153    })
154  
155    test("throws if not given a random string", () => {
156      const o = new CaptchaJs({ client: "demo", secret: "secret" });
157      expect(() => o.makePassword(undefined)).toThrow('No random string supplied');
158    })
159  
160    test("returns the same password with the same random string", () => {
161      const o = new CaptchaJs({ client: "demo", secret: "secret" });
162      const password1 = o.makePassword("I am a random string");
163      const password2 = o.makePassword("I am a random string");
164      expect(password1).toEqual(password2);
165    })
166  })
167  
168  describe("random string validation", () => {
169    let o;
170  
171    beforeEach(() => {
172      o = new CaptchaJs({ client: "demo", secret: "secret" });
173    });
174  
175    test("reject a random string we didn't generate", () => {
176      expect(o.validateRandomString("I am a test string")).toBeFalsy();
177    })
178  
179    test("accept a random string we did generate", () => {
180      const randomString = o.getRandomString();
181      expect(o.validateRandomString(randomString)).toBeTruthy();
182    })
183  
184    test("can only use a random string once", () => {
185      const randomString = o.getRandomString();
186      expect(o.validateRandomString(randomString)).toBeTruthy();
187      expect(o.validateRandomString(randomString)).toBeFalsy();
188    })
189  });
190  
191  describe("password checks", () => {
192    test("valid password with matching random string passes", () => {
193      const o = new CaptchaJs({ client: "demo", secret: "secret" });
194      const rs = o.getRandomString();
195      const password = o.makePassword(rs);
196      expect(o.verifyPassword(rs, password)).toBeTruthy();
197    })
198  
199    test("password that's too long gets rejected", () => {
200      const o = new CaptchaJs({ client: "demo", secret: "secret" });
201      const rs = o.getRandomString();
202      expect(o.verifyPassword(rs, "too long")).toBeFalsy();
203    })
204  
205    test("valid password with different random string fails", () => {
206      const o = new CaptchaJs({ client: "demo", secret: "secret" });
207      const rs = o.getRandomString();
208      const otherRs = o.getRandomString();
209      const password = o.makePassword(rs);
210      expect(o.verifyPassword(otherRs, password)).toBeFalsy();
211    })
212  
213    test("invalid password with valid random string is rejected", () => {
214      const o = new CaptchaJs({ client: "demo", secret: "secret" });
215      const rs = o.getRandomString();
216      expect(o.verifyPassword(rs, "abcdef")).toBeFalsy();
217    })
218  
219    test("empty password with valid random string is rejected", () => {
220      const o = new CaptchaJs({ client: "demo", secret: "secret" });
221      const rs = o.getRandomString();
222      expect(o.verifyPassword(rs, undefined)).toBeFalsy();
223    })
224  
225    test("valid password with empty random string is rejected", () => {
226      const o = new CaptchaJs({ client: "demo", secret: "secret" });
227      const rs = o.getRandomString();
228      expect(o.verifyPassword(undefined, "abcdef")).toBeFalsy();
229    })
230  
231    test("empty password with empty random string is rejected", () => {
232      const o = new CaptchaJs({ client: "demo", secret: "secret" });
233      const rs = o.getRandomString();
234      expect(o.verifyPassword(undefined, undefined)).toBeFalsy();
235    })
236  })