test: fix the install-flags structural guard failing on main (#3116)

Two defects, the second hidden behind the first. CI runs ruff only, so
neither shows up there.

The generic-403 guard counted the copy across all of js/common.js while its
docstring describes exactly the two occurrences inside handle403Response. A
third, unrelated use at line 722 builds the batch-uninstall error message, so
the file-wide count tripped on it. Scoped the count to the handle403Response
block via the existing _js_function_block helper. This part is not
platform-specific; the count is 3 on Linux and Windows alike.

With that passing, the test reached a loop calling js_file.read_text() with no
encoding. That uses the locale encoding, so on cp1252 Windows it raises
UnicodeDecodeError on the four js files containing emoji. Passed
encoding="utf-8" explicitly, and did the same for the other four read_text
calls in the file, which read ASCII sources today and so pass by luck.
This commit is contained in:
Dhevenddra K G
2026-08-02 15:08:30 +09:00
committed by GitHub
parent 25f519ed0c
commit f124e5cfc6
+11 -6
View File
@@ -54,7 +54,7 @@ class JsCopyStructuralTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.common_src = JS_COMMON_PATH.read_text()
cls.common_src = JS_COMMON_PATH.read_text(encoding="utf-8")
def test_surface_messages_name_their_flag(self):
"""Both install 403 branches pass a flag-naming defaultMessage."""
@@ -76,14 +76,19 @@ class JsCopyStructuralTest(unittest.TestCase):
"""The generic fallback copy stays (exactly its two occurrences in
handle403Response), and no other handle403Response caller across
js/ gains a defaultMessage."""
self.assertEqual(self.common_src.count(GENERIC_403_COPY), 2)
# Count inside handle403Response rather than file-wide. The same
# sentence is legitimately reused elsewhere in common.js to build a
# batch-uninstall error message, which is not a caller of
# handle403Response and so is outside this guard's contract.
handle_block = _js_function_block(self.common_src, "handle403Response")
self.assertEqual(handle_block.count(GENERIC_403_COPY), 2)
surface_blocks = "".join(
_js_function_block(self.common_src, name)
for name in ("install_pip", "install_via_git_url")
)
allowed_two_arg = {a for a in _handle403_call_args(surface_blocks) if "," in a}
for js_file in sorted((REPO_ROOT / "js").glob("*.js")):
source = js_file.read_text()
source = js_file.read_text(encoding="utf-8")
for args in _handle403_call_args(source):
if "," in args:
self.assertIn(
@@ -98,7 +103,7 @@ class StructuralSecurityGuardsTest(unittest.TestCase):
def test_no_new_install_route_surface(self):
"""No new HTTP surface for git-URL/pip install."""
source = MANAGER_SERVER_PATH.read_text()
source = MANAGER_SERVER_PATH.read_text(encoding="utf-8")
routes = set(re.findall(r"@routes\.post\(\"([^\"]+)\"\)", source))
expected_surfaces = {
"/customnode/install/git_url",
@@ -117,14 +122,14 @@ class StructuralSecurityGuardsTest(unittest.TestCase):
def test_cm_cli_ungated(self):
"""cm-cli stays a local operator tool — no gate, no flag lookup."""
source = CM_CLI_PATH.read_text()
source = CM_CLI_PATH.read_text(encoding="utf-8")
for token in FLAG_TOKENS + ("is_allowed_security_level", "is_dedicated_install_allowed"):
self.assertNotIn(token, source, "cm-cli.py must stay ungated")
def test_no_autoseed_in_migration(self):
"""The migration module never references the flags (explicit
opt-in only — no auto-seed from security_level)."""
source = MANAGER_MIGRATION_PATH.read_text()
source = MANAGER_MIGRATION_PATH.read_text(encoding="utf-8")
for token in FLAG_TOKENS:
self.assertNotIn(
token, source,