defmodule Towerops.Accounts.VerifyTotpOnlyTest do
  use Towerops.DataCase, async: true

  import Towerops.AccountsFixtures

  alias Towerops.Accounts

  describe "verify_totp_only/2" do
    setup do
      user = user_fixture()

      # Create TOTP device
      {:ok, device, _secret} =
        Accounts.create_totp_device(user.id, "Test Device")

      %{user: user, device: device}
    end

    test "accepts valid TOTP codes", %{user: user, device: device} do
      code = NimbleTOTP.verification_code(device.totp_secret)

      assert {:ok, returned_user} = Accounts.verify_totp_only(user, code)
      assert returned_user.id == user.id
    end

    test "rejects invalid TOTP codes", %{user: user} do
      assert {:error, :invalid_code} = Accounts.verify_totp_only(user, "000000")
    end

    test "rejects recovery codes", %{user: user} do
      # Recovery codes are longer than 6 digits
      recovery_code = "ABCD-EFGH-IJKL"

      assert {:error, :recovery_code_not_allowed} =
               Accounts.verify_totp_only(user, recovery_code)
    end

    test "rejects codes longer than 6 digits", %{user: user} do
      assert {:error, :recovery_code_not_allowed} =
               Accounts.verify_totp_only(user, "1234567890")
    end

    test "rejects codes with whitespace", %{user: user} do
      assert {:error, :recovery_code_not_allowed} =
               Accounts.verify_totp_only(user, "  123456  ")
    end

    test "rejects codes with hyphens", %{user: user} do
      assert {:error, :recovery_code_not_allowed} =
               Accounts.verify_totp_only(user, "123-456")
    end
  end
end
