import { describe, expect, test } from "bun:test"

import { PASSWORD_MIN, checkNewPassword } from "@/lib/password"

/**
 * The two rules the settings screen applies before it asks the server anything,
 * and that `changeOwnPassword` applies again where the answer counts. They are
 * tested once because they are one function called from both sides.
 *
 * No literal six anywhere below. A test that hard-codes the number would pass
 * for the wrong reason the day somebody changes it.
 */

describe("how long a new password has to be", () => {
  test("one character short is short", () => {
    const password = "x".repeat(PASSWORD_MIN - 1)
    expect(checkNewPassword(password, password)).toBe("too_short")
  })

  test("exactly the minimum is enough", () => {
    const password = "x".repeat(PASSWORD_MIN)
    expect(checkNewPassword(password, password)).toBeNull()
  })

  test("an empty pair is short rather than matching", () => {
    expect(checkNewPassword("", "")).toBe("too_short")
  })
})

describe("typing it twice", () => {
  test("two long enough and different is a mismatch", () => {
    expect(checkNewPassword("elephant", "elephants")).toBe("mismatch")
  })

  /**
   * Somebody who types a four-character password into both boxes has made one
   * mistake, not two. Being told the two do not match would send them to fix
   * the field that is already right.
   */
  test("too short is said before not matching", () => {
    const short = "x".repeat(PASSWORD_MIN - 1)
    expect(checkNewPassword(short, `${short}y`)).toBe("too_short")
  })

  test("a difference in case is a difference", () => {
    expect(checkNewPassword("Elephant", "elephant")).toBe("mismatch")
  })

  test("a trailing space is a difference, and is not trimmed away", () => {
    expect(checkNewPassword("elephant", "elephant ")).toBe("mismatch")
  })
})
