diff --git a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_services.dart b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_services.dart index 546bd90079e..15a76b761ef 100644 --- a/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_services.dart +++ b/packages/devtools_app/lib/src/screens/deep_link_validation/deep_links_services.dart @@ -26,6 +26,8 @@ const postHeader = {'Content-Type': 'application/json'}; // The keys used in both android and ios domain validation API. const _domainNameKey = 'domainName'; const _checkNameKey = 'checkName'; +const _severityLevelKey = 'severityLevel'; +const _severityLevelError = 'ERROR'; const _failedChecksKey = 'failedChecks'; const _domainBatchSize = 500; @@ -194,7 +196,8 @@ class DeepLinksService { for (final failedCheck in failedChecks) { final checkName = failedCheck[_checkNameKey] as String; final domainError = iosCheckNameToDomainError[checkName]; - if (domainError != null) { + final severityLevel = failedCheck[_severityLevelKey] as String; + if (domainError != null && severityLevel == _severityLevelError) { domainErrors .putIfAbsent(domainName, () => []) .add(domainError); diff --git a/packages/devtools_app/test/deep_link_vlidation/deep_links_screen_test.dart b/packages/devtools_app/test/deep_link_vlidation/deep_links_screen_test.dart index 0e855d6a185..57ea2d50184 100644 --- a/packages/devtools_app/test/deep_link_vlidation/deep_links_screen_test.dart +++ b/packages/devtools_app/test/deep_link_vlidation/deep_links_screen_test.dart @@ -214,9 +214,8 @@ void main() { (WidgetTester tester) async { final deepLinksController = TestDeepLinksController( hasAndroidDomainErrors: true, - hasIosDomainErrors: true, + iosValidationResponse: iosValidationResponseWithError, ); - deepLinksController ..selectedProject.value = FlutterProject( path: '/abc', @@ -269,7 +268,7 @@ void main() { (WidgetTester tester) async { final deepLinksController = TestDeepLinksController( hasAndroidDomainErrors: true, - hasIosDomainErrors: true, + iosValidationResponse: iosValidationResponseWithError, ); deepLinksController @@ -298,6 +297,44 @@ void main() { }, ); + testWidgetsWithWindowSize( + 'Don\'t show domain errors when they are just warnings', + windowSize, + (WidgetTester tester) async { + final deepLinksController = TestDeepLinksController( + iosValidationResponse: iosValidationResponseWithWarning, + ); + + deepLinksController + ..selectedProject.value = FlutterProject( + path: '/abc', + androidVariants: ['debug', 'release'], + iosBuildOptions: xcodeBuildOptions, + ) + ..fakeAndroidDeepLinks = [ + androidDeepLinkJson('www.domain1.com'), + androidDeepLinkJson('www.google.com'), + ] + ..fakeIosDomains = [defaultDomain]; + + await pumpDeepLinkScreen( + tester, + controller: deepLinksController, + ); + + expect(find.text('www.domain1.com'), findsOneWidget); + expect(find.text('example.com'), findsOneWidget); + expect(find.text('www.google.com'), findsOneWidget); + + await tester.tap(find.text('example.com')); + await tester.pumpAndSettle(const Duration(milliseconds: 500)); + + final domainErrors = + deepLinksController.selectedLink.value!.domainErrors; + expect(domainErrors.length, 0); + }, + ); + testWidgetsWithWindowSize( 'search links', windowSize, @@ -394,8 +431,9 @@ void main() { 'filter links with validation result', windowSize, (WidgetTester tester) async { - final deepLinksController = - TestDeepLinksController(hasIosDomainErrors: true); + final deepLinksController = TestDeepLinksController( + iosValidationResponse: iosValidationResponseWithError, + ); deepLinksController ..selectedProject.value = FlutterProject( @@ -448,7 +486,9 @@ void main() { 'sort links', windowSize, (WidgetTester tester) async { - final deepLinksController = TestDeepLinksController(); + final deepLinksController = TestDeepLinksController( + iosValidationResponse: iosValidationResponseWithError, + ); deepLinksController ..selectedProject.value = FlutterProject( @@ -456,8 +496,7 @@ void main() { androidVariants: ['debug', 'release'], iosBuildOptions: xcodeBuildOptions, ) - ..fakeIosDomains = [defaultDomain, 'domain1.com', 'domain2.com'] - ..hasIosDomainErrors = true; + ..fakeIosDomains = [defaultDomain, 'domain1.com', 'domain2.com']; await pumpDeepLinkScreen( tester, diff --git a/packages/devtools_app/test/test_infra/test_data/deep_link/fake_responses.dart b/packages/devtools_app/test/test_infra/test_data/deep_link/fake_responses.dart index 583cd8cfd14..ae073da3a82 100644 --- a/packages/devtools_app/test/test_infra/test_data/deep_link/fake_responses.dart +++ b/packages/devtools_app/test/test_infra/test_data/deep_link/fake_responses.dart @@ -176,6 +176,84 @@ const iosValidationResponseWithNoError = ''' } '''; +const iosValidationResponseWithWarning = ''' +{ + "validationResults": [ + { + "domainName": "example.com", + "passedChecks": [ + { + "checkName": "HTTPS_ACCESSIBILITY", + "resultType": "PASSED", + "severityLevel": "ERROR" + }, + { + "checkName": "NON_REDIRECT", + "resultType": "PASSED", + "severityLevel": "ERROR" + }, + { + "checkName": "EXISTENCE", + "resultType": "PASSED", + "severityLevel": "ERROR" + }, + { + "checkName": "APP_IDENTIFIER", + "resultType": "PASSED", + "severityLevel": "ERROR" + }, + { + "checkName": "FILE_FORMAT", + "resultType": "PASSED", + "severityLevel": "ERROR" + } + ], + "failedChecks": [ + { + "checkName": "DEFAULTS_FORMAT", + "resultType": "FAILED_INDEPENDENTLY", + "severityLevel": "WARNING" + } + ], + "status": "VALIDATION_COMPLETE", + "aasaAppPaths": [ + { + "aasaAppId": { + "bundleId": "bundle.id", + "teamId": "AAABBB" + }, + "aasaPaths": [ + { + "path": "/ios-path1", + "queryParams": [ + { + "key": "dplnk", + "value": "?*" + } + ], + "isCaseSensitive": true, + "isPercentEncoded": true + }, + { + "path": "/ios-path2", + "isExcluded": true, + "queryParams": [ + { + "key": "dplnk", + "value": "?*" + } + ], + "isCaseSensitive": true, + "isPercentEncoded": true + } + ] + } + ] + } + ] +} +'''; + const iosValidationResponseWithError = ''' { "validationResults": [ diff --git a/packages/devtools_app/test/test_infra/utils/deep_links_utils.dart b/packages/devtools_app/test/test_infra/utils/deep_links_utils.dart index 5ddc45eac17..3b5cf5cd22c 100644 --- a/packages/devtools_app/test/test_infra/utils/deep_links_utils.dart +++ b/packages/devtools_app/test/test_infra/utils/deep_links_utils.dart @@ -16,7 +16,7 @@ final defaultAndroidDeeplink = androidDeepLinkJson(defaultDomain); class TestDeepLinksService extends DeepLinksService { TestDeepLinksService({ this.hasAndroidDomainErrors = false, - this.hasIosDomainErrors = false, + this.iosValidationResponse = '', }) { // Create a mock client to return fake responses. _client = MockClient((request) async { @@ -28,11 +28,7 @@ class TestDeepLinksService extends DeepLinksService { } } if (request.url == Uri.parse(iosDomainValidationURL)) { - if (hasIosDomainErrors) { - return Response(iosValidationResponseWithError, 200); - } else { - return Response(iosValidationResponseWithNoError, 200); - } + return Response(iosValidationResponse, 200); } return Response('this is a body', 404); }); @@ -44,24 +40,24 @@ class TestDeepLinksService extends DeepLinksService { Client get client => _client; final bool hasAndroidDomainErrors; - final bool hasIosDomainErrors; + final String iosValidationResponse; } class TestDeepLinksController extends DeepLinksController { TestDeepLinksController({ this.hasAndroidDomainErrors = false, - this.hasIosDomainErrors = false, + this.iosValidationResponse = iosValidationResponseWithNoError, }) { _deepLinksService = TestDeepLinksService( hasAndroidDomainErrors: hasAndroidDomainErrors, - hasIosDomainErrors: hasIosDomainErrors, + iosValidationResponse: iosValidationResponse, ); } List fakeAndroidDeepLinks = []; bool hasAndroidDomainErrors = false; bool hasAndroidPathErrors = false; - bool hasIosDomainErrors = false; + String iosValidationResponse = ''; List fakeIosDomains = []; late DeepLinksService _deepLinksService;