Skip to content

Commit 2de6630

Browse files
authored
Merge pull request #2664 from instructure/release/parent-3.14.0-54
Release Parent 3.14.0 (54)
2 parents 18710ff + a7594d8 commit 2de6630

File tree

1,052 files changed

+34086
-8269
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,052 files changed

+34086
-8269
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ App | Description
5959
Module | Description
6060
--- | ---
6161
annotations | A wrapper for the PSPDFKit library and logic for annotation handling and converting in PDF documents.
62-
blueprint | An MVP Architecture that depends on PandaRecyclerView. (deprecated)
6362
buildSrc | Library for common gradle dependencies and gradle transformers that are used by the project.
6463
canvas-api-2 | Canvas for Android Api used to talk to the Canvas LMS and is testable.
6564
dataseedingapi | gRPC wrapper for Canvas that enables creating data to test the apps.

apps/flutter_parent/lib/l10n/res/intl_fr_CA.arb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@
741741
"placeholders_order": [],
742742
"placeholders": {}
743743
},
744-
"Syllabus": "Programme",
744+
"Syllabus": "Plan de cours",
745745
"@Syllabus": {
746746
"description": "Label for the \"Syllabus\" tab in course details",
747747
"type": "text",

apps/flutter_parent/lib/screens/login_landing_screen.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class LoginLandingScreen extends StatelessWidget {
6363
// TODO: needs test
6464
locator<QuickNav>().push(
6565
context,
66-
WebLoginScreen(snicker.domain,
66+
WebLoginScreen(
67+
snicker.domain,
6768
user: snicker.username,
6869
pass: snicker.password),
6970
);
@@ -361,7 +362,7 @@ class LoginLandingScreen extends StatelessWidget {
361362
locator<QuickNav>().pushRoute(
362363
context,
363364
PandaRouter.loginWeb(lastAccount.item1.domain,
364-
accountName: lastAccount.item1.name!, loginFlow: lastAccount.item2));
365+
accountName: lastAccount.item1.name!, authenticationProvider: lastAccount.item1.authenticationProvider, loginFlow: lastAccount.item2));
365366
}
366367

367368
void _changeLoginFlow(BuildContext context) {

apps/flutter_parent/lib/screens/web_login/web_login_screen.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ class _WebLoginScreenState extends State<WebLoginScreen> {
216216
);
217217
final lastAccount = new SchoolDomain((builder) =>
218218
builder
219+
..authenticationProvider = widget.authenticationProvider
219220
..domain = widget.domain
220221
..name = widget.accountName);
221222
ApiPrefs.setLastAccount(lastAccount, widget.loginFlow);

apps/flutter_parent/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ description: Canvas Parent
2525
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
2626
# Read more about iOS versioning at
2727
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
28-
version: 3.13.0+53
28+
version: 3.14.0+54
2929

3030
module:
3131
androidX: true

apps/parent/src/androidTest/java/com/instructure/parentapp/ui/compose/courses/details/CourseDetailsScreenTest.kt

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ package com.instructure.parentapp.ui.compose.courses.details
2020
import androidx.compose.ui.test.assertHasClickAction
2121
import androidx.compose.ui.test.assertIsDisplayed
2222
import androidx.compose.ui.test.assertIsNotDisplayed
23+
import androidx.compose.ui.test.hasAnyAncestor
2324
import androidx.compose.ui.test.hasContentDescription
2425
import androidx.compose.ui.test.hasParent
2526
import androidx.compose.ui.test.hasTestTag
27+
import androidx.compose.ui.test.hasText
2628
import androidx.compose.ui.test.junit4.createComposeRule
2729
import androidx.compose.ui.test.onNodeWithContentDescription
2830
import androidx.compose.ui.test.onNodeWithTag
@@ -50,6 +52,7 @@ class CourseDetailsScreenTest {
5052
isLoading = true
5153
),
5254
actionHandler = {},
55+
applyOnWebView = {},
5356
navigationActionClick = {}
5457
)
5558
}
@@ -67,6 +70,7 @@ class CourseDetailsScreenTest {
6770
isError = true
6871
),
6972
actionHandler = {},
73+
applyOnWebView = {},
7074
navigationActionClick = {}
7175
)
7276
}
@@ -86,9 +90,10 @@ class CourseDetailsScreenTest {
8690
isLoading = false,
8791
isError = false,
8892
courseName = "Course 1",
89-
tabs = listOf(TabType.SYLLABUS, TabType.SUMMARY)
93+
tabs = listOf(TabType.SYLLABUS)
9094
),
9195
actionHandler = {},
96+
applyOnWebView = {},
9297
navigationActionClick = {}
9398
)
9499
}
@@ -100,21 +105,13 @@ class CourseDetailsScreenTest {
100105
.assertHasClickAction()
101106
composeTestRule.onNodeWithText("Course 1")
102107
.assertIsDisplayed()
103-
composeTestRule.onNodeWithText("SYLLABUS")
104-
.assertIsDisplayed()
105-
composeTestRule.onNodeWithText("SUMMARY")
106-
.assertIsDisplayed()
107-
composeTestRule.onNodeWithTag("courseDetailsTabRow")
108-
.assertIsDisplayed()
109-
composeTestRule.onNodeWithTag("courseDetailsPager")
110-
.assertIsDisplayed()
111108
composeTestRule.onNodeWithContentDescription("Send a message about this course")
112109
.assertIsDisplayed()
113110
.assertHasClickAction()
114111
}
115112

