Skip to content

Commit

Permalink
[student][MBL-13019][RC-6.6] Fix assignment deets discussion crash (#217
Browse files Browse the repository at this point in the history
)

* [student][MBL-13019] Fix assignment deets discussion crash

* improve the bad stuff

* fix it lmao
  • Loading branch information
TrevorNeedham authored Aug 7, 2019
1 parent 5c9bcef commit 38f1f70
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ package com.instructure.student.mobius.assignmentDetails

import android.content.Context
import androidx.core.content.ContextCompat
import com.instructure.canvasapi2.models.Assignment
import com.instructure.canvasapi2.models.DiscussionTopicHeader
import com.instructure.canvasapi2.models.Quiz
import com.instructure.canvasapi2.models.*
import com.instructure.canvasapi2.utils.DateHelper
import com.instructure.canvasapi2.utils.NumberHelper
import com.instructure.canvasapi2.utils.isRtl
Expand All @@ -37,6 +35,8 @@ import com.instructure.student.mobius.assignmentDetails.ui.gradeCell.GradeCellVi
import com.instructure.student.mobius.common.ui.Presenter
import java.text.DateFormat
import java.util.*
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract

object AssignmentDetailsPresenter : Presenter<AssignmentDetailsModel, AssignmentDetailsViewState> {
override fun present(model: AssignmentDetailsModel, context: Context): AssignmentDetailsViewState {
Expand Down Expand Up @@ -290,13 +290,17 @@ object AssignmentDetailsPresenter : Presenter<AssignmentDetailsModel, Assignment
}

private fun getDiscussionHeaderViewState(context: Context, discussionTopicHeader: DiscussionTopicHeader): DiscussionHeaderViewState {
val authorAvatarUrl = discussionTopicHeader.author?.avatarImageUrl
// Can't have a discussion topic header with a null author or date
val authorName = discussionTopicHeader.author!!.displayName!!
val authoredDate = DateHelper.getMonthDayAtTime(context, discussionTopicHeader.postedDate, context.getString(R.string.at))!!
val attachmentIconVisibility = discussionTopicHeader.attachments.isNotEmpty()
return if (discussionTopicHeader.author.isDiscussionAuthorNull()) {
DiscussionHeaderViewState.NoAuthor
} else {
val authorAvatarUrl = discussionTopicHeader.author?.avatarImageUrl
// Can't have a discussion topic header with a null author or date
val authorName = discussionTopicHeader.author?.displayName ?: context.getString(R.string.discussions_unknown_author)
val authoredDate = DateHelper.getMonthDayAtTime(context, discussionTopicHeader.postedDate, context.getString(R.string.at)) ?: context.getString(R.string.discussions_unknown_date)
val attachmentIconVisibility = discussionTopicHeader.attachments.isNotEmpty()

return DiscussionHeaderViewState(authorAvatarUrl, authorName, authoredDate, attachmentIconVisibility)
DiscussionHeaderViewState.Loaded(authorAvatarUrl, authorName, authoredDate, attachmentIconVisibility)
}
}

private fun getDiscussionText(discussionTopicHeader: DiscussionTopicHeader): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,15 @@ class AssignmentDetailsView(
}

private fun renderDiscussionTopicHeader(discussionHeaderViewState: DiscussionHeaderViewState) {
ProfileUtils.loadAvatarForUser(authorAvatar, discussionHeaderViewState.authorName, discussionHeaderViewState.authorAvatarUrl)
authorAvatar.setupAvatarA11y(discussionHeaderViewState.authorName)
authorName.text = discussionHeaderViewState.authorName
authoredDate.text = discussionHeaderViewState.authoredDate
attachmentIcon.setVisible(discussionHeaderViewState.attachmentIconVisibility)
if(discussionHeaderViewState is DiscussionHeaderViewState.Loaded) {
ProfileUtils.loadAvatarForUser(authorAvatar, discussionHeaderViewState.authorName, discussionHeaderViewState.authorAvatarUrl)
authorAvatar.setupAvatarA11y(discussionHeaderViewState.authorName)
authorName.text = discussionHeaderViewState.authorName
authoredDate.text = discussionHeaderViewState.authoredDate
attachmentIcon.setVisible(discussionHeaderViewState.attachmentIconVisibility)
} else {
discussionTopicHeaderContainer.setVisible(false)
}
}

override fun onDispose() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,15 @@ data class QuizDescriptionViewState(
val allowedAttempts: String
)

data class DiscussionHeaderViewState(
val authorAvatarUrl: String? = null,
val authorName: String,
val authoredDate: String,
val attachmentIconVisibility: Boolean
)
sealed class DiscussionHeaderViewState {

data class Loaded(
val authorAvatarUrl: String? = null,
val authorName: String,
val authoredDate: String,
val attachmentIconVisibility: Boolean
) : DiscussionHeaderViewState()

object NoAuthor : DiscussionHeaderViewState()

}
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,39 @@ class AssignmentDetailsPresenterTest : Assert() {

val model = baseModel.copy(assignmentResult = DataResult.Success(assignment))
val state = AssignmentDetailsPresenter.present(model, context) as AssignmentDetailsViewState.Loaded
val expectedState = DiscussionHeaderViewState(authorAvatarUrl, authorName, authoredDate, attachmentIconVisibility)
val expectedState = DiscussionHeaderViewState.Loaded(authorAvatarUrl, authorName, authoredDate, attachmentIconVisibility)

assertEquals(expectedState, state.discussionHeaderViewState)
}

@Test
fun `Description contains DiscussionHeaderState with unknown author and date, when assignment is discussion with no author name or date`() {
val authorAvatarUrl = "pretty-hodor.com"
val authorName = "Unknown Author"
val authoredDate = "Unknown Date"
val discussionMessage = "yo yo yo"
val attachmentIconVisibility = false
val discussionTopicHeader = baseDiscussion.copy(message = discussionMessage, author = DiscussionParticipant(avatarImageUrl = authorAvatarUrl), postedDate = null)
val assignment = baseAssignment.copy(submissionTypesRaw = listOf("discussion_topic"), discussionTopicHeader = discussionTopicHeader)

val model = baseModel.copy(assignmentResult = DataResult.Success(assignment))
val state = AssignmentDetailsPresenter.present(model, context) as AssignmentDetailsViewState.Loaded
val expectedState = DiscussionHeaderViewState.Loaded(authorAvatarUrl, authorName, authoredDate, attachmentIconVisibility)

assertEquals(expectedState, state.discussionHeaderViewState)
}

@Test
fun `Description contains DiscussionHeaderState NoAuthor with when assignment is discussion with no author`() {
val discussionMessage = "yo yo yo"
val calendar = GregorianCalendar.getInstance()
calendar.set(2019, 6, 23, 9, 59)
val discussionTopicHeader = baseDiscussion.copy(message = discussionMessage, author = DiscussionParticipant(), postedDate = calendar.time)
val assignment = baseAssignment.copy(submissionTypesRaw = listOf("discussion_topic"), discussionTopicHeader = discussionTopicHeader)

val model = baseModel.copy(assignmentResult = DataResult.Success(assignment))
val state = AssignmentDetailsPresenter.present(model, context) as AssignmentDetailsViewState.Loaded
val expectedState = DiscussionHeaderViewState.NoAuthor

assertEquals(expectedState, state.discussionHeaderViewState)
}
Expand All @@ -662,7 +694,7 @@ class AssignmentDetailsPresenterTest : Assert() {

val model = baseModel.copy(assignmentResult = DataResult.Success(assignment))
val state = AssignmentDetailsPresenter.present(model, context) as AssignmentDetailsViewState.Loaded
val expectedState = DiscussionHeaderViewState(authorAvatarUrl, authorName, authoredDate, attachmentIconVisibility)
val expectedState = DiscussionHeaderViewState.Loaded(authorAvatarUrl, authorName, authoredDate, attachmentIconVisibility)

assertEquals(expectedState, state.discussionHeaderViewState)
}
Expand Down
1 change: 0 additions & 1 deletion apps/teacher/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,6 @@
<string name="discussions_reply">Reply</string>
<string name="discussions_edit">Edit</string>
<string name="discussions_forbidden">Replies are only visible to those who have posted at least one reply.</string>
<string name="discussions_unknown_author">Unknown Author</string>
<string name="discussions_delete">Delete Discussion</string>
<string name="discussions_delete_title">Delete Discussion?</string>
<string name="discussions_delete_message">This will delete the whole discussion and thread.</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,9 @@ data class DiscussionParticipant(
var avatarImageUrl: String? = null,
@SerializedName("html_url")
var htmlUrl: String? = null
) : CanvasModel<DiscussionParticipant>()
) : CanvasModel<DiscussionParticipant>()

fun DiscussionParticipant?.isDiscussionAuthorNull(): Boolean {
return this == null ||
(id == 0L && displayName == null && avatarImageUrl == null && htmlUrl == null)
}
2 changes: 2 additions & 0 deletions libs/pandares/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,8 @@
<string name="viewDiscussion">View Discussion</string>
<string name="lockedModule">This assignment is locked by the module \"%1$s\".</string>
<string name="chooseMediaFile">Choose Media File</string>
<string name="discussions_unknown_author">Unknown Author</string>
<string name="discussions_unknown_date">Unknown Date</string>
<string name="a11y_gradeLetterMinusContentDescription">%s. minus</string>
<string name="a11y_letterGrade">%s.</string>
<string name="a11y_gradeCellContentDescription">%s %s</string>
Expand Down

0 comments on commit 38f1f70

Please sign in to comment.