diff --git a/packages/package_info_plus/package_info_plus/example/integration_test/package_info_plus_web_test.dart b/packages/package_info_plus/package_info_plus/example/integration_test/package_info_plus_web_test.dart index 1ba5fa7b48..cdb5e6a58f 100644 --- a/packages/package_info_plus/package_info_plus/example/integration_test/package_info_plus_web_test.dart +++ b/packages/package_info_plus/package_info_plus/example/integration_test/package_info_plus_web_test.dart @@ -234,6 +234,28 @@ void main() { Uri.parse('file:///a/b/c/version.json?cachebuster=1'), ); }); + + testWidgets('Get correct versionJsonUrl for relative base URLs', ( + tester, + ) async { + final Uri rootRelative = plugin.versionJsonUrl( + '/static/companion/flutter/', + 1, + ); + expect( + rootRelative.isScheme('http') || rootRelative.isScheme('https'), + isTrue, + ); + expect(rootRelative.path, '/static/companion/flutter/version.json'); + expect(rootRelative.query, 'cachebuster=1'); + + final Uri pathRelative = plugin.versionJsonUrl('flutter/', 1); + expect( + pathRelative.isScheme('http') || pathRelative.isScheme('https'), + isTrue, + ); + expect(pathRelative.path, endsWith('/flutter/version.json')); + }); }); group('Package Info Web (using MockAssetManager)', () { @@ -273,6 +295,39 @@ void main() { }); }); + testWidgets( + 'Get correct values when the AssetManager baseUrl is relative', + (tester) async { + // A relative engine `assetBase`, e.g. '/static/companion/flutter/', is + // supported by the engine for apps embedded in another page. + const String assetBase = '/static/companion/flutter/'; + const String assetsDir = 'assets'; + + when(assetManagerMock.assetsDir).thenReturn(assetsDir); + when( + assetManagerMock.getAssetUrl(''), + ).thenReturn('$assetBase$assetsDir/'); + when( + client.get( + argThat( + predicate( + (uri) => uri.path == '/static/companion/flutter/version.json', + ), + ), + ), + ).thenAnswer( + (_) => Future.value(http.Response(jsonEncode(VERSION_JSON), 200)), + ); + + final versionMap = await plugin.getAll(); + + expect(versionMap.appName, VERSION_JSON['app_name']); + expect(versionMap.version, VERSION_JSON['version']); + expect(versionMap.buildNumber, VERSION_JSON['build_number']); + expect(versionMap.packageName, VERSION_JSON['package_name']); + }, + ); + testWidgets( 'Has preference for the custom base URL over the other 2 locations', (tester) async { diff --git a/packages/package_info_plus/package_info_plus/lib/src/package_info_plus_web.dart b/packages/package_info_plus/package_info_plus/lib/src/package_info_plus_web.dart index 3e884cae36..b7018781bd 100644 --- a/packages/package_info_plus/package_info_plus/lib/src/package_info_plus_web.dart +++ b/packages/package_info_plus/package_info_plus/lib/src/package_info_plus_web.dart @@ -26,7 +26,9 @@ class PackageInfoPlusWebPlugin extends PackageInfoPlatform { /// Get version.json full url. Uri versionJsonUrl(String baseUrl, int cacheBuster) { - final baseUri = Uri.parse(baseUrl); + // A relative base URL (e.g. an engine `assetBase` of '/app/') has no + // origin, so resolve it against the document like the browser does. + final baseUri = Uri.parse(web.window.document.baseURI).resolve(baseUrl); final regExp = RegExp(r'[^/]+\.html.*'); final String originPath = '${baseUri._origin}${baseUri.path.replaceAll(regExp, '')}';