Skip to content

Commit 6c2194d

Browse files
committed
fix: enforce archive release channel qualifier behavior
1 parent 8cd332e commit 6c2194d

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

lib/src/services/archive_service.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'releases_service/releases_client.dart';
1414

1515
class ArchiveService extends ContextualService {
1616
static const _supportedArchiveChannels = {'stable', 'beta', 'dev'};
17+
static const _supportedArchiveReleaseQualifiers = {'beta', 'dev'};
1718

1819
const ArchiveService(super.context);
1920

@@ -54,6 +55,36 @@ class ArchiveService extends ContextualService {
5455
}
5556

5657
if (version.isRelease) {
58+
final releaseQualifier = version.releaseChannel?.name;
59+
if (releaseQualifier != null) {
60+
if (releaseQualifier == FlutterChannel.stable.name) {
61+
throw const AppException(
62+
'Archive installation does not support the "@stable" qualifier. '
63+
'Use the version without a channel suffix, or use @beta/@dev.',
64+
);
65+
}
66+
67+
if (!_supportedArchiveReleaseQualifiers.contains(releaseQualifier)) {
68+
throw AppException(
69+
'Archive installation supports release qualifiers only for '
70+
'@beta and @dev. Received "@$releaseQualifier".',
71+
);
72+
}
73+
74+
final channelReleases =
75+
await releaseClient.getChannelReleases(releaseQualifier);
76+
for (final release in channelReleases) {
77+
if (release.version == version.version) {
78+
return release;
79+
}
80+
}
81+
82+
throw AppException(
83+
'Release ${version.version} could not be found in the '
84+
'$releaseQualifier channel releases metadata.',
85+
);
86+
}
87+
5788
final release = await releaseClient.getReleaseByVersion(version.version);
5889
if (release == null) {
5990
throw AppException(

test/services/archive_service_test.dart

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,64 @@ void main() {
200200
),
201201
);
202202
});
203+
204+
test('uses channel-specific lookup for @beta qualifiers', () async {
205+
final version = FlutterVersion.parse('2.2.2@beta');
206+
207+
when(() => mockReleaseClient.getChannelReleases('beta')).thenAnswer(
208+
(_) async => [],
209+
);
210+
211+
await expectLater(
212+
archiveService.install(version, tempDir),
213+
throwsA(
214+
isA<AppException>().having(
215+
(e) => e.message,
216+
'message',
217+
contains('beta channel releases metadata'),
218+
),
219+
),
220+
);
221+
222+
verify(() => mockReleaseClient.getChannelReleases('beta')).called(1);
223+
verifyNever(() => mockReleaseClient.getReleaseByVersion(any()));
224+
});
225+
226+
test('rejects @stable qualifier for release versions', () async {
227+
final version = FlutterVersion.parse('2.2.2@stable');
228+
229+
expect(
230+
() => archiveService.install(version, tempDir),
231+
throwsA(
232+
isA<AppException>().having(
233+
(e) => e.message,
234+
'message',
235+
contains('does not support the "@stable" qualifier'),
236+
),
237+
),
238+
);
239+
240+
verifyNever(() => mockReleaseClient.getChannelReleases(any()));
241+
verifyNever(() => mockReleaseClient.getReleaseByVersion(any()));
242+
});
243+
244+
test('rejects unsupported release qualifiers like @master', () async {
245+
final version = FlutterVersion.parse('2.2.2@master');
246+
247+
expect(
248+
() => archiveService.install(version, tempDir),
249+
throwsA(
250+
isA<AppException>().having(
251+
(e) => e.message,
252+
'message',
253+
contains('@beta and @dev'),
254+
),
255+
),
256+
);
257+
258+
verifyNever(() => mockReleaseClient.getChannelReleases(any()));
259+
verifyNever(() => mockReleaseClient.getReleaseByVersion(any()));
260+
});
203261
});
204262

205263
group('archive download and extraction failures', () {

0 commit comments

Comments
 (0)