added guardian letters with chat and multiple answer functionalities
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:marianum_mobile/api/marianumconnect/queries/parent_letters/parent_letter_models.dart';
|
||||
import 'package:marianum_mobile/view/pages/parent_letters/parent_letter_form_policy.dart';
|
||||
import 'package:marianum_mobile/view/pages/parent_letters/widgets/parent_letter_attachments.dart';
|
||||
|
||||
const _choice = ParentLetterField(
|
||||
id: 'f1',
|
||||
type: ParentLetterFieldType.singleChoice,
|
||||
label: 'Teilnahme?',
|
||||
isRequired: true,
|
||||
options: [
|
||||
ParentLetterOption(id: 'yes', label: 'Ja'),
|
||||
ParentLetterOption(id: 'no', label: 'Nein'),
|
||||
],
|
||||
);
|
||||
const _optionalChoice = ParentLetterField(
|
||||
id: 'f2',
|
||||
type: ParentLetterFieldType.singleChoice,
|
||||
);
|
||||
const _unknownRequired = ParentLetterField(id: 'f3', isRequired: true);
|
||||
const _unknownOptional = ParentLetterField(id: 'f4');
|
||||
|
||||
const _answered = ParentLetterResponse(
|
||||
answers: [
|
||||
ParentLetterAnswer(fieldId: 'f1', optionIds: ['no']),
|
||||
],
|
||||
);
|
||||
|
||||
ParentLetterChildState _child({
|
||||
bool editable = true,
|
||||
ParentLetterResponse? response,
|
||||
}) => ParentLetterChildState(
|
||||
childId: 'c1',
|
||||
editable: editable,
|
||||
response: response,
|
||||
);
|
||||
|
||||
void main() {
|
||||
group('ParentLetterFormPolicy.resolve', () {
|
||||
test('letters without a request have no form', () {
|
||||
expect(
|
||||
ParentLetterFormPolicy.resolve(request: null, child: _child()),
|
||||
isNull,
|
||||
);
|
||||
});
|
||||
|
||||
test('mode follows the server verdict and the existing response', () {
|
||||
const request = ParentLetterRequest(fields: [_choice]);
|
||||
ParentLetterFormMode mode(ParentLetterChildState child) =>
|
||||
ParentLetterFormPolicy.resolve(request: request, child: child)!.mode;
|
||||
|
||||
expect(mode(_child()), ParentLetterFormMode.open);
|
||||
expect(mode(_child(response: _answered)), ParentLetterFormMode.change);
|
||||
expect(
|
||||
mode(_child(editable: false, response: _answered)),
|
||||
ParentLetterFormMode.done,
|
||||
);
|
||||
expect(mode(_child(editable: false)), ParentLetterFormMode.closed);
|
||||
});
|
||||
|
||||
test('an unknown required field blocks the form', () {
|
||||
final policy = ParentLetterFormPolicy.resolve(
|
||||
request: const ParentLetterRequest(fields: [_choice, _unknownRequired]),
|
||||
child: _child(),
|
||||
)!;
|
||||
expect(policy.mode, ParentLetterFormMode.unsupported);
|
||||
expect(policy.canSubmit, isFalse);
|
||||
});
|
||||
|
||||
test('an answered letter stays readable despite unknown fields', () {
|
||||
final policy = ParentLetterFormPolicy.resolve(
|
||||
request: const ParentLetterRequest(fields: [_choice, _unknownRequired]),
|
||||
child: _child(editable: false, response: _answered),
|
||||
)!;
|
||||
expect(policy.mode, ParentLetterFormMode.done);
|
||||
});
|
||||
|
||||
test('unknown optional fields are skipped', () {
|
||||
final policy = ParentLetterFormPolicy.resolve(
|
||||
request: const ParentLetterRequest(fields: [_choice, _unknownOptional]),
|
||||
child: _child(),
|
||||
)!;
|
||||
expect(policy.mode, ParentLetterFormMode.open);
|
||||
expect(policy.fields, [_choice]);
|
||||
});
|
||||
});
|
||||
|
||||
group('submit semantics', () {
|
||||
ParentLetterFormPolicy policy(
|
||||
ParentLetterRequest request, {
|
||||
ParentLetterResponse? response,
|
||||
}) => ParentLetterFormPolicy.resolve(
|
||||
request: request,
|
||||
child: _child(response: response),
|
||||
)!;
|
||||
|
||||
test('acknowledgement', () {
|
||||
final p = policy(const ParentLetterRequest());
|
||||
expect(p.isAcknowledgement, isTrue);
|
||||
expect(p.submitIsFinal, isTrue);
|
||||
expect(p.submitLabel, 'Zur Kenntnis genommen');
|
||||
expect(p.isComplete(const {}), isTrue);
|
||||
expect(p.answersFor(const {}), isEmpty);
|
||||
});
|
||||
|
||||
test('plain choice can be changed later', () {
|
||||
const request = ParentLetterRequest(fields: [_choice]);
|
||||
expect(policy(request).submitIsFinal, isFalse);
|
||||
expect(policy(request).submitLabel, 'Rückmeldung absenden');
|
||||
expect(
|
||||
policy(request, response: _answered).submitLabel,
|
||||
'Rückmeldung ändern',
|
||||
);
|
||||
});
|
||||
|
||||
test('signature makes the response final', () {
|
||||
final p = policy(
|
||||
const ParentLetterRequest(fields: [_choice], signatureRequired: true),
|
||||
);
|
||||
expect(p.submitIsFinal, isTrue);
|
||||
expect(p.isAcknowledgement, isFalse);
|
||||
expect(p.submitLabel, 'Unterschreiben und absenden');
|
||||
});
|
||||
|
||||
test('only required fields must be answered', () {
|
||||
final p = policy(
|
||||
const ParentLetterRequest(fields: [_choice, _optionalChoice]),
|
||||
);
|
||||
expect(p.isComplete(const {}), isFalse);
|
||||
expect(p.isComplete(const {'f2': 'x'}), isFalse);
|
||||
expect(p.isComplete(const {'f1': 'yes'}), isTrue);
|
||||
});
|
||||
|
||||
test('answers contain exactly the selected fields', () {
|
||||
final p = policy(
|
||||
const ParentLetterRequest(fields: [_choice, _optionalChoice]),
|
||||
);
|
||||
expect(p.answersFor(const {'f1': 'yes', 'stale': 'x'}), const [
|
||||
ParentLetterAnswer(fieldId: 'f1', optionIds: ['yes']),
|
||||
]);
|
||||
});
|
||||
|
||||
test('selectionOf restores a previous response', () {
|
||||
expect(ParentLetterFormPolicy.selectionOf(_answered), {'f1': 'no'});
|
||||
expect(ParentLetterFormPolicy.selectionOf(null), isEmpty);
|
||||
});
|
||||
});
|
||||
|
||||
group('safeAttachmentFileName', () {
|
||||
String name(String fileName) => safeAttachmentFileName(
|
||||
ParentLetterAttachment(id: 'a', fileName: fileName),
|
||||
);
|
||||
|
||||
test('keeps ordinary names', () {
|
||||
expect(name('Elternbrief 10b.pdf'), 'Elternbrief 10b.pdf');
|
||||
});
|
||||
|
||||
test('strips path parts and reserved characters', () {
|
||||
expect(name('../../etc/passwd'), 'passwd');
|
||||
expect(name(r'C:\Users\x\brief?.pdf'), 'brief_.pdf');
|
||||
});
|
||||
|
||||
test('never returns an empty or relative name', () {
|
||||
expect(name(''), 'Anhang');
|
||||
expect(name('foo/..'), 'Anhang');
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user