Skip to content

Commit 007afd2

Browse files
[Student][MBL-13267] Graded non-gradeable assignment push notification work around (#334)
* [Student][MBL-13267] Graded non-gradeable assignment push notification work around * Add test for new logic
1 parent ba7563d commit 007afd2

File tree

7 files changed

+201
-157
lines changed

7 files changed

+201
-157
lines changed

apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/AssignmentDetailsModels.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,6 @@ data class AssignmentDetailsModel(
9191
val quizResult: DataResult<Quiz>? = null,
9292
val ltiTool: DataResult<LTITool>? = null,
9393
val databaseSubmission: Submission? = null,
94-
val videoFileUri: Uri? = null
94+
val videoFileUri: Uri? = null,
95+
var shouldRouteToSubmissionDetails: Boolean = false
9596
)

apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/AssignmentDetailsUpdate.kt

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

1919
import com.instructure.canvasapi2.models.Assignment
20-
import com.instructure.canvasapi2.models.Quiz
21-
import com.instructure.canvasapi2.utils.*
20+
import com.instructure.canvasapi2.utils.DataResult
21+
import com.instructure.canvasapi2.utils.mapToAttachment
22+
import com.instructure.canvasapi2.utils.toApiString
2223
import com.instructure.student.Submission
2324
import com.instructure.student.mobius.common.ui.UpdateInit
2425
import com.spotify.mobius.First
@@ -109,17 +110,23 @@ class AssignmentDetailsUpdate : UpdateInit<AssignmentDetailsModel, AssignmentDet
109110
}
110111
is AssignmentDetailsEvent.DataLoaded -> {
111112
val dbSubmission = dbSubmissionIfNewest(event.submission, event.assignmentResult?.dataOrNull?.submission)
112-
Next.next<AssignmentDetailsModel, AssignmentDetailsEffect>(
113-
model.copy(
114-
isLoading = false,
115-
assignmentResult = event.assignmentResult,
116-
isStudioEnabled = event.isStudioEnabled,
117-
studioLTIToolResult = event.studioLTIToolResult,
118-
ltiTool = event.ltiToolResult,
119-
quizResult = event.quizResult,
120-
databaseSubmission = dbSubmission
121-
)
113+
val newModel = model.copy(
114+
isLoading = false,
115+
assignmentResult = event.assignmentResult,
116+
isStudioEnabled = event.isStudioEnabled,
117+
studioLTIToolResult = event.studioLTIToolResult,
118+
ltiTool = event.ltiToolResult,
119+
quizResult = event.quizResult,
120+
databaseSubmission = dbSubmission
122121
)
122+
123+
if (newModel.shouldRouteToSubmissionDetails) {
124+
Next.next<AssignmentDetailsModel, AssignmentDetailsEffect>(
125+
newModel.copy(shouldRouteToSubmissionDetails = false), setOf(AssignmentDetailsEffect.ShowSubmissionView(model.assignmentId, model.course))
126+
)
127+
} else {
128+
Next.next<AssignmentDetailsModel, AssignmentDetailsEffect>(newModel)
129+
}
123130
}
124131
is AssignmentDetailsEvent.InternalRouteRequested -> {
125132
val effect = AssignmentDetailsEffect.RouteInternally(

apps/student/src/main/java/com/instructure/student/mobius/assignmentDetails/ui/AssignmentDetailsFragment.kt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ class AssignmentDetailsFragment :
3838
MobiusFragment<AssignmentDetailsModel, AssignmentDetailsEvent, AssignmentDetailsEffect, AssignmentDetailsView, AssignmentDetailsViewState>(),
3939
Bookmarkable {
4040

41+
val canvasContext by ParcelableArg<Course>(key = Const.CANVAS_CONTEXT)
42+
@get:PageViewUrlParam(name = "assignmentId")
43+
val assignmentId by LongArg(key = Const.ASSIGNMENT_ID)
44+
val submissionId by StringArg(key = Const.SUBMISSION_ID, default = "")
45+
4146
override val bookmark: Bookmarker
4247
get() {
4348
val assignment = controller.model.assignmentResult?.dataOrNull
@@ -48,16 +53,11 @@ class AssignmentDetailsFragment :
4853
)
4954
}
5055

51-
val canvasContext by ParcelableArg<Course>(key = Const.CANVAS_CONTEXT)
52-
5356
override fun onCreate(savedInstanceState: Bundle?) {
5457
NewRelic.setInteractionName(this::class.java.simpleName)
5558
super.onCreate(savedInstanceState)
5659
}
5760

58-
@get:PageViewUrlParam(name = "assignmentId")
59-
val assignmentId by LongArg(key = Const.ASSIGNMENT_ID)
60-
6161
override fun makeEffectHandler() = AssignmentDetailsEffectHandler(requireContext(), assignmentId)
6262

6363
override fun makeUpdate() = AssignmentDetailsUpdate()
@@ -67,12 +67,11 @@ class AssignmentDetailsFragment :
6767

6868
override fun makePresenter() = AssignmentDetailsPresenter
6969

70-
override fun makeInitModel() = AssignmentDetailsModel(assignmentId, canvasContext)
70+
override fun makeInitModel() = AssignmentDetailsModel(assignmentId, canvasContext, shouldRouteToSubmissionDetails = submissionId.isNotBlank())
7171

7272
override fun getExternalEventSources() = listOf(AssignmentDetailsEventBusSource())
7373

7474
companion object {
75-
7675
const val VIDEO_REQUEST_CODE = 45519
7776
const val CHOOSE_MEDIA_REQUEST_CODE = 45520
7877

@@ -101,13 +100,17 @@ class AssignmentDetailsFragment :
101100
CanvasRestAdapter.clearCacheUrls("assignments/$assignmentId")
102101
}
103102

103+
if (route.paramsHash.containsKey(RouterParams.SUBMISSION_ID)) {
104+
// Indicate that we want to route to the Submission Details page - this will give us a small backstack, allowing the user to hit back and go to Assignment Details instead
105+
// of closing the app (in the case of when the app isn't running and the user hits a push notification that takes them to Submission Details)
106+
route.arguments.putString(Const.SUBMISSION_ID, route.paramsHash[RouterParams.SUBMISSION_ID])
107+
}
108+
104109
return AssignmentDetailsFragment().withArgs(route.arguments)
105110
}
106111

107112
fun isFileRequest(requestCode: Int): Boolean {
108113
return requestCode in listOf(VIDEO_REQUEST_CODE, CHOOSE_MEDIA_REQUEST_CODE)
109114
}
110-
111115
}
112-
113116
}

