added guardian login with views for their assigned childs
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:marianum_mobile/session/nextcloud_credentials.dart';
|
||||
import 'package:marianum_mobile/session/session.dart';
|
||||
import 'package:marianum_mobile/session/session_codec.dart';
|
||||
|
||||
String _basic(String user, String secret) =>
|
||||
'Basic ${base64Encode(utf8.encode('$user:$secret'))}';
|
||||
|
||||
void main() {
|
||||
group('decodeSession – installs from before guardian accounts', () {
|
||||
test('username + password without a kind is a credential session', () {
|
||||
final session = decodeSession({
|
||||
'username': 'max',
|
||||
'password': 'pw',
|
||||
'nextcloud_app_password': 'app',
|
||||
'nextcloud_app_password_talk': 'talk',
|
||||
});
|
||||
expect(session, isA<CredentialSession>());
|
||||
final credential = session! as CredentialSession;
|
||||
expect(credential.username, 'max');
|
||||
expect(credential.password, 'pw');
|
||||
expect(credential.isDemo, isFalse);
|
||||
expect(credential.nextcloud.appPassword, 'app');
|
||||
expect(credential.nextcloud.appPasswordTalk, 'talk');
|
||||
expect(credential.nextcloud.usesLoginFlow, isFalse);
|
||||
});
|
||||
|
||||
test('login-flow and demo flags are carried over', () {
|
||||
final session =
|
||||
decodeSession({
|
||||
'username': 'demo@x',
|
||||
'password': 'demo',
|
||||
'is_demo': 'true',
|
||||
'nextcloud_login_flow': 'true',
|
||||
})!
|
||||
as CredentialSession;
|
||||
expect(session.isDemo, isTrue);
|
||||
expect(session.nextcloud.usesLoginFlow, isTrue);
|
||||
});
|
||||
|
||||
test('missing password means signed out', () {
|
||||
expect(decodeSession({'username': 'max'}), isNull);
|
||||
expect(decodeSession({}), isNull);
|
||||
});
|
||||
});
|
||||
|
||||
group('decodeSession – guardian', () {
|
||||
test('guardian kind with e-mail', () {
|
||||
final session = decodeSession({
|
||||
'session_kind': 'guardian',
|
||||
'guardian_email': 'eltern@example.org',
|
||||
});
|
||||
expect(session, isA<GuardianSession>());
|
||||
expect(session!.nextcloud, isNull);
|
||||
expect((session as GuardianSession).email, 'eltern@example.org');
|
||||
});
|
||||
|
||||
test('guardian kind without e-mail is invalid', () {
|
||||
expect(decodeSession({'session_kind': 'guardian'}), isNull);
|
||||
});
|
||||
|
||||
test('an unknown kind from a newer app version reads as signed out', () {
|
||||
expect(
|
||||
decodeSession({
|
||||
'session_kind': 'something-new',
|
||||
'username': 'max',
|
||||
'password': 'pw',
|
||||
}),
|
||||
isNull,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('encodeSessionFields', () {
|
||||
test('round-trips a credential session', () {
|
||||
final original = CredentialSession(
|
||||
username: 'max',
|
||||
password: 'pw',
|
||||
usesLoginFlow: true,
|
||||
);
|
||||
final decoded =
|
||||
decodeSession(encodeSessionFields(original))! as CredentialSession;
|
||||
expect(decoded.username, 'max');
|
||||
expect(decoded.password, 'pw');
|
||||
expect(decoded.nextcloud.usesLoginFlow, isTrue);
|
||||
});
|
||||
|
||||
test('guardian clears credential fields', () {
|
||||
final fields = encodeSessionFields(
|
||||
const GuardianSession(email: 'e@x.de'),
|
||||
);
|
||||
expect(fields['username'], isNull);
|
||||
expect(fields['password'], isNull);
|
||||
expect(fields.containsKey('username'), isTrue);
|
||||
expect(decodeSession(fields), isA<GuardianSession>());
|
||||
});
|
||||
});
|
||||
|
||||
group('NextcloudCredentials', () {
|
||||
const base = NextcloudCredentials(username: 'max', password: 'pw');
|
||||
|
||||
test('prefers the app password once available', () {
|
||||
expect(base.basicAuthHeader, _basic('max', 'pw'));
|
||||
final withApp = base.copyWith(appPassword: () => 'app');
|
||||
expect(withApp.basicAuthHeader, _basic('max', 'app'));
|
||||
expect(withApp.secret, 'app');
|
||||
expect(withApp.realPasswordBasicAuthHeader, _basic('max', 'pw'));
|
||||
});
|
||||
|
||||
test('talk header needs its own app password', () {
|
||||
expect(() => base.talkBasicAuthHeader, throwsStateError);
|
||||
final withTalk = base.copyWith(appPasswordTalk: () => 't');
|
||||
expect(withTalk.talkBasicAuthHeader, _basic('max', 't'));
|
||||
});
|
||||
|
||||
test('login-flow accounts share the flow password for talk', () {
|
||||
final flow = base.copyWith(
|
||||
appPassword: () => 'flow',
|
||||
usesLoginFlow: true,
|
||||
);
|
||||
expect(flow.talkBasicAuthHeader, _basic('max', 'flow'));
|
||||
});
|
||||
|
||||
test('copyWith can clear an app password', () {
|
||||
final cleared = base
|
||||
.copyWith(appPassword: () => 'app')
|
||||
.copyWith(appPassword: () => null);
|
||||
expect(cleared.hasAppPassword, isFalse);
|
||||
expect(cleared.secret, 'pw');
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user