feat(shorebird_cli): add login command (#24)
This commit is contained in:
@@ -50,6 +50,7 @@ class ShorebirdCliCommandRunner extends CompletionCommandRunner<int> {
|
||||
final buildCodePushApiClient =
|
||||
codePushApiClientBuilder ?? ShorebirdCodePushApiClient.new;
|
||||
|
||||
addCommand(LoginCommand(auth: authentication, logger: _logger));
|
||||
addCommand(
|
||||
PublishCommand(
|
||||
auth: authentication,
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export 'login_command.dart';
|
||||
export 'publish_command.dart';
|
||||
export 'update_command.dart';
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
|
||||
/// {@template login_command}
|
||||
///
|
||||
/// `shorebird login`
|
||||
/// Login as a new Shorebird user.
|
||||
/// {@endtemplate}
|
||||
class LoginCommand extends Command<int> {
|
||||
/// {@macro login_command}
|
||||
LoginCommand({required Auth auth, required Logger logger})
|
||||
: _auth = auth,
|
||||
_logger = logger;
|
||||
|
||||
@override
|
||||
String get description => 'Login as a new Shorebird user.';
|
||||
|
||||
@override
|
||||
String get name => 'login';
|
||||
|
||||
final Auth _auth;
|
||||
final Logger _logger;
|
||||
|
||||
@override
|
||||
Future<int> run() async {
|
||||
final session = _auth.currentSession;
|
||||
if (session != null) {
|
||||
_logger
|
||||
..info('You are already logged in.')
|
||||
..info("Run 'shorebird logout' to log out and try again.");
|
||||
return ExitCode.success.code;
|
||||
}
|
||||
|
||||
final apiKey = _logger.prompt(
|
||||
'${lightGreen.wrap('?')} Please enter your API Key:',
|
||||
);
|
||||
final loginProgress = _logger.progress('Logging into shorebird.dev');
|
||||
try {
|
||||
_auth.login(projectId: 'example', apiKey: apiKey);
|
||||
loginProgress.complete();
|
||||
_logger.success('You are now logged in.');
|
||||
return ExitCode.success.code;
|
||||
} catch (error) {
|
||||
loginProgress.fail();
|
||||
_logger.err(error.toString());
|
||||
return ExitCode.software.code;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import 'package:mason_logger/mason_logger.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
import 'package:shorebird_cli/src/auth/auth.dart';
|
||||
import 'package:shorebird_cli/src/auth/session.dart';
|
||||
import 'package:shorebird_cli/src/commands/login_command.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
class _MockAuth extends Mock implements Auth {}
|
||||
|
||||
class _MockLogger extends Mock implements Logger {}
|
||||
|
||||
class _MockProgress extends Mock implements Progress {}
|
||||
|
||||
void main() {
|
||||
group('LoginCommand', () {
|
||||
const apiKey = 'test-api-key';
|
||||
const projectId = 'example';
|
||||
const session = Session(apiKey: apiKey, projectId: projectId);
|
||||
|
||||
late Logger logger;
|
||||
late Auth auth;
|
||||
late LoginCommand loginCommand;
|
||||
|
||||
setUp(() {
|
||||
logger = _MockLogger();
|
||||
auth = _MockAuth();
|
||||
loginCommand = LoginCommand(auth: auth, logger: logger);
|
||||
|
||||
when(() => logger.progress(any())).thenReturn(_MockProgress());
|
||||
});
|
||||
|
||||
test('exits with code 0 when already logged in', () async {
|
||||
when(() => auth.currentSession).thenReturn(session);
|
||||
|
||||
final result = await loginCommand.run();
|
||||
expect(result, equals(ExitCode.success.code));
|
||||
|
||||
verify(() => logger.info('You are already logged in.')).called(1);
|
||||
verify(
|
||||
() => logger.info("Run 'shorebird logout' to log out and try again."),
|
||||
).called(1);
|
||||
});
|
||||
|
||||
test('exits with code 70 when error occurs', () async {
|
||||
final error = Exception('oops something went wrong!');
|
||||
when(() => logger.prompt(any())).thenReturn(apiKey);
|
||||
when(() => auth.currentSession).thenReturn(null);
|
||||
when(
|
||||
() => auth.login(
|
||||
apiKey: any(named: 'apiKey'),
|
||||
projectId: any(named: 'projectId'),
|
||||
),
|
||||
).thenThrow(error);
|
||||
|
||||
final result = await loginCommand.run();
|
||||
expect(result, equals(ExitCode.software.code));
|
||||
|
||||
verify(() => logger.progress('Logging into shorebird.dev')).called(1);
|
||||
verify(
|
||||
() => auth.login(apiKey: apiKey, projectId: projectId),
|
||||
).called(1);
|
||||
verify(() => logger.err(error.toString())).called(1);
|
||||
});
|
||||
|
||||
test('exits with code 0 when logged in successfully', () async {
|
||||
when(() => logger.prompt(any())).thenReturn(apiKey);
|
||||
when(() => auth.currentSession).thenReturn(null);
|
||||
when(
|
||||
() => auth.login(
|
||||
apiKey: any(named: 'apiKey'),
|
||||
projectId: any(named: 'projectId'),
|
||||
),
|
||||
).thenAnswer((_) async {});
|
||||
|
||||
final result = await loginCommand.run();
|
||||
expect(result, equals(ExitCode.success.code));
|
||||
|
||||
verify(() => logger.progress('Logging into shorebird.dev')).called(1);
|
||||
verify(
|
||||
() => auth.login(apiKey: apiKey, projectId: projectId),
|
||||
).called(1);
|
||||
verify(
|
||||
() => logger.success('You are now logged in.'),
|
||||
).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user