Skip to content

Commit 51f367f

Browse files
author
serverpod_cloud
committed
feat(cli): d534295c0d86790db4619f834f7a74d9001467ac
1 parent fd9516a commit 51f367f

4 files changed

Lines changed: 164 additions & 0 deletions

File tree

serverpod_cloud_cli/lib/command_runner/cloud_cli_command_runner.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import 'package:serverpod_cloud_cli/command_runner/commands/project_command.dart
1818
import 'package:serverpod_cloud_cli/command_runner/commands/secret_command.dart';
1919
import 'package:serverpod_cloud_cli/command_runner/commands/deployments_command.dart';
2020
import 'package:serverpod_cloud_cli/command_runner/commands/version_command.dart';
21+
import 'package:serverpod_cloud_cli/command_runner/commands/me_command.dart';
2122
import 'package:serverpod_cloud_cli/shared/exceptions/exit_exceptions.dart';
2223
import 'package:serverpod_cloud_cli/command_runner/helpers/cloud_cli_service_provider.dart';
2324
import 'package:serverpod_cloud_cli/command_runner/helpers/cli_version_checker.dart';
@@ -145,6 +146,7 @@ class CloudCliCommandRunner extends BetterCommandRunner<GlobalOption, void> {
145146
runner.addCommands([
146147
runner._versionCommand,
147148
CloudAuthCommand(logger: logger),
149+
CloudMeCommand(logger: logger),
148150
CloudProjectCommand(logger: logger),
149151
CloudDeployCommand(logger: logger),
150152
CloudVariableCommand(logger: logger),
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import 'package:config/config.dart';
2+
import 'package:serverpod_cloud_cli/command_runner/cloud_cli_command.dart';
3+
import 'package:serverpod_cloud_cli/commands/me/me.dart';
4+
5+
import 'categories.dart';
6+
7+
class CloudMeCommand extends CloudCliCommand {
8+
@override
9+
final name = 'me';
10+
11+
@override
12+
final description = 'Show information about the current user.';
13+
14+
@override
15+
String get category => CommandCategories.manage;
16+
17+
CloudMeCommand({required super.logger}) : super(options: []);
18+
19+
@override
20+
Future<void> runWithConfig(final Configuration commandConfig) async {
21+
await MeCommands.showCurrentUser(
22+
runner.serviceProvider.cloudApiClient,
23+
logger: logger,
24+
);
25+
}
26+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import 'package:ground_control_client/ground_control_client.dart';
2+
import 'package:serverpod_cloud_cli/command_logger/command_logger.dart';
3+
import 'package:serverpod_cloud_cli/util/printers/table_printer.dart';
4+
5+
abstract class MeCommands {
6+
static Future<void> showCurrentUser(
7+
final Client cloudApiClient, {
8+
required final CommandLogger logger,
9+
}) async {
10+
final user = await cloudApiClient.users.readUser();
11+
12+
String planDisplayName = 'No plan';
13+
try {
14+
final subscriptionInfo = await cloudApiClient.plans.getSubscriptionInfo();
15+
planDisplayName = subscriptionInfo.planDisplayName;
16+
} on NoSubscriptionException {
17+
planDisplayName = 'No plan';
18+
} on Exception catch (e) {
19+
logger.debug('Failed to fetch subscription info: $e');
20+
}
21+
22+
final table = TablePrinter(
23+
headers: ['Email', 'Plan'],
24+
rows: [
25+
[user.email, planDisplayName],
26+
],
27+
);
28+
table.writeLines(logger.line);
29+
}
30+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import 'dart:async';
2+
3+
import 'package:mocktail/mocktail.dart';
4+
import 'package:test/test.dart';
5+
6+
import 'package:serverpod_cloud_cli/command_runner/cloud_cli_command_runner.dart';
7+
import 'package:serverpod_cloud_cli/command_runner/commands/me_command.dart';
8+
import 'package:serverpod_cloud_cli/command_runner/helpers/cloud_cli_service_provider.dart';
9+
import 'package:ground_control_client/ground_control_client.dart';
10+
import 'package:ground_control_client/ground_control_client_test_tools.dart';
11+
12+
import '../../test_utils/command_logger_matchers.dart';
13+
import '../../test_utils/test_command_logger.dart';
14+
15+
void main() {
16+
final logger = TestCommandLogger();
17+
18+
final client = ClientMock(
19+
authKeyProvider: InMemoryKeyManager.authenticated(),
20+
);
21+
22+
final cli = CloudCliCommandRunner.create(
23+
logger: logger,
24+
serviceProvider: CloudCliServiceProvider(
25+
apiClientFactory: (final globalCfg) => client,
26+
),
27+
);
28+
29+
tearDown(() async {
30+
logger.clear();
31+
});
32+
33+
test('Given me command when instantiated then requires login', () {
34+
expect(CloudMeCommand(logger: logger).requireLogin, isTrue);
35+
});
36+
37+
group('Given authenticated user', () {
38+
group('when executing me command with subscription', () {
39+
late Future commandResult;
40+
setUp(() {
41+
when(() => client.users.readUser()).thenAnswer(
42+
(_) async => UserBuilder().withEmail('test@example.com').build(),
43+
);
44+
45+
when(() => client.plans.getSubscriptionInfo()).thenAnswer(
46+
(_) async => SubscriptionInfoBuilder()
47+
.withPlanDisplayName('Early Access')
48+
.build(),
49+
);
50+
51+
commandResult = cli.run(['me']);
52+
});
53+
54+
test('then completes successfully', () async {
55+
await expectLater(commandResult, completes);
56+
});
57+
58+
test('then outputs user information in table format', () async {
59+
await commandResult;
60+
61+
expect(logger.lineCalls, isNotEmpty);
62+
expect(
63+
logger.lineCalls,
64+
containsAllInOrder([
65+
equalsLineCall(line: 'Email | Plan '),
66+
equalsLineCall(line: '-----------------+-------------'),
67+
equalsLineCall(line: 'test@example.com | Early Access'),
68+
]),
69+
);
70+
});
71+
});
72+
73+
group('when executing me command without subscription', () {
74+
late Future commandResult;
75+
setUp(() {
76+
when(() => client.users.readUser()).thenAnswer(
77+
(_) async => UserBuilder().withEmail('test@example.com').build(),
78+
);
79+
80+
when(
81+
() => client.plans.getSubscriptionInfo(),
82+
).thenThrow(NoSubscriptionException(message: 'No subscription'));
83+
84+
commandResult = cli.run(['me']);
85+
});
86+
87+
test('then completes successfully', () async {
88+
await expectLater(commandResult, completes);
89+
});
90+
91+
test('then outputs user information with no plan', () async {
92+
await commandResult;
93+
94+
expect(logger.lineCalls, isNotEmpty);
95+
expect(
96+
logger.lineCalls,
97+
containsAllInOrder([
98+
equalsLineCall(line: 'Email | Plan '),
99+
equalsLineCall(line: '-----------------+--------'),
100+
equalsLineCall(line: 'test@example.com | No plan'),
101+
]),
102+
);
103+
});
104+
});
105+
});
106+
}

0 commit comments

Comments
 (0)