Skip to content

Commit 5bf853d

Browse files
authored
[MBL-19252][Student][Teacher] Ungraded items now appear in syllabus (#3305)
Test plan: See ticket. refs: MBL-19252 affects: Student, Teacher release note: Fixed a bug where some syllabus items would not appear.
1 parent e602078 commit 5bf853d

File tree

37 files changed

+7767
-98
lines changed

37 files changed

+7767
-98
lines changed

apps/student/src/main/java/com/instructure/student/di/SyllabusModule.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package com.instructure.student.di
22

33
import com.instructure.canvasapi2.apis.CalendarEventAPI
44
import com.instructure.canvasapi2.apis.CourseAPI
5+
import com.instructure.canvasapi2.apis.PlannerAPI
56
import com.instructure.pandautils.room.offline.daos.CourseSettingsDao
7+
import com.instructure.pandautils.room.offline.daos.PlannerItemDao
68
import com.instructure.pandautils.room.offline.facade.CourseFacade
79
import com.instructure.pandautils.room.offline.facade.ScheduleItemFacade
810
import com.instructure.pandautils.utils.FeatureFlagProvider
@@ -22,18 +24,20 @@ class SyllabusModule {
2224
@Provides
2325
fun provideNetworkDataSource(
2426
courseApi: CourseAPI.CoursesInterface,
25-
calendarEventApi: CalendarEventAPI.CalendarEventInterface
27+
calendarEventApi: CalendarEventAPI.CalendarEventInterface,
28+
plannerApi: PlannerAPI.PlannerInterface
2629
): SyllabusNetworkDataSource {
27-
return SyllabusNetworkDataSource(courseApi, calendarEventApi)
30+
return SyllabusNetworkDataSource(courseApi, calendarEventApi, plannerApi)
2831
}
2932

3033
@Provides
3134
fun provideLocalDataSource(
3235
courseSettingsDao: CourseSettingsDao,
3336
courseFacade: CourseFacade,
34-
scheduleItemFacade: ScheduleItemFacade
37+
scheduleItemFacade: ScheduleItemFacade,
38+
plannerItemDao: PlannerItemDao
3539
): SyllabusLocalDataSource {
36-
return SyllabusLocalDataSource(courseSettingsDao, courseFacade, scheduleItemFacade)
40+
return SyllabusLocalDataSource(courseSettingsDao, courseFacade, scheduleItemFacade, plannerItemDao)
3741
}
3842

3943
@Provides

apps/student/src/main/java/com/instructure/student/features/calendar/StudentCalendarRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import com.instructure.canvasapi2.utils.ApiPrefs
2626
import com.instructure.canvasapi2.utils.DataResult
2727
import com.instructure.canvasapi2.utils.depaginate
2828
import com.instructure.canvasapi2.utils.hasActiveEnrollment
29-
import com.instructure.canvasapi2.utils.isValidTerm
3029
import com.instructure.pandautils.features.calendar.CalendarRepository
3130
import com.instructure.pandautils.room.calendar.daos.CalendarFilterDao
3231
import com.instructure.pandautils.room.calendar.entities.CalendarFilterEntity
@@ -54,6 +53,7 @@ class StudentCalendarRepository(
5453
startDate,
5554
endDate,
5655
emptyList(), // We always request all the events for students and filter locally
56+
null,
5757
restParams
5858
).depaginate {
5959
plannerApi.nextPagePlannerItems(it, restParams)

apps/student/src/main/java/com/instructure/student/mobius/syllabus/SyllabusEffectHandler.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
package com.instructure.student.mobius.syllabus
1818

1919
import com.instructure.canvasapi2.apis.CalendarEventAPI
20-
import com.instructure.canvasapi2.managers.CalendarEventManager
21-
import com.instructure.canvasapi2.managers.CourseManager
2220
import com.instructure.canvasapi2.models.ScheduleItem
2321
import com.instructure.canvasapi2.utils.DataResult
2422
import com.instructure.canvasapi2.utils.exhaustive
@@ -56,14 +54,25 @@ class SyllabusEffectHandler(private val repository: SyllabusRepository) : Effect
5654

5755
val assignments = repository.getCalendarEvents(true, CalendarEventAPI.CalendarEventType.ASSIGNMENT, null, null, contextCodes, effect.forceNetwork)
5856
val events = repository.getCalendarEvents(true, CalendarEventAPI.CalendarEventType.CALENDAR, null, null, contextCodes, effect.forceNetwork)
57+
val plannerItems = repository.getPlannerItems(null, null, contextCodes, "all_ungraded_todo_items", effect.forceNetwork)
58+
5959
val endList = mutableListOf<ScheduleItem>()
6060

6161
assignments.map { endList.addAll(it) }
6262
events.map { endList.addAll(it) }
63+
plannerItems.map { items ->
64+
// Filter out assignments, quizzes, and calendar events as they're already fetched above
65+
val filteredItems = items.filter {
66+
it.plannableType != com.instructure.canvasapi2.models.PlannableType.ASSIGNMENT &&
67+
it.plannableType != com.instructure.canvasapi2.models.PlannableType.QUIZ &&
68+
it.plannableType != com.instructure.canvasapi2.models.PlannableType.CALENDAR_EVENT
69+
}
70+
endList.addAll(filteredItems.map { it.toScheduleItem() })
71+
}
6372

6473
endList.sort()
6574

66-
summaryResult = if (assignments.isFail && events.isFail) {
75+
summaryResult = if (assignments.isFail && events.isFail && plannerItems.isFail) {
6776
DataResult.Fail((assignments as? DataResult.Fail)?.failure)
6877
} else {
6978
DataResult.Success(endList)

apps/student/src/main/java/com/instructure/student/mobius/syllabus/SyllabusRepository.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package com.instructure.student.mobius.syllabus
2121
import com.instructure.canvasapi2.apis.CalendarEventAPI
2222
import com.instructure.canvasapi2.models.Course
2323
import com.instructure.canvasapi2.models.CourseSettings
24+
import com.instructure.canvasapi2.models.PlannerItem
2425
import com.instructure.canvasapi2.models.ScheduleItem
2526
import com.instructure.canvasapi2.utils.DataResult
2627
import com.instructure.pandautils.repository.Repository
@@ -55,4 +56,14 @@ class SyllabusRepository(
5556
): DataResult<List<ScheduleItem>> {
5657
return dataSource().getCalendarEvents(allEvents, type, startDate, endDate, canvasContexts, forceNetwork)
5758
}
59+
60+
suspend fun getPlannerItems(
61+
startDate: String?,
62+
endDate: String?,
63+
contextCodes: List<String>,
64+
filter: String?,
65+
forceNetwork: Boolean
66+
): DataResult<List<PlannerItem>> {
67+
return dataSource().getPlannerItems(startDate, endDate, contextCodes, filter, forceNetwork)
68+
}
5869
}

apps/student/src/main/java/com/instructure/student/mobius/syllabus/datasource/SyllabusDataSource.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package com.instructure.student.mobius.syllabus.datasource
2121
import com.instructure.canvasapi2.apis.CalendarEventAPI
2222
import com.instructure.canvasapi2.models.Course
2323
import com.instructure.canvasapi2.models.CourseSettings
24+
import com.instructure.canvasapi2.models.PlannerItem
2425
import com.instructure.canvasapi2.models.ScheduleItem
2526
import com.instructure.canvasapi2.utils.DataResult
2627

@@ -38,4 +39,12 @@ interface SyllabusDataSource {
3839
canvasContexts: List<String>,
3940
forceNetwork: Boolean
4041
): DataResult<List<ScheduleItem>>
42+
43+
suspend fun getPlannerItems(
44+
startDate: String?,
45+
endDate: String?,
46+
contextCodes: List<String>,
47+
filter: String?,
48+
forceNetwork: Boolean
49+
): DataResult<List<PlannerItem>>
4150
}

apps/student/src/main/java/com/instructure/student/mobius/syllabus/datasource/SyllabusLocalDataSource.kt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,19 @@ package com.instructure.student.mobius.syllabus.datasource
2121
import com.instructure.canvasapi2.apis.CalendarEventAPI
2222
import com.instructure.canvasapi2.models.Course
2323
import com.instructure.canvasapi2.models.CourseSettings
24+
import com.instructure.canvasapi2.models.PlannerItem
2425
import com.instructure.canvasapi2.models.ScheduleItem
2526
import com.instructure.canvasapi2.utils.DataResult
2627
import com.instructure.pandautils.room.offline.daos.CourseSettingsDao
28+
import com.instructure.pandautils.room.offline.daos.PlannerItemDao
2729
import com.instructure.pandautils.room.offline.facade.CourseFacade
2830
import com.instructure.pandautils.room.offline.facade.ScheduleItemFacade
2931

3032
class SyllabusLocalDataSource(
3133
private val courseSettingsDao: CourseSettingsDao,
3234
private val courseFacade: CourseFacade,
33-
private val scheduleItemFacade: ScheduleItemFacade
35+
private val scheduleItemFacade: ScheduleItemFacade,
36+
private val plannerItemDao: PlannerItemDao
3437
) : SyllabusDataSource {
3538

3639
override suspend fun getCourseSettings(courseId: Long, forceNetwork: Boolean): CourseSettings? {
@@ -58,4 +61,31 @@ class SyllabusLocalDataSource(
5861
}
5962

6063
}
64+
65+
override suspend fun getPlannerItems(
66+
startDate: String?,
67+
endDate: String?,
68+
contextCodes: List<String>,
69+
filter: String?,
70+
forceNetwork: Boolean
71+
): DataResult<List<PlannerItem>> {
72+
return try {
73+
val courseIds = contextCodes.mapNotNull { contextCode ->
74+
val parts = contextCode.split("_")
75+
if (parts.size == 2 && parts[0] == "course") {
76+
parts[1].toLongOrNull()
77+
} else null
78+
}
79+
80+
val plannerItems = if (courseIds.isNotEmpty()) {
81+
plannerItemDao.findByCourseIds(courseIds).map { it.toApiModel() }
82+
} else {
83+
emptyList()
84+
}
85+
86+
DataResult.Success(plannerItems)
87+
} catch (e: Exception) {
88+
DataResult.Fail()
89+
}
90+
}
6191
}

apps/student/src/main/java/com/instructure/student/mobius/syllabus/datasource/SyllabusNetworkDataSource.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,19 @@ package com.instructure.student.mobius.syllabus.datasource
2020

2121
import com.instructure.canvasapi2.apis.CalendarEventAPI
2222
import com.instructure.canvasapi2.apis.CourseAPI
23+
import com.instructure.canvasapi2.apis.PlannerAPI
2324
import com.instructure.canvasapi2.builders.RestParams
2425
import com.instructure.canvasapi2.models.Course
2526
import com.instructure.canvasapi2.models.CourseSettings
27+
import com.instructure.canvasapi2.models.PlannerItem
2628
import com.instructure.canvasapi2.models.ScheduleItem
2729
import com.instructure.canvasapi2.utils.DataResult
2830
import com.instructure.canvasapi2.utils.depaginate
2931

3032
class SyllabusNetworkDataSource(
3133
private val courseApi: CourseAPI.CoursesInterface,
32-
private val calendarEventApi: CalendarEventAPI.CalendarEventInterface
34+
private val calendarEventApi: CalendarEventAPI.CalendarEventInterface,
35+
private val plannerApi: PlannerAPI.PlannerInterface
3336
) : SyllabusDataSource {
3437

3538
override suspend fun getCourseSettings(courseId: Long, forceNetwork: Boolean): CourseSettings? {
@@ -60,4 +63,21 @@ class SyllabusNetworkDataSource(
6063
restParams
6164
).depaginate { calendarEventApi.next(it, restParams) }
6265
}
66+
67+
override suspend fun getPlannerItems(
68+
startDate: String?,
69+
endDate: String?,
70+
contextCodes: List<String>,
71+
filter: String?,
72+
forceNetwork: Boolean
73+
): DataResult<List<PlannerItem>> {
74+
val restParams = RestParams(usePerPageQueryParam = true, isForceReadFromNetwork = forceNetwork)
75+
return plannerApi.getPlannerItems(
76+
startDate,
77+
endDate,
78+
contextCodes,
79+
filter,
80+
restParams
81+
).depaginate { plannerApi.nextPagePlannerItems(it, restParams) }
82+
}
6383
}

apps/student/src/main/java/com/instructure/student/widget/todo/ToDoWidgetRepository.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class ToDoWidgetRepository(
4949
startDate,
5050
endDate,
5151
contextCodes,
52+
null,
5253
restParams
5354
).depaginate {
5455
plannerApi.nextPagePlannerItems(it, restParams)

apps/student/src/test/java/com/instructure/student/features/calendar/StudentCalendarRepositoryTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class StudentCalendarRepositoryTest {
5555

5656
@Test(expected = IllegalStateException::class)
5757
fun `Throw exception when request fails`() = runTest {
58-
coEvery { plannerApi.getPlannerItems(any(), any(), any(), any()) } returns DataResult.Fail()
58+
coEvery { plannerApi.getPlannerItems(any(), any(), any(), any(), any()) } returns DataResult.Fail()
5959

6060
calendarRepository.getPlannerItems("2023-1-1", "2023-1-2", emptyList(), true)
6161
}
@@ -73,7 +73,7 @@ class StudentCalendarRepositoryTest {
7373
createPlannerItem(2, 6, PlannableType.CALENDAR_EVENT)
7474
)
7575

76-
coEvery { plannerApi.getPlannerItems(any(), any(), any(), any()) } returns DataResult.Success(plannerItems)
76+
coEvery { plannerApi.getPlannerItems(any(), any(), any(), any(), any()) } returns DataResult.Success(plannerItems)
7777

7878
val result = calendarRepository.getPlannerItems("2023-1-1", "2023-1-2", emptyList(), true)
7979

@@ -92,7 +92,7 @@ class StudentCalendarRepositoryTest {
9292
createPlannerItem(2, 6, PlannableType.CALENDAR_EVENT)
9393
)
9494

95-
coEvery { plannerApi.getPlannerItems(any(), any(), any(), any()) } returns DataResult.Success(
95+
coEvery { plannerApi.getPlannerItems(any(), any(), any(), any(), any()) } returns DataResult.Success(
9696
plannerItems1,
9797
linkHeaders = LinkHeaders(nextUrl = "next")
9898
)

apps/student/src/test/java/com/instructure/student/test/syllabus/SyllabusEffectHandlerTest.kt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ class SyllabusEffectHandlerTest : Assert() {
105105
)
106106
} returns DataResult.Fail()
107107

108+
coEvery {
109+
syllabusRepository.getPlannerItems(
110+
any(),
111+
any(),
112+
any(),
113+
any(),
114+
any()
115+
)
116+
} returns DataResult.Fail()
117+
108118
connection.accept(SyllabusEffect.LoadData(courseId, false))
109119

110120
verify(timeout = 100) {
@@ -170,6 +180,16 @@ class SyllabusEffectHandlerTest : Assert() {
170180
)
171181
} returns DataResult.Success(calendarEvents)
172182

183+
coEvery {
184+
syllabusRepository.getPlannerItems(
185+
any(),
186+
any(),
187+
any(),
188+
any(),
189+
any()
190+
)
191+
} returns DataResult.Success(emptyList())
192+
173193
connection.accept(SyllabusEffect.LoadData(courseId, false))
174194

175195
verify(timeout = 100) {
@@ -217,6 +237,16 @@ class SyllabusEffectHandlerTest : Assert() {
217237
)
218238
} returns DataResult.Fail()
219239

240+
coEvery {
241+
syllabusRepository.getPlannerItems(
242+
any(),
243+
any(),
244+
any(),
245+
any(),
246+
any()
247+
)
248+
} returns DataResult.Success(emptyList())
249+
220250
connection.accept(SyllabusEffect.LoadData(courseId, false))
221251

222252
verify(timeout = 100) {
@@ -264,6 +294,16 @@ class SyllabusEffectHandlerTest : Assert() {
264294
)
265295
} returns DataResult.Success(calendarEvents)
266296

297+
coEvery {
298+
syllabusRepository.getPlannerItems(
299+
any(),
300+
any(),
301+
any(),
302+
any(),
303+
any()
304+
)
305+
} returns DataResult.Success(emptyList())
306+
267307
connection.accept(SyllabusEffect.LoadData(courseId, false))
268308

269309
verify(timeout = 100) {

0 commit comments

Comments
 (0)