@_nazmiforreal/flutter-ota 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +1 -1
  2. package/bin/flutter-ota-linux-x64 +0 -0
  3. package/dart-src/packages/cli-tools/.dart_tool/package_config.json +46 -76
  4. package/dart-src/packages/cli-tools/.dart_tool/package_graph.json +140 -166
  5. package/dart-src/packages/cli-tools/README.md +1 -1
  6. package/dart-src/packages/cli-tools/lib/flutter_ota_kit_cli.dart +30 -17
  7. package/dart-src/packages/cli-tools/lib/src/backend.dart +30 -31
  8. package/dart-src/packages/cli-tools/lib/src/cli_base.dart +3 -1
  9. package/dart-src/packages/cli-tools/lib/src/commands/build.dart +44 -43
  10. package/dart-src/packages/cli-tools/lib/src/commands/bundle.dart +265 -239
  11. package/dart-src/packages/cli-tools/lib/src/commands/channel.dart +75 -66
  12. package/dart-src/packages/cli-tools/lib/src/commands/config_command.dart +39 -35
  13. package/dart-src/packages/cli-tools/lib/src/commands/console.dart +30 -27
  14. package/dart-src/packages/cli-tools/lib/src/commands/deploy.dart +88 -72
  15. package/dart-src/packages/cli-tools/lib/src/commands/doctor.dart +66 -29
  16. package/dart-src/packages/cli-tools/lib/src/commands/fingerprint.dart +10 -6
  17. package/dart-src/packages/cli-tools/lib/src/commands/init.dart +299 -190
  18. package/dart-src/packages/cli-tools/lib/src/commands/keys.dart +24 -23
  19. package/dart-src/packages/cli-tools/lib/src/commands/migrate.dart +111 -97
  20. package/dart-src/packages/cli-tools/lib/src/commands/pocketbase.dart +237 -0
  21. package/dart-src/packages/cli-tools/lib/src/commands/rollback.dart +43 -34
  22. package/dart-src/packages/cli-tools/lib/src/commands/storage.dart +57 -53
  23. package/dart-src/packages/cli-tools/lib/src/config.dart +227 -93
  24. package/dart-src/packages/cli-tools/lib/src/operations.dart +9 -8
  25. package/dart-src/packages/cli-tools/lib/src/pack.dart +26 -25
  26. package/dart-src/packages/cli-tools/lib/src/pocketbase/data_bootstrap.dart +39 -0
  27. package/dart-src/packages/cli-tools/lib/src/pocketbase/hooks/bundles.pb.js +56 -0
  28. package/dart-src/packages/cli-tools/lib/src/pocketbase/installer.dart +189 -0
  29. package/dart-src/packages/cli-tools/lib/src/pocketbase/process_manager.dart +123 -0
  30. package/dart-src/packages/cli-tools/lib/src/pocketbase/schema_installer.dart +237 -0
  31. package/dart-src/packages/cli-tools/lib/src/runner.dart +36 -15
  32. package/dart-src/packages/cli-tools/lib/src/sign.dart +13 -5
  33. package/dart-src/packages/cli-tools/lib/src/ui/ui.dart +10 -13
  34. package/dart-src/packages/cli-tools/lib/src/util.dart +3 -1
  35. package/dart-src/packages/cli-tools/pubspec.lock +69 -116
  36. package/dart-src/packages/cli-tools/pubspec.yaml +25 -7
  37. package/dart-src/packages/cli-tools/test/backends_test.dart +62 -32
  38. package/dart-src/packages/cli-tools/test/build_pack_test.dart +4 -4
  39. package/dart-src/packages/cli-tools/test/cli_test.dart +89 -42
  40. package/dart-src/packages/cli-tools/test/mocks/mock_aws_s3_client.dart +8 -13
  41. package/dart-src/packages/cli-tools/test/mocks/mock_d1_client.dart +23 -18
  42. package/dart-src/packages/cli-tools/test/mocks/mock_pocketbase_client.dart +197 -0
  43. package/dart-src/packages/cli-tools/test/mocks/mock_postgres_client.dart +70 -46
  44. package/dart-src/packages/cli-tools/test/pocketbase_installer_test.dart +72 -0
  45. package/dart-src/packages/cli-tools/test/pocketbase_schema_test.dart +107 -0
  46. package/dart-src/packages/cli-tools/test/pocketbase_smoke_test.dart +59 -0
  47. package/dart-src/packages/core/README.md +2 -2
  48. package/dart-src/packages/core/example/lib/main.dart +69 -0
  49. package/dart-src/packages/core/lib/flutter_ota_kit_core.dart +1 -1
  50. package/dart-src/packages/core/lib/src/app_update_info.dart +17 -15
  51. package/dart-src/packages/core/lib/src/bundle.dart +102 -94
  52. package/dart-src/packages/core/lib/src/bundle_artifacts.dart +1 -2
  53. package/dart-src/packages/core/lib/src/bundle_patch_artifact.dart +15 -16
  54. package/dart-src/packages/core/lib/src/changed_asset.dart +24 -22
  55. package/dart-src/packages/core/lib/src/get_bundles_args.dart +13 -13
  56. package/dart-src/packages/core/lib/src/metadata.dart +9 -7
  57. package/dart-src/packages/core/lib/src/patch_info.dart +8 -7
  58. package/dart-src/packages/core/lib/src/platform.dart +4 -3
  59. package/dart-src/packages/core/lib/src/rollout.dart +14 -11
  60. package/dart-src/packages/core/lib/src/semver_range.dart +49 -39
  61. package/dart-src/packages/core/lib/src/semver_version.dart +8 -7
  62. package/dart-src/packages/core/lib/src/status.dart +4 -3
  63. package/dart-src/packages/core/lib/src/update_bundle_params.dart +7 -7
  64. package/dart-src/packages/core/lib/src/uuid.dart +1 -2
  65. package/dart-src/packages/core/pubspec.yaml +6 -7
  66. package/dart-src/packages/core/test/rollout_test.dart +15 -8
  67. package/dart-src/packages/core/test/semver_test.dart +5 -2
  68. package/dart-src/packages/core/test/types_test.dart +26 -24
  69. package/dart-src/packages/core/test/uuid_test.dart +3 -1
  70. package/dart-src/packages/core/tool/dbg.dart +1 -0
  71. package/dart-src/plugins/aws/CHANGELOG.md +6 -0
  72. package/dart-src/plugins/aws/example/lib/main.dart +60 -0
  73. package/dart-src/plugins/aws/lib/flutter_ota_kit_aws.dart +5 -1
  74. package/dart-src/plugins/aws/lib/src/aws_cloudfront_client.dart +11 -16
  75. package/dart-src/plugins/aws/lib/src/aws_cloudfront_signer.dart +7 -2
  76. package/dart-src/plugins/aws/lib/src/aws_database.dart +14 -18
  77. package/dart-src/plugins/aws/lib/src/aws_s3_client.dart +23 -18
  78. package/dart-src/plugins/aws/lib/src/aws_ssm_client.dart +5 -4
  79. package/dart-src/plugins/aws/lib/src/aws_storage.dart +2 -3
  80. package/dart-src/plugins/aws/lib/src/aws_storage_profile.dart +10 -16
  81. package/dart-src/plugins/aws/lib/src/with_cloudfront_signed_url.dart +6 -9
  82. package/dart-src/plugins/aws/pubspec.yaml +15 -10
  83. package/dart-src/plugins/aws/test/aws_database_test.dart +51 -57
  84. package/dart-src/plugins/aws/test/mock_aws_s3_client.dart +8 -13
  85. package/dart-src/plugins/cloudflare/CHANGELOG.md +7 -0
  86. package/dart-src/plugins/cloudflare/example/lib/main.dart +62 -0
  87. package/dart-src/plugins/cloudflare/lib/flutter_ota_kit_cloudflare.dart +4 -2
  88. package/dart-src/plugins/cloudflare/lib/src/cloudflare_worker_database.dart +3 -3
  89. package/dart-src/plugins/cloudflare/lib/src/d1_build_where.dart +3 -2
  90. package/dart-src/plugins/cloudflare/lib/src/d1_bundle_mapper.dart +24 -27
  91. package/dart-src/plugins/cloudflare/lib/src/d1_database_plugin.dart +22 -30
  92. package/dart-src/plugins/cloudflare/lib/src/r2_config.dart +1 -1
  93. package/dart-src/plugins/cloudflare/lib/src/r2_s3_client.dart +21 -29
  94. package/dart-src/plugins/cloudflare/lib/src/r2_storage.dart +7 -7
  95. package/dart-src/plugins/cloudflare/lib/src/r2_storage_profile.dart +7 -15
  96. package/dart-src/plugins/cloudflare/pubspec.yaml +14 -9
  97. package/dart-src/plugins/cloudflare/test/cloudflare_worker_database_test.dart +46 -42
  98. package/dart-src/plugins/cloudflare/test/d1_database_test.dart +100 -90
  99. package/dart-src/plugins/cloudflare/test/mock_d1_client.dart +23 -18
  100. package/dart-src/plugins/cloudflare/test/mock_r2_client.dart +8 -13
  101. package/dart-src/plugins/cloudflare/test/r2_storage_test.dart +1 -4
  102. package/dart-src/plugins/plugin-core/CHANGELOG.md +16 -0
  103. package/dart-src/plugins/plugin-core/example/lib/main.dart +61 -0
  104. package/dart-src/plugins/plugin-core/lib/flutter_ota_kit_plugin_core.dart +3 -7
  105. package/dart-src/plugins/plugin-core/lib/src/asset_storage_layout.dart +5 -5
  106. package/dart-src/plugins/plugin-core/lib/src/bundle_helpers.dart +23 -0
  107. package/dart-src/plugins/plugin-core/lib/src/bundle_storage_layout.dart +16 -10
  108. package/dart-src/plugins/plugin-core/lib/src/bundle_unit_of_work.dart +31 -26
  109. package/dart-src/plugins/plugin-core/lib/src/calculate_pagination.dart +5 -1
  110. package/dart-src/plugins/plugin-core/lib/src/content_addressed_assets.dart +1 -1
  111. package/dart-src/plugins/plugin-core/lib/src/create_blob_database_plugin.dart +78 -71
  112. package/dart-src/plugins/plugin-core/lib/src/create_database_plugin.dart +56 -35
  113. package/dart-src/plugins/plugin-core/lib/src/create_storage_plugin.dart +10 -13
  114. package/dart-src/plugins/plugin-core/lib/src/paginate_bundles.dart +30 -17
  115. package/dart-src/plugins/plugin-core/lib/src/parse_storage_uri.dart +3 -1
  116. package/dart-src/plugins/plugin-core/lib/src/query_bundles.dart +5 -3
  117. package/dart-src/plugins/plugin-core/lib/src/request_update_bundle_state.dart +2 -4
  118. package/dart-src/plugins/plugin-core/lib/src/storage_helpers.dart +18 -0
  119. package/dart-src/plugins/plugin-core/lib/src/types.dart +7 -6
  120. package/dart-src/plugins/plugin-core/pubspec.yaml +12 -9
  121. package/dart-src/plugins/plugin-core/test/asset_storage_layout_test.dart +13 -9
  122. package/dart-src/plugins/plugin-core/test/bundle_unit_of_work_test.dart +28 -15
  123. package/dart-src/plugins/plugin-core/test/create_blob_database_plugin_test.dart +254 -122
  124. package/dart-src/plugins/plugin-core/test/create_database_plugin_test.dart +36 -32
  125. package/dart-src/plugins/plugin-core/test/create_storage_plugin_test.dart +18 -15
  126. package/dart-src/plugins/plugin-core/test/generate_min_bundle_id_test.dart +8 -3
  127. package/dart-src/plugins/plugin-core/test/get_update_info_test.dart +682 -693
  128. package/dart-src/plugins/plugin-core/test/helpers_test.dart +45 -21
  129. package/dart-src/plugins/plugin-core/test/query_bundles_test.dart +76 -13
  130. package/dart-src/plugins/plugin-core/test/uuidv7_test.dart +20 -9
  131. package/dart-src/plugins/pocketbase/CHANGELOG.md +8 -0
  132. package/dart-src/plugins/pocketbase/LICENSE +21 -0
  133. package/dart-src/plugins/pocketbase/README.md +54 -0
  134. package/dart-src/plugins/pocketbase/example/lib/main.dart +62 -0
  135. package/dart-src/plugins/pocketbase/lib/flutter_ota_kit_pocketbase.dart +28 -0
  136. package/dart-src/plugins/pocketbase/lib/src/pocketbase_bundle_mapper.dart +121 -0
  137. package/dart-src/plugins/pocketbase/lib/src/pocketbase_client.dart +349 -0
  138. package/dart-src/plugins/pocketbase/lib/src/pocketbase_config.dart +61 -0
  139. package/dart-src/plugins/pocketbase/lib/src/pocketbase_database.dart +278 -0
  140. package/dart-src/plugins/pocketbase/lib/src/pocketbase_storage.dart +255 -0
  141. package/dart-src/plugins/pocketbase/pubspec.yaml +26 -0
  142. package/dart-src/plugins/pocketbase/test/pb_uri_test.dart +12 -0
  143. package/dart-src/plugins/postgres/CHANGELOG.md +6 -0
  144. package/dart-src/plugins/postgres/example/lib/main.dart +67 -0
  145. package/dart-src/plugins/postgres/lib/flutter_ota_kit_postgres.dart +3 -6
  146. package/dart-src/plugins/postgres/lib/src/postgres_bundle_mapper.dart +32 -52
  147. package/dart-src/plugins/postgres/lib/src/postgres_config.dart +3 -1
  148. package/dart-src/plugins/postgres/lib/src/postgres_database.dart +28 -38
  149. package/dart-src/plugins/postgres/lib/src/postgres_get_update_info.dart +16 -14
  150. package/dart-src/plugins/postgres/lib/src/postgres_storage.dart +26 -14
  151. package/dart-src/plugins/postgres/lib/src/postgres_types.dart +27 -28
  152. package/dart-src/plugins/postgres/pubspec.yaml +14 -9
  153. package/dart-src/plugins/postgres/test/mock_postgres_client.dart +62 -39
  154. package/dart-src/plugins/postgres/test/postgres_bundle_mapper_test.dart +3 -4
  155. package/dart-src/plugins/postgres/test/postgres_database_test.dart +102 -73
  156. package/dart-src/plugins/postgres/test/postgres_storage_runtime_test.dart +60 -0
  157. package/dart-src/plugins/supabase/CHANGELOG.md +17 -0
  158. package/dart-src/plugins/supabase/README.md +2 -2
  159. package/dart-src/plugins/supabase/example/lib/main.dart +63 -0
  160. package/dart-src/plugins/supabase/lib/flutter_ota_kit_supabase.dart +2 -0
  161. package/dart-src/plugins/supabase/lib/src/error_message.dart +11 -0
  162. package/dart-src/plugins/supabase/lib/src/supabase_bundle_mapper.dart +34 -58
  163. package/dart-src/plugins/supabase/lib/src/supabase_client_adapter.dart +3 -13
  164. package/dart-src/plugins/supabase/lib/src/supabase_client_http.dart +34 -52
  165. package/dart-src/plugins/supabase/lib/src/supabase_database.dart +38 -30
  166. package/dart-src/plugins/supabase/lib/src/supabase_edge_function_storage.dart +21 -29
  167. package/dart-src/plugins/supabase/lib/src/supabase_signed_url_batcher.dart +7 -19
  168. package/dart-src/plugins/supabase/lib/src/supabase_storage.dart +18 -29
  169. package/dart-src/plugins/supabase/lib/src/types.dart +26 -26
  170. package/dart-src/plugins/supabase/pubspec.yaml +14 -9
  171. package/dart-src/plugins/supabase/test/mock_supabase_client.dart +57 -57
  172. package/dart-src/plugins/supabase/test/supabase_bundle_mapper_test.dart +30 -27
  173. package/dart-src/plugins/supabase/test/supabase_database_test.dart +26 -35
  174. package/dart-src/plugins/supabase/test/supabase_storage_test.dart +27 -34
  175. package/package.json +2 -2
  176. package/scripts/vendor.sh +1 -1
