feat(shorebird_cli)!: rename shorebird subscription cancel to shorebird account downgrade (#731)

This commit is contained in:
Felix Angelov
2023-06-29 09:59:42 -07:00
committed by GitHub
parent 08dff59533
commit 1e4bc3eb8f
8 changed files with 31 additions and 70 deletions
@@ -68,7 +68,6 @@ class ShorebirdCliCommandRunner extends CompletionCommandRunner<int> {
addCommand(ReleaseCommand());
addCommand(ReleasesCommand());
addCommand(RunCommand());
addCommand(SubscriptionCommand());
addCommand(UpgradeCommand());
}
@@ -1,4 +1,5 @@
export 'account_command.dart';
export 'account_usage_command.dart';
export 'create_account_command.dart';
export 'downgrade_account_command.dart';
export 'upgrade_account_command.dart';
@@ -10,6 +10,7 @@ class AccountCommand extends ShorebirdCommand {
AccountCommand() {
addSubcommand(AccountUsageCommand());
addSubcommand(CreateAccountCommand());
addSubcommand(DowngradeAccountCommand());
addSubcommand(UpgradeAccountCommand());
}
@@ -10,22 +10,20 @@ import 'package:shorebird_cli/src/shorebird_environment.dart';
import 'package:shorebird_cli/src/shorebird_validation_mixin.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
class CancelSubscriptionCommand extends ShorebirdCommand
class DowngradeAccountCommand extends ShorebirdCommand
with ShorebirdConfigMixin, ShorebirdValidationMixin {
CancelSubscriptionCommand({super.buildCodePushClient});
DowngradeAccountCommand({super.buildCodePushClient});
@override
String get name => 'cancel';
String get name => 'downgrade';
@override
String get description => 'Cancel your Shorebird subscription.';
String get description => 'Downgrade your Shorebird account.';
@override
Future<int> run() async {
try {
await validatePreconditions(
checkUserIsAuthenticated: true,
);
await validatePreconditions(checkUserIsAuthenticated: true);
} on PreconditionFailedException catch (e) {
return e.exitCode.code;
}
@@ -48,36 +46,39 @@ class CancelSubscriptionCommand extends ShorebirdCommand
}
if (!user.hasActiveSubscription) {
logger.err('You do not have an active subscription.');
logger.err('You do not have a "teams" subscription.');
return ExitCode.software.code;
}
final confirm = logger.confirm(
red.wrap('This will cancel your Shorebird subscription. Are you sure?'),
red.wrap(
'''This will downgrade your Shorebird plan to the "hobby" tier. Are you sure?''',
),
);
if (!confirm) {
logger.info('Aborting.');
return ExitCode.success.code;
}
final progress = logger.progress('Canceling your subscription');
final progress = logger.progress('Downgrading your plan');
final DateTime cancellationDate;
try {
cancellationDate = await client.cancelSubscription();
} catch (error) {
progress.fail('Failed to cancel subscription. Error: $error');
progress.fail('Failed to downgrade plan. Error: $error');
return ExitCode.software.code;
}
final formattedDate = DateFormat.yMMMMd().format(cancellationDate);
progress.complete(
'''
Your subscription has been canceled.
Your plan has been downgraded.
Note: Your access to Shorebird will continue until $formattedDate, after which all data stored by Shorebird will be deleted as per our privacy policy: https://shorebird.dev/privacy.html.
Note: Your current plan will continue until $formattedDate, after which your account will be on the "hobby" tier.
Apps on devices you've built with Shorebird will continue to function normally, but will not receive further updates.''',
Apps on devices you've built with Shorebird will continue to function normally, but will be subject to the limits of the "hobby" tier.''',
);
return ExitCode.success.code;
@@ -12,5 +12,4 @@ export 'patch/patch.dart';
export 'release/release.dart';
export 'releases/releases.dart';
export 'run_command.dart';
export 'subscription/subscription_command.dart';
export 'upgrade_command.dart';
@@ -1 +0,0 @@
export 'cancel_subscription_command.dart';
@@ -1,20 +0,0 @@
import 'package:shorebird_cli/src/command.dart';
import 'package:shorebird_cli/src/commands/subscription/subscription.dart';
/// {@template subscription_command}
///
/// `shorebird subscription`
/// Manage your Shorebird subscription.
/// {@endtemplate}
class SubscriptionCommand extends ShorebirdCommand {
/// {@macro subscription_command}
SubscriptionCommand() {
addSubcommand(CancelSubscriptionCommand());
}
@override
String get name => 'subscription';
@override
String get description => 'Manage your Shorebird subscription.';
}
@@ -3,7 +3,7 @@ import 'package:mason_logger/mason_logger.dart';
import 'package:mocktail/mocktail.dart';
import 'package:scoped/scoped.dart';
import 'package:shorebird_cli/src/auth/auth.dart';
import 'package:shorebird_cli/src/commands/subscription/cancel_subscription_command.dart';
import 'package:shorebird_cli/src/commands/account/account.dart';
import 'package:shorebird_cli/src/logger.dart';
import 'package:shorebird_code_push_client/shorebird_code_push_client.dart';
import 'package:test/test.dart';
@@ -19,7 +19,7 @@ class _MockLogger extends Mock implements Logger {}
class _MockProgress extends Mock implements Progress {}
void main() {
group(CancelSubscriptionCommand, () {
group(DowngradeAccountCommand, () {
const noSubscriptionUser = User(id: 1, email: 'tester1@shorebird.dev');
const subscriptionUser = User(
id: 2,
@@ -32,7 +32,7 @@ void main() {
late http.Client httpClient;
late Logger logger;
late Progress progress;
late CancelSubscriptionCommand command;
late DowngradeAccountCommand command;
R runWithOverrides<R>(R Function() body) {
return runScoped(
@@ -56,7 +56,7 @@ void main() {
when(() => logger.progress(any())).thenReturn(progress);
command = runWithOverrides(
() => CancelSubscriptionCommand(
() => DowngradeAccountCommand(
buildCodePushClient: ({
required http.Client httpClient,
Uri? hostedUri,
@@ -123,7 +123,7 @@ void main() {
expect(result, ExitCode.software.code);
verify(
() => logger.err(
any(that: contains('You do not have an active subscription')),
any(that: contains('You do not have a "teams" subscription')),
),
).called(1);
},
@@ -135,13 +135,7 @@ void main() {
() => codePushClient.getCurrentUser(),
).thenAnswer((_) async => subscriptionUser);
when(
() => logger.confirm(
any(
that: contains(
'This will cancel your Shorebird subscription. Are you sure?',
),
),
),
() => logger.confirm(any(that: contains('Are you sure?'))),
).thenReturn(false);
final result = await runWithOverrides(command.run);
@@ -156,13 +150,7 @@ void main() {
() => codePushClient.getCurrentUser(),
).thenAnswer((_) async => subscriptionUser);
when(
() => logger.confirm(
any(
that: contains(
'This will cancel your Shorebird subscription. Are you sure?',
),
),
),
() => logger.confirm(any(that: contains('Are you sure?'))),
).thenReturn(true);
when(() => codePushClient.cancelSubscription()).thenThrow(
Exception('an error occurred'),
@@ -172,9 +160,7 @@ void main() {
expect(result, ExitCode.software.code);
verify(
() => progress.fail(
any(that: contains('an error occurred')),
),
() => progress.fail(any(that: contains('an error occurred'))),
).called(1);
});
@@ -183,16 +169,11 @@ void main() {
const cancellationTimestamp = 1681455600;
when(() => auth.isAuthenticated).thenReturn(true);
when(() => codePushClient.getCurrentUser())
.thenAnswer((_) async => subscriptionUser);
when(
() => logger.confirm(
any(
that: contains(
'This will cancel your Shorebird subscription. Are you sure?',
),
),
),
() => codePushClient.getCurrentUser(),
).thenAnswer((_) async => subscriptionUser);
when(
() => logger.confirm(any(that: contains('Are you sure?'))),
).thenReturn(true);
when(() => codePushClient.cancelSubscription()).thenAnswer(
@@ -209,8 +190,8 @@ void main() {
() => progress.complete(
any(
that: stringContainsInOrder([
'Your subscription has been canceled.',
'Your access to Shorebird will continue until April 14, 2023'
'Your plan has been downgraded.',
'''Note: Your current plan will continue until April 14, 2023, after which your account will be on the "hobby" tier.'''
]),
),
),