Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ import com.instructure.canvasapi2.builders.RestBuilder
import com.instructure.canvasapi2.builders.RestParams
import com.instructure.canvasapi2.models.ErrorReport
import com.instructure.canvasapi2.models.ErrorReportResult
import com.instructure.canvasapi2.utils.DataResult
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST
import retrofit2.http.Query
import retrofit2.http.Tag


object ErrorReportAPI {
Expand Down Expand Up @@ -52,6 +54,20 @@ object ErrorReportAPI {
@Query("error[become_user]") becomeUser: String,
@Body body: String
): Call<ErrorReportResult>

@POST("/api/v1/error_reports")
suspend fun postErrorReport(
@Query("error[subject]") subject: String,
@Query("error[url]") url: String,
@Query("error[email]") email: String,
@Query("error[comments]") comments: String,
@Query("error[user_perceived_severity]") userPerceivedSeverity: String,
@Query("error[name]") name: String,
@Query("error[user_roles]") userRoles: String,
@Query("error[become_user]") becomeUser: String,
@Body body: String,
@Tag params: RestParams,
): DataResult<ErrorReportResult>
}

fun postErrorReport(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,23 @@ package com.instructure.canvasapi2.apis
import com.instructure.canvasapi2.StatusCallback
import com.instructure.canvasapi2.builders.RestBuilder
import com.instructure.canvasapi2.builders.RestParams
import com.instructure.canvasapi2.models.HelpLink
import com.instructure.canvasapi2.models.HelpLinks
import com.instructure.canvasapi2.utils.DataResult
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Tag

object HelpLinksAPI {
interface HelpLinksAPI {
@GET("accounts/self/help_links")
fun getHelpLinks(): Call<HelpLinks>

@GET("accounts/self/help_links")
suspend fun getHelpLinks(@Tag params: RestParams): DataResult<HelpLinks>

@GET("/help_links")
suspend fun getCanvasHelpLinks(@Tag params: RestParams): DataResult<List<HelpLink>>
}

fun getHelpLinks(adapter: RestBuilder, params: RestParams, callback: StatusCallback<HelpLinks>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.instructure.canvasapi2.apis.CourseAPI
import com.instructure.canvasapi2.apis.DiscussionAPI
import com.instructure.canvasapi2.apis.DomainServicesAuthenticationAPI
import com.instructure.canvasapi2.apis.EnrollmentAPI
import com.instructure.canvasapi2.apis.ErrorReportAPI
import com.instructure.canvasapi2.apis.ExperienceAPI
import com.instructure.canvasapi2.apis.ExternalToolAPI
import com.instructure.canvasapi2.apis.FeaturesAPI
Expand Down Expand Up @@ -441,6 +442,16 @@ class ApiModule {
): JourneyAssistAPI {
return journeyRestBuilder.build(JourneyAssistAPI::class.java)
}

@Provides
fun provideErrorReportApi(): ErrorReportAPI.ErrorReportInterface {
return RestBuilder().build(ErrorReportAPI.ErrorReportInterface::class.java, RestParams())
}

@Provides
fun provideHelpLinksInterfaceApi(): HelpLinksAPI.HelpLinksAPI {
return RestBuilder().build(HelpLinksAPI.HelpLinksAPI::class.java, RestParams())
}
}

@EarlyEntryPoint
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
/*
* Copyright (C) 2025 - present Instructure, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.instructure.horizon.ui.features.account

import androidx.compose.ui.test.junit4.createComposeRule
import androidx.navigation.compose.rememberNavController
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.instructure.horizon.features.account.reportabug.ReportABugScreen
import com.instructure.horizon.features.account.reportabug.ReportABugUiState
import com.instructure.horizon.ui.features.account.pages.ReportABugPage
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@HiltAndroidTest
@RunWith(AndroidJUnit4::class)
class ReportABugScreenUiTest {
@get:Rule
val composeTestRule = createComposeRule()

private val page by lazy { ReportABugPage(composeTestRule) }

@Test
fun testScreenDisplaysWithTitle() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertScreenDisplayed()
}

@Test
fun testScreenDisplaysDescriptionMessage() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertDescriptionMessageDisplayed()
}

@Test
fun testScreenDisplaysCloseButton() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertCloseButtonDisplayed()
}

@Test
fun testScreenDisplaysTopicField() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertTopicFieldDisplayed()
}

@Test
fun testScreenDisplaysSubjectField() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertSubjectFieldDisplayed()
}

@Test
fun testScreenDisplaysDescriptionField() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertDescriptionFieldDisplayed()
}

@Test
fun testScreenDisplaysCancelButton() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertCancelButtonDisplayed()
}

@Test
fun testScreenDisplaysSubmitButton() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertSubmitButtonDisplayed()
}

@Test
fun testSubjectFieldShowsRequiredIndicator() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertSubjectRequiredIndicator()
}

@Test
fun testDescriptionFieldShowsRequiredIndicator() {
val uiState = ReportABugUiState()

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertDescriptionRequiredIndicator()
}

@Test
fun testSelectedTopicDisplays() {
val uiState = ReportABugUiState(
selectedTopic = "Minor issue"
)

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertSelectedTopicDisplayed("Minor issue")
}

@Test
fun testTopicErrorDisplays() {
val uiState = ReportABugUiState(
topicError = "Topic is required"
)

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertTopicError("Topic is required")
}

@Test
fun testSubjectErrorDisplays() {
val uiState = ReportABugUiState(
subjectError = "Subject is required"
)

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertSubjectError("Subject is required")
}

@Test
fun testDescriptionErrorDisplays() {
val uiState = ReportABugUiState(
descriptionError = "Description is required"
)

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertDescriptionError("Description is required")
}

@Test
fun testNotLoadingStateEnablesSubmitButton() {
val uiState = ReportABugUiState(
isLoading = false
)

composeTestRule.setContent {
ReportABugScreen(uiState, rememberNavController())
}

page.assertNotLoading()
}

}
Loading
Loading