defmodule BearCli.CredentialsTest do use ExUnit.Case, async: true alias BearCli.Credentials test "save/load round-trips JSON" do path = tmp_path() on_exit(fn -> File.rm(path) end) assert :ok == Credentials.save( %{"issuer" => "x", "access_token" => "tok", "email" => "a@b.c"}, path ) assert {:ok, %{"access_token" => "tok", "email" => "a@b.c"}} = Credentials.load(path) end test "save creates the file with 0600 permissions" do path = tmp_path() on_exit(fn -> File.rm(path) end) :ok = Credentials.save(%{"access_token" => "tok"}, path) mode = File.stat!(path).mode assert Bitwise.band(mode, 0o777) == 0o600 end test "save creates the parent directory" do base = Path.join(System.tmp_dir!(), "bear_cli_nested_#{System.unique_integer([:positive])}") path = Path.join([base, "sub", "credentials.json"]) on_exit(fn -> File.rm_rf(base) end) :ok = Credentials.save(%{"a" => "b"}, path) assert File.regular?(path) end test "load returns :error for a missing file" do assert :error == Credentials.load("/nonexistent/credentials.json") end test "load returns :error for corrupt JSON" do path = tmp_path() on_exit(fn -> File.rm(path) end) File.write!(path, "{not json") assert :error == Credentials.load(path) end test "delete removes the file and is idempotent" do path = tmp_path() on_exit(fn -> File.rm(path) end) :ok = Credentials.save(%{"a" => "b"}, path) assert :ok == Credentials.delete(path) assert :error == Credentials.load(path) assert :ok == Credentials.delete(path) end defp tmp_path do Path.join(System.tmp_dir!(), "bear_cli_creds_#{System.unique_integer([:positive])}.json") end end