#include <doctest/doctest.h>
#include "torlinkc/util/net.hpp"
using namespace torlinkc;
TEST_CASE("parseRetryAfter reads delay-seconds as milliseconds") {
auto ms = parseRetryAfter("120");
REQUIRE(ms.has_value());
CHECK(*ms == 120'000);
}
TEST_CASE("parseRetryAfter returns nullopt for an empty value") { CHECK_FALSE(parseRetryAfter("").has_value()); }
TEST_CASE("parseRetryAfter parses an HTTP-date relative to now") {
// Far enough in the future that the test can't flake on execution time.
auto ms = parseRetryAfter("Wed, 01 Jan 2099 00:00:00 GMT");
REQUIRE(ms.has_value());
CHECK(*ms > 0);
}
TEST_CASE("parseRetryAfter returns nullopt for garbage") { CHECK_FALSE(parseRetryAfter("not-a-date").has_value()); }
TEST_CASE("backoffDelay never exceeds the cap") {
for (int attempt = 0; attempt < 10; ++attempt) {
auto ms = backoffDelay(attempt, 500, 20000);
CHECK(ms >= 0);
CHECK(ms <= 20000);
}
}
TEST_CASE("backoffDelay honors an explicit Retry-After floor") {
auto ms = backoffDelay(0, 500, 20000, 15000);
CHECK(ms >= 15000);
}
TEST_CASE("backoffDelay grows with the attempt number (upper bound doubles each time)") {
// The jittered value is randomized, but the *ceiling* (baseMs * 2^attempt,
// capped) must grow monotonically until it saturates at capMs.
CHECK(500 * (1 << 0) < 500 * (1 << 1));
CHECK(500 * (1 << 1) < 500 * (1 << 2));
}