116113
@Test
117-
fun assertCourseDetailsContentWithJustOnTab() {
114+
fun assertCourseDetailsContentWithJustOneTab() {
118115
composeTestRule.setContent {
119116
CourseDetailsScreen(
120117
uiState = CourseDetailsUiState(
@@ -124,6 +121,7 @@ class CourseDetailsScreenTest {
124121
tabs = listOf(TabType.SYLLABUS)
125122
),
126123
actionHandler = {},
124+
applyOnWebView = {},
127125
navigationActionClick = {}
128126
)
129127
}
@@ -138,4 +136,25 @@ class CourseDetailsScreenTest {
138136
.assertIsDisplayed()
139137
.assertHasClickAction()
140138
}
139+
140+
@Test
141+
fun assertSnackbarText() {
142+
composeTestRule.setContent {
143+
CourseDetailsScreen(
144+
uiState = CourseDetailsUiState(
145+
isLoading = false,
146+
isError = false,
147+
courseName = "Course 1",
148+
tabs = listOf(TabType.SYLLABUS),
149+
snackbarMessage = "Snackbar message"
150+
),
151+
actionHandler = {},
152+
applyOnWebView = {},
153+
navigationActionClick = {}
154+
)
155+
}
156+
157+
val snackbarText = composeTestRule.onNode(hasText("Snackbar message").and(hasAnyAncestor(hasTestTag("snackbarHost"))))
158+
snackbarText.assertIsDisplayed()
159+
}
141160
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright (C) 2024 - present Instructure, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
package com.instructure.parentapp.ui.compose.courses.details.frontpage
19+
20+
import androidx.compose.ui.test.assertHasClickAction
21+
import androidx.compose.ui.test.assertIsDisplayed
22+
import androidx.compose.ui.test.junit4.createComposeRule
23+
import androidx.compose.ui.test.onNodeWithTag
24+
import androidx.compose.ui.test.onNodeWithText
25+
import androidx.test.ext.junit.runners.AndroidJUnit4
26+
import com.instructure.parentapp.features.courses.details.frontpage.FrontPageContent
27+
import com.instructure.parentapp.features.courses.details.frontpage.FrontPageUiState
28+
import org.junit.Rule
29+
import org.junit.Test
30+
import org.junit.runner.RunWith
31+
32+
33+
@RunWith(AndroidJUnit4::class)
34+
class FrontPageScreenTest {
35+
36+
@get:Rule
37+
val composeTestRule = createComposeRule()
38+
39+
@Test
40+
fun assertLoadingContent() {
41+
composeTestRule.setContent {
42+
FrontPageContent(
43+
uiState = FrontPageUiState(
44+
isLoading = true
45+
),
46+
actionHandler = {},
47+
applyOnWebView = {},
48+
onLtiButtonPressed = {}
49+
)
50+
}
51+
52+
composeTestRule.onNodeWithTag("loading")
53+
.assertIsDisplayed()
54+
}
55+
56+
@Test
57+
fun assertErrorContent() {
58+
composeTestRule.setContent {
59+
FrontPageContent(
60+
uiState = FrontPageUiState(
61+
isLoading = false,
62+
isError = true
63+
),
64+
actionHandler = {},
65+
applyOnWebView = {},
66+
onLtiButtonPressed = {}
67+
)
68+
}
69+
70+
composeTestRule.onNodeWithText("An unexpected error occurred.")
71+
.assertIsDisplayed()
72+
composeTestRule.onNodeWithText("Retry")
73+
.assertIsDisplayed()
74+
.assertHasClickAction()
75+
}
76+
77+
@Test
78+
fun assertCourseDetailsContent() {
79+
composeTestRule.setContent {
80+
FrontPageContent(
81+
uiState = FrontPageUiState(
82+
isLoading = false,
83+
isError = false,
84+
htmlContent = "Front page content"
85+
),
86+
actionHandler = {},
87+
applyOnWebView = {},
88+
onLtiButtonPressed = {}
89+
)
90+
}
91+
92+
composeTestRule.onNodeWithTag("CourseDetailsWebViewScreen")
93+
.assertIsDisplayed()
94+
}
95+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright (C) 2024 - present Instructure, Inc.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, version 3 of the License.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License
14+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
*
16+
*/
17+
package com.instructure.parentapp.ui.compose.courses.details.summary
18+
19+
import androidx.compose.ui.test.assertHasClickAction
20+
import androidx.compose.ui.test.assertIsDisplayed
21+
import androidx.compose.ui.test.junit4.createComposeRule
22+
import androidx.compose.ui.test.onNodeWithTag
23+
import androidx.compose.ui.test.onNodeWithText
24+
import androidx.test.ext.junit.runners.AndroidJUnit4
25+
import com.instructure.canvasapi2.models.ScheduleItem
26+
import com.instructure.canvasapi2.utils.toApiString
27+
import com.instructure.canvasapi2.utils.toSimpleDate
28+
import com.instructure.pandautils.utils.toFormattedString
29+
import com.instructure.parentapp.features.courses.details.summary.ScreenState
30+
import com.instructure.parentapp.features.courses.details.summary.SummaryContent
31+
import com.instructure.parentapp.features.courses.details.summary.SummaryUiState
32+
import org.junit.Rule
33+
import org.junit.Test
34+
import org.junit.runner.RunWith
35+
import java.util.Calendar
36+
37+
@RunWith(AndroidJUnit4::class)
38+
class SummaryScreenTest {
39+
@get:Rule
40+
val composeTestRule = createComposeRule()
41+
42+
@Test
43+
fun assertLoadingContent() {
44+
composeTestRule.setContent {
45+
SummaryContent(
46+
uiState = SummaryUiState(
47+
state = ScreenState.Loading
48+
),
49+
onRefresh = {},
50+
navigateToAssignmentDetails = { _, _ ->},
51+
navigateToCalendarEvent = { _, _, _ ->}
52+
)
53+
}
54+
55+
composeTestRule.onNodeWithTag("Loading")
56+
.assertIsDisplayed()
57+
}
58+
59+
@Test
60+
fun assertErrorContent() {
61+
composeTestRule.setContent {
62+
SummaryContent(
63+
uiState = SummaryUiState(
64+
state = ScreenState.Error
65+
),
66+
onRefresh = {},
67+
navigateToAssignmentDetails = { _, _ ->},
68+
navigateToCalendarEvent = { _, _, _ ->}
69+
)
70+
}
71+
72+
composeTestRule.onNodeWithText("Failed to load summary")
73+
.assertIsDisplayed()
74+
composeTestRule.onNodeWithText("Retry")
75+
.assertIsDisplayed()
76+
.assertHasClickAction()
77+
}
78+
79+
@Test
80+
fun assertEmptyContent() {
81+
composeTestRule.setContent {
82+
SummaryContent(
83+
uiState = SummaryUiState(
84+
state = ScreenState.Empty
85+
),
86+
onRefresh = {},
87+
navigateToAssignmentDetails = { _, _ ->},
88+
navigateToCalendarEvent = { _, _, _ ->}
89+
)
90+
}
91+
92+
composeTestRule.onNodeWithText("No summary items to display")
93+
.assertIsDisplayed()
94+
}
95+
96+
@Test
97+
fun assertSuccessContent() {
98+
val assignmentDueDate = Calendar.getInstance().apply { add(Calendar.DAY_OF_MONTH, 1) }
99+
composeTestRule.setContent {
100+
SummaryContent(
101+
uiState = SummaryUiState(
102+
state = ScreenState.Content,
103+
courseId = 1,
104+
items = listOf(
105+
ScheduleItem(
106+
title = "Assignment 1",
107+
startAt = assignmentDueDate.time.toApiString(),
108+
type = "assignment"
109+
),
110+
ScheduleItem(
111+
title = "Calendar 1",
112+
type = "event"
113+
)
114+
)
115+
),
116+
onRefresh = {},
117+
navigateToAssignmentDetails = { _, _ ->},
118+
navigateToCalendarEvent = { _, _, _ ->}
119+
)
120+
}
121+
122+
composeTestRule.onNodeWithText("Assignment 1")
123+
.assertIsDisplayed()
124+
composeTestRule.onNodeWithText(assignmentDueDate.time.toApiString().toSimpleDate()?.toFormattedString().orEmpty())
125+
.assertIsDisplayed()
126+
127+
composeTestRule.onNodeWithText("Calendar 1")
128+
.assertIsDisplayed()
129+
composeTestRule.onNodeWithText("No Due Date")
130+
.assertIsDisplayed()
131+
}
132+
}

0 commit comments

Comments
 (0)