defmodule GitGud.Storage.DiskTest do
use ExUnit.Case, async: false
alias GitGud.Storage.Disk
setup do
# Each test gets a fresh subdirectory under the configured root so
# they don't trip over each other; tear it down after.
base =
Application.get_env(:git_gud, GitGud.Storage.Disk, [])
|> Keyword.fetch!(:root)
dir = Path.join(base, "disk-test-#{System.unique_integer([:positive])}")
File.mkdir_p!(dir)
Application.put_env(:git_gud, GitGud.Storage.Disk, root: dir)
on_exit(fn ->
_ = File.rm_rf(dir)
Application.put_env(:git_gud, GitGud.Storage.Disk, root: base)
end)
:ok
end
test "put/get/delete roundtrip" do
assert :ok = Disk.put("bucket-a", "objs/abc", "hello world", [])
assert {:ok, "hello world"} = Disk.get("bucket-a", "objs/abc")
assert :ok = Disk.delete("bucket-a", "objs/abc")
assert {:error, :not_found} = Disk.get("bucket-a", "objs/abc")
end
test "delete is idempotent on missing keys" do
assert :ok = Disk.delete("bucket-a", "never/existed")
end
test "sanitizes path components against traversal" do
assert :ok = Disk.put("bucket-a", "../../etc/passwd", "evil", [])
# The traversal segments are stripped, so the actual on-disk file
# lives at <root>/bucket-a/etc/passwd. Confirm it's contained.
root = Application.get_env(:git_gud, GitGud.Storage.Disk)[:root]
path = Disk.object_path("bucket-a", "../../etc/passwd")
assert String.starts_with?(path, root)
end
test "presign_url + verify_token round-trips with matching method" do
{:ok, url} = Disk.presign_url("b1", "k1", :get, expires_in: 60)
%URI{query: query} = URI.parse(url)
token = URI.decode_query(query)["token"]
assert {:ok, %{bucket: "b1", key: "k1"}} = Disk.verify_token(token, :get)
assert {:error, :wrong_method} = Disk.verify_token(token, :put)
end
test "verify_token fails on a fabricated token" do
assert {:error, _} = Disk.verify_token("not-a-real-token", :get)
end
end
2.0 KiB · text
5af55d9