From 158764fef0baa1618585b8be020715cbc1594207 Mon Sep 17 00:00:00 2001 From: Felix Angelov Date: Mon, 23 Sep 2024 13:11:08 -0400 Subject: [PATCH] feat(shorebird_cli): add api.shorebird.dev access validator (#2491) --- packages/shorebird_cli/lib/src/doctor.dart | 1 + .../shorebird_api_access_validator.dart | 25 ++++++ .../lib/src/validators/validators.dart | 1 + .../shorebird_api_access_validator_test.dart | 83 +++++++++++++++++++ 4 files changed, 110 insertions(+) create mode 100644 packages/shorebird_cli/lib/src/validators/shorebird_api_access_validator.dart create mode 100644 packages/shorebird_cli/test/src/validators/shorebird_api_access_validator_test.dart diff --git a/packages/shorebird_cli/lib/src/doctor.dart b/packages/shorebird_cli/lib/src/doctor.dart index bd458a5c..ba4c91e2 100644 --- a/packages/shorebird_cli/lib/src/doctor.dart +++ b/packages/shorebird_cli/lib/src/doctor.dart @@ -29,6 +29,7 @@ class Doctor { ShorebirdVersionValidator(), ShorebirdFlutterValidator(), AndroidInternetPermissionValidator(), + ShorebirdApiAccessValidator(), StorageAccessValidator(), ShorebirdYamlAssetValidator(), ]; diff --git a/packages/shorebird_cli/lib/src/validators/shorebird_api_access_validator.dart b/packages/shorebird_cli/lib/src/validators/shorebird_api_access_validator.dart new file mode 100644 index 00000000..3494b363 --- /dev/null +++ b/packages/shorebird_cli/lib/src/validators/shorebird_api_access_validator.dart @@ -0,0 +1,25 @@ +import 'dart:io'; + +import 'package:shorebird_cli/src/http_client/http_client.dart'; +import 'package:shorebird_cli/src/validators/validators.dart'; + +/// Verifies that the user has access to api.shorebird.dev. +class ShorebirdApiAccessValidator extends Validator { + @override + String get description => 'Has access to api.shorebird.dev'; + + @override + Future> validate() async { + final uri = Uri.parse('https://api.shorebird.dev'); + final result = await httpClient.get(uri); + if (result.statusCode != HttpStatus.ok) { + return [ + const ValidationIssue( + severity: ValidationIssueSeverity.error, + message: 'Unable to access api.shorebird.dev', + ), + ]; + } + return []; + } +} diff --git a/packages/shorebird_cli/lib/src/validators/validators.dart b/packages/shorebird_cli/lib/src/validators/validators.dart index 7c5703ce..ecc91e98 100644 --- a/packages/shorebird_cli/lib/src/validators/validators.dart +++ b/packages/shorebird_cli/lib/src/validators/validators.dart @@ -6,6 +6,7 @@ import 'package:shorebird_cli/src/shorebird_process.dart'; export 'android_internet_permission_validator.dart'; export 'flavor_validator.dart'; +export 'shorebird_api_access_validator.dart'; export 'shorebird_flutter_validator.dart'; export 'shorebird_version_validator.dart'; export 'shorebird_yaml_asset_validator.dart'; diff --git a/packages/shorebird_cli/test/src/validators/shorebird_api_access_validator_test.dart b/packages/shorebird_cli/test/src/validators/shorebird_api_access_validator_test.dart new file mode 100644 index 00000000..92688366 --- /dev/null +++ b/packages/shorebird_cli/test/src/validators/shorebird_api_access_validator_test.dart @@ -0,0 +1,83 @@ +import 'dart:io'; + +import 'package:http/http.dart' as http; +import 'package:mocktail/mocktail.dart'; +import 'package:scoped_deps/scoped_deps.dart'; +import 'package:shorebird_cli/src/http_client/http_client.dart'; +import 'package:shorebird_cli/src/validators/validators.dart'; +import 'package:test/test.dart'; + +import '../mocks.dart'; + +void main() { + group(ShorebirdApiAccessValidator, () { + late http.Client httpClient; + late ShorebirdApiAccessValidator validator; + + R runWithOverrides(R Function() body) { + return runScoped( + () => body(), + values: { + httpClientRef.overrideWith(() => httpClient), + }, + ); + } + + setUpAll(() { + registerFallbackValue(Uri()); + }); + + setUp(() { + httpClient = MockHttpClient(); + validator = ShorebirdApiAccessValidator(); + + when(() => httpClient.get(any())).thenAnswer( + (_) async => http.Response('', HttpStatus.ok), + ); + }); + + group('description', () { + test('has a non-empty description', () { + expect(validator.description, isNotEmpty); + }); + }); + + group('validate', () { + group('when url is accessible', () { + setUp(() { + when(() => httpClient.get(any())).thenAnswer( + (_) async => http.Response('', HttpStatus.ok), + ); + }); + + test('returns empty list of validation issues', () async { + final results = await runWithOverrides(validator.validate); + expect(results, isEmpty); + }); + }); + + group('when url is inaccessible', () { + setUp(() { + when(() => httpClient.get(any())).thenAnswer( + (_) async => http.Response('Not Found', HttpStatus.notFound), + ); + }); + + test('returns validation error', () async { + final results = await runWithOverrides(validator.validate); + expect( + results, + equals( + [ + const ValidationIssue( + severity: ValidationIssueSeverity.error, + message: 'Unable to access api.shorebird.dev', + ), + ], + ), + ); + }); + }); + }); + }); +}