Skip to content

Commit

Permalink
Automatically select next weekday in homework dialog. (#1136)
Browse files Browse the repository at this point in the history
Fixes #1135
  • Loading branch information
Jonas-Sander authored Oct 27, 2023
1 parent 90d4bd3 commit 5c6e329
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 27 deletions.
15 changes: 14 additions & 1 deletion app/lib/homework/homework_dialog/homework_dialog_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import 'package:analytics/analytics.dart';
import 'package:bloc/bloc.dart';
import 'package:bloc_presentation/bloc_presentation.dart';
import 'package:clock/clock.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:common_domain_models/common_domain_models.dart';
import 'package:date/date.dart';
import 'package:date/weekday.dart';
import 'package:equatable/equatable.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:files_basics/files_models.dart';
Expand Down Expand Up @@ -372,6 +374,7 @@ class HomeworkDialogBloc extends Bloc<HomeworkDialogEvent, HomeworkDialogState>
final Analytics analytics;
final MarkdownAnalytics markdownAnalytics;
final NextLessonCalculator nextLessonCalculator;
final Clock _clock;
HomeworkDto? _initialHomework;
late final IList<CloudFile> _initialAttachments;
late final bool isEditing;
Expand Down Expand Up @@ -402,8 +405,10 @@ class HomeworkDialogBloc extends Bloc<HomeworkDialogEvent, HomeworkDialogState>
required this.nextLessonCalculator,
required this.analytics,
required this.markdownAnalytics,
Clock? clock,
HomeworkId? homeworkId,
}) : super(homeworkId != null
}) : _clock = clock ?? const Clock(),
super(homeworkId != null
? LoadingHomework(homeworkId, isEditing: true)
: emptyCreateHomeworkDialogState) {
isEditing = homeworkId != null;
Expand Down Expand Up @@ -574,6 +579,14 @@ class HomeworkDialogBloc extends Bloc<HomeworkDialogEvent, HomeworkDialogState>
await nextLessonCalculator.tryCalculateNextLesson(course.id);
if (nextLesson != null) {
add(DueDateChanged(nextLesson));
} else {
final today = _clock.now().toDate();
final daysUntilNextSchoolday = switch (today.weekDayEnum) {
WeekDay.friday => 3, // Monday
WeekDay.saturday => 2, // Monday
_ => 1 // Tomorrow
};
add(DueDateChanged(today.addDays(daysUntilNextSchoolday)));
}
},
);
Expand Down
66 changes: 40 additions & 26 deletions app/test/homework/homework_dialog_bloc_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'dart:io';
import 'dart:typed_data';

import 'package:analytics/analytics.dart';
import 'package:clock/clock.dart';
import 'package:common_domain_models/common_domain_models.dart';
import 'package:date/date.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
Expand All @@ -21,7 +22,6 @@ import 'package:mockito/mockito.dart';
import 'package:rxdart/rxdart.dart';
import 'package:sharezone/homework/homework_dialog/homework_dialog_bloc.dart';
import 'package:sharezone/markdown/markdown_analytics.dart';
import 'package:sharezone/util/next_lesson_calculator/next_lesson_calculator.dart';
import 'package:time/time.dart';

import '../analytics/analytics_test.dart';
Expand All @@ -44,9 +44,10 @@ void main() {
analytics = Analytics(analyticsBackend);
});

HomeworkDialogBloc createBlocForNewHomeworkDialog() {
HomeworkDialogBloc createBlocForNewHomeworkDialog({Clock? clock}) {
return HomeworkDialogBloc(
api: homeworkDialogApi,
clock: clock,
nextLessonCalculator: nextLessonCalculator,
analytics: analytics,
markdownAnalytics: MarkdownAnalytics(analytics),
Expand All @@ -69,6 +70,43 @@ void main() {
homeworkDialogApi.addCourseForTesting(course);
}

test('If no next lesson date is found the next weekday will be taken',
() async {
Future<void> testNextLessonDate(
String currentDate, String expectedLessonDate) async {
// The course does not have any lessons in the timetable, so we fallback
// to automatically using the next schoolday. We currently assume that
// all users have schooldays from Monday to Friday. We also don't take
// holidays into account.
nextLessonCalculator.dateToReturn = null;
final testClock = Clock.fixed(Date.parse(currentDate).toDateTime);
addCourse(courseWith(id: 'foo'));
final bloc = createBlocForNewHomeworkDialog(clock: testClock);

bloc.add(CourseChanged(CourseId('foo')));
await pumpEventQueue();

final state = bloc.state as Ready;
expect(state.dueDate.$1, Date.parse(expectedLessonDate));
}

// | Current date | Next lesson date |
// Friday Monday
await testNextLessonDate('2023-10-06', '2023-10-09');
// Saturday Monday
await testNextLessonDate('2023-10-07', '2023-10-09');
// Sunday Monday
await testNextLessonDate('2023-10-08', '2023-10-09');
// Monday Tuesday
await testNextLessonDate('2023-10-09', '2023-10-10');
// Tuesday Wednesday
await testNextLessonDate('2023-10-10', '2023-10-11');
// Wednesday Thursday
await testNextLessonDate('2023-10-11', '2023-10-12');
// Thursday Friday
await testNextLessonDate('2023-10-12', '2023-10-13');
});

test(
'Shows error if title is not filled out when creating a new homework and Save is called',
() async {
Expand Down Expand Up @@ -212,30 +250,6 @@ void main() {
.firstWhere((element) => element.dueDate.$1 != null);
expect(state.dueDate.$1, nextLessonDate);
});
test(
'leaves due date as not selected if null is returned by $NextLessonCalculator',
() async {
final bloc = createBlocForNewHomeworkDialog();
addCourse(courseWith(
id: 'foo_course',
));

bloc.add(CourseChanged(CourseId('foo_course')));

nextLessonCalculator.dateToReturn = null;
await bloc.stream
.whereType<Ready>()
.firstWhere((element) => element.course is CourseChosen);

// Make sure that we wait for the due date to be set (might be delayed,
// after the course is set and returned by the view)
await pumpEventQueue(times: 100);
await Future.delayed(Duration.zero);
await pumpEventQueue(times: 100);

final state = bloc.state as Ready;
expect(state.dueDate.$1, null);
});
test('Returns empty dialog when called for creating a new homework', () {
final bloc = createBlocForNewHomeworkDialog();
expect(bloc.state, emptyCreateHomeworkDialogState);
Expand Down
6 changes: 6 additions & 0 deletions lib/date/lib/src/date.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ class Date {
}
}

extension DateTimeToDate on DateTime {
Date toDate() {
return Date.fromDateTime(this);
}
}

class DateParser {
final Date _date;

Expand Down

0 comments on commit 5c6e329

Please sign in to comment.