added guardian letters with chat and multiple answer functionalities
This commit is contained in:
@@ -29,9 +29,15 @@ void main() {
|
||||
|
||||
final effective = AppModule.effectiveModuleOrder(settingsWith(custom));
|
||||
|
||||
// parentLetters and ticker are both missing and follow timetable in the
|
||||
// declared order, so they line up behind it.
|
||||
expect(
|
||||
effective.indexOf(Modules.parentLetters),
|
||||
effective.indexOf(Modules.timetable) + 1,
|
||||
);
|
||||
expect(
|
||||
effective.indexOf(Modules.ticker),
|
||||
effective.indexOf(Modules.timetable) + 1,
|
||||
effective.indexOf(Modules.parentLetters) + 1,
|
||||
);
|
||||
expect(effective.toSet(), Modules.values.toSet());
|
||||
});
|
||||
@@ -94,10 +100,11 @@ void main() {
|
||||
final student = CredentialSession(username: 'max', password: 'pw');
|
||||
const guardian = GuardianSession(email: 'e@x.de');
|
||||
|
||||
test('password accounts see every module', () {
|
||||
for (final m in Modules.values) {
|
||||
expect(AppModule.isAvailableFor(m, student), isTrue, reason: m.name);
|
||||
}
|
||||
test('password accounts see every module but the guardian ones', () {
|
||||
final hidden = Modules.values
|
||||
.where((m) => !AppModule.isAvailableFor(m, student))
|
||||
.toSet();
|
||||
expect(hidden, {Modules.parentLetters});
|
||||
});
|
||||
|
||||
test('guardians lose exactly the Nextcloud modules', () {
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:marianum_mobile/api/marianumconnect/queries/parent_letters/parent_letter_models.dart';
|
||||
import 'package:marianum_mobile/state/app/modules/parent_letters/bloc/parent_letters_state.dart';
|
||||
import 'package:marianum_mobile/state/app/modules/parent_letters/parent_letters_logic.dart';
|
||||
|
||||
ParentLetterSummary _letter(
|
||||
String id, {
|
||||
bool read = true,
|
||||
List<String> childIds = const ['c1'],
|
||||
}) => ParentLetterSummary(
|
||||
id: id,
|
||||
sentAt: DateTime(2026, 9, 20),
|
||||
read: read,
|
||||
childIds: childIds,
|
||||
);
|
||||
|
||||
void main() {
|
||||
test('firstPageState takes over list and counters', () {
|
||||
final state = firstPageState(
|
||||
ParentLetterListResponse(
|
||||
items: [_letter('a')],
|
||||
hasMore: true,
|
||||
unreadCount: 2,
|
||||
openCount: 1,
|
||||
),
|
||||
);
|
||||
expect(state.letters.single.id, 'a');
|
||||
expect(state.hasMore, isTrue);
|
||||
expect(state.unreadCount, 2);
|
||||
expect(state.openCount, 1);
|
||||
});
|
||||
|
||||
test('appendOlderPage appends without duplicating known letters', () {
|
||||
final state = ParentLettersState(
|
||||
letters: [_letter('a'), _letter('b')],
|
||||
hasMore: true,
|
||||
);
|
||||
final next = appendOlderPage(
|
||||
state,
|
||||
ParentLetterListResponse(items: [_letter('b'), _letter('c')]),
|
||||
);
|
||||
expect(next.letters.map((l) => l.id), ['a', 'b', 'c']);
|
||||
expect(next.hasMore, isFalse);
|
||||
});
|
||||
|
||||
group('withLetterRead', () {
|
||||
final state = ParentLettersState(
|
||||
letters: [_letter('a', read: false), _letter('b')],
|
||||
unreadCount: 1,
|
||||
);
|
||||
|
||||
test('marks the letter and lowers the counter', () {
|
||||
final next = withLetterRead(state, 'a');
|
||||
expect(next.letters.first.read, isTrue);
|
||||
expect(next.unreadCount, 0);
|
||||
});
|
||||
|
||||
test('returns the same state for read or unknown letters', () {
|
||||
expect(identical(withLetterRead(state, 'b'), state), isTrue);
|
||||
expect(identical(withLetterRead(state, 'x'), state), isTrue);
|
||||
});
|
||||
|
||||
test('never drops the counter below zero', () {
|
||||
final drifted = state.copyWith(unreadCount: 0);
|
||||
expect(withLetterRead(drifted, 'a').unreadCount, 0);
|
||||
});
|
||||
});
|
||||
|
||||
group('withSummary', () {
|
||||
final open = _letter('b').copyWith(status: ParentLetterStatus.open);
|
||||
final state = ParentLettersState(
|
||||
letters: [_letter('a'), open],
|
||||
openCount: 3,
|
||||
);
|
||||
|
||||
test('replaces the letter in place and lowers the open counter', () {
|
||||
final next = withSummary(
|
||||
state,
|
||||
open.copyWith(status: ParentLetterStatus.done),
|
||||
);
|
||||
expect(next.letters.map((l) => l.id), ['a', 'b']);
|
||||
expect(next.letters.last.status, ParentLetterStatus.done);
|
||||
expect(next.openCount, 2);
|
||||
});
|
||||
|
||||
test('keeps the counter while the letter stays open', () {
|
||||
expect(withSummary(state, open.copyWith(read: false)).openCount, 3);
|
||||
});
|
||||
|
||||
test('ignores letters the inbox does not hold', () {
|
||||
expect(identical(withSummary(state, _letter('x')), state), isTrue);
|
||||
});
|
||||
});
|
||||
|
||||
test('filterLettersByChild keeps letters that concern the child', () {
|
||||
final letters = [
|
||||
_letter('a', childIds: ['c1']),
|
||||
_letter('b', childIds: ['c2']),
|
||||
_letter('c', childIds: ['c1', 'c2']),
|
||||
];
|
||||
expect(filterLettersByChild(letters, null), letters);
|
||||
expect(filterLettersByChild(letters, 'c2').map((l) => l.id), ['b', 'c']);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user