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
1 change: 1 addition & 0 deletions .github/workflows/upload-app-store-screenshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ name: Upload App Store Screenshots
- macos
- ios
- iphone
- iphone65
- ipad
- watch
- visionpro
Expand Down
8 changes: 0 additions & 8 deletions Tests/ScriptsTests/test_release_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -913,14 +913,6 @@ def test_app_store_screenshot_upload_workflow_uses_safe_defaults(self):
self.assertIn("default: \"\"", workflow)
self.assertIn("type: string", workflow)
self.assertNotIn("- MAC_OS", workflow)
self.assertIn("options:", workflow)
self.assertIn("- macos", workflow)
self.assertIn("- ios", workflow)
self.assertIn("- iphone", workflow)
self.assertIn("- ipad", workflow)
self.assertIn("- watch", workflow)
self.assertIn("- visionpro", workflow)
self.assertIn("- tvos", workflow)

def test_app_store_review_workflow_supports_prepare_only(self):
workflow = self.read(".github/workflows/submit-app-store-review.yml")
Expand Down
60 changes: 60 additions & 0 deletions Tests/ScriptsTests/test_upload_app_store_screenshots.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

MODULE_PATH = Path(__file__).resolve().parents[2] / "scripts" / "upload-app-store-screenshots.py"
SCREENSHOT_ROOT = MODULE_PATH.parents[1] / "Resources" / "AppStore" / "Screenshots"
WORKFLOW_PATH = MODULE_PATH.parents[1] / ".github" / "workflows" / "upload-app-store-screenshots.yml"
SPEC = importlib.util.spec_from_file_location("upload_app_store_screenshots", MODULE_PATH)
if SPEC is None or SPEC.loader is None:
raise RuntimeError(f"Unable to load {MODULE_PATH}")
Expand All @@ -19,6 +20,36 @@
SPEC.loader.exec_module(upload_app_store_screenshots)


def workflow_choice_options(workflow: str, input_name: str) -> list[str]:
lines = workflow.splitlines()
marker = f" {input_name}:"
try:
start = lines.index(marker)
except ValueError as error:
raise AssertionError(f"workflow input not found: {input_name}") from error

block = []
for line in lines[start + 1 :]:
if line and len(line) - len(line.lstrip()) <= 6:
break
block.append(line)

try:
options_start = next(index for index, line in enumerate(block) if line.strip() == "options:")
except StopIteration as error:
raise AssertionError(f"workflow input has no options: {input_name}") from error

options = []
for line in block[options_start + 1 :]:
stripped = line.strip()
if not stripped.startswith("- "):
break
options.append(stripped[2:].strip('"\''))
if not options:
raise AssertionError(f"workflow input has no choice values: {input_name}")
return options


class FakeASCClient:
def __init__(self):
self.requests: list[tuple[Any, ...]] = []
Expand Down Expand Up @@ -448,6 +479,35 @@ def test_selected_assets_preserves_configured_set_and_asset_order(self):
],
)

def test_workflow_screenshot_set_choices_match_approved_sets(self):
options = workflow_choice_options(WORKFLOW_PATH.read_text(), "screenshot_set")

self.assertEqual(set(options), set(upload_app_store_screenshots.APPROVED_SETS))
self.assertEqual(len(options), len(set(options)))
self.assertEqual(options[0], "macos")

def test_workflow_choice_options_scopes_to_the_named_input(self):
workflow = """\
"on":
workflow_dispatch:
inputs:
decoy:
type: choice
options:
- wrong
screenshot_set:
type: choice
options:
- macos
- "ios"
trailing:
type: string
"""

self.assertEqual(workflow_choice_options(workflow, "screenshot_set"), ["macos", "ios"])
with self.assertRaisesRegex(AssertionError, "workflow input not found: missing"):
workflow_choice_options(workflow, "missing")

def test_full_platform_upload_prunes_unapproved_display_type_screenshots(self):
client = FakeASCClient()
client.screenshot_sets = [
Expand Down