This is an automated email from the ASF dual-hosted git repository.

pabloem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git


The following commit(s) were added to refs/heads/master by this push:
     new f1adfdd7f24 Issue26977 changing sdk bug (#26978)
f1adfdd7f24 is described below

commit f1adfdd7f24b65742bf66292943feba1a1ec94df
Author: Dmitry Repin <[email protected]>
AuthorDate: Wed Jun 21 00:45:55 2023 +0400

    Issue26977 changing sdk bug (#26978)
    
    * temp comment
    
    * handled examples failed to load error
    
    * issue26858 minor changes
    
    * issue26938 fixed examples loading twice
    
    * issue26977 fix change sdk bug
    
    * revert testing feature
    
    * remove unused imports
    
    * rename method
    
    * issue26977 tests added
    
    * fixed test
    
    * issue26977 fixed sdk changing tests
    
    * method extracted
    
    * tests simplified
    
    * fixed tests
    
    * Upgrade Flutter to v3.10.4 (#26977)
    
    ---------
    
    Co-authored-by: Alexey Inkin <[email protected]>
---
 .github/workflows/playground_frontend_test.yml     |   2 +-
 .github/workflows/tour_of_beam_frontend_test.yml   |   4 +-
 .../cloudbuild/scripts/tob_deploy_infra_backend.sh |   5 +-
 .../frontend/integration_test/tour_page_test.dart  | 101 +++++++++++++++++++++
 .../frontend/lib/cache/unit_content.dart           |   2 +-
 .../tour-of-beam/frontend/lib/models/node.dart     |  11 ++-
 .../frontend/lib/pages/tour/state.dart             |  43 +++++----
 learning/tour-of-beam/frontend/pubspec.lock        |   2 +-
 learning/tour-of-beam/frontend/pubspec.yaml        |   2 +-
 playground/frontend/Dockerfile                     |   2 +-
 .../frontend/playground_components/pubspec.yaml    |   2 +-
 .../playground_components_dev/pubspec.yaml         |   2 +-
 playground/frontend/pubspec.lock                   |   2 +-
 playground/frontend/pubspec.yaml                   |   2 +-
 14 files changed, 148 insertions(+), 34 deletions(-)

diff --git a/.github/workflows/playground_frontend_test.yml 
b/.github/workflows/playground_frontend_test.yml
index 3a09148c06c..7d5287ea5a1 100644
--- a/.github/workflows/playground_frontend_test.yml
+++ b/.github/workflows/playground_frontend_test.yml
@@ -37,7 +37,7 @@ jobs:
     runs-on: ubuntu-latest
 
     env:
-      FLUTTER_VERSION: '3.10.2'
+      FLUTTER_VERSION: '3.10.4'
 
     steps:
       - uses: actions/checkout@v3
diff --git a/.github/workflows/tour_of_beam_frontend_test.yml 
b/.github/workflows/tour_of_beam_frontend_test.yml
index ab6f9bc9c8b..1bd416e89e4 100644
--- a/.github/workflows/tour_of_beam_frontend_test.yml
+++ b/.github/workflows/tour_of_beam_frontend_test.yml
@@ -35,11 +35,11 @@ concurrency:
 
 jobs:
   tour_of_beam_test:
-    name: Tour of Beam Test
+    name: Tour of Beam Frontend Test
     runs-on: ubuntu-latest
 
     env:
-      FLUTTER_VERSION: '3.10.2'
+      FLUTTER_VERSION: '3.10.4'
 
     steps:
       - uses: actions/checkout@v3
diff --git 
a/learning/tour-of-beam/cloudbuild/scripts/tob_deploy_infra_backend.sh 
b/learning/tour-of-beam/cloudbuild/scripts/tob_deploy_infra_backend.sh
index d9714887412..7467992d443 100644
--- a/learning/tour-of-beam/cloudbuild/scripts/tob_deploy_infra_backend.sh
+++ b/learning/tour-of-beam/cloudbuild/scripts/tob_deploy_infra_backend.sh
@@ -18,6 +18,7 @@
 # under the License.
 
 export DEBIAN_FRONTEND=noninteractive
+export FLUTTER_VERSION=3.10.4
 
 apt-get -qq  update
 
@@ -37,9 +38,9 @@ unzip terraform_1.4.2_linux_amd64.zip
 
 mv terraform /usr/local/bin/terraform
 
-wget -nv 
https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.10.2-stable.tar.xz
+wget -nv 
https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_$FLUTTER_VERSION-stable.tar.xz
 
-tar xf flutter_linux_3.10.2-stable.tar.xz
+tar xf flutter_linux_$FLUTTER_VERSION-stable.tar.xz
 
 git config --global --add safe.directory /usr/local/bin/flutter
 
diff --git 
a/learning/tour-of-beam/frontend/integration_test/tour_page_test.dart 
b/learning/tour-of-beam/frontend/integration_test/tour_page_test.dart
index 258bb19b136..a683eeff00c 100644
--- a/learning/tour-of-beam/frontend/integration_test/tour_page_test.dart
+++ b/learning/tour-of-beam/frontend/integration_test/tour_page_test.dart
@@ -18,6 +18,7 @@
 
 // ignore_for_file: avoid_print
 
+import 'package:collection/collection.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:get_it/get_it.dart';
@@ -26,7 +27,9 @@ import 
'package:playground_components/playground_components.dart';
 import 'package:playground_components_dev/playground_components_dev.dart';
 import 'package:tour_of_beam/cache/content_tree.dart';
 import 'package:tour_of_beam/cache/sdk.dart';
+import 'package:tour_of_beam/cache/unit_content.dart';
 import 'package:tour_of_beam/components/builders/content_tree.dart';
+import 'package:tour_of_beam/models/content_tree.dart';
 import 'package:tour_of_beam/models/module.dart';
 import 'package:tour_of_beam/models/parent_node.dart';
 import 'package:tour_of_beam/models/unit.dart';
@@ -35,6 +38,7 @@ import 'package:tour_of_beam/pages/tour/state.dart';
 import 'package:tour_of_beam/pages/tour/widgets/playground.dart';
 import 'package:tour_of_beam/pages/tour/widgets/unit.dart';
 import 'package:tour_of_beam/pages/tour/widgets/unit_content.dart';
+import 'package:tour_of_beam/state.dart';
 
 import 'common/common.dart';
 import 'common/common_finders.dart';
@@ -55,6 +59,7 @@ void main() {
       await _checkHighlightsSelectedUnit(wt);
       await _checkRunCodeWorks(wt);
       await _checkResizeUnitContent(wt);
+      await _checkSdkChanges(wt);
 
       expect(
         ExamplesLoader.failedToLoadExamples,
@@ -246,3 +251,99 @@ Set<String> _getExpandedIds(WidgetTester wt) {
   final controller = getContentTreeController(wt);
   return controller.expandedIds;
 }
+
+Future<void> _checkSdkChanges(WidgetTester wt) async {
+  await _selectUnitWithSnippetsInAllSdks(wt);
+  await _checkSnippetChangesOnSdkChanging(wt);
+}
+
+Future<void> _selectUnitWithSnippetsInAllSdks(WidgetTester wt) async {
+  final unitWithSnippets = await _findUnitWithSnippetsInAllSdks(wt);
+
+  if (unitWithSnippets == null) {
+    fail('No unit with snippets in all sdks');
+  }
+
+  final controller = getContentTreeController(wt);
+  controller.onNodePressed(unitWithSnippets);
+  await wt.pumpAndSettle();
+}
+
+Future<UnitModel?> _findUnitWithSnippetsInAllSdks(WidgetTester wt) async {
+  final commonUnits = await _getCommonUnitsInAllSdks(wt);
+  for (final unit in commonUnits) {
+    if (await _hasSnippetsInAllSdks(unit)) {
+      return unit;
+    }
+  }
+  return null;
+}
+
+Future<bool> _hasSnippetsInAllSdks(UnitModel unit) async {
+  final unitContentCache = GetIt.instance.get<UnitContentCache>();
+  final sdks = GetIt.instance.get<SdkCache>().getSdks();
+  for (final sdk in sdks) {
+    final unitContent = await unitContentCache.getUnitContent(sdk.id, unit.id);
+    if (unitContent.taskSnippetId == null) {
+      return false;
+    }
+  }
+  return true;
+}
+
+Future<Set<UnitModel>> _getCommonUnitsInAllSdks(WidgetTester wt) async {
+  final contentTrees = await _loadAllContentTrees(wt);
+  final sdkUnits = List<Set<UnitModel>>.empty(growable: true);
+  for (final tree in contentTrees) {
+    sdkUnits.add(tree.getUnits().toSet());
+  }
+
+  // Identifies and stores the common units across all lists within
+  // the 'sdkUnits' list by iteratively removing elements from the first list
+  // that don't exist in the subsequent lists.
+  final commonUnitTitles = sdkUnits.first;
+  for (final units in sdkUnits.skip(1)) {
+    commonUnitTitles.removeWhere((u) => !units.contains(u));
+  }
+
+  return commonUnitTitles;
+}
+
+Future<List<ContentTreeModel>> _loadAllContentTrees(WidgetTester wt) async {
+  final sdkCache = GetIt.instance.get<SdkCache>();
+  final contentTreeCache = GetIt.instance.get<ContentTreeCache>();
+  final sdks = sdkCache.getSdks();
+  final nullableTrees = await Future.wait(
+    sdks.map((sdk) async => contentTreeCache.getContentTree(sdk)),
+  );
+
+  return nullableTrees.whereNotNull().toList(growable: false);
+}
+
+Future<void> _checkSnippetChangesOnSdkChanging(WidgetTester wt) async {
+  final defaultSdk = _getTourNotifier(wt).playgroundController.sdk;
+  final sdkCache = GetIt.instance.get<SdkCache>();
+
+  for (final sdk in sdkCache.getSdks()) {
+    if (sdk == defaultSdk) {
+      continue;
+    }
+
+    await _setSdk(sdk.title, wt);
+
+    final selectedExample =
+        _getTourNotifier(wt).playgroundController.selectedExample;
+    final appNotifier = GetIt.instance.get<AppNotifier>();
+    final actualSdk = selectedExample?.sdk;
+    expect(actualSdk, appNotifier.sdk);
+  }
+
+  await _setSdk(defaultSdk!.title, wt);
+}
+
+Future<void> _setSdk(String title, WidgetTester wt) async {
+  await wt.tapAndSettle(find.sdkDropdown());
+  await wt.tapAndSettle(
+    find.dropdownMenuItemWithText(title).first,
+  );
+}
diff --git a/learning/tour-of-beam/frontend/lib/cache/unit_content.dart 
b/learning/tour-of-beam/frontend/lib/cache/unit_content.dart
index e474f499b54..63e5f60e2d9 100644
--- a/learning/tour-of-beam/frontend/lib/cache/unit_content.dart
+++ b/learning/tour-of-beam/frontend/lib/cache/unit_content.dart
@@ -34,7 +34,7 @@ class UnitContentCache extends Cache {
     String unitId,
   ) async {
     final future = _futures[sdkId]?[unitId];
-    if (future == null || _unitContents[sdkId]![unitId] == null) {
+    if (future == null || _unitContents[sdkId]?[unitId] == null) {
       await _loadUnitContent(sdkId, unitId);
     }
 
diff --git a/learning/tour-of-beam/frontend/lib/models/node.dart 
b/learning/tour-of-beam/frontend/lib/models/node.dart
index 9450ad073b2..1780bdef1d1 100644
--- a/learning/tour-of-beam/frontend/lib/models/node.dart
+++ b/learning/tour-of-beam/frontend/lib/models/node.dart
@@ -16,6 +16,8 @@
  * limitations under the License.
  */
 
+import 'package:equatable/equatable.dart';
+
 import '../repositories/models/node.dart';
 import '../repositories/models/node_type_enum.dart';
 import 'group.dart';
@@ -23,7 +25,7 @@ import 'parent_node.dart';
 import 'unit.dart';
 
 /// The data class for any Tour of Beam node of a content tree.
-abstract class NodeModel {
+abstract class NodeModel with EquatableMixin {
   final String id;
   final String title;
   final NodeModel? parent;
@@ -60,6 +62,13 @@ abstract class NodeModel {
     }
   }
 
+  @override
+  List<Object?> get props => [
+        id,
+        title,
+        parent,
+      ];
+
   NodeModel? getLastNodeFromBreadcrumbIds(List<String> breadcrumbIds);
 
   List<UnitModel> getUnits();
diff --git a/learning/tour-of-beam/frontend/lib/pages/tour/state.dart 
b/learning/tour-of-beam/frontend/lib/pages/tour/state.dart
index 08b3b092de3..c99df29d4c8 100644
--- a/learning/tour-of-beam/frontend/lib/pages/tour/state.dart
+++ b/learning/tour-of-beam/frontend/lib/pages/tour/state.dart
@@ -30,6 +30,7 @@ import '../../cache/unit_progress.dart';
 import '../../enums/save_code_status.dart';
 import '../../enums/snippet_type.dart';
 import '../../models/event_context.dart';
+import '../../models/node.dart';
 import '../../models/unit.dart';
 import '../../models/unit_content.dart';
 import '../../services/analytics/events/unit_closed.dart';
@@ -64,7 +65,6 @@ class TourNotifier extends ChangeNotifier with 
PageStateMixin<void> {
         playgroundController = _createPlaygroundController(initialSdk.id) {
     _appNotifier.sdk ??= initialSdk;
     contentTreeController.addListener(_onUnitChanged);
-    _unitContentCache.addListener(_onUnitChanged);
     _appNotifier.addListener(_onAppNotifierChanged);
     _authNotifier.addListener(_onAuthChanged);
     _saveCodeDebounced = _saveCode.debounced(
@@ -125,10 +125,10 @@ class TourNotifier extends ChangeNotifier with 
PageStateMixin<void> {
   Future<void> _onAppNotifierChanged() async {
     playgroundController.setSdk(currentSdk);
     _listenToCurrentSnippetEditingController();
-
-    await _unitProgressCache.loadUnitProgress(currentSdk);
-    _trySetSnippetType(SnippetType.saved);
-    await _loadSnippetByType();
+    final currentNode = contentTreeController.currentNode;
+    if (currentNode != null) {
+      await _loadUnit(currentNode);
+    }
   }
 
   Future<void> _onUnitChanged() async {
@@ -137,25 +137,29 @@ class TourNotifier extends ChangeNotifier with 
PageStateMixin<void> {
     if (currentNode is! UnitModel) {
       await _emptyPlayground();
     } else {
-      _setUnitContent(null);
-      notifyListeners();
+      await _loadUnit(currentNode);
+    }
+    notifyListeners();
+  }
 
-      final content = await _unitContentCache.getUnitContent(
-        currentSdk.id,
-        currentNode.id,
-      );
+  Future<void> _loadUnit(NodeModel node) async {
+    _setUnitContent(null);
+    notifyListeners();
 
-      _setUnitContent(content);
-      await _unitProgressCache.loadUnitProgress(currentSdk);
+    final content = await _unitContentCache.getUnitContent(
+      currentSdk.id,
+      node.id,
+    );
 
-      if (content != _currentUnitContent) {
-        return; // Changed while waiting.
-      }
+    _setUnitContent(content);
+    await _unitProgressCache.loadUnitProgress(currentSdk);
 
-      _trySetSnippetType(SnippetType.saved);
-      await _loadSnippetByType();
+    if (content != _currentUnitContent) {
+      return; // Changed while waiting.
     }
-    notifyListeners();
+
+    _trySetSnippetType(SnippetType.saved);
+    await _loadSnippetByType();
   }
 
   void _setUnitContent(UnitContentModel? unitContent) {
@@ -378,7 +382,6 @@ class TourNotifier extends ChangeNotifier with 
PageStateMixin<void> {
 
   @override
   Future<void> dispose() async {
-    _unitContentCache.removeListener(_onUnitChanged);
     contentTreeController.removeListener(_onUnitChanged);
     _appNotifier.removeListener(_onAppNotifierChanged);
     _authNotifier.removeListener(_onAuthChanged);
diff --git a/learning/tour-of-beam/frontend/pubspec.lock 
b/learning/tour-of-beam/frontend/pubspec.lock
index 09d418372e4..5cde8a54211 100644
--- a/learning/tour-of-beam/frontend/pubspec.lock
+++ b/learning/tour-of-beam/frontend/pubspec.lock
@@ -1417,4 +1417,4 @@ packages:
     version: "3.1.2"
 sdks:
   dart: ">=3.0.2 <4.0.0"
-  flutter: ">=3.10.2"
+  flutter: ">=3.10.4"
diff --git a/learning/tour-of-beam/frontend/pubspec.yaml 
b/learning/tour-of-beam/frontend/pubspec.yaml
index 45004337ca5..75e699b36f6 100644
--- a/learning/tour-of-beam/frontend/pubspec.yaml
+++ b/learning/tour-of-beam/frontend/pubspec.yaml
@@ -24,7 +24,7 @@ version: 0.1.0
 
 environment:
   sdk: '>=3.0.2 <4.0.0'
-  flutter: '>=3.10.2'
+  flutter: '>=3.10.4'
 
 dependencies:
   app_state: ^0.9.3
diff --git a/playground/frontend/Dockerfile b/playground/frontend/Dockerfile
index 848fc697f30..02f24347f9b 100644
--- a/playground/frontend/Dockerfile
+++ b/playground/frontend/Dockerfile
@@ -17,7 +17,7 @@
 ###############################################################################
 
 FROM debian:11 as build
-ARG FLUTTER_VERSION=3.10.2
+ARG FLUTTER_VERSION=3.10.4
 ARG BUILD_COMMIT_HASH
 ARG BUILD_COMMIT_SECONDS_SINCE_EPOCH
 
diff --git a/playground/frontend/playground_components/pubspec.yaml 
b/playground/frontend/playground_components/pubspec.yaml
index e8212aeee97..e0394dab9f7 100644
--- a/playground/frontend/playground_components/pubspec.yaml
+++ b/playground/frontend/playground_components/pubspec.yaml
@@ -22,7 +22,7 @@ publish_to: none
 
 environment:
   sdk: '>=3.0.2 <4.0.0'
-  flutter: '>=3.10.2'
+  flutter: '>=3.10.4'
 
 dependencies:
   aligned_dialog: ^0.0.6
diff --git a/playground/frontend/playground_components_dev/pubspec.yaml 
b/playground/frontend/playground_components_dev/pubspec.yaml
index 6b54797343c..ae9424b9606 100644
--- a/playground/frontend/playground_components_dev/pubspec.yaml
+++ b/playground/frontend/playground_components_dev/pubspec.yaml
@@ -22,7 +22,7 @@ publish_to: none
 
 environment:
   sdk: '>=3.0.2 <4.0.0'
-  flutter: '>=3.10.2'
+  flutter: '>=3.10.4'
 
 dependencies:
   app_state: ^0.9.3
diff --git a/playground/frontend/pubspec.lock b/playground/frontend/pubspec.lock
index 9da4688d5f3..425e33e4de7 100644
--- a/playground/frontend/pubspec.lock
+++ b/playground/frontend/pubspec.lock
@@ -1377,4 +1377,4 @@ packages:
     version: "3.1.2"
 sdks:
   dart: ">=3.0.2 <4.0.0"
-  flutter: ">=3.10.2"
+  flutter: ">=3.10.4"
diff --git a/playground/frontend/pubspec.yaml b/playground/frontend/pubspec.yaml
index 793773f560e..066ab4aa6ad 100644
--- a/playground/frontend/pubspec.yaml
+++ b/playground/frontend/pubspec.yaml
@@ -22,7 +22,7 @@ version: 1.0.0+1
 
 environment:
   sdk: '>=3.0.2 <4.0.0'
-  flutter: '>=3.10.2'
+  flutter: '>=3.10.4'
 
 dependencies:
   akvelon_flutter_issue_106664_workaround: ^0.1.2

Reply via email to