Skip to content

Commit

Permalink
[Student][MBL-13267] Graded non-gradeable assignment push notificatio…
Browse files Browse the repository at this point in the history
…n work around (#334)

* [Student][MBL-13267] Graded non-gradeable assignment push notification work around

* Add test for new logic
  • Loading branch information
StephenBrough authored Oct 3, 2019
1 parent ba7563d commit 007afd2
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,6 @@ data class AssignmentDetailsModel(
val quizResult: DataResult<Quiz>? = null,
val ltiTool: DataResult<LTITool>? = null,
val databaseSubmission: Submission? = null,
val videoFileUri: Uri? = null
val videoFileUri: Uri? = null,
var shouldRouteToSubmissionDetails: Boolean = false
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
package com.instructure.student.mobius.assignmentDetails

import com.instructure.canvasapi2.models.Assignment
import com.instructure.canvasapi2.models.Quiz
import com.instructure.canvasapi2.utils.*
import com.instructure.canvasapi2.utils.DataResult
import com.instructure.canvasapi2.utils.mapToAttachment
import com.instructure.canvasapi2.utils.toApiString
import com.instructure.student.Submission
import com.instructure.student.mobius.common.ui.UpdateInit
import com.spotify.mobius.First
Expand Down Expand Up @@ -109,17 +110,23 @@ class AssignmentDetailsUpdate : UpdateInit<AssignmentDetailsModel, AssignmentDet
}
is AssignmentDetailsEvent.DataLoaded -> {
val dbSubmission = dbSubmissionIfNewest(event.submission, event.assignmentResult?.dataOrNull?.submission)
Next.next<AssignmentDetailsModel, AssignmentDetailsEffect>(
model.copy(
isLoading = false,
assignmentResult = event.assignmentResult,
isStudioEnabled = event.isStudioEnabled,
studioLTIToolResult = event.studioLTIToolResult,
ltiTool = event.ltiToolResult,
quizResult = event.quizResult,
databaseSubmission = dbSubmission
)
val newModel = model.copy(
isLoading = false,
assignmentResult = event.assignmentResult,
isStudioEnabled = event.isStudioEnabled,
studioLTIToolResult = event.studioLTIToolResult,
ltiTool = event.ltiToolResult,
quizResult = event.quizResult,
databaseSubmission = dbSubmission
)

if (newModel.shouldRouteToSubmissionDetails) {
Next.next<AssignmentDetailsModel, AssignmentDetailsEffect>(
newModel.copy(shouldRouteToSubmissionDetails = false), setOf(AssignmentDetailsEffect.ShowSubmissionView(model.assignmentId, model.course))
)
} else {
Next.next<AssignmentDetailsModel, AssignmentDetailsEffect>(newModel)
}
}
is AssignmentDetailsEvent.InternalRouteRequested -> {
val effect = AssignmentDetailsEffect.RouteInternally(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ class AssignmentDetailsFragment :
MobiusFragment<AssignmentDetailsModel, AssignmentDetailsEvent, AssignmentDetailsEffect, AssignmentDetailsView, AssignmentDetailsViewState>(),
Bookmarkable {

val canvasContext by ParcelableArg<Course>(key = Const.CANVAS_CONTEXT)
@get:PageViewUrlParam(name = "assignmentId")
val assignmentId by LongArg(key = Const.ASSIGNMENT_ID)
val submissionId by StringArg(key = Const.SUBMISSION_ID, default = "")

override val bookmark: Bookmarker
get() {
val assignment = controller.model.assignmentResult?.dataOrNull
Expand All @@ -48,16 +53,11 @@ class AssignmentDetailsFragment :
)
}

val canvasContext by ParcelableArg<Course>(key = Const.CANVAS_CONTEXT)

override fun onCreate(savedInstanceState: Bundle?) {
NewRelic.setInteractionName(this::class.java.simpleName)
super.onCreate(savedInstanceState)
}

@get:PageViewUrlParam(name = "assignmentId")
val assignmentId by LongArg(key = Const.ASSIGNMENT_ID)

override fun makeEffectHandler() = AssignmentDetailsEffectHandler(requireContext(), assignmentId)

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

override fun makePresenter() = AssignmentDetailsPresenter

override fun makeInitModel() = AssignmentDetailsModel(assignmentId, canvasContext)
override fun makeInitModel() = AssignmentDetailsModel(assignmentId, canvasContext, shouldRouteToSubmissionDetails = submissionId.isNotBlank())

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

companion object {

const val VIDEO_REQUEST_CODE = 45519
const val CHOOSE_MEDIA_REQUEST_CODE = 45520

Expand Down Expand Up @@ -101,13 +100,17 @@ class AssignmentDetailsFragment :
CanvasRestAdapter.clearCacheUrls("assignments/$assignmentId")
}

if (route.paramsHash.containsKey(RouterParams.SUBMISSION_ID)) {
// 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
// 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)
route.arguments.putString(Const.SUBMISSION_ID, route.paramsHash[RouterParams.SUBMISSION_ID])
}

return AssignmentDetailsFragment().withArgs(route.arguments)
}

fun isFileRequest(requestCode: Int): Boolean {
return requestCode in listOf(VIDEO_REQUEST_CODE, CHOOSE_MEDIA_REQUEST_CODE)
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ object RouteMatcher : BaseRouteMatcher() {
// Submissions
// :sliding_tab_type can be /rubric or /submissions (used to navigate to the nested fragment)
routes.add(Route(courseOrGroup("/:${RouterParams.COURSE_ID}/assignments/:${RouterParams.ASSIGNMENT_ID}/:${RouterParams.SLIDING_TAB_TYPE}"), AssignmentDetailsFragment::class.java, SubmissionDetailsFragment::class.java))
routes.add(Route(courseOrGroup("/:${RouterParams.COURSE_ID}/assignments/:${RouterParams.ASSIGNMENT_ID}/:${RouterParams.SLIDING_TAB_TYPE}/:${RouterParams.SUBMISSION_ID}"), AssignmentDetailsFragment::class.java, SubmissionDetailsFragment::class.java))
// 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)
routes.add(Route(courseOrGroup("/:${RouterParams.COURSE_ID}/assignments/:${RouterParams.ASSIGNMENT_ID}/:${RouterParams.SLIDING_TAB_TYPE}/:${RouterParams.SUBMISSION_ID}"), AssignmentDetailsFragment::class.java))

// Settings
routes.add(Route(courseOrGroup("/:${RouterParams.COURSE_ID}/settings"), CourseSettingsFragment::class.java))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,39 @@ class AssignmentDetailsUpdateTest : Assert() {
.then(assertThatNext(NextMatchers.hasModel(expectedModel)))
}

@Test
fun `DataLoaded event with shouldRouteToSubmissionDetails = true, updates model and sends ShowSubmissionView effect`() {
val assignment = Assignment(id = assignmentId)
val submission = mockkSubmission()
val startModel = initModel.copy(shouldRouteToSubmissionDetails = true)
val expectedModel = initModel.copy(
isLoading = false,
assignmentResult = DataResult.Success(assignment),
isStudioEnabled = true,
ltiTool = DataResult.Fail(null),
databaseSubmission = submission,
shouldRouteToSubmissionDetails = false
)
updateSpec
.given(startModel)
.whenEvent(
AssignmentDetailsEvent.DataLoaded(
assignmentResult = expectedModel.assignmentResult,
isStudioEnabled = true,
studioLTIToolResult = null,
ltiToolResult = expectedModel.ltiTool,
submission = submission,
quizResult = null
)
)
.then(
assertThatNext(
NextMatchers.hasModel(expectedModel),
matchesEffects<AssignmentDetailsModel, AssignmentDetailsEffect>(AssignmentDetailsEffect.ShowSubmissionView(expectedModel.assignmentId, expectedModel.course))
)
)
}

@Test
fun `SubmissionStatusUpdated event updates the model`() {
val submission = mockkSubmission()
Expand Down
Loading

0 comments on commit 007afd2

Please sign in to comment.