Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions bootstrap/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,31 @@
},
"additionalProperties": False,
},
"shell_menu_cleanup": {
"description": "Windows right-click menu cleanup state. Three arrays cover the three places shell verbs hide: com_handlers_blocked writes CLSIDs to the HKLM Shell Extensions Blocked list, static_verbs_disabled writes an empty LegacyDisable REG_SZ under a verb key, appx_packages_removed passes a wildcard pattern to Get-AppxPackage | Remove-AppxPackage for MSIX-packaged shell extensions.",
"type": "object",
Comment thread
tommyjcarpenter marked this conversation as resolved.
"properties": {
"windows": {
Comment thread
tommyjcarpenter marked this conversation as resolved.
"type": "object",
"properties": {
"com_handlers_blocked": {
"type": "array",
"items": {"$ref": "#/definitions/shell_menu_com_handler"},
},
"static_verbs_disabled": {
"type": "array",
"items": {"$ref": "#/definitions/shell_menu_static_verb"},
},
"appx_packages_removed": {
"type": "array",
"items": {"$ref": "#/definitions/shell_menu_appx_package"},
},
},
"additionalProperties": False,
},
},
"additionalProperties": False,
},
},
"definitions": {
"dir": {
Expand Down Expand Up @@ -187,6 +212,42 @@
},
"additionalProperties": False,
},
"shell_menu_com_handler": {
"type": "object",
"required": ["clsid"],
"properties": {
"clsid": {
"type": "string",
"description": "CLSID like '{3D1975AF-48C6-4f8e-A182-BE0E08FA86A9}'. Written as a value name (empty REG_SZ) under HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Blocked.",
},
"name": {"type": "string", "description": "Human-readable label for logs"},
},
"additionalProperties": False,
},
"shell_menu_static_verb": {
"type": "object",
"required": ["path"],
"properties": {
"path": {
"type": "string",
"description": "Registry path to the verb key, e.g. 'HKLM:\\\\Software\\\\Classes\\\\Directory\\\\shell\\\\AnyCode'. An empty LegacyDisable REG_SZ is written under the key, hiding the verb from the menu without deleting it. Treated as already-done if the key doesn't exist on the current machine.",
},
"name": {"type": "string", "description": "Human-readable label for logs"},
},
"additionalProperties": False,
},
"shell_menu_appx_package": {
"type": "object",
"required": ["name_pattern"],
"properties": {
"name_pattern": {
"type": "string",
"description": "Wildcard package name pattern for Get-AppxPackage, e.g. '*Mp3tag.ShellExtension*'. Matching packages are uninstalled with Remove-AppxPackage.",
},
"name": {"type": "string", "description": "Human-readable label for logs"},
},
"additionalProperties": False,
},
},
"additionalProperties": False,
}
Expand Down
48 changes: 48 additions & 0 deletions tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,53 @@ def test_prereq_packages_validated_too(self):
config_validate({"prereq_packages": {"mac": {"bogus_type": ["x"]}}})


class TestShellMenuCleanupSchema(unittest.TestCase):
def test_valid_full(self):
config_validate(
{
"shell_menu_cleanup": {
"windows": {
"com_handlers_blocked": [{"clsid": "{3D1975AF-48C6-4f8e-A182-BE0E08FA86A9}", "name": "Foo"}],
"static_verbs_disabled": [
{"path": "HKLM:\\Software\\Classes\\Directory\\shell\\AnyCode", "name": "AnyCode"}
],
"appx_packages_removed": [{"name_pattern": "*Mp3tag.ShellExtension*", "name": "Mp3tag"}],
}
}
}
)

def test_valid_minimal_required_only(self):
# name is optional everywhere; only the required key per definition is needed
config_validate(
{
"shell_menu_cleanup": {
"windows": {
"com_handlers_blocked": [{"clsid": "{abc}"}],
"static_verbs_disabled": [{"path": "HKLM:\\x"}],
"appx_packages_removed": [{"name_pattern": "*x*"}],
}
}
}
)

def test_missing_required_clsid_rejected(self):
with self.assertRaises(ValidationError):
config_validate({"shell_menu_cleanup": {"windows": {"com_handlers_blocked": [{"name": "Foo"}]}}})

def test_missing_required_path_rejected(self):
with self.assertRaises(ValidationError):
config_validate({"shell_menu_cleanup": {"windows": {"static_verbs_disabled": [{"name": "Foo"}]}}})

def test_unknown_property_rejected(self):
# typo'd array key under windows is not in properties → additionalProperties False
with self.assertRaises(ValidationError):
config_validate({"shell_menu_cleanup": {"windows": {"com_handlers_blockd": [{"clsid": "{x}"}]}}})

def test_unknown_os_section_rejected(self):
with self.assertRaises(ValidationError):
config_validate({"shell_menu_cleanup": {"linux": {"com_handlers_blocked": [{"clsid": "{x}"}]}}})


if __name__ == "__main__":
unittest.main()
Loading