Skip to content

Commit

Permalink
feat(shorebird_cli): add login command (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
felangel authored Mar 6, 2023
1 parent 32e5ec1 commit 806b891
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/shorebird_cli/lib/src/command_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class ShorebirdCliCommandRunner extends CompletionCommandRunner<int> {
final buildCodePushApiClient =
codePushApiClientBuilder ?? ShorebirdCodePushApiClient.new;

addCommand(LoginCommand(auth: authentication, logger: _logger));
addCommand(
PublishCommand(
auth: authentication,
Expand Down
1 change: 1 addition & 0 deletions packages/shorebird_cli/lib/src/commands/commands.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export 'login_command.dart';
export 'publish_command.dart';
export 'update_command.dart';
50 changes: 50 additions & 0 deletions packages/shorebird_cli/lib/src/commands/login_command.dart
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
87 changes: 87 additions & 0 deletions packages/shorebird_cli/test/src/commands/login_command_test.dart
Original file line number Diff line number Diff line change
@@ -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);
});
});
}

0 comments on commit 806b891

Please sign in to comment.