blob: 94fec7e5f1110c710adb9914d6a7c98213667da8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
-- Unit checks for the two avatar email filters, run under a standalone Lua
-- by t0504-email-avatar.sh with the script path as the first argument. The
-- two scripts differ only in the service they point at, so the expected host
-- is picked from the script's name. The second argument chooses how the
-- openssl.digest dependency is met, stub swaps in the deterministic fake
-- from the harness, and real uses an installed luaossl and adds the one
-- check only a genuine MD5 can pass.

local test_directory = arg[0]:match("^(.*)/") or "."
local h = dofile(test_directory .. "/harness.lua")

local script = arg[1]
local mode = arg[2] or "stub"

local base_url = "https://www.gravatar.com/avatar/"
local alt_text = "Gravatar"
if script:find("libravatar", 1, true) then
	base_url = "https://seccdn.libravatar.org/avatar/"
	alt_text = "Libravatar"
end

if mode == "stub" then
	h.stub_digest()
end

h.load(script)

local function render(email, name)
	return h.run({ email, "commit" }, { name })
end

local function hash_of(output)
	local prefix = base_url:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")
	return output:match("src='" .. prefix .. "(%x+)%?")
end

local out, ret = render("<author@example.com>", "A U Thor")
h.contains("an icon is drawn for an address", out, "<img src='" .. base_url)
h.contains("the size lands in the query", out, "?s=13&amp;d=retro'")
h.contains("the alt text names the service", out, "alt='" .. alt_text .. "'")
h.contains("width matches the size", out, "width='13'")
h.contains("height matches the size", out, "height='13'")
h.contains("the fetch is deferred", out, "loading='lazy' decoding='async'")
h.contains("the name follows the icon", out, "> A U Thor")
h.equals("close answers zero", ret, 0)
h.check("the hash is hex", hash_of(out) ~= nil)

-- The service hashes the trimmed lowercase address, so every spelling of one
-- address has to reach it as the same hash.
local plain = hash_of(render("author@example.com", "x"))
local wrapped = hash_of(render("<author@example.com>", "x"))
local shouting = hash_of(render("  <AUTHOR@Example.COM>  ", "x"))
h.check("angle brackets do not change the hash", plain == wrapped)
h.check("case and padding do not change the hash", plain == shouting)

local other = hash_of(render("other@example.com", "x"))
h.check("a different address hashes differently", plain ~= other)

out = render(nil, "A U Thor")
h.equals("no address draws no icon", out, "A U Thor")

out = render("", "A U Thor")
h.equals("an empty address draws no icon", out, "A U Thor")

out = render("<>", "A U Thor")
h.equals("empty angle brackets draw no icon", out, "A U Thor")

out = h.run({ "<author@example.com>", "commit" }, { "A U ", "Thor" })
h.contains("the name is buffered across writes", out, "> A U Thor")

if mode == "real" then
	out = render("test@example.com", "x")
	h.equals("a known address hashes to its published md5", hash_of(out), "55502f40dc8b7c769880b10874abc9d0")
end

h.finish()