apps/student/src/main/java/com/instructure/student/router/RouteMatcher.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ object RouteMatcher : BaseRouteMatcher() {
159159
// Submissions
160160
// :sliding_tab_type can be /rubric or /submissions (used to navigate to the nested fragment)
161161
routes.add(Route(courseOrGroup("/:${RouterParams.COURSE_ID}/assignments/:${RouterParams.ASSIGNMENT_ID}/:${RouterParams.SLIDING_TAB_TYPE}"), AssignmentDetailsFragment::class.java, SubmissionDetailsFragment::class.java))
162-
routes.add(Route(courseOrGroup("/:${RouterParams.COURSE_ID}/assignments/:${RouterParams.ASSIGNMENT_ID}/:${RouterParams.SLIDING_TAB_TYPE}/:${RouterParams.SUBMISSION_ID}"), AssignmentDetailsFragment::class.java, SubmissionDetailsFragment::class.java))
162+
// Route to Assignment Details first - no submission/on paper assignments won't have grades on the Submission Details page, but we also need to account for routing to submission comments (Assignment Details will check for that)
163+
routes.add(Route(courseOrGroup("/:${RouterParams.COURSE_ID}/assignments/:${RouterParams.ASSIGNMENT_ID}/:${RouterParams.SLIDING_TAB_TYPE}/:${RouterParams.SUBMISSION_ID}"), AssignmentDetailsFragment::class.java))
163164

164165
// Settings
165166
routes.add(Route(courseOrGroup("/:${RouterParams.COURSE_ID}/settings"), CourseSettingsFragment::class.java))

apps/student/src/test/java/com/instructure/student/test/assignment/details/AssignmentDetailsUpdateTest.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,39 @@ class AssignmentDetailsUpdateTest : Assert() {
488488
.then(assertThatNext(NextMatchers.hasModel(expectedModel)))
489489
}
490490

491+
@Test
492+
fun `DataLoaded event with shouldRouteToSubmissionDetails = true, updates model and sends ShowSubmissionView effect`() {
493+
val assignment = Assignment(id = assignmentId)
494+
val submission = mockkSubmission()
495+
val startModel = initModel.copy(shouldRouteToSubmissionDetails = true)
496+
val expectedModel = initModel.copy(
497+
isLoading = false,
498+
assignmentResult = DataResult.Success(assignment),
499+
isStudioEnabled = true,
500+
ltiTool = DataResult.Fail(null),
501+
databaseSubmission = submission,
502+
shouldRouteToSubmissionDetails = false
503+
)
504+
updateSpec
505+
.given(startModel)
506+
.whenEvent(
507+
AssignmentDetailsEvent.DataLoaded(
508+
assignmentResult = expectedModel.assignmentResult,
509+
isStudioEnabled = true,
510+
studioLTIToolResult = null,
511+
ltiToolResult = expectedModel.ltiTool,
512+
submission = submission,
513+
quizResult = null
514+
)
515+
)
516+
.then(
517+
assertThatNext(
518+
NextMatchers.hasModel(expectedModel),
519+
matchesEffects<AssignmentDetailsModel, AssignmentDetailsEffect>(AssignmentDetailsEffect.ShowSubmissionView(expectedModel.assignmentId, expectedModel.course))
520+
)
521+
)
522+
}
523+
491524
@Test
492525
fun `SubmissionStatusUpdated event updates the model`() {
493526
val submission = mockkSubmission()

0 commit comments

Comments
 (0)