Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(appstore-connect): Fix empty dSYMUrl detection #29830

Merged
merged 5 commits into from
Nov 9, 2021
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
5 changes: 2 additions & 3 deletions src/sentry/utils/appleconnect/appstore_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,15 +386,14 @@ def _get_dsym_url(bundles: Optional[List[JSONData]]) -> Union[NoDsymUrl, str]:
for b in bundles
if safe.get_path(b, "attributes", "bundleType", default="APP") == "APP_CLIP"
]
if any(app_clip_urls):
sentry_sdk.capture_message("App_CLIP has dSYMUrl")
if not all(isinstance(url, NoDsymUrl) for url in app_clip_urls):
sentry_sdk.capture_message("App Clip's bundle has a dSYMUrl")

app_bundles = [
app_bundle
for app_bundle in bundles
if safe.get_path(app_bundle, "attributes", "bundleType", default="APP") != "APP_CLIP"
]

if not app_bundles:
return NoDsymUrl.NOT_NEEDED
elif len(app_bundles) > 1:
Expand Down
113 changes: 100 additions & 13 deletions tests/sentry/utils/appleconnect/test_appstore_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import textwrap
import urllib.parse
from typing import Optional
from unittest import mock

import pytest
import requests
Expand Down Expand Up @@ -163,16 +164,18 @@ def test_dsyms_needed(
appstore_connect.get_build_info(session, api_credentials, app_id, include_expired=True)
)

found_build = None

for build in builds:
if build.build_number == "332":
found_build = build
break
else:
pytest.fail("Build 332 not found")

assert build.build_number == "332"
assert isinstance(build.dsym_url, str)
assert build.dsym_url.startswith("http://iosapps.itunes.apple.com/itunes-assets/")
assert "accessKey=" in build.dsym_url
assert found_build is not None
assert found_build.build_number == "332"
assert isinstance(found_build.dsym_url, str)
assert found_build.dsym_url.startswith("http://iosapps.itunes.apple.com/itunes-assets/")
assert "accessKey=" in found_build.dsym_url

def test_no_dsyms_needed(
self,
Expand All @@ -188,14 +191,15 @@ def test_no_dsyms_needed(
appstore_connect.get_build_info(session, api_credentials, app_id, include_expired=True)
)

found_build = None
for build in builds:
if build.build_number == "333":
found_build = build
break
else:
pytest.fail("Build 333 not found")

assert build.build_number == "333"
assert build.dsym_url is appstore_connect.NoDsymUrl.NOT_NEEDED
assert found_build is not None
assert found_build.build_number == "333"
assert found_build.dsym_url is appstore_connect.NoDsymUrl.NOT_NEEDED


class TestGetDsymUrl:
Expand All @@ -211,6 +215,7 @@ def test_one_bundle_strange_url(self) -> None:
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-0116775a6eab",
"attributes": {
"bundleType": "APP",
"dSYMUrl": 1,
},
}
Expand All @@ -225,6 +230,7 @@ def test_one_bundle_no_url(self) -> None:
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-0116775a6eab",
"attributes": {
"bundleType": "APP",
"dSYMUrl": None,
},
}
Expand All @@ -239,6 +245,7 @@ def test_one_bundle_has_url(self) -> None:
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-0116775a6eab",
"attributes": {
"bundleType": "APP",
"dSYMUrl": url,
},
}
Expand All @@ -252,13 +259,15 @@ def test_multi_bundle_no_url(self) -> None:
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-0116775a6eab",
"attributes": {
"bundleType": "APP",
"dSYMUrl": None,
},
},
{
"type": "buildBundles",
"id": "5e231f58-31c6-47cc-b4f8-56952d44a158",
"attributes": {
"bundleType": "APP",
"dSYMUrl": None,
},
},
Expand All @@ -274,21 +283,23 @@ def test_multi_bundle_has_url(self) -> None:
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-0116775a6eab",
"attributes": {
"bundleType": "APP",
"dSYMUrl": first_url,
},
},
{
"type": "buildBundles",
"id": "5e231f58-31c6-47cc-b4f8-56952d44a158",
"attributes": {
"bundleType": "APP",
"dSYMUrl": second_url,
},
},
]
assert appstore_connect._get_dsym_url(bundles) is first_url
assert appstore_connect._get_dsym_url(bundles) == first_url

bundles.reverse()
assert appstore_connect._get_dsym_url(bundles) is second_url
assert appstore_connect._get_dsym_url(bundles) == second_url

def test_multi_bundle_mixed_urls(self) -> None:
url = "http://iosapps.itunes.apple.com/itunes-assets/very-real-url"
Expand All @@ -297,19 +308,95 @@ def test_multi_bundle_mixed_urls(self) -> None:
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-0116775a6eab",
"attributes": {
"bundleType": "APP",
"dSYMUrl": url,
},
},
{
"type": "buildBundles",
"id": "5e231f58-31c6-47cc-b4f8-56952d44a158",
"attributes": {
"bundleType": "APP",
"dSYMUrl": None,
},
},
]

assert appstore_connect._get_dsym_url(bundles) is url
assert appstore_connect._get_dsym_url(bundles) == url

bundles.reverse()
assert appstore_connect._get_dsym_url(bundles) is NoDsymUrl.NOT_NEEDED

def test_multi_bundle_appclip_no_urls(self) -> None:
bundles = [
{
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-0116775a6eab",
"attributes": {
"bundleType": "APP",
"dSYMUrl": None,
},
},
{
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-1227886b7fbc",
"attributes": {
"bundleType": "APP_CLIP",
"dSYMUrl": None,
},
},
]

with mock.patch("sentry_sdk.capture_message") as capture_message:
assert appstore_connect._get_dsym_url(bundles) is NoDsymUrl.NOT_NEEDED
assert capture_message.call_count == 0

def test_multi_bundle_appclip_has_urls(self) -> None:
url = "http://iosapps.itunes.apple.com/itunes-assets/very-real-url"
bundles = [
{
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-0116775a6eab",
"attributes": {
"bundleType": "APP",
"dSYMUrl": url,
},
},
{
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-1227886b7fbc",
"attributes": {
"bundleType": "APP_CLIP",
"dSYMUrl": url,
},
},
]

with mock.patch("sentry_sdk.capture_message") as capture_message:
assert appstore_connect._get_dsym_url(bundles) == url
assert capture_message.call_count == 1

def test_multi_bundle_appclip_mixed_clip_no_url(self) -> None:
url = "http://iosapps.itunes.apple.com/itunes-assets/very-real-url"
bundles = [
{
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-0116775a6eab",
"attributes": {
"bundleType": "APP",
"dSYMUrl": None,
},
},
{
"type": "buildBundles",
"id": "59467f37-371e-4755-afcd-1227886b7fbc",
"attributes": {
"bundleType": "APP_CLIP",
"dSYMUrl": url,
},
},
]

with mock.patch("sentry_sdk.capture_message") as capture_message:
assert appstore_connect._get_dsym_url(bundles) is NoDsymUrl.NOT_NEEDED
assert capture_message.call_count == 1