added support for 2fa login with browser flow
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:marianum_mobile/api/marianumcloud/login_flow/login_flow_api.dart';
|
||||
|
||||
void main() {
|
||||
group('LoginFlowInit.fromJson', () {
|
||||
test('parses a complete init response', () {
|
||||
final init = LoginFlowInit.fromJson({
|
||||
'poll': {
|
||||
'token': 'abc123',
|
||||
'endpoint': 'https://cloud.example.org/login/v2/poll',
|
||||
},
|
||||
'login': 'https://cloud.example.org/login/v2/flow/xyz',
|
||||
});
|
||||
expect(init.loginUrl, 'https://cloud.example.org/login/v2/flow/xyz');
|
||||
expect(init.pollToken, 'abc123');
|
||||
expect(init.pollEndpoint, 'https://cloud.example.org/login/v2/poll');
|
||||
});
|
||||
|
||||
test('throws on missing login url', () {
|
||||
expect(
|
||||
() => LoginFlowInit.fromJson({
|
||||
'poll': {'token': 't', 'endpoint': 'e'},
|
||||
}),
|
||||
throwsFormatException,
|
||||
);
|
||||
});
|
||||
|
||||
test('throws on missing poll token or endpoint', () {
|
||||
expect(
|
||||
() => LoginFlowInit.fromJson({
|
||||
'poll': {'endpoint': 'e'},
|
||||
'login': 'l',
|
||||
}),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => LoginFlowInit.fromJson({
|
||||
'poll': {'token': 't'},
|
||||
'login': 'l',
|
||||
}),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => LoginFlowInit.fromJson({'login': 'l'}),
|
||||
throwsFormatException,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('LoginFlowCredentials.fromJson', () {
|
||||
test('parses a complete poll response', () {
|
||||
final credentials = LoginFlowCredentials.fromJson({
|
||||
'server': 'https://cloud.example.org',
|
||||
'loginName': 'jdoe',
|
||||
'appPassword': 'secret-app-password',
|
||||
});
|
||||
expect(credentials.server, 'https://cloud.example.org');
|
||||
expect(credentials.loginName, 'jdoe');
|
||||
expect(credentials.appPassword, 'secret-app-password');
|
||||
});
|
||||
|
||||
test('tolerates a missing server field', () {
|
||||
final credentials = LoginFlowCredentials.fromJson({
|
||||
'loginName': 'jdoe',
|
||||
'appPassword': 'secret',
|
||||
});
|
||||
expect(credentials.server, '');
|
||||
});
|
||||
|
||||
test('throws on missing loginName or appPassword', () {
|
||||
expect(
|
||||
() => LoginFlowCredentials.fromJson({'appPassword': 'secret'}),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => LoginFlowCredentials.fromJson({'loginName': 'jdoe'}),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => LoginFlowCredentials.fromJson({
|
||||
'loginName': 'jdoe',
|
||||
'appPassword': '',
|
||||
}),
|
||||
throwsFormatException,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('LoginFlowApi.loginNameMatches', () {
|
||||
test('matches case-insensitively and ignores surrounding whitespace', () {
|
||||
expect(
|
||||
LoginFlowApi.loginNameMatches(expected: 'jdoe', actual: 'JDoe'),
|
||||
isTrue,
|
||||
);
|
||||
expect(
|
||||
LoginFlowApi.loginNameMatches(expected: 'jdoe', actual: ' jdoe '),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects a different account', () {
|
||||
expect(
|
||||
LoginFlowApi.loginNameMatches(expected: 'jdoe', actual: 'other'),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -53,6 +53,45 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('registrationTypesFor', () {
|
||||
test('password accounts maintain both registrations', () {
|
||||
expect(
|
||||
PushRegistration.registrationTypesFor(
|
||||
usesLoginFlow: false,
|
||||
hasTalkAppPassword: false,
|
||||
),
|
||||
PushRegistrationType.values,
|
||||
);
|
||||
expect(
|
||||
PushRegistration.registrationTypesFor(
|
||||
usesLoginFlow: false,
|
||||
hasTalkAppPassword: true,
|
||||
),
|
||||
PushRegistrationType.values,
|
||||
);
|
||||
});
|
||||
|
||||
test('flow account without talk app password is talk-only', () {
|
||||
expect(
|
||||
PushRegistration.registrationTypesFor(
|
||||
usesLoginFlow: true,
|
||||
hasTalkAppPassword: false,
|
||||
),
|
||||
[PushRegistrationType.talk],
|
||||
);
|
||||
});
|
||||
|
||||
test('flow account with second (talk) app password maintains both', () {
|
||||
expect(
|
||||
PushRegistration.registrationTypesFor(
|
||||
usesLoginFlow: true,
|
||||
hasTalkAppPassword: true,
|
||||
),
|
||||
PushRegistrationType.values,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('pushTokenVariant', () {
|
||||
test('general uses the raw token, talk appends the suffix', () {
|
||||
expect(pushTokenVariant('tok', PushRegistrationType.general), 'tok');
|
||||
|
||||
Reference in New Issue
Block a user