docs(updater): correct PaperMC UA/fixture overclaims, re-tier the boundary

An out-of-band curl of the live Fill v3 endpoint contradicted two claims the
previous commit shipped and surfaced a mis-tiering:

- User-Agent is NOT enforced: fill.papermc.io/v3/projects/velocity returned
  HTTP 200 to a bare curl UA. The comments claimed a generic UA "is refused"
  and the API "REQUIRES" a contact UA. Reword to what is true — PaperMC's usage
  policy asks for a descriptive UA and may block generic ones, but sending it is
  etiquette/defensive here, not a gate Felis depends on.
- The test fixture's shape was invented, not captured: the real "versions"
  object groups the entire 3.x line under a single key "3.0.0", not the
  per-minor keys the fixture used. Replace it with the real body (keys and
  version strings as returned). The key-agnostic parser already produced the
  right answer, and an independent max-stable check confirms 3.4.0.
- Re-tier doc.go: the GitHub Releases source is verifiable-here (the same
  httptest-testable shape as PaperMC), not integration remainder. It is why
  3 of 4 components report "latest unknown" today and is the next verifiable
  slice — the release-source work is only ~half done until it exists.

No production logic changed. WSL oracle: build + vet clean, internal/updater
10/10, full tree go test RC=0 (19 ok, 0 fail).
This commit is contained in:
flyemoji committed 2026-07-05 00:28:36 +09:00
1 parent 96b3cc901c
commit 9896fe16c3
3 files changed
+62 -35

No files matched your search

+29 -15
View File
@@ -8,22 +8,32 @@ import (
"testing"
)
// velocityV3Fixture is the PaperMC Fill v3 GET /v3/projects/velocity body — its shape
// and version strings captured verbatim from the live API on 2026-07-04. Grounding
// the fixture in the real response is what makes this a contract test rather than a
// self-referential one: the newest overall version is a -SNAPSHOT (3.5.0-SNAPSHOT)
// while the newest stable release is 3.4.0, so the stable filter is exercised against
// real-world data, not an invented shape. (The v2 API this replaces now returns 410.)
// velocityV3Fixture is the PaperMC Fill v3 GET /v3/projects/velocity response body,
// captured from the live API on 2026-07-04 (keys and version strings exactly as
// returned; JSON whitespace normalized). Grounding the fixture in the real response is
// what makes this a contract test rather than a self-referential one:
// - the newest overall version is a -SNAPSHOT (3.5.0-SNAPSHOT) while the newest
// stable release is 3.4.0, so the stable filter runs against real data; and
// - the "versions" object groups the ENTIRE 3.x line under a single key "3.0.0"
// (not per-minor keys), so a parser that trusted the group key to bound the
// versions inside it would be wrong — proof the key-agnostic flatten is required.
// (The v2 API this replaces now returns HTTP 410.)
const velocityV3Fixture = `{
"project": {"id": "velocity", "name": "Velocity"},
"versions": {
"3.5": ["3.5.0-SNAPSHOT"],
"3.4": ["3.4.0", "3.4.0-SNAPSHOT"],
"3.3": ["3.3.0-SNAPSHOT"],
"3.2": ["3.2.0-SNAPSHOT"],
"3.1": ["3.1.2-SNAPSHOT", "3.1.1", "3.1.1-SNAPSHOT", "3.1.0"],
"1.1": ["1.1.9"],
"1.0": ["1.0.10"]
"3.0.0": [
"3.5.0-SNAPSHOT",
"3.4.0",
"3.4.0-SNAPSHOT",
"3.3.0-SNAPSHOT",
"3.2.0-SNAPSHOT",
"3.1.2-SNAPSHOT",
"3.1.1",
"3.1.1-SNAPSHOT",
"3.1.0"
],
"1.1.0": ["1.1.9"],
"1.0.0": ["1.0.10"]
}
}`
@@ -61,8 +71,12 @@ func TestPaperMCLatestStableFiltersSnapshots(t *testing.T) {
}
}
// TestPaperMCSendsNonGenericUserAgent proves Felis transmits the contact-carrying,
// non-generic User-Agent the Fill v3 API requires (a generic UA is refused upstream).
// TestPaperMCSendsNonGenericUserAgent proves Felis transmits a descriptive,
// contact-carrying User-Agent rather than a generic library default. PaperMC's API
// usage policy asks for this and reserves the right to block anonymous/generic agents;
// upstream enforcement was not active on the project endpoint as of 2026-07-04 (a bare
// UA got HTTP 200), so this verifies OUR compliance with the policy, not an upstream
// gate we depend on.
func TestPaperMCSendsNonGenericUserAgent(t *testing.T) {
var gotUA string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {