diff --git a/packages/shorebird_cli/lib/src/commands/account/account_usage_command.dart b/packages/shorebird_cli/lib/src/commands/account/account_usage_command.dart index 529f784e..7a596db4 100644 --- a/packages/shorebird_cli/lib/src/commands/account/account_usage_command.dart +++ b/packages/shorebird_cli/lib/src/commands/account/account_usage_command.dart @@ -55,6 +55,10 @@ extension on GetUsageResponse { totalPatchInstalls += appUsage.patchInstallCount; } + final remainingPatchInstalls = patchInstallLimit == null + ? '∞' + : '${patchInstallLimit! - totalPatchInstalls}'; + return ''' ${Table( cellStyle: cellStyle, @@ -87,9 +91,9 @@ ${Table( ), ).render()} -${styleBold.wrap('${lightCyan.wrap('${patchInstallLimit - totalPatchInstalls}')} patch installs remaining in the current billing period.')} +${styleBold.wrap('${lightCyan.wrap(remainingPatchInstalls)} patch installs remaining in the current billing period.')} -${currentPeriodStart != null && currentPeriodEnd != null ? 'Current Billing Period: ${lightCyan.wrap(DateFormat.yMMMd().format(currentPeriodStart!))} - ${lightCyan.wrap(DateFormat.yMMMd().format(currentPeriodEnd!))}' : ''} +Current Billing Period: ${lightCyan.wrap(DateFormat.yMMMd().format(currentPeriodStart))} - ${lightCyan.wrap(DateFormat.yMMMd().format(currentPeriodEnd))} ${styleBold.wrap('*Usage data is not reported in real-time and may be delayed by up to 48 hours.')}'''; } diff --git a/packages/shorebird_cli/test/src/commands/account/account_usage_command_test.dart b/packages/shorebird_cli/test/src/commands/account/account_usage_command_test.dart index 71bf369b..f7b9b07b 100644 --- a/packages/shorebird_cli/test/src/commands/account/account_usage_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/account/account_usage_command_test.dart @@ -108,7 +108,56 @@ void main() { ${styleBold.wrap('${lightCyan.wrap('${20000 - 84}')} patch installs remaining in the current billing period.')} -Current Billing Period: ${lightCyan.wrap(DateFormat.yMMMd().format(usage.currentPeriodStart!))} - ${lightCyan.wrap(DateFormat.yMMMd().format(usage.currentPeriodEnd!))} +Current Billing Period: ${lightCyan.wrap(DateFormat.yMMMd().format(usage.currentPeriodStart))} - ${lightCyan.wrap(DateFormat.yMMMd().format(usage.currentPeriodEnd))} + +${styleBold.wrap('*Usage data is not reported in real-time and may be delayed by up to 48 hours.')}'''), + ), + ), + ).called(1); + }); + + test('exits with code 0 when usage is fetched (unlimited).', () async { + final usage = GetUsageResponse( + apps: const [ + AppUsage( + id: 'test-app-id', + name: 'test app 2', + patchInstallCount: 42, + ), + AppUsage( + id: 'test-app-id', + name: 'test app 2', + patchInstallCount: 42, + ), + ], + currentPeriodStart: DateTime(2023), + currentPeriodEnd: DateTime(2023, 2), + ); + when( + () => codePushClientWrapper.getUsage(), + ).thenAnswer((_) async => usage); + + final result = await runWithOverrides(command.run); + + expect(result, ExitCode.success.code); + verify(() => logger.info('📈 Usage')).called(1); + verify( + () => logger.info( + any( + that: contains(''' +┌────────────┬────────────────┐ +│ App │ Patch Installs │ +├────────────┼────────────────┤ +│ test app 2 │ 42 │ +├────────────┼────────────────┤ +│ test app 2 │ 42 │ +├────────────┼────────────────┤ +│ Total │ 84 │ +└────────────┴────────────────┘ + +${styleBold.wrap('∞ patch installs remaining in the current billing period.')} + +Current Billing Period: ${lightCyan.wrap(DateFormat.yMMMd().format(usage.currentPeriodStart))} - ${lightCyan.wrap(DateFormat.yMMMd().format(usage.currentPeriodEnd))} ${styleBold.wrap('*Usage data is not reported in real-time and may be delayed by up to 48 hours.')}'''), ), diff --git a/packages/shorebird_code_push_client/lib/src/version.dart b/packages/shorebird_code_push_client/lib/src/version.dart index 21da5edd..7055b3fc 100644 --- a/packages/shorebird_code_push_client/lib/src/version.dart +++ b/packages/shorebird_code_push_client/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '0.2.0+1'; +const packageVersion = '0.3.0+1'; diff --git a/packages/shorebird_code_push_client/pubspec.yaml b/packages/shorebird_code_push_client/pubspec.yaml index f4b93930..b1291ce3 100644 --- a/packages/shorebird_code_push_client/pubspec.yaml +++ b/packages/shorebird_code_push_client/pubspec.yaml @@ -1,6 +1,6 @@ name: shorebird_code_push_client description: Library which allows Dart applications to interact with the ShoreBird CodePush API -version: 0.2.0+1 +version: 0.3.0+1 repository: https://github.com/shorebirdtech/shorebird publish_to: none diff --git a/packages/shorebird_code_push_protocol/lib/src/messages/get_usage/get_usage_response.dart b/packages/shorebird_code_push_protocol/lib/src/messages/get_usage/get_usage_response.dart index 10b9d6fb..7619da71 100644 --- a/packages/shorebird_code_push_protocol/lib/src/messages/get_usage/get_usage_response.dart +++ b/packages/shorebird_code_push_protocol/lib/src/messages/get_usage/get_usage_response.dart @@ -11,9 +11,9 @@ class GetUsageResponse { /// {@macro get_usage_response} const GetUsageResponse({ required this.apps, - required this.patchInstallLimit, - this.currentPeriodStart, - this.currentPeriodEnd, + required this.currentPeriodStart, + required this.currentPeriodEnd, + this.patchInstallLimit, }); /// Converts a Map to a [GetUsageResponse]. @@ -26,14 +26,15 @@ class GetUsageResponse { /// The usage per app. final List apps; - /// The start of the current billin period. - final DateTime? currentPeriodStart; + /// The start of the current billing period. + final DateTime currentPeriodStart; - /// The end of the current billin period. - final DateTime? currentPeriodEnd; + /// The end of the current billing period. + final DateTime currentPeriodEnd; /// The upper limit of patch installs for the current billing period. - final int patchInstallLimit; + /// If `null`, there is no limit. + final int? patchInstallLimit; } /// {@template app_usage} diff --git a/packages/shorebird_code_push_protocol/lib/src/messages/get_usage/get_usage_response.g.dart b/packages/shorebird_code_push_protocol/lib/src/messages/get_usage/get_usage_response.g.dart index 66c89581..151a0ca6 100644 --- a/packages/shorebird_code_push_protocol/lib/src/messages/get_usage/get_usage_response.g.dart +++ b/packages/shorebird_code_push_protocol/lib/src/messages/get_usage/get_usage_response.g.dart @@ -19,27 +19,27 @@ GetUsageResponse _$GetUsageResponseFromJson(Map json) => (v) => (v as List) .map((e) => AppUsage.fromJson(e as Map)) .toList()), + currentPeriodStart: $checkedConvert( + 'current_period_start', (v) => DateTime.parse(v as String)), + currentPeriodEnd: $checkedConvert( + 'current_period_end', (v) => DateTime.parse(v as String)), patchInstallLimit: - $checkedConvert('patch_install_limit', (v) => v as int), - currentPeriodStart: $checkedConvert('current_period_start', - (v) => v == null ? null : DateTime.parse(v as String)), - currentPeriodEnd: $checkedConvert('current_period_end', - (v) => v == null ? null : DateTime.parse(v as String)), + $checkedConvert('patch_install_limit', (v) => v as int?), ); return val; }, fieldKeyMap: const { - 'patchInstallLimit': 'patch_install_limit', 'currentPeriodStart': 'current_period_start', - 'currentPeriodEnd': 'current_period_end' + 'currentPeriodEnd': 'current_period_end', + 'patchInstallLimit': 'patch_install_limit' }, ); Map _$GetUsageResponseToJson(GetUsageResponse instance) => { 'apps': instance.apps.map((e) => e.toJson()).toList(), - 'current_period_start': instance.currentPeriodStart?.toIso8601String(), - 'current_period_end': instance.currentPeriodEnd?.toIso8601String(), + 'current_period_start': instance.currentPeriodStart.toIso8601String(), + 'current_period_end': instance.currentPeriodEnd.toIso8601String(), 'patch_install_limit': instance.patchInstallLimit, };