Closes#38, #39 and #40; adds the client side of #41.
- Every request goes to /api/v1. MusicServerClient gets a token with
Settings.api_password the first time one is needed, reuses it, and on a
401 gets a new one and sends the request once more. Switching server gets
a new token too. Callers never see the token.
- Sync is started with POST, as MusicServer 5.0 requires.
- The client has every endpoint in the server's OpenAPI spec, including
statistics, soundtracks and songs by UUID, version, downloads and tokens.
- tools/generate_api_types.gd generates a typed class per schema in
server/openapi.json into server/generated/. Song info, statistics and
versions are passed to callers as these classes. A list the server sends
as null is an empty list.
- FakeHttpTransport hands out tokens and answers 401 without one, so every
test goes through the token flow. New tests cover the token handling,
every endpoint and each generated class.
At startup and after resetting the playlist, loading the song list and
preloading the first song started at the same time. When the list
answered last, it cleared the playlist and dropped the preloaded song.
Preloading now starts once the list has loaded, and loading the list is
retried if it fails.
Covers a cache size above 1: songs are preloaded until the setting is
reached, playing a song tops the cache up again, and the cache keeps
filling after a failed download once the server answers again.
The previous tests never compiled: they used GUT's assert functions,
Godot 3 APIs and reassigned autoload functions, so no test ran.
- 90 tests: unit tests for the playlist, songs, player scoring, time
formatting, search and the server client, plus integration tests
that run MainWindow and SyncWindow against a fake server
- Keybind tests check that Alt+<number> and Ctrl+Alt+<number> keep
following the player rows while players are added and removed
- run_tests.sh finds Godot and runs the suite headless (~10 seconds)
- CI runs the tests before the build job in gitea-build.yaml; the
separate test.yml used a GitHub action that does not exist
- GdUnit4 is committed instead of ignored, since the project enables
it, and .gitea/ is no longer ignored
- Exported builds leave out tests/ and addons/gdUnit4/