@@ -15,20 +15,19 @@ Bundle _appVersionBundle({
15
15
  String? message,
16
16
  int? rolloutCohortCount,
17
17
  List<String>? targetCohorts,
18
- }) =>
19
- Bundle(
20
- id: id,
21
- platform: Platform.android,
22
- shouldForceUpdate: shouldForceUpdate,
23
- enabled: enabled,
24
- fileHash: _defaultFileHash,
25
- storageUri: _defaultStorageUri,
26
- channel: channel,
27
- targetAppVersion: targetAppVersion,
28
- message: message ?? _defaultBundleMessage,
29
- rolloutCohortCount: rolloutCohortCount,
30
- targetCohorts: targetCohorts,
31
- );
18
+ }) => Bundle(
19
+ id: id,
20
+ platform: Platform.android,
21
+ shouldForceUpdate: shouldForceUpdate,
22
+ enabled: enabled,
23
+ fileHash: _defaultFileHash,
24
+ storageUri: _defaultStorageUri,
25
+ channel: channel,
26
+ targetAppVersion: targetAppVersion,
27
+ message: message ?? _defaultBundleMessage,
28
+ rolloutCohortCount: rolloutCohortCount,
29
+ targetCohorts: targetCohorts,
30
+ );
32
31
 
33
32
  Bundle _fingerprintBundle({
34
33
  required String id,
@@ -39,20 +38,19 @@ Bundle _fingerprintBundle({
39
38
  String? message,
40
39
  int? rolloutCohortCount,
41
40
  List<String>? targetCohorts,
42
- }) =>
43
- Bundle(
44
- id: id,
45
- platform: Platform.android,
46
- shouldForceUpdate: shouldForceUpdate,
47
- enabled: enabled,
48
- fileHash: _defaultFileHash,
49
- storageUri: _defaultStorageUri,
50
- channel: channel,
51
- fingerprintHash: fingerprintHash,
52
- message: message ?? _defaultBundleMessage,
53
- rolloutCohortCount: rolloutCohortCount,
54
- targetCohorts: targetCohorts,
55
- );
41
+ }) => Bundle(
42
+ id: id,
43
+ platform: Platform.android,
44
+ shouldForceUpdate: shouldForceUpdate,
45
+ enabled: enabled,
46
+ fileHash: _defaultFileHash,
47
+ storageUri: _defaultStorageUri,
48
+ channel: channel,
49
+ fingerprintHash: fingerprintHash,
50
+ message: message ?? _defaultBundleMessage,
51
+ rolloutCohortCount: rolloutCohortCount,
52
+ targetCohorts: targetCohorts,
53
+ );
56
54
 
57
55
  AppVersionGetBundlesArgs _appArgs({
58
56
  String appVersion = '1.0',
@@ -60,15 +58,14 @@ AppVersionGetBundlesArgs _appArgs({
60
58
  String? minBundleId,
61
59
  String channel = 'production',
62
60
  String? cohort,
63
- }) =>
64
- AppVersionGetBundlesArgs(
65
- platform: Platform.android,
66
- bundleId: bundleId,
67
- minBundleId: minBundleId ?? nilUuid,
68
- channel: channel,
69
- cohort: cohort,
70
- appVersion: appVersion,
71
- );
61
+ }) => AppVersionGetBundlesArgs(
62
+ platform: Platform.android,
63
+ bundleId: bundleId,
64
+ minBundleId: minBundleId ?? nilUuid,
65
+ channel: channel,
66
+ cohort: cohort,
67
+ appVersion: appVersion,
68
+ );
72
69
 
73
70
  FingerprintGetBundlesArgs _fpArgs({
74
71
  String fingerprintHash = 'hash1',
@@ -76,15 +73,14 @@ FingerprintGetBundlesArgs _fpArgs({
76
73
  String? minBundleId,
77
74
  String channel = 'production',
78
75
  String? cohort,
79
- }) =>
80
- FingerprintGetBundlesArgs(
81
- platform: Platform.android,
82
- bundleId: bundleId,
83
- minBundleId: minBundleId ?? nilUuid,
84
- channel: channel,
85
- cohort: cohort,
86
- fingerprintHash: fingerprintHash,
87
- );
76
+ }) => FingerprintGetBundlesArgs(
77
+ platform: Platform.android,
78
+ bundleId: bundleId,
79
+ minBundleId: minBundleId ?? nilUuid,
80
+ channel: channel,
81
+ cohort: cohort,
82
+ fingerprintHash: fingerprintHash,
83
+ );
88
84
 
89
85
  // ---------------------------------------------------------------------------
90
86
  // App version strategy
