Skip to content

Commit

Permalink
Add editing custom grade types (#1616)
Browse files Browse the repository at this point in the history
Adds `GradeService.editCustomGradeType` that can be used to edit a
custom grade type. Currently this means that the display name can be
changed, in the future maybe an icon as well.

Fixes #1531
  • Loading branch information
Jonas-Sander authored May 6, 2024
1 parent 2d1eebb commit 3870d4a
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 0 deletions.
32 changes: 32 additions & 0 deletions app/lib/grades/grades_service/grades_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,38 @@ class GradesService {
_updateState(newState);
}

/// Edits properties of a custom grade type.
///
/// Throws [ArgumentError] if the [displayName] is empty.
///
/// Throws [GradeTypeNotFoundException] if the grade type with the given [id]
/// does not exist.
///
/// Throws [ArgumentError] if the grade type with the given [id] is a
/// predefined grade type.
void editCustomGradeType(
{required GradeTypeId id, required String displayName}) {
if (displayName.isEmpty) {
throw ArgumentError('The display name must not be empty.');
}

final isPredefinedGradeType =
GradeType.predefinedGradeTypes.map((gt) => gt.id).contains(id);
if (isPredefinedGradeType) {
throw ArgumentError('Cannot edit a predefined grade type.');
}
if (!_hasGradeTypeWithId(id)) {
throw GradeTypeNotFoundException(id);
}

final newCustomGradeTypes = _customGradeTypes.replaceAllWhere(
(element) => element.id == id,
GradeType(id: id, displayName: displayName));

final newState = _state.copyWith(customGradeTypes: newCustomGradeTypes);
_updateState(newState);
}

/// Deletes a custom grade type and removes it from all weight maps.
///
/// A custom grade type can only be deleted if it is not assigned to any grade
Expand Down
63 changes: 63 additions & 0 deletions app/test/grades/grade_types_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -371,5 +371,68 @@ void main() {
expect(gradeTypeIds, containsOnce(const GradeTypeId('custom')));
expect(gradeTypeIds, containsOnce(GradeType.oralParticipation.id));
});
test('Trying to edit a predefined grade type will throw an ArgumentError',
() {
final controller = GradesTestController();

for (final gradeType in controller.getPossibleGradeTypes()) {
expect(
() => controller.editCustomGradeType(gradeType.id,
displayName: 'foo'),
throwsArgumentError);
}
});
test(
'Trying to edit an unknown custom grade type will throw an $GradeTypeNotFoundException',
() {
final controller = GradesTestController();

expect(
() => controller.editCustomGradeType(const GradeTypeId('foo'),
displayName: 'foo'),
throwsA(const GradeTypeNotFoundException(GradeTypeId('foo'))));
});
test('One can change the name of a custom grade type', () {
final controller = GradesTestController();
controller.createCustomGradeType(
const GradeType(id: GradeTypeId('foo'), displayName: 'foo'));

controller.createTerm(termWith(
id: const TermId('foo'),
finalGradeType: const GradeTypeId('foo'),
subjects: [
subjectWith(
id: const SubjectId('bar'),
finalGradeType: const GradeTypeId('foo'),
grades: [
gradeWith(
id: const GradeId('bar'),
type: const GradeTypeId('foo'),
value: 3,
),
],
),
],
));

controller.editCustomGradeType(const GradeTypeId('foo'),
displayName: 'bar');

expect(controller.getCustomGradeTypes().single.displayName, 'bar');
expect(controller.term(const TermId('foo')).finalGradeType.displayName,
'bar');
});
test(
'Trying to edit the name of a custom grade type to an empty string throws an $ArgumentError',
() {
final controller = GradesTestController();
controller.createCustomGradeType(
const GradeType(id: GradeTypeId('foo'), displayName: 'foo'));

expect(
() => controller.editCustomGradeType(const GradeTypeId('foo'),
displayName: ''),
throwsArgumentError);
});
});
}
4 changes: 4 additions & 0 deletions app/test/grades/grades_test_common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ class GradesTestController {
{required TermId termId, required GradeTypeId gradeTypeId}) {
service.editTerm(id: termId, finalGradeType: gradeTypeId);
}

void editCustomGradeType(GradeTypeId id, {required String displayName}) {
service.editCustomGradeType(id: id, displayName: displayName);
}
}

TestTerm termWith({
Expand Down

0 comments on commit 3870d4a

Please sign in to comment.