diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index 9be7cc87d5d..9bf48f6ac87 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.14+2 + +* Fixes a bug where using `cloudMapId` for cloud-based styling would fail if the `style` property was also present. + ## 0.5.14+1 * Stops processing events and cancels subscriptions when controller is disposed. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/cloud_map_styles_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/cloud_map_styles_test.dart new file mode 100644 index 00000000000..9de80a09ac6 --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/cloud_map_styles_test.dart @@ -0,0 +1,131 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'package:flutter/widgets.dart' + show Directionality, SizedBox, TextDirection; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps/google_maps.dart' as gmaps; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart' + show + CameraPosition, + LatLng, + MapConfiguration, + MapEvent, + MapWidgetConfiguration; +import 'package:google_maps_flutter_web/google_maps_flutter_web.dart' + show GoogleMapController; +import 'package:integration_test/integration_test.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + MapWidgetConfiguration cfg() => const MapWidgetConfiguration( + initialCameraPosition: CameraPosition(target: LatLng(0, 0), zoom: 1), + textDirection: TextDirection.ltr, + ); + + testWidgets('cloudMapId present => mapId set & styles omitted', ( + WidgetTester tester, + ) async { + const MapConfiguration testMapConfig = MapConfiguration( + mapId: 'test-cloud-map-id', + ); + + await tester.pumpWidget( + const Directionality(textDirection: TextDirection.ltr, child: SizedBox()), + ); + + final StreamController> stream = + StreamController>(); + addTearDown(() { + // Stream is closed by controller.dispose() + }); + + gmaps.MapOptions? captured; + + final GoogleMapController controller = GoogleMapController( + mapId: 1, // Internal controller ID + streamController: stream, + widgetConfiguration: cfg(), + mapConfiguration: testMapConfig, // cloudMapId is set here + ); + + controller.debugSetOverrides( + setOptions: (gmaps.MapOptions options) { + captured = options; + }, + ); + + final List styles = [ + gmaps.MapTypeStyle() + ..featureType = 'road' + ..elementType = 'geometry', + ]; + + controller.updateStyles(styles); + + await tester.pump(); + + expect(captured, isNotNull); + expect(captured!.mapId, testMapConfig.mapId); + expect( + captured!.styles == null || captured!.styles!.isEmpty, + isTrue, + reason: 'When cloudMapId is set, styles must not be applied.', + ); + + controller.dispose(); + }); + + testWidgets('no cloudMapId => styles applied', (WidgetTester tester) async { + await tester.pumpWidget( + const Directionality(textDirection: TextDirection.ltr, child: SizedBox()), + ); + + final StreamController> stream = + StreamController>(); + addTearDown(() { + // Stream is closed by controller.dispose() + }); + + gmaps.MapOptions? captured; + final GoogleMapController controller = GoogleMapController( + mapId: 2, // Internal controller ID + streamController: stream, + widgetConfiguration: cfg(), + ); + + controller.debugSetOverrides( + setOptions: (gmaps.MapOptions options) { + captured = options; + }, + ); + + final List styles = [ + gmaps.MapTypeStyle() + ..featureType = 'poi' + ..elementType = 'labels', + ]; + + controller.updateStyles(styles); + + await tester.pump(); + + expect(captured, isNotNull); + expect( + captured!.mapId, + anyOf(isNull, isEmpty), + reason: 'mapId should be empty/null when no Cloud Map is used.', + ); + expect(captured!.styles, isNotNull); + expect( + captured!.styles, + isNotEmpty, + reason: 'When cloudMapId is null, styles should be applied.', + ); + + controller.dispose(); + }); +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 2515636170e..8ab60e8c285 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -121,8 +121,10 @@ gmaps.MapOptions _configurationAndStyleToGmapsOptions( options.fullscreenControl = false; options.streetViewControl = false; - // See updateMapConfiguration for why this is not using configuration.style. - options.styles = styles; + // If using cloud map, do not set options.styles + if (configuration.cloudMapId == null) { + options.styles = styles; + } options.mapId = configuration.cloudMapId; diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 05f90f1a0ce..672b6d7a069 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.5.14+1 +version: 0.5.14+2 environment: sdk: ^3.7.0