@@ -113,59 +109,65 @@ void main() {
113
109
  expect(update, isNull);
114
110
  });
115
111
 
116
- test('returns null when app version does not qualify for higher version',
117
- () async {
118
- final bundles = [
119
- _appVersionBundle(
120
- id: '00000000-0000-0000-0000-000000000001',
121
- targetAppVersion: '1.1',
122
- ),
123
- ];
124
-
125
- final update = await getUpdateInfo(bundles, _appArgs());
126
- expect(update, isNull);
127
- });
112
+ test(
113
+ 'returns null when app version does not qualify for higher version',
114
+ () async {
115
+ final bundles = [
116
+ _appVersionBundle(
117
+ id: '00000000-0000-0000-0000-000000000001',
118
+ targetAppVersion: '1.1',
119
+ ),
120
+ ];
128
121
 
129
- test('target app version compatibility with available higher version',
130
- () async {
131
- final bundles = [
132
- _appVersionBundle(
133
- id: '01963024-c131-7971-8725-ab47e232df41',
134
- targetAppVersion: '1.0.0',
135
- ),
136
- _appVersionBundle(
137
- id: '01963024-c131-7971-8725-ab47e232df42',
138
- targetAppVersion: '1.0.1',
139
- ),
140
- ];
122
+ final update = await getUpdateInfo(bundles, _appArgs());
123
+ expect(update, isNull);
124
+ },
125
+ );
141
126
 
142
- final update = await getUpdateInfo(
143
- bundles,
144
- _appArgs(bundleId: '01963024-c131-7971-8725-ab47e232df41'),
145
- );
146
- expect(update, isNull);
147
- });
127
+ test(
128
+ 'target app version compatibility with available higher version',
129
+ () async {
130
+ final bundles = [
131
+ _appVersionBundle(
132
+ id: '01963024-c131-7971-8725-ab47e232df41',
133
+ targetAppVersion: '1.0.0',
134
+ ),
135
+ _appVersionBundle(
136
+ id: '01963024-c131-7971-8725-ab47e232df42',
137
+ targetAppVersion: '1.0.1',
138
+ ),
139
+ ];
148
140
 
149
- test('applies update when higher semver-compatible bundle is available',
150
- () async {
151
- final bundles = [
152
- _appVersionBundle(
153
- id: '00000000-0000-0000-0000-000000000001',
154
- targetAppVersion: '1.x.x',
155
- ),
156
- _appVersionBundle(
157
- id: '00000000-0000-0000-0000-000000000002',
158
- targetAppVersion: '1.0',
159
- ),
160
- ];
141
+ final update = await getUpdateInfo(
142
+ bundles,
143
+ _appArgs(bundleId: '01963024-c131-7971-8725-ab47e232df41'),
144
+ );
145
+ expect(update, isNull);
146
+ },
147
+ );
161
148
 
162
- final update = await getUpdateInfo(bundles, _appArgs());
163
- expect(update, isNotNull);
164
- expect(update!.id, '00000000-0000-0000-0000-000000000002');
165
- expect(update.shouldForceUpdate, isFalse);
166
- expect(update.status, UpdateStatus.update);
167
- expect(update.message, 'hello');
168
- });
149
+ test(
150
+ 'applies update when higher semver-compatible bundle is available',
151
+ () async {
152
+ final bundles = [
153
+ _appVersionBundle(
154
+ id: '00000000-0000-0000-0000-000000000001',
155
+ targetAppVersion: '1.x.x',
156
+ ),
157
+ _appVersionBundle(
158
+ id: '00000000-0000-0000-0000-000000000002',
159
+ targetAppVersion: '1.0',
160
+ ),
161
+ ];
162
+
163
+ final update = await getUpdateInfo(bundles, _appArgs());
164
+ expect(update, isNotNull);
165
+ expect(update!.id, '00000000-0000-0000-0000-000000000002');
166
+ expect(update.shouldForceUpdate, isFalse);
167
+ expect(update.status, UpdateStatus.update);
168
+ expect(update.message, 'hello');
169
+ },
170
+ );
169
171
 
170
172
  test('applies update when shouldForceUpdate is true', () async {
171
173
  final bundles = [
@@ -215,27 +217,30 @@ void main() {
215
217
  expect(update.status, UpdateStatus.update);
216
218
  });
217
219
 
218
- test('falls back to older enabled bundle when latest is disabled', () async {
219
- final bundles = [
220
- _appVersionBundle(
221
- id: '00000000-0000-0000-0000-000000000002',
222
- targetAppVersion: '1.0',
223
- shouldForceUpdate: true,
224
- enabled: false,
225
- ),
226
- _appVersionBundle(
227
- id: '00000000-0000-0000-0000-000000000001',
228
- targetAppVersion: '1.0',
229
- shouldForceUpdate: false,
230
- ),
231
- ];
232
-
233
- final update = await getUpdateInfo(bundles, _appArgs());
234
- expect(update, isNotNull);
235
- expect(update!.id, '00000000-0000-0000-0000-000000000001');
236
- expect(update.shouldForceUpdate, isFalse);
237
- expect(update.status, UpdateStatus.update);
238
- });
220
+ test(
221
+ 'falls back to older enabled bundle when latest is disabled',
222
+ () async {
223
+ final bundles = [
224
+ _appVersionBundle(
225
+ id: '00000000-0000-0000-0000-000000000002',
226
+ targetAppVersion: '1.0',
227
+ shouldForceUpdate: true,
228
+ enabled: false,
229
+ ),
230
+ _appVersionBundle(
231
+ id: '00000000-0000-0000-0000-000000000001',
232
+ targetAppVersion: '1.0',
233
+ shouldForceUpdate: false,
234
+ ),
235
+ ];
236
+
237
+ final update = await getUpdateInfo(bundles, _appArgs());
238
+ expect(update, isNotNull);
239
+ expect(update!.id, '00000000-0000-0000-0000-000000000001');
240
+ expect(update.shouldForceUpdate, isFalse);
241
+ expect(update.status, UpdateStatus.update);
242
+ },
243
+ );
239
244
 
240
245
  test('returns null if all bundles are disabled', () async {
241
246
  final bundles = [
@@ -255,24 +260,26 @@ void main() {
255
260
  expect(update, isNull);
256
261
  });
257
262
 
258
- test('rollback if latest bundle is disabled and no other updates enabled',
259
- () async {
260
- final bundles = [
261
- _appVersionBundle(
262
- id: '00000000-0000-0000-0000-000000000002',
263
- targetAppVersion: '1.0',
264
- enabled: false,
265
- ),
266
- _appVersionBundle(
267
- id: '00000000-0000-0000-0000-000000000001',
268
- targetAppVersion: '1.0',
269
- enabled: false,
270
- ),
271
- ];
263
+ test(
264
+ 'rollback if latest bundle is disabled and no other updates enabled',
265
+ () async {
266
+ final bundles = [
267
+ _appVersionBundle(
268
+ id: '00000000-0000-0000-0000-000000000002',
269
+ targetAppVersion: '1.0',
270
+ enabled: false,
271
+ ),
272
+ _appVersionBundle(
273
+ id: '00000000-0000-0000-0000-000000000001',
274
+ targetAppVersion: '1.0',
275
+ enabled: false,
276
+ ),
277
+ ];
272
278
 
273
- final update = await getUpdateInfo(bundles, _appArgs());
274
- expect(update, isNull);
275
- });
279
+ final update = await getUpdateInfo(bundles, _appArgs());
280
+ expect(update, isNull);
281
+ },
282
+ );
276
283
 
277
284
  test('applies update when same-version bundle is available', () async {
278
285
  final bundles = [
@@ -291,18 +298,20 @@ void main() {
291
298
  expect(update.message, 'hi');
292
299
  });
293
300
 
294
- test('forces rollback if no matching bundle exists for provided bundleId',
295
- () async {
296
- final update = await getUpdateInfo(
297
- [],
298
- _appArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
299
- );
300
- expect(update, isNotNull);
301
- expect(update!.id, nilUuid);
302
- expect(update.shouldForceUpdate, isTrue);
303
- expect(update.status, UpdateStatus.rollback);
304
- expect(update.message, isNull);
305
- });
301
+ test(
302
+ 'forces rollback if no matching bundle exists for provided bundleId',
303
+ () async {
304
+ final update = await getUpdateInfo(
305
+ [],
306
+ _appArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
307
+ );
308
+ expect(update, isNotNull);
309
+ expect(update!.id, nilUuid);
310
+ expect(update.shouldForceUpdate, isTrue);
311
+ expect(update.status, UpdateStatus.rollback);
312
+ expect(update.message, isNull);
313
+ },
314
+ );
306
315
 
307
316
  test('returns null if user is already up-to-date', () async {
308
317
  final bundles = [
@@ -341,67 +350,71 @@ void main() {
341
350
  expect(update.status, UpdateStatus.rollback);
342
351
  });
343
352
 
344
- test('selects next available bundle even if shouldForceUpdate is false',
345
- () async {
346
- final bundles = [
347
- _appVersionBundle(
348
- id: '00000000-0000-0000-0000-000000000003',
349
- targetAppVersion: '1.0',
350
- ),
351
- _appVersionBundle(
352
- id: '00000000-0000-0000-0000-000000000002',
353
- targetAppVersion: '1.0',
354
- ),
355
- _appVersionBundle(
356
- id: '00000000-0000-0000-0000-000000000001',
357
- targetAppVersion: '1.0',
358
- ),
359
- ];
353
+ test(
354
+ 'selects next available bundle even if shouldForceUpdate is false',
355
+ () async {
356
+ final bundles = [
357
+ _appVersionBundle(
358
+ id: '00000000-0000-0000-0000-000000000003',
359
+ targetAppVersion: '1.0',
360
+ ),
361
+ _appVersionBundle(
362
+ id: '00000000-0000-0000-0000-000000000002',
363
+ targetAppVersion: '1.0',
364
+ ),
365
+ _appVersionBundle(
366
+ id: '00000000-0000-0000-0000-000000000001',
367
+ targetAppVersion: '1.0',
368
+ ),
369
+ ];
360
370
 
361
- final update = await getUpdateInfo(
362
- bundles,
363
- _appArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
364
- );
365
- expect(update, isNotNull);
366
- expect(update!.id, '00000000-0000-0000-0000-000000000003');
367
- expect(update.shouldForceUpdate, isFalse);
368
- expect(update.status, UpdateStatus.update);
369
- });
371
+ final update = await getUpdateInfo(
372
+ bundles,
373
+ _appArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
374
+ );
375
+ expect(update, isNotNull);
376
+ expect(update!.id, '00000000-0000-0000-0000-000000000003');
377
+ expect(update.shouldForceUpdate, isFalse);
378
+ expect(update.status, UpdateStatus.update);
379
+ },
380
+ );
370
381
 
371
- test('applies highest available bundle even if app version unchanged',
372
- () async {
373
- final bundles = [
374
- _appVersionBundle(
375
- id: '00000000-0000-0000-0000-000000000005',
376
- targetAppVersion: '1.0',
377
- ),
378
- _appVersionBundle(
379
- id: '00000000-0000-0000-0000-000000000004',
380
- targetAppVersion: '1.0',
381
- ),
382
- _appVersionBundle(
383
- id: '00000000-0000-0000-0000-000000000003',
384
- targetAppVersion: '1.0',
385
- ),
386
- _appVersionBundle(
387
- id: '00000000-0000-0000-0000-000000000002',
388
- targetAppVersion: '1.0',
389
- ),
390
- _appVersionBundle(
391
- id: '00000000-0000-0000-0000-000000000001',
392
- targetAppVersion: '1.0',
393
- ),
394
- ];
382
+ test(
383
+ 'applies highest available bundle even if app version unchanged',
384
+ () async {
385
+ final bundles = [
386
+ _appVersionBundle(
387
+ id: '00000000-0000-0000-0000-000000000005',
388
+ targetAppVersion: '1.0',
389
+ ),
390
+ _appVersionBundle(
391
+ id: '00000000-0000-0000-0000-000000000004',
392
+ targetAppVersion: '1.0',
393
+ ),
394
+ _appVersionBundle(
395
+ id: '00000000-0000-0000-0000-000000000003',
396
+ targetAppVersion: '1.0',
397
+ ),
398
+ _appVersionBundle(
399
+ id: '00000000-0000-0000-0000-000000000002',
400
+ targetAppVersion: '1.0',
401
+ ),
402
+ _appVersionBundle(
403
+ id: '00000000-0000-0000-0000-000000000001',
404
+ targetAppVersion: '1.0',
405
+ ),
406
+ ];
395
407
 
396
- final update = await getUpdateInfo(
397
- bundles,
398
- _appArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
399
- );
400
- expect(update, isNotNull);
401
- expect(update!.id, '00000000-0000-0000-0000-000000000005');
402
- expect(update.shouldForceUpdate, isFalse);
403
- expect(update.status, UpdateStatus.update);
404
- });
408
+ final update = await getUpdateInfo(
409
+ bundles,
410
+ _appArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
411
+ );
412
+ expect(update, isNotNull);
413
+ expect(update!.id, '00000000-0000-0000-0000-000000000005');
414
+ expect(update.shouldForceUpdate, isFalse);
415
+ expect(update.status, UpdateStatus.update);
416
+ },
417
+ );
405
418
 
406
419
  test('returns null if newest matching bundle is disabled', () async {
407
420
  final bundles = [
@@ -493,34 +506,35 @@ void main() {
493
506
  expect(update, isNull);
494
507
  });
495
508
 
496
- test('returns bundle when available bundle higher than minBundleId',
497
- () async {
498
- final bundles = [
499
- _appVersionBundle(
500
- id: '0195715d-42db-7475-9204-31819efc2f1d',
501
- targetAppVersion: '1.0',
502
- ),
503
- _appVersionBundle(
504
- id: '0195715a-ce29-7c55-97d3-53af4fe369b7',
505
- targetAppVersion: '1.0',
506
- ),
507
- ];
509
+ test(
510
+ 'returns bundle when available bundle higher than minBundleId',
511
+ () async {
512
+ final bundles = [
513
+ _appVersionBundle(
514
+ id: '0195715d-42db-7475-9204-31819efc2f1d',
515
+ targetAppVersion: '1.0',
516
+ ),
517
+ _appVersionBundle(
518
+ id: '0195715a-ce29-7c55-97d3-53af4fe369b7',
519
+ targetAppVersion: '1.0',
520
+ ),
521
+ ];
508
522
 
509
- final update = await getUpdateInfo(
510
- bundles,
511
- _appArgs(
512
- minBundleId: '0195715b-9591-7000-8000-000000000000',
513
- bundleId: '0195715b-9591-7000-8000-000000000000',
514
- ),
515
- );
516
- expect(update, isNotNull);
517
- expect(update!.id, '0195715d-42db-7475-9204-31819efc2f1d');
518
- expect(update.shouldForceUpdate, isFalse);
519
- expect(update.status, UpdateStatus.update);
520
- });
523
+ final update = await getUpdateInfo(
524
+ bundles,
525
+ _appArgs(
526
+ minBundleId: '0195715b-9591-7000-8000-000000000000',
527
+ bundleId: '0195715b-9591-7000-8000-000000000000',
528
+ ),
529
+ );
530
+ expect(update, isNotNull);
531
+ expect(update!.id, '0195715d-42db-7475-9204-31819efc2f1d');
532
+ expect(update.shouldForceUpdate, isFalse);
533
+ expect(update.status, UpdateStatus.update);
534
+ },
535
+ );
521
536
 
522
- test('rollback when current bundle disabled and only bundles below minBundleId',
523
- () async {
537
+ test('rollback when current bundle disabled and only bundles below minBundleId', () async {
524
538
  final bundles = [
525
539
  _appVersionBundle(
526
540
  id: '0195715d-42db-7475-9204-31819efc2f1d',
@@ -546,83 +560,88 @@ void main() {
546
560
  expect(update.status, UpdateStatus.rollback);
547
561
  });
548
562
 
549
- test('rollback when current bundle does not exist and only below minBundleId',
550
- () async {
551
- final bundles = [
552
- _appVersionBundle(
553
- id: '0195715a-ce29-7c55-97d3-53af4fe369b7',
554
- targetAppVersion: '1.0',
555
- ),
556
- ];
563
+ test(
564
+ 'rollback when current bundle does not exist and only below minBundleId',
565
+ () async {
566
+ final bundles = [
567
+ _appVersionBundle(
568
+ id: '0195715a-ce29-7c55-97d3-53af4fe369b7',
569
+ targetAppVersion: '1.0',
570
+ ),
571
+ ];
557
572
 
558
- final update = await getUpdateInfo(
559
- bundles,
560
- _appArgs(
561
- minBundleId: '0195715b-9591-7000-8000-000000000000',
562
- bundleId: '0195715d-42db-7475-9204-31819efc2f1d',
563
- ),
564
- );
565
- expect(update, isNotNull);
566
- expect(update!.id, nilUuid);
567
- expect(update.shouldForceUpdate, isTrue);
568
- expect(update.status, UpdateStatus.rollback);
569
- });
573
+ final update = await getUpdateInfo(
574
+ bundles,
575
+ _appArgs(
576
+ minBundleId: '0195715b-9591-7000-8000-000000000000',
577
+ bundleId: '0195715d-42db-7475-9204-31819efc2f1d',
578
+ ),
579
+ );
580
+ expect(update, isNotNull);
581
+ expect(update!.id, nilUuid);
582
+ expect(update.shouldForceUpdate, isTrue);
583
+ expect(update.status, UpdateStatus.rollback);
584
+ },
585
+ );
570
586
 
571
- test('returns null when current bundle enabled and no updates available',
572
- () async {
573
- final bundles = [
574
- _appVersionBundle(
575
- id: '0195715d-42db-7475-9204-31819efc2f1d',
576
- targetAppVersion: '1.0',
577
- ),
578
- _appVersionBundle(
579
- id: '0195715a-ce29-7c55-97d3-53af4fe369b7',
580
- targetAppVersion: '1.0',
581
- ),
582
- ];
587
+ test(
588
+ 'returns null when current bundle enabled and no updates available',
589
+ () async {
590
+ final bundles = [
591
+ _appVersionBundle(
592
+ id: '0195715d-42db-7475-9204-31819efc2f1d',
593
+ targetAppVersion: '1.0',
594
+ ),
595
+ _appVersionBundle(
596
+ id: '0195715a-ce29-7c55-97d3-53af4fe369b7',
597
+ targetAppVersion: '1.0',
598
+ ),
599
+ ];
583
600
 
584
- final update = await getUpdateInfo(
585
- bundles,
586
- _appArgs(
587
- minBundleId: '0195715b-9591-7000-8000-000000000000',
588
- bundleId: '0195715d-42db-7475-9204-31819efc2f1d',
589
- ),
590
- );
591
- expect(update, isNull);
592
- });
601
+ final update = await getUpdateInfo(
602
+ bundles,
603
+ _appArgs(
604
+ minBundleId: '0195715b-9591-7000-8000-000000000000',
605
+ bundleId: '0195715d-42db-7475-9204-31819efc2f1d',
606
+ ),
607
+ );
608
+ expect(update, isNull);
609
+ },
610
+ );
593
611
 
594
- test('rollback when current bundle does not exist and all below minBundleId',
595
- () async {
596
- final bundles = [
597
- _appVersionBundle(
598
- id: '01957165-bee7-7df3-a25d-6686f01b02ba',
599
- targetAppVersion: '1.0',
600
- ),
601
- _appVersionBundle(
602
- id: '01957165-19fb-75af-a361-131c17a65ef2',
603
- targetAppVersion: '1.0',
604
- ),
605
- _appVersionBundle(
606
- id: '01957164-fbc6-785f-98ce-a6ae459f6e4f',
607
- targetAppVersion: '1.0',
608
- ),
609
- ];
612
+ test(
613
+ 'rollback when current bundle does not exist and all below minBundleId',
614
+ () async {
615
+ final bundles = [
616
+ _appVersionBundle(
617
+ id: '01957165-bee7-7df3-a25d-6686f01b02ba',
618
+ targetAppVersion: '1.0',
619
+ ),
620
+ _appVersionBundle(
621
+ id: '01957165-19fb-75af-a361-131c17a65ef2',
622
+ targetAppVersion: '1.0',
623
+ ),
624
+ _appVersionBundle(
625
+ id: '01957164-fbc6-785f-98ce-a6ae459f6e4f',
626
+ targetAppVersion: '1.0',
627
+ ),
628
+ ];
610
629
 
611
- final update = await getUpdateInfo(
612
- bundles,
613
- _appArgs(
614
- minBundleId: '01957166-6e63-7000-8000-000000000000',
615
- bundleId: '01957167-0389-7064-8d86-f8af7950daed',
616
- ),
617
- );
618
- expect(update, isNotNull);
619
- expect(update!.id, nilUuid);
620
- expect(update.shouldForceUpdate, isTrue);
621
- expect(update.status, UpdateStatus.rollback);
622
- });
630
+ final update = await getUpdateInfo(
631
+ bundles,
632
+ _appArgs(
633
+ minBundleId: '01957166-6e63-7000-8000-000000000000',
634
+ bundleId: '01957167-0389-7064-8d86-f8af7950daed',
635
+ ),
636
+ );
637
+ expect(update, isNotNull);
638
+ expect(update!.id, nilUuid);
639
+ expect(update.shouldForceUpdate, isTrue);
640
+ expect(update.status, UpdateStatus.rollback);
641
+ },
642
+ );
623
643
 
624
- test('rollback to bundle when current does not exist and bundle between minBundleId and bundleId',
625
- () async {
644
+ test('rollback to bundle when current does not exist and bundle between minBundleId and bundleId', () async {
626
645
  final bundles = [
627
646
  _appVersionBundle(
628
647
  id: '0195716c-82f5-7e5e-ac8c-d4fbf5bc7555',
@@ -702,10 +721,7 @@ void main() {
702
721
  ),
703
722
  ];
704
723
 
705
- final update = await getUpdateInfo(
706
- bundles,
707
- _appArgs(channel: 'beta'),
708
- );
724
+ final update = await getUpdateInfo(bundles, _appArgs(channel: 'beta'));
709
725
  expect(update, isNotNull);
710
726
  expect(update!.id, '00000000-0000-0000-0000-000000000001');
711
727
  expect(update.message, 'hello');
@@ -713,37 +729,42 @@ void main() {
713
729
  expect(update.status, UpdateStatus.update);
714
730
  });
715
731
 
716
- test('returns null when minBundleId is greater than current bundle', () async {
717
- final bundles = [
718
- _appVersionBundle(
719
- id: '01957b63-7d11-7281-b8e7-1120ccfdb8ab',
720
- targetAppVersion: '1.0',
721
- ),
722
- ];
732
+ test(
733
+ 'returns null when minBundleId is greater than current bundle',
734
+ () async {
735
+ final bundles = [
736
+ _appVersionBundle(
737
+ id: '01957b63-7d11-7281-b8e7-1120ccfdb8ab',
738
+ targetAppVersion: '1.0',
739
+ ),
740
+ ];
723
741
 
724
- final update = await getUpdateInfo(
725
- bundles,
726
- _appArgs(
727
- bundleId: '01957b63-7d11-7281-b8e7-1120ccfdb8ab',
728
- minBundleId: '01957bb4-b13c-7000-8000-000000000000',
729
- ),
730
- );
731
- expect(update, isNull);
732
- });
742
+ final update = await getUpdateInfo(
743
+ bundles,
744
+ _appArgs(
745
+ bundleId: '01957b63-7d11-7281-b8e7-1120ccfdb8ab',
746
+ minBundleId: '01957bb4-b13c-7000-8000-000000000000',
747
+ ),
748
+ );
749
+ expect(update, isNull);
750
+ },
751
+ );
733
752
 
734
- test('returns null when no bundles and minBundleId equals bundleId', () async {
735
- final update = await getUpdateInfo(
736
- [],
737
- _appArgs(
738
- bundleId: '0195d325-767a-7000-8000-000000000000',
739
- minBundleId: '0195d325-767a-7000-8000-000000000000',
740
- ),
741
- );
742
- expect(update, isNull);
743
- });
753
+ test(
754
+ 'returns null when no bundles and minBundleId equals bundleId',
755
+ () async {
756
+ final update = await getUpdateInfo(
757
+ [],
758
+ _appArgs(
759
+ bundleId: '0195d325-767a-7000-8000-000000000000',
760
+ minBundleId: '0195d325-767a-7000-8000-000000000000',
761
+ ),
762
+ );
763
+ expect(update, isNull);
764
+ },
765
+ );
744
766
 
745
- test('applies update when bundle higher than minBundleId and bundleId equals minBundleId',
746
- () async {
767
+ test('applies update when bundle higher than minBundleId and bundleId equals minBundleId', () async {
747
768
  final bundles = [
748
769
  _appVersionBundle(
749
770
  id: '01963024-c131-7971-8725-ab47e232df40',
@@ -784,24 +805,25 @@ void main() {
784
805
  expect(update.status, UpdateStatus.update);
785
806
  });
786
807
 
787
- test('returns null for bounded range >= 5.7.0 <= 5.7.4 with version 5.7.5',
788
- () async {
789
- final bundles = [
790
- _appVersionBundle(
791
- id: '00000000-0000-0000-0000-000000000001',
792
- targetAppVersion: '>= 5.7.0 <= 5.7.4',
793
- ),
794
- ];
808
+ test(
809
+ 'returns null for bounded range >= 5.7.0 <= 5.7.4 with version 5.7.5',
810
+ () async {
811
+ final bundles = [
812
+ _appVersionBundle(
813
+ id: '00000000-0000-0000-0000-000000000001',
814
+ targetAppVersion: '>= 5.7.0 <= 5.7.4',
815
+ ),
816
+ ];
795
817
 
796
- final update = await getUpdateInfo(
797
- bundles,
798
- _appArgs(appVersion: '5.7.5'),
799
- );
800
- expect(update, isNull);
801
- });
818
+ final update = await getUpdateInfo(
819
+ bundles,
820
+ _appArgs(appVersion: '5.7.5'),
821
+ );
822
+ expect(update, isNull);
823
+ },
824
+ );
802
825
 
803
- test('applies update when many distinct target app versions are compatible',
804
- () async {
826
+ test('applies update when many distinct target app versions are compatible', () async {
805
827
  final bundles = <Bundle>[];
806
828
  for (var index = 0; index < 200; index++) {
807
829
  final bundleNumber = index + 1;
@@ -813,7 +835,10 @@ void main() {
813
835
  );
814
836
  }
815
837
 
816
- final update = await getUpdateInfo(bundles, _appArgs(appVersion: '1.0.0'));
838
+ final update = await getUpdateInfo(
839
+ bundles,
840
+ _appArgs(appVersion: '1.0.0'),
841
+ );
817
842
  expect(update, isNotNull);
818
843
  expect(update!.id, '00000000-0000-0000-0000-000000000200');
819
844
  expect(update.message, 'hello');
@@ -846,46 +871,50 @@ void main() {
846
871
  expect(update, isNull);
847
872
  });
848
873
 
849
- test('fingerprint hash compatibility with available higher version',
850
- () async {
851
- final bundles = [
852
- _fingerprintBundle(
853
- id: '01963024-c131-7971-8725-ab47e232df41',
854
- fingerprintHash: 'hash1',
855
- ),
856
- _fingerprintBundle(
857
- id: '01963024-c131-7971-8725-ab47e232df42',
858
- fingerprintHash: 'hash2',
859
- ),
860
- ];
861
-
862
- final update = await getUpdateInfo(
863
- bundles,
864
- _fpArgs(bundleId: '01963024-c131-7971-8725-ab47e232df41'),
865
- );
866
- expect(update, isNull);
867
- });
874
+ test(
875
+ 'fingerprint hash compatibility with available higher version',
876
+ () async {
877
+ final bundles = [
878
+ _fingerprintBundle(
879
+ id: '01963024-c131-7971-8725-ab47e232df41',
880
+ fingerprintHash: 'hash1',
881
+ ),
882
+ _fingerprintBundle(
883
+ id: '01963024-c131-7971-8725-ab47e232df42',
884
+ fingerprintHash: 'hash2',
885
+ ),
886
+ ];
868
887
 
869
- test('applies update when higher fingerprint-matching bundle available',
870
- () async {
871
- final bundles = [
872
- _fingerprintBundle(
873
- id: '00000000-0000-0000-0000-000000000001',
874
- fingerprintHash: 'hash1',
875
- ),
876
- _fingerprintBundle(
877
- id: '00000000-0000-0000-0000-000000000002',
878
- fingerprintHash: 'hash2',
879
- ),
880
- ];
888
+ final update = await getUpdateInfo(
889
+ bundles,
890
+ _fpArgs(bundleId: '01963024-c131-7971-8725-ab47e232df41'),
891
+ );
892
+ expect(update, isNull);
893
+ },
894
+ );
881
895
 
882
- final update = await getUpdateInfo(bundles, _fpArgs());
883
- expect(update, isNotNull);
884
- expect(update!.id, '00000000-0000-0000-0000-000000000001');
885
- expect(update.shouldForceUpdate, isFalse);
886
- expect(update.status, UpdateStatus.update);
887
- expect(update.message, 'hello');
888
- });
896
+ test(
897
+ 'applies update when higher fingerprint-matching bundle available',
898
+ () async {
899
+ final bundles = [
900
+ _fingerprintBundle(
901
+ id: '00000000-0000-0000-0000-000000000001',
902
+ fingerprintHash: 'hash1',
903
+ ),
904
+ _fingerprintBundle(
905
+ id: '00000000-0000-0000-0000-000000000002',
906
+ fingerprintHash: 'hash2',
907
+ ),
908
+ ];
909
+
910
+ final update = await getUpdateInfo(bundles, _fpArgs());
911
+ expect(update, isNotNull);
912
+ expect(update!.id, '00000000-0000-0000-0000-000000000001');
913
+ expect(update.shouldForceUpdate, isFalse);
914
+ expect(update.status, UpdateStatus.update);
915
+ expect(update.message, 'hello');
916
+ },
917
+ );
889
918
 
890
919
  test('applies update when shouldForceUpdate is true', () async {
891
920
  final bundles = [
@@ -932,51 +961,35 @@ void main() {
932
961
  expect(update!.id, '00000000-0000-0000-0000-000000000005');
933
962
  expect(update.shouldForceUpdate, isFalse);
934
963
  expect(update.message, 'hello');
935
- expect(update.status, UpdateStatus.update);
936
- });
937
-
938
- test('falls back to older enabled bundle when latest is disabled', () async {
939
- final bundles = [
940
- _fingerprintBundle(
941
- id: '00000000-0000-0000-0000-000000000002',
942
- fingerprintHash: 'hash1',
943
- shouldForceUpdate: true,
944
- enabled: false,
945
- ),
946
- _fingerprintBundle(
947
- id: '00000000-0000-0000-0000-000000000001',
948
- fingerprintHash: 'hash1',
949
- shouldForceUpdate: false,
950
- ),
951
- ];
952
-
953
- final update = await getUpdateInfo(bundles, _fpArgs());
954
- expect(update, isNotNull);
955
- expect(update!.id, '00000000-0000-0000-0000-000000000001');
956
- expect(update.shouldForceUpdate, isFalse);
957
- expect(update.status, UpdateStatus.update);
958
- });
959
-
960
- test('returns null if all bundles are disabled', () async {
961
- final bundles = [
962
- _fingerprintBundle(
963
- id: '00000000-0000-0000-0000-000000000002',
964
- fingerprintHash: 'hash1',
965
- enabled: false,
966
- ),
967
- _fingerprintBundle(
968
- id: '00000000-0000-0000-0000-000000000001',
969
- fingerprintHash: 'hash1',
970
- enabled: false,
971
- ),
972
- ];
973
-
974
- final update = await getUpdateInfo(bundles, _fpArgs());
975
- expect(update, isNull);
964
+ expect(update.status, UpdateStatus.update);
976
965
  });
977
966
 
978
- test('rollback if latest bundle is disabled and no other updates enabled',
979
- () async {
967
+ test(
968
+ 'falls back to older enabled bundle when latest is disabled',
969
+ () async {
970
+ final bundles = [
971
+ _fingerprintBundle(
972
+ id: '00000000-0000-0000-0000-000000000002',
973
+ fingerprintHash: 'hash1',
974
+ shouldForceUpdate: true,
975
+ enabled: false,
976
+ ),
977
+ _fingerprintBundle(
978
+ id: '00000000-0000-0000-0000-000000000001',
979
+ fingerprintHash: 'hash1',
980
+ shouldForceUpdate: false,
981
+ ),
982
+ ];
983
+
984
+ final update = await getUpdateInfo(bundles, _fpArgs());
985
+ expect(update, isNotNull);
986
+ expect(update!.id, '00000000-0000-0000-0000-000000000001');
987
+ expect(update.shouldForceUpdate, isFalse);
988
+ expect(update.status, UpdateStatus.update);
989
+ },
990
+ );
991
+
992
+ test('returns null if all bundles are disabled', () async {
980
993
  final bundles = [
981
994
  _fingerprintBundle(
982
995
  id: '00000000-0000-0000-0000-000000000002',
@@ -994,6 +1007,27 @@ void main() {
994
1007
  expect(update, isNull);
995
1008
  });
996
1009
 
1010
+ test(
1011
+ 'rollback if latest bundle is disabled and no other updates enabled',
1012
+ () async {
1013
+ final bundles = [
1014
+ _fingerprintBundle(
1015
+ id: '00000000-0000-0000-0000-000000000002',
1016
+ fingerprintHash: 'hash1',
1017
+ enabled: false,
1018
+ ),
1019
+ _fingerprintBundle(
1020
+ id: '00000000-0000-0000-0000-000000000001',
1021
+ fingerprintHash: 'hash1',
1022
+ enabled: false,
1023
+ ),
1024
+ ];
1025
+
1026
+ final update = await getUpdateInfo(bundles, _fpArgs());
1027
+ expect(update, isNull);
1028
+ },
1029
+ );
1030
+
997
1031
  test('applies update when same-fingerprint bundle is available', () async {
998
1032
  final bundles = [
999
1033
  _fingerprintBundle(
@@ -1011,17 +1045,19 @@ void main() {
1011
1045
  expect(update.message, 'hi');
1012
1046
  });
1013
1047
 
1014
- test('forces rollback if no matching bundle exists for provided bundleId',
1015
- () async {
1016
- final update = await getUpdateInfo(
1017
- [],
1018
- _appArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
1019
- );
1020
- expect(update, isNotNull);
1021
- expect(update!.id, nilUuid);
1022
- expect(update.shouldForceUpdate, isTrue);
1023
- expect(update.status, UpdateStatus.rollback);
1024
- });
1048
+ test(
1049
+ 'forces rollback if no matching bundle exists for provided bundleId',
1050
+ () async {
1051
+ final update = await getUpdateInfo(
1052
+ [],
1053
+ _appArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
1054
+ );
1055
+ expect(update, isNotNull);
1056
+ expect(update!.id, nilUuid);
1057
+ expect(update.shouldForceUpdate, isTrue);
1058
+ expect(update.status, UpdateStatus.rollback);
1059
+ },
1060
+ );
1025
1061
 
1026
1062
  test('returns null if user is already up-to-date', () async {
1027
1063
  final bundles = [
@@ -1060,67 +1096,71 @@ void main() {
1060
1096
  expect(update.status, UpdateStatus.rollback);
1061
1097
  });
1062
1098
 
1063
- test('selects next available bundle even if shouldForceUpdate is false',
1064
- () async {
1065
- final bundles = [
1066
- _fingerprintBundle(
1067
- id: '00000000-0000-0000-0000-000000000003',
1068
- fingerprintHash: 'hash1',
1069
- ),
1070
- _fingerprintBundle(
1071
- id: '00000000-0000-0000-0000-000000000002',
1072
- fingerprintHash: 'hash1',
1073
- ),
1074
- _fingerprintBundle(
1075
- id: '00000000-0000-0000-0000-000000000001',
1076
- fingerprintHash: 'hash1',
1077
- ),
1078
- ];
1099
+ test(
1100
+ 'selects next available bundle even if shouldForceUpdate is false',
1101
+ () async {
1102
+ final bundles = [
1103
+ _fingerprintBundle(
1104
+ id: '00000000-0000-0000-0000-000000000003',
1105
+ fingerprintHash: 'hash1',
1106
+ ),
1107
+ _fingerprintBundle(
1108
+ id: '00000000-0000-0000-0000-000000000002',
1109
+ fingerprintHash: 'hash1',
1110
+ ),
1111
+ _fingerprintBundle(
1112
+ id: '00000000-0000-0000-0000-000000000001',
1113
+ fingerprintHash: 'hash1',
1114
+ ),
1115
+ ];
1079
1116
 
1080
- final update = await getUpdateInfo(
1081
- bundles,
1082
- _fpArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
1083
- );
1084
- expect(update, isNotNull);
1085
- expect(update!.id, '00000000-0000-0000-0000-000000000003');
1086
- expect(update.shouldForceUpdate, isFalse);
1087
- expect(update.status, UpdateStatus.update);
1088
- });
1117
+ final update = await getUpdateInfo(
1118
+ bundles,
1119
+ _fpArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
1120
+ );
1121
+ expect(update, isNotNull);
1122
+ expect(update!.id, '00000000-0000-0000-0000-000000000003');
1123
+ expect(update.shouldForceUpdate, isFalse);
1124
+ expect(update.status, UpdateStatus.update);
1125
+ },
1126
+ );
1089
1127
 
1090
- test('applies highest available bundle even if fingerprint unchanged',
1091
- () async {
1092
- final bundles = [
1093
- _fingerprintBundle(
1094
- id: '00000000-0000-0000-0000-000000000005',
1095
- fingerprintHash: 'hash1',
1096
- ),
1097
- _fingerprintBundle(
1098
- id: '00000000-0000-0000-0000-000000000004',
1099
- fingerprintHash: 'hash1',
1100
- ),
1101
- _fingerprintBundle(
1102
- id: '00000000-0000-0000-0000-000000000003',
1103
- fingerprintHash: 'hash1',
1104
- ),
1105
- _fingerprintBundle(
1106
- id: '00000000-0000-0000-0000-000000000002',
1107
- fingerprintHash: 'hash1',
1108
- ),
1109
- _fingerprintBundle(
1110
- id: '00000000-0000-0000-0000-000000000001',
1111
- fingerprintHash: 'hash1',
1112
- ),
1113
- ];
1128
+ test(
1129
+ 'applies highest available bundle even if fingerprint unchanged',
1130
+ () async {
1131
+ final bundles = [
1132
+ _fingerprintBundle(
1133
+ id: '00000000-0000-0000-0000-000000000005',
1134
+ fingerprintHash: 'hash1',
1135
+ ),
1136
+ _fingerprintBundle(
1137
+ id: '00000000-0000-0000-0000-000000000004',
1138
+ fingerprintHash: 'hash1',
1139
+ ),
1140
+ _fingerprintBundle(
1141
+ id: '00000000-0000-0000-0000-000000000003',
1142
+ fingerprintHash: 'hash1',
1143
+ ),
1144
+ _fingerprintBundle(
1145
+ id: '00000000-0000-0000-0000-000000000002',
1146
+ fingerprintHash: 'hash1',
1147
+ ),
1148
+ _fingerprintBundle(
1149
+ id: '00000000-0000-0000-0000-000000000001',
1150
+ fingerprintHash: 'hash1',
1151
+ ),
1152
+ ];
1114
1153
 
1115
- final update = await getUpdateInfo(
1116
- bundles,
1117
- _fpArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
1118
- );
1119
- expect(update, isNotNull);
1120
- expect(update!.id, '00000000-0000-0000-0000-000000000005');
1121
- expect(update.shouldForceUpdate, isFalse);
1122
- expect(update.status, UpdateStatus.update);
1123
- });
1154
+ final update = await getUpdateInfo(
1155
+ bundles,
1156
+ _fpArgs(bundleId: '00000000-0000-0000-0000-000000000002'),
1157
+ );
1158
+ expect(update, isNotNull);
1159
+ expect(update!.id, '00000000-0000-0000-0000-000000000005');
1160
+ expect(update.shouldForceUpdate, isFalse);
1161
+ expect(update.status, UpdateStatus.update);
1162
+ },
1163
+ );
1124
1164
  });
1125
1165
 
1126
1166
  // ---------------------------------------------------------------------------
@@ -1134,10 +1174,7 @@ void main() {
1134
1174
  rolloutCohortCount: 0,
1135
1175
  );
1136
1176
 
1137
- final update = await getUpdateInfo(
1138
- [bundle],
1139
- _appArgs(cohort: '1'),
1140
- );
1177
+ final update = await getUpdateInfo([bundle], _appArgs(cohort: '1'));
1141
1178
  expect(update, isNull);
1142
1179
  });
1143
1180
 
@@ -1148,10 +1185,7 @@ void main() {
1148
1185
  rolloutCohortCount: 1000,
1149
1186
  );
1150
1187
 
1151
- final update = await getUpdateInfo(
1152
- [bundle],
1153
- _appArgs(cohort: '1'),
1154
- );
1188
+ final update = await getUpdateInfo([bundle], _appArgs(cohort: '1'));
1155
1189
  expect(update, isNotNull);
1156
1190
  expect(update!.id, bundle.id);
1157
1191
  expect(update.shouldForceUpdate, isFalse);
@@ -1165,10 +1199,7 @@ void main() {
1165
1199
  rolloutCohortCount: null,
1166
1200
  );
1167
1201
 
1168
- final update = await getUpdateInfo(
1169
- [bundle],
1170
- _appArgs(cohort: '1'),
1171
- );
1202
+ final update = await getUpdateInfo([bundle], _appArgs(cohort: '1'));
1172
1203
  expect(update, isNotNull);
1173
1204
  expect(update!.id, bundle.id);
1174
1205
  expect(update.shouldForceUpdate, isFalse);
@@ -1182,10 +1213,9 @@ void main() {
1182
1213
  rolloutCohortCount: 1000,
1183
1214
  );
1184
1215
 
1185
- final update = await getUpdateInfo(
1186
- [bundle],
1187
- _appArgs(cohort: 'qa-group'),
1188
- );
1216
+ final update = await getUpdateInfo([
1217
+ bundle,
1218
+ ], _appArgs(cohort: 'qa-group'));
1189
1219
  expect(update, isNull);
1190
1220
  });
1191
1221
 
@@ -1197,42 +1227,44 @@ void main() {
1197
1227
  targetCohorts: ['qa-group'],
1198
1228
  );
1199
1229
 
1200
- final update = await getUpdateInfo(
1201
- [bundle],
1202
- _appArgs(cohort: 'qa-group'),
1203
- );
1230
+ final update = await getUpdateInfo([
1231
+ bundle,
1232
+ ], _appArgs(cohort: 'qa-group'));
1204
1233
  expect(update, isNotNull);
1205
1234
  expect(update!.id, bundle.id);
1206
1235
  expect(update.shouldForceUpdate, isFalse);
1207
1236
  expect(update.status, UpdateStatus.update);
1208
1237
  });
1209
1238
 
1210
- test('keeps numeric rollout active when targetCohorts are configured',
1211
- () async {
1212
- final bundleId = '00000000-0000-0000-0000-000000000022';
1213
- final eligibleCohort = _findNumericCohort(bundleId, (pos) => pos < 200);
1239
+ test(
1240
+ 'keeps numeric rollout active when targetCohorts are configured',
1241
+ () async {
1242
+ final bundleId = '00000000-0000-0000-0000-000000000022';
1243
+ final eligibleCohort = _findNumericCohort(bundleId, (pos) => pos < 200);
1214
1244
 
1215
- final bundle = _appVersionBundle(
1216
- id: bundleId,
1217
- targetAppVersion: '1.0',
1218
- rolloutCohortCount: 200,
1219
- targetCohorts: ['qa-group'],
1220
- );
1245
+ final bundle = _appVersionBundle(
1246
+ id: bundleId,
1247
+ targetAppVersion: '1.0',
1248
+ rolloutCohortCount: 200,
1249
+ targetCohorts: ['qa-group'],
1250
+ );
1221
1251
 
1222
- final update = await getUpdateInfo(
1223
- [bundle],
1224
- _appArgs(cohort: eligibleCohort),
1225
- );
1226
- expect(update, isNotNull);
1227
- expect(update!.id, bundle.id);
1228
- expect(update.shouldForceUpdate, isFalse);
1229
- expect(update.status, UpdateStatus.update);
1230
- });
1252
+ final update = await getUpdateInfo([
1253
+ bundle,
1254
+ ], _appArgs(cohort: eligibleCohort));
1255
+ expect(update, isNotNull);
1256
+ expect(update!.id, bundle.id);
1257
+ expect(update.shouldForceUpdate, isFalse);
1258
+ expect(update.status, UpdateStatus.update);
1259
+ },
1260
+ );
1231
1261
 
1232
1262
  test('includes targeted numeric cohorts outside the rollout set', () async {
1233
1263
  final bundleId = '00000000-0000-0000-0000-000000000023';
1234
- final targetedNumericCohort =
1235
- _findNumericCohort(bundleId, (pos) => pos >= 200);
1264
+ final targetedNumericCohort = _findNumericCohort(
1265
+ bundleId,
1266
+ (pos) => pos >= 200,
1267
+ );
1236
1268
 
1237
1269
  final bundle = _appVersionBundle(
1238
1270
  id: bundleId,
@@ -1241,69 +1273,59 @@ void main() {
1241
1273
  targetCohorts: [targetedNumericCohort],
1242
1274
  );
1243
1275
 
1244
- final update = await getUpdateInfo(
1245
- [bundle],
1246
- _appArgs(cohort: targetedNumericCohort),
1247
- );
1276
+ final update = await getUpdateInfo([
1277
+ bundle,
1278
+ ], _appArgs(cohort: targetedNumericCohort));
1248
1279
  expect(update, isNotNull);
1249
1280
  expect(update!.id, bundle.id);
1250
1281
  expect(update.shouldForceUpdate, isFalse);
1251
1282
  expect(update.status, UpdateStatus.update);
1252
1283
  });
1253
1284
 
1254
- test('returns latest eligible update when newer bundle targets different cohort',
1255
- () async {
1285
+ test('returns latest eligible update when newer bundle targets different cohort', () async {
1256
1286
  final eligibleBundleId = '00000000-0000-0000-0000-000000000020';
1257
1287
  final blockedBundleId = '00000000-0000-0000-0000-000000000021';
1258
- final eligibleCohort =
1259
- _findNumericCohort(eligibleBundleId, (pos) => pos < 200);
1260
-
1261
- final update = await getUpdateInfo(
1262
- [
1263
- _appVersionBundle(
1264
- id: eligibleBundleId,
1265
- targetAppVersion: '1.0',
1266
- rolloutCohortCount: 200,
1267
- ),
1268
- _appVersionBundle(
1269
- id: blockedBundleId,
1270
- targetAppVersion: '1.0',
1271
- rolloutCohortCount: 0,
1272
- targetCohorts: ['qa-group'],
1273
- ),
1274
- ],
1275
- _appArgs(cohort: eligibleCohort),
1288
+ final eligibleCohort = _findNumericCohort(
1289
+ eligibleBundleId,
1290
+ (pos) => pos < 200,
1276
1291
  );
1292
+
1293
+ final update = await getUpdateInfo([
1294
+ _appVersionBundle(
1295
+ id: eligibleBundleId,
1296
+ targetAppVersion: '1.0',
1297
+ rolloutCohortCount: 200,
1298
+ ),
1299
+ _appVersionBundle(
1300
+ id: blockedBundleId,
1301
+ targetAppVersion: '1.0',
1302
+ rolloutCohortCount: 0,
1303
+ targetCohorts: ['qa-group'],
1304
+ ),
1305
+ ], _appArgs(cohort: eligibleCohort));
1277
1306
  expect(update, isNotNull);
1278
1307
  expect(update!.id, eligibleBundleId);
1279
1308
  expect(update.shouldForceUpdate, isFalse);
1280
1309
  expect(update.status, UpdateStatus.update);
1281
1310
  });
1282
1311
 
1283
- test('re-evaluates current bundle eligibility and rolls back',
1284
- () async {
1312
+ test('re-evaluates current bundle eligibility and rolls back', () async {
1285
1313
  final previousBundleId = '00000000-0000-0000-0000-000000000020';
1286
1314
  final currentBundleId = '00000000-0000-0000-0000-000000000021';
1287
1315
 
1288
- final update = await getUpdateInfo(
1289
- [
1290
- _appVersionBundle(
1291
- id: previousBundleId,
1292
- targetAppVersion: '1.0',
1293
- rolloutCohortCount: 1000,
1294
- ),
1295
- _appVersionBundle(
1296
- id: currentBundleId,
1297
- targetAppVersion: '1.0',
1298
- rolloutCohortCount: 0,
1299
- targetCohorts: ['qa-group'],
1300
- ),
1301
- ],
1302
- _appArgs(
1303
- bundleId: currentBundleId,
1304
- cohort: '1',
1316
+ final update = await getUpdateInfo([
1317
+ _appVersionBundle(
1318
+ id: previousBundleId,
1319
+ targetAppVersion: '1.0',
1320
+ rolloutCohortCount: 1000,
1305
1321
  ),
1306
- );
1322
+ _appVersionBundle(
1323
+ id: currentBundleId,
1324
+ targetAppVersion: '1.0',
1325
+ rolloutCohortCount: 0,
1326
+ targetCohorts: ['qa-group'],
1327
+ ),
1328
+ ], _appArgs(bundleId: currentBundleId, cohort: '1'));
1307
1329
  expect(update, isNotNull);
1308
1330
  expect(update!.id, previousBundleId);
1309
1331
  expect(update.shouldForceUpdate, isTrue);
@@ -1313,20 +1335,14 @@ void main() {
1313
1335
  test('re-evaluates eligibility and falls back to init bundle', () async {
1314
1336
  final currentBundleId = '00000000-0000-0000-0000-000000000021';
1315
1337
 
1316
- final update = await getUpdateInfo(
1317
- [
1318
- _appVersionBundle(
1319
- id: currentBundleId,
1320
- targetAppVersion: '1.0',
1321
- rolloutCohortCount: 0,
1322
- targetCohorts: ['qa-group'],
1323
- ),
1324
- ],
1325
- _appArgs(
1326
- bundleId: currentBundleId,
1327
- cohort: '1',
1338
+ final update = await getUpdateInfo([
1339
+ _appVersionBundle(
1340
+ id: currentBundleId,
1341
+ targetAppVersion: '1.0',
1342
+ rolloutCohortCount: 0,
1343
+ targetCohorts: ['qa-group'],
1328
1344
  ),
1329
- );
1345
+ ], _appArgs(bundleId: currentBundleId, cohort: '1'));
1330
1346
  expect(update, isNotNull);
1331
1347
  expect(update!.id, nilUuid);
1332
1348
  expect(update.shouldForceUpdate, isTrue);
@@ -1366,10 +1382,7 @@ void main() {
1366
1382
  rolloutCohortCount: 0,
1367
1383
  );
1368
1384
 
1369
- final update = await getUpdateInfo(
1370
- [bundle],
1371
- _fpArgs(cohort: '1'),
1372
- );
1385
+ final update = await getUpdateInfo([bundle], _fpArgs(cohort: '1'));
1373
1386
  expect(update, isNull);
1374
1387
  });
1375
1388
 
@@ -1380,10 +1393,7 @@ void main() {
1380
1393
  rolloutCohortCount: 1000,
1381
1394
  );
1382
1395
 
1383
- final update = await getUpdateInfo(
1384
- [bundle],
1385
- _fpArgs(cohort: '1'),
1386
- );
1396
+ final update = await getUpdateInfo([bundle], _fpArgs(cohort: '1'));
1387
1397
  expect(update, isNotNull);
1388
1398
  expect(update!.id, bundle.id);
1389
1399
  expect(update.shouldForceUpdate, isFalse);
@@ -1397,10 +1407,7 @@ void main() {
1397
1407
  rolloutCohortCount: null,
1398
1408
  );
1399
1409
 
1400
- final update = await getUpdateInfo(
1401
- [bundle],
1402
- _fpArgs(cohort: '1'),
1403
- );
1410
+ final update = await getUpdateInfo([bundle], _fpArgs(cohort: '1'));
1404
1411
  expect(update, isNotNull);
1405
1412
  expect(update!.id, bundle.id);
1406
1413
  expect(update.shouldForceUpdate, isFalse);
@@ -1414,10 +1421,7 @@ void main() {
1414
1421
  rolloutCohortCount: 1000,
1415
1422
  );
1416
1423
 
1417
- final update = await getUpdateInfo(
1418
- [bundle],
1419
- _fpArgs(cohort: 'qa-group'),
1420
- );
1424
+ final update = await getUpdateInfo([bundle], _fpArgs(cohort: 'qa-group'));
1421
1425
  expect(update, isNull);
1422
1426
  });
1423
1427
 
@@ -1429,42 +1433,42 @@ void main() {
1429
1433
  targetCohorts: ['qa-group'],
1430
1434
  );
1431
1435
 
1432
- final update = await getUpdateInfo(
1433
- [bundle],
1434
- _fpArgs(cohort: 'qa-group'),
1435
- );
1436
+ final update = await getUpdateInfo([bundle], _fpArgs(cohort: 'qa-group'));
1436
1437
  expect(update, isNotNull);
1437
1438
  expect(update!.id, bundle.id);
1438
1439
  expect(update.shouldForceUpdate, isFalse);
1439
1440
  expect(update.status, UpdateStatus.update);
1440
1441
  });
1441
1442
 
1442
- test('keeps numeric rollout active when targetCohorts are configured',
1443
- () async {
1444
- final bundleId = '00000000-0000-0000-0000-000000000022';
1445
- final eligibleCohort = _findNumericCohort(bundleId, (pos) => pos < 200);
1443
+ test(
1444
+ 'keeps numeric rollout active when targetCohorts are configured',
1445
+ () async {
1446
+ final bundleId = '00000000-0000-0000-0000-000000000022';
1447
+ final eligibleCohort = _findNumericCohort(bundleId, (pos) => pos < 200);
1446
1448
 
1447
- final bundle = _fingerprintBundle(
1448
- id: bundleId,
1449
- fingerprintHash: 'hash1',
1450
- rolloutCohortCount: 200,
1451
- targetCohorts: ['qa-group'],
1452
- );
1449
+ final bundle = _fingerprintBundle(
1450
+ id: bundleId,
1451
+ fingerprintHash: 'hash1',
1452
+ rolloutCohortCount: 200,
1453
+ targetCohorts: ['qa-group'],
1454
+ );
1453
1455
 
1454
- final update = await getUpdateInfo(
1455
- [bundle],
1456
- _fpArgs(cohort: eligibleCohort),
1457
- );
1458
- expect(update, isNotNull);
1459
- expect(update!.id, bundle.id);
1460
- expect(update.shouldForceUpdate, isFalse);
1461
- expect(update.status, UpdateStatus.update);
1462
- });
1456
+ final update = await getUpdateInfo([
1457
+ bundle,
1458
+ ], _fpArgs(cohort: eligibleCohort));
1459
+ expect(update, isNotNull);
1460
+ expect(update!.id, bundle.id);
1461
+ expect(update.shouldForceUpdate, isFalse);
1462
+ expect(update.status, UpdateStatus.update);
1463
+ },
1464
+ );
1463
1465
 
1464
1466
  test('includes targeted numeric cohorts outside the rollout set', () async {
1465
1467
  final bundleId = '00000000-0000-0000-0000-000000000023';
1466
- final targetedNumericCohort =
1467
- _findNumericCohort(bundleId, (pos) => pos >= 200);
1468
+ final targetedNumericCohort = _findNumericCohort(
1469
+ bundleId,
1470
+ (pos) => pos >= 200,
1471
+ );
1468
1472
 
1469
1473
  final bundle = _fingerprintBundle(
1470
1474
  id: bundleId,
@@ -1473,39 +1477,36 @@ void main() {
1473
1477
  targetCohorts: [targetedNumericCohort],
1474
1478
  );
1475
1479
 
1476
- final update = await getUpdateInfo(
1477
- [bundle],
1478
- _fpArgs(cohort: targetedNumericCohort),
1479
- );
1480
+ final update = await getUpdateInfo([
1481
+ bundle,
1482
+ ], _fpArgs(cohort: targetedNumericCohort));
1480
1483
  expect(update, isNotNull);
1481
1484
  expect(update!.id, bundle.id);
1482
1485
  expect(update.shouldForceUpdate, isFalse);
1483
1486
  expect(update.status, UpdateStatus.update);
1484
1487
  });
1485
1488
 
1486
- test('returns latest eligible update when newer bundle targets different cohort',
1487
- () async {
1489
+ test('returns latest eligible update when newer bundle targets different cohort', () async {
1488
1490
  final eligibleBundleId = '00000000-0000-0000-0000-000000000020';
1489
1491
  final blockedBundleId = '00000000-0000-0000-0000-000000000021';
1490
- final eligibleCohort =
1491
- _findNumericCohort(eligibleBundleId, (pos) => pos < 200);
1492
-
1493
- final update = await getUpdateInfo(
1494
- [
1495
- _fingerprintBundle(
1496
- id: eligibleBundleId,
1497
- fingerprintHash: 'hash1',
1498
- rolloutCohortCount: 200,
1499
- ),
1500
- _fingerprintBundle(
1501
- id: blockedBundleId,
1502
- fingerprintHash: 'hash1',
1503
- rolloutCohortCount: 0,
1504
- targetCohorts: ['qa-group'],
1505
- ),
1506
- ],
1507
- _fpArgs(cohort: eligibleCohort),
1492
+ final eligibleCohort = _findNumericCohort(
1493
+ eligibleBundleId,
1494
+ (pos) => pos < 200,
1508
1495
  );
1496
+
1497
+ final update = await getUpdateInfo([
1498
+ _fingerprintBundle(
1499
+ id: eligibleBundleId,
1500
+ fingerprintHash: 'hash1',
1501
+ rolloutCohortCount: 200,
1502
+ ),
1503
+ _fingerprintBundle(
1504
+ id: blockedBundleId,
1505
+ fingerprintHash: 'hash1',
1506
+ rolloutCohortCount: 0,
1507
+ targetCohorts: ['qa-group'],
1508
+ ),
1509
+ ], _fpArgs(cohort: eligibleCohort));
1509
1510
  expect(update, isNotNull);
1510
1511
  expect(update!.id, eligibleBundleId);
1511
1512
  expect(update.shouldForceUpdate, isFalse);
@@ -1516,25 +1517,19 @@ void main() {
1516
1517
  final previousBundleId = '00000000-0000-0000-0000-000000000020';
1517
1518
  final currentBundleId = '00000000-0000-0000-0000-000000000021';
1518
1519
 
1519
- final update = await getUpdateInfo(
1520
- [
1521
- _fingerprintBundle(
1522
- id: previousBundleId,
1523
- fingerprintHash: 'hash1',
1524
- rolloutCohortCount: 1000,
1525
- ),
1526
- _fingerprintBundle(
1527
- id: currentBundleId,
1528
- fingerprintHash: 'hash1',
1529
- rolloutCohortCount: 0,
1530
- targetCohorts: ['qa-group'],
1531
- ),
1532
- ],
1533
- _fpArgs(
1534
- bundleId: currentBundleId,
1535
- cohort: '1',
1520
+ final update = await getUpdateInfo([
1521
+ _fingerprintBundle(
1522
+ id: previousBundleId,
1523
+ fingerprintHash: 'hash1',
1524
+ rolloutCohortCount: 1000,
1536
1525
  ),
1537
- );
1526
+ _fingerprintBundle(
1527
+ id: currentBundleId,
1528
+ fingerprintHash: 'hash1',
1529
+ rolloutCohortCount: 0,
1530
+ targetCohorts: ['qa-group'],
1531
+ ),
1532
+ ], _fpArgs(bundleId: currentBundleId, cohort: '1'));
1538
1533
  expect(update, isNotNull);
1539
1534
  expect(update!.id, previousBundleId);
1540
1535
  expect(update.shouldForceUpdate, isTrue);
@@ -1544,20 +1539,14 @@ void main() {
1544
1539
  test('re-evaluates eligibility and falls back to init bundle', () async {
1545
1540
  final currentBundleId = '00000000-0000-0000-0000-000000000021';
1546
1541
 
1547
- final update = await getUpdateInfo(
1548
- [
1549
- _fingerprintBundle(
1550
- id: currentBundleId,
1551
- fingerprintHash: 'hash1',
1552
- rolloutCohortCount: 0,
1553
- targetCohorts: ['qa-group'],
1554
- ),
1555
- ],
1556
- _fpArgs(
1557
- bundleId: currentBundleId,
1558
- cohort: '1',
1542
+ final update = await getUpdateInfo([
1543
+ _fingerprintBundle(
1544
+ id: currentBundleId,
1545
+ fingerprintHash: 'hash1',
1546
+ rolloutCohortCount: 0,
1547
+ targetCohorts: ['qa-group'],
1559
1548
  ),
1560
- );
1549
+ ], _fpArgs(bundleId: currentBundleId, cohort: '1'));
1561
1550
  expect(update, isNotNull);
1562
1551
  expect(update!.id, nilUuid);
1563
1552
  expect(update.shouldForceUpdate, isTrue);