mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-07-25 06:11:36 +00:00
* Update GitHub repo references from feedback* to feedBack* * rename: slopsmith -> feedBack, byron -> got-feedBack Renames across the entire codebase: - slopsmith/Slopsmith/SLOPSMITH/SlopSmith -> feedBack/FeedBack/FEEDBACK/FeedBack - byron/Byron/Byrongamatos -> got-feedBack/got-feedBack/got-feedBack - /home/byron/ -> /opt/got-feedBack/ - byron@ougsoft.com -> hi@got-feedBack.org - github.com/byrongamatos/ -> github.com/got-feedback/ - com.byron. -> com.got-feedback. - SLOPSMITH_ env vars -> FEEDBACK_ with backward-compat fallback - Protocol/storage strings migrated with read-old/write-new pattern - window.slopsmith JS API -> window.feedBack (canonical) + backward-compat alias Refs: #rename-slopsmith * rename: complete regen against current main + fix backward-compat alias Regenerated the slopsmith->feedBack / byron->got-feedBack rename on top of current main (3 commits had landed since the branch: #572/#554/#574), resolving the four content conflicts in favour of main's newer content (autoplay/auto-exit, accuracy-badge, Virtuoso re-home, feedpak badge). Completion fixes on top of the mechanical rename: - Re-apply rename to post-branch content the original rename never saw: window.slopsmith(.Tour) consumers in lessons.js / notifications.js / onboarding-tour.js, and the matching JS + python tests (autoplay_exit, progression_*, test_feedpak_extension FEEDBACK_* env vars). The test env vars now match server.py (which reads FEEDBACK_SYNC_STARTUP / FEEDBACK_SKIP_STARTUP_TASKS), so the sync-startup test exercises the real path again. - Restore the window.slopsmith backward-compat alias dropped during conflict resolution, and move the bus aliases to AFTER the _feedBackExisting merge block so they reference the fully-assembled object (also fixes the loop_api.test.js API-surface regex, which the original PR latently broke). - Drop the stray empty data/web_library.db (runtime DB lives in CONFIG_DIR) and gitignore it. - Fix stale tone-source test: feed[dB]ack -> fee[dB]ack to match shipped source labels. Verified locally (org CI billing-blocked): JS 819/819 pass; pytest 1669 passed / 1683 collected with 0 import errors; zero residual slopsmith/byron except the two intentional window.slopsmith aliases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * rename: implement advertised backward-compat + prune dead community plugins Address gaps where PR #537's "Backward compatibility" section was advertised but not implemented, and clean up the community plugin list. Env vars (FEEDBACK_* canonical, legacy SLOPSMITH_* honoured): - New lib/env_compat.py (getenv_compat / env_flag_compat) + tests. server.py (_env_flag + all FEEDBACK_* reads), diagnostics_hardware, gp2midi and tailwind_rebuild now resolve the legacy alias, so existing SLOPSMITH_UI / SLOPSMITH_PLUGINS_DIR / etc. deployments keep working. - Fix the rename collapsing plugins/__init__.py and minigames/routes.py from `FEEDBACK_PLUGINS_DIR or SLOPSMITH_PLUGINS_DIR` into a redundant `FEEDBACK_ or FEEDBACK_` (the fallback was silently lost). Storage (app.js update-channel): - Read feedBack-update-channel, fall back to legacy slopsmith-update-channel, and clear the legacy key on write — so a user's update-channel preference survives the rename instead of resetting to "stable". Community plugin list (README): the rename rewrote third-party repo URLs we don't own. Probed every one; their owners never renamed, so: - Restore the 13 live community plugins to their real slopsmith-* names. - Prune 6 that are 404 to the public (topkoa splitscreen/stems, OmikronApex tuner, Jafz2001 nam-rig-builder, DeathlySin song-preview, Erikcb91 shuffle). - Fix a pre-existing Guitar Theory clone-command typo (nam-tone -> guitar-theory). Verified: env_compat 7/7, JS 819/819, pytest 1690 collected / 0 import errors, rename-sensitive + startup suites green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: byrongamatos <xasiklas@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
127 lines
4.4 KiB
Python
127 lines
4.4 KiB
Python
"""Tests for builtin diagnostic sloppak seeding into DLC."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib
|
|
import os
|
|
import sys
|
|
import time
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture()
|
|
def server_mod(tmp_path, monkeypatch, isolate_logging):
|
|
monkeypatch.setenv("CONFIG_DIR", str(tmp_path))
|
|
monkeypatch.delenv("DLC_DIR", raising=False)
|
|
sys.modules.pop("server", None)
|
|
mod = importlib.import_module("server")
|
|
yield mod
|
|
|
|
|
|
def test_seed_creates_builtin_diagnostic_sloppak(tmp_path, server_mod):
|
|
"""First seed copies the bundled sloppak into diagnostics-builtin/."""
|
|
dlc = tmp_path / "dlc"
|
|
dlc.mkdir()
|
|
source = server_mod._feedBack_server_root() / server_mod._BUILTIN_DIAGNOSTIC_SOURCES[0][1]
|
|
if not source.is_file():
|
|
pytest.skip(f"source sloppak not present in checkout: {source}")
|
|
|
|
server_mod._seed_builtin_diagnostic_sloppaks(dlc)
|
|
|
|
dest = dlc / server_mod._BUILTIN_DIAGNOSTIC_SUBDIR / server_mod._BUILTIN_DIAGNOSTIC_SOURCES[0][0]
|
|
assert dest.is_file()
|
|
assert dest.stat().st_size == source.stat().st_size
|
|
|
|
|
|
def test_seed_is_idempotent_when_destination_exists(tmp_path, server_mod):
|
|
"""Second seed leaves an up-to-date destination unchanged."""
|
|
dlc = tmp_path / "dlc"
|
|
dlc.mkdir()
|
|
source = server_mod._feedBack_server_root() / server_mod._BUILTIN_DIAGNOSTIC_SOURCES[0][1]
|
|
if not source.is_file():
|
|
pytest.skip(f"source sloppak not present in checkout: {source}")
|
|
|
|
server_mod._seed_builtin_diagnostic_sloppaks(dlc)
|
|
dest = dlc / server_mod._BUILTIN_DIAGNOSTIC_SUBDIR / server_mod._BUILTIN_DIAGNOSTIC_SOURCES[0][0]
|
|
first_mtime = dest.stat().st_mtime_ns
|
|
first_size = dest.stat().st_size
|
|
|
|
server_mod._seed_builtin_diagnostic_sloppaks(dlc)
|
|
|
|
assert dest.stat().st_mtime_ns == first_mtime
|
|
assert dest.stat().st_size == first_size
|
|
|
|
|
|
def test_seed_skips_when_destination_is_newer(tmp_path, server_mod):
|
|
"""An existing newer destination is not overwritten."""
|
|
dlc = tmp_path / "dlc"
|
|
dlc.mkdir()
|
|
source = server_mod._feedBack_server_root() / server_mod._BUILTIN_DIAGNOSTIC_SOURCES[0][1]
|
|
if not source.is_file():
|
|
pytest.skip(f"source sloppak not present in checkout: {source}")
|
|
dest_dir = dlc / server_mod._BUILTIN_DIAGNOSTIC_SUBDIR
|
|
dest_dir.mkdir(parents=True)
|
|
dest_name = server_mod._BUILTIN_DIAGNOSTIC_SOURCES[0][0]
|
|
dest = dest_dir / dest_name
|
|
dest.write_bytes(b"user-owned diagnostic copy")
|
|
future = time.time() + 3600
|
|
os.utime(dest, (future, future))
|
|
|
|
server_mod._seed_builtin_diagnostic_sloppaks(dlc)
|
|
|
|
assert dest.read_bytes() == b"user-owned diagnostic copy"
|
|
|
|
|
|
def test_seed_refuses_to_follow_symlink_destination(tmp_path, server_mod):
|
|
"""A symlink at the destination is skipped, not written through."""
|
|
dlc = tmp_path / "dlc"
|
|
dlc.mkdir()
|
|
source = server_mod._feedBack_server_root() / server_mod._BUILTIN_DIAGNOSTIC_SOURCES[0][1]
|
|
if not source.is_file():
|
|
pytest.skip(f"source sloppak not present in checkout: {source}")
|
|
|
|
outside = tmp_path / "outside.txt"
|
|
outside.write_bytes(b"do not overwrite me")
|
|
dest_dir = dlc / server_mod._BUILTIN_DIAGNOSTIC_SUBDIR
|
|
dest_dir.mkdir(parents=True)
|
|
dest = dest_dir / server_mod._BUILTIN_DIAGNOSTIC_SOURCES[0][0]
|
|
dest.symlink_to(outside)
|
|
|
|
server_mod._seed_builtin_diagnostic_sloppaks(dlc)
|
|
|
|
# The symlink target must be untouched and the link left as-is.
|
|
assert outside.read_bytes() == b"do not overwrite me"
|
|
assert dest.is_symlink()
|
|
|
|
|
|
def test_seed_refuses_symlinked_seed_directory(tmp_path, server_mod):
|
|
"""A symlinked diagnostics-builtin directory is skipped entirely."""
|
|
dlc = tmp_path / "dlc"
|
|
dlc.mkdir()
|
|
outside_dir = tmp_path / "outside_dir"
|
|
outside_dir.mkdir()
|
|
(dlc / server_mod._BUILTIN_DIAGNOSTIC_SUBDIR).symlink_to(
|
|
outside_dir, target_is_directory=True
|
|
)
|
|
|
|
server_mod._seed_builtin_diagnostic_sloppaks(dlc)
|
|
|
|
# Nothing was written through the directory symlink into the link target.
|
|
assert list(outside_dir.iterdir()) == []
|
|
|
|
|
|
def test_seed_missing_source_does_not_crash(tmp_path, server_mod, monkeypatch):
|
|
"""Missing bundled source logs and returns without raising."""
|
|
dlc = tmp_path / "dlc"
|
|
dlc.mkdir()
|
|
monkeypatch.setattr(
|
|
server_mod,
|
|
"_BUILTIN_DIAGNOSTIC_SOURCES",
|
|
[("missing.sloppak", "docs/diagnostics/does-not-exist.sloppak")],
|
|
)
|
|
|
|
server_mod._seed_builtin_diagnostic_sloppaks(dlc)
|
|
|
|
assert not (dlc / server_mod._BUILTIN_DIAGNOSTIC_SUBDIR / "missing.sloppak").exists()
|