SWE 430 Exercise 1 --- Password Checker

Exercise 1 Instructions

Use test-driven development (TDD) along with qUnit, the xUnit testing framework, to implement the password checker code module (defined below) for a DoD information system. Ensure you write the unit test before writing the code to pass the unit test (write test => check if test fails => write production code => run all unit tests => refactor => run tests => go to next test case).

Turn in both the source code (code.coffee) and the unit tests (test.coffee) on blackboard Exercise 1 Submission. If you have any questions, run into problems, or need clarification, please let me know. Your production code will be evaluated by running it against a set of reference test cases (written according to the specification). Your unit test cases will be evaluate by using them to test a faulty implementation.

Password Checker Specification

The check function in the password module determines if a proposed password is valid or not. Function signature: String X list of Strings => boolean X String

Precondition: All previous passwords are assumed to be valid (you don't have to test that the previous passwords are valid, only test the proposed password.) Example usage:

proposed_password = 'P@55W*rd'
previous_passwords = ['aaAA11!!', 'bbBB22@@']
[result, reason] = password.check(proposed_password, previous_passwords)

The result variable would evaluate to true and the reason would be ""; the empty string.

proposed_password = 'aaaaaaaaaaaaaaaBB22##'
previous_passwords = ['aaAA11!!', 'bbBB22@@']
[result, reason] = password.check(proposed_password, previous_passwords)

In this case, the result variable would evaluate to false and the reason would be "too long". Even though the password fails 2 rules, "too long" and "4+ char substring", only the reason for the first failure (according to the order listed below) is reported.

The only global variable your code should export is an object (which will serve as a module) named password which contains a function named check. This is accomplished in the same way we export the target object which contains both the Target and the Grid classes in Example 1.

window.password = {}
password.check = (proposed_password, previous_passwords) ->
    # body of function goes here
    # ...

In order to be declared "valid," all accepted passwords must adhere to the following criteria:

  1. A password must be at least 8 (too short) and no more than 20 characters long (too long).
  2. A password is comprised of only ASCII printable characters. No whitespcae---tabs, space, etc., control characters, or unicode is allowed (not printable ASCII).
  3. Each password must contain:
  4. A password cannot be similar to any of the user's previous six passwords. "Similar to" is defined as having any of the following:

The appropriate "reason string" for each rule is shown in parentheses and in green. The check() function only returns one reason for a password failure. If a password fails multiple rules, only the reason for the first rule failed, according to the order listed above, is returned by the function. Be sure to use the exact reason strings listed above---they are case sensitive.

Lyall Jonathan Di Trapani 13 Feb 2013