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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
require 'minitest/autorun'
require_relative '../../lib/simple_cookie_jar'
class TestSimpleCookieJar < Minitest::Test
def setup
@jar = SimpleCookieJar.new(max_domains: 100)
end
def test_basic_cookie_storage
@jar.add_cookies("session=abc123", "https://example.com")
assert_equal "session=abc123", @jar.cookies_for_request("https://example.com")
end
def test_multiple_cookies_single_header
@jar.add_cookies("session=abc123; user=john", "https://example.com")
assert_equal "session=abc123; user=john", @jar.cookies_for_request("https://example.com")
end
def test_multiple_set_cookie_headers
# Simulate multiple Set-Cookie headers joined with newlines
@jar.add_cookies("session=abc123\nuser=john\ntheme=dark", "https://example.com")
assert_equal "session=abc123; user=john; theme=dark", @jar.cookies_for_request("https://example.com")
end
def test_domain_isolation
@jar.add_cookies("session=abc", "https://site1.com")
@jar.add_cookies("session=xyz", "https://site2.com")
assert_equal "session=abc", @jar.cookies_for_request("https://site1.com")
assert_equal "session=xyz", @jar.cookies_for_request("https://site2.com")
end
def test_domain_case_insensitive
@jar.add_cookies("session=abc", "https://EXAMPLE.COM")
assert_equal "session=abc", @jar.cookies_for_request("https://example.com")
assert_equal "session=abc", @jar.cookies_for_request("https://Example.Com")
end
def test_subdomain_isolation
@jar.add_cookies("session=main", "https://example.com")
@jar.add_cookies("session=sub", "https://sub.example.com")
assert_equal "session=main", @jar.cookies_for_request("https://example.com")
assert_equal "session=sub", @jar.cookies_for_request("https://sub.example.com")
end
def test_cookie_overwrite_same_domain
@jar.add_cookies("session=old", "https://example.com")
@jar.add_cookies("session=new", "https://example.com")
assert_equal "session=new", @jar.cookies_for_request("https://example.com")
end
def test_cleanup_behavior
# Fill beyond limit
150.times { |i| @jar.add_cookies("test=#{i}", "https://site#{i}.com") }
# Should have cleaned up to 50 domains (half of max_domains)
assert_equal 50, @jar.stats[:domains]
end
def test_stats_tracking
@jar.add_cookies("test=1", "https://site1.com")
@jar.add_cookies("test=2", "https://site2.com")
stats = @jar.stats
assert_equal 2, stats[:domains]
assert_equal 100, stats[:max_domains]
assert_equal 2, stats[:requests_processed]
assert stats[:memory_estimate_kb] > 0
end
def test_invalid_url_handling
@jar.add_cookies("test=value", "not-a-url")
assert_nil @jar.cookies_for_request("not-a-url")
# Should not crash on malformed URLs
@jar.add_cookies("test=value", "http://[invalid")
assert_nil @jar.cookies_for_request("http://[invalid")
end
def test_nil_and_empty_input_handling
@jar.add_cookies(nil, "https://example.com")
@jar.add_cookies("", "https://example.com")
@jar.add_cookies("test=value", nil)
@jar.add_cookies("test=value", "")
# Should not crash and should not store anything
assert_nil @jar.cookies_for_request("https://example.com")
end
def test_malformed_cookie_header_handling
# Test various malformed cookie headers
@jar.add_cookies("no-equals-sign", "https://example.com")
@jar.add_cookies("=empty-name", "https://example.com")
@jar.add_cookies("valid=cookie; no-equals; another=valid", "https://example.com")
# Should extract only valid cookies
result = @jar.cookies_for_request("https://example.com")
assert result.include?("valid=cookie")
assert result.include?("another=valid")
refute result.include?("no-equals-sign")
refute result.include?("=empty-name")
end
def test_cookie_attributes_ignored
# Cookies often have attributes like Path, Domain, Secure, HttpOnly
@jar.add_cookies("session=abc123; Path=/; Domain=.example.com; Secure; HttpOnly", "https://example.com")
# Should only store the name=value part
assert_equal "session=abc123", @jar.cookies_for_request("https://example.com")
end
def test_thread_safety
threads = 10.times.map do |i|
Thread.new do
100.times { |j| @jar.add_cookies("test=#{i}-#{j}", "https://thread#{i}-#{j}.com") }
end
end
threads.each(&:join)
# Should not crash and should have reasonable domain count
assert @jar.stats[:domains] <= 100
assert @jar.stats[:requests_processed] == 1000
end
def test_concurrent_read_write
# Test concurrent reads and writes
write_thread = Thread.new do
1000.times { |i| @jar.add_cookies("test=#{i}", "https://write#{i}.com") }
end
read_thread = Thread.new do
1000.times { |i| @jar.cookies_for_request("https://read#{i}.com") }
end
write_thread.join
read_thread.join
# Should not crash
assert @jar.stats[:domains] <= 100
end
def test_emergency_cleanup
# Create a jar with very small limit to test emergency cleanup
small_jar = SimpleCookieJar.new(max_domains: 10)
# Manually force the jar into an over-limit state to test emergency cleanup
# Add 16 domains directly to trigger emergency cleanup (16 > 10 * 1.5 = 15)
16.times { |i| small_jar.instance_variable_get(:@cookies)["site#{i}.com"] = "test=#{i}" }
# Now add one more cookie, which should trigger emergency cleanup
small_jar.add_cookies("test=final", "https://final.com")
# Should have been reset to 0 due to emergency cleanup (clears everything including new cookie)
assert_equal 0, small_jar.stats[:domains]
end
def test_url_with_path_and_query
@jar.add_cookies("session=abc", "https://example.com/path/to/page?query=value")
# Should work with different paths on same domain
assert_equal "session=abc", @jar.cookies_for_request("https://example.com/different/path")
assert_equal "session=abc", @jar.cookies_for_request("https://example.com")
end
def test_http_vs_https
@jar.add_cookies("session=http", "http://example.com")
@jar.add_cookies("session=https", "https://example.com")
# Should treat HTTP and HTTPS as same domain
assert_equal "session=https", @jar.cookies_for_request("http://example.com")
assert_equal "session=https", @jar.cookies_for_request("https://example.com")
end
def test_port_handling
@jar.add_cookies("session=8080", "https://example.com:8080")
@jar.add_cookies("session=443", "https://example.com:443")
# Should treat different ports as same domain
assert_equal "session=443", @jar.cookies_for_request("https://example.com")
assert_equal "session=443", @jar.cookies_for_request("https://example.com:8080")
end
end
|