This commit is contained in:
Rune Dyselinck 2023-05-15 21:53:04 +02:00
parent 74526bc984
commit 860fb5fac1
20 changed files with 1492 additions and 49 deletions

View file

@ -3,6 +3,19 @@
<component name="AndroidTestResultsUserPreferences"> <component name="AndroidTestResultsUserPreferences">
<option name="androidTestResultsTableState"> <option name="androidTestResultsTableState">
<map> <map>
<entry key="-2044973516">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1837850877"> <entry key="-1837850877">
<value> <value>
<AndroidTestResultsTableState> <AndroidTestResultsTableState>
@ -16,6 +29,32 @@
</AndroidTestResultsTableState> </AndroidTestResultsTableState>
</value> </value>
</entry> </entry>
<entry key="-1681729085">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1581714358">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1481613533"> <entry key="-1481613533">
<value> <value>
<AndroidTestResultsTableState> <AndroidTestResultsTableState>
@ -44,6 +83,45 @@
</AndroidTestResultsTableState> </AndroidTestResultsTableState>
</value> </value>
</entry> </entry>
<entry key="-1285939142">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1276338630">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1258568374">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1161392067"> <entry key="-1161392067">
<value> <value>
<AndroidTestResultsTableState> <AndroidTestResultsTableState>
@ -57,6 +135,266 @@
</AndroidTestResultsTableState> </AndroidTestResultsTableState>
</value> </value>
</entry> </entry>
<entry key="-1079552584">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1045932662">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-575726278">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-269932762">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-37490609">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="22559516">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="170823802">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="226104554">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="487145018">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="619060798">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="642418831">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="822092471">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1072291594">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1104400266">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1132914986">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1254913002">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1298910724">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1303027710">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1404776915">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1472661094">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_XL_API_30" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1663472220"> <entry key="1663472220">
<value> <value>
<AndroidTestResultsTableState> <AndroidTestResultsTableState>

View file

@ -7,7 +7,7 @@ plugins {
id 'com.google.dagger.hilt.android' id 'com.google.dagger.hilt.android'
// Protobuf // Protobuf
id 'com.google.protobuf' version '0.8.17' id 'com.google.protobuf' version '0.9.0'
// Firebase // Firebase
id 'com.google.gms.google-services' id 'com.google.gms.google-services'

View file

@ -0,0 +1,74 @@
package be.ugent.sel.studeez
import androidx.compose.material.FloatingActionButton
import androidx.compose.ui.test.hasClickAction
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.common.composable.AddButtonActions
import be.ugent.sel.studeez.common.composable.ExpandedAddButton
import org.junit.Rule
import org.junit.Test
class FabTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun expandFabTest() {
var expand = false
composeTestRule.setContent {
FloatingActionButton(
onClick = {expand = true}
) {}
}
composeTestRule.waitForIdle()
composeTestRule
.onNode(hasClickAction())
.assertExists()
.performClick()
assert(expand)
}
@Test
fun fabTest() {
var task = false
var session = false
var friend = false
composeTestRule.setContent {
ExpandedAddButton(
addButtonActions = AddButtonActions(
{task = true},
{friend = true},
{session = true}
)
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithContentDescription("Session")
.assertExists()
.performClick()
composeTestRule
.onNodeWithContentDescription("Task")
.assertExists()
.performClick()
composeTestRule
.onNodeWithContentDescription("Friend")
.assertExists()
.performClick()
assert(task)
assert(session)
assert(friend)
}
}

View file

@ -1,6 +1,9 @@
package be.ugent.sel.studeez package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onAllNodesWithContentDescription
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.drawer.DrawerActions
@ -8,6 +11,7 @@ import be.ugent.sel.studeez.common.composable.feed.FeedUiState
import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions
import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.data.local.models.FeedEntry
import be.ugent.sel.studeez.screens.home.HomeScreen import be.ugent.sel.studeez.screens.home.HomeScreen
import org.junit.Assert
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -16,20 +20,31 @@ class HomeScreenTest {
val composeTestRule = createComposeRule() val composeTestRule = createComposeRule()
@Test @Test
fun sessionRecapTestt() { fun homeScreenTest() {
var saveCalled = false var continueTask = false
composeTestRule.setContent { composeTestRule.setContent {
HomeScreen( HomeScreen(
open = {}, open = {},
drawerActions = DrawerActions({}, {}, {}, {}, {}), drawerActions = DrawerActions({}, {}, {}, {}, {}),
navigationBarActions = NavigationBarActions({false}, {}, {}, {}, {}, {}, {}, {}), navigationBarActions = NavigationBarActions({false}, {}, {}, {}, {}, {}, {}, {}),
feedUiState = FeedUiState.Succes(mapOf()), feedUiState = FeedUiState.Succes(mapOf(
continueTask = {_, _ -> }, "08 May 2023" to listOf(
FeedEntry(
argb_color = 0xFFABD200,
subJectName = "Test Subject",
taskName = "Test Task",
totalStudyTime = 600,
)
)
)),
continueTask = {_, _ -> continueTask = true },
onEmptyFeedHelp = {} onEmptyFeedHelp = {}
) )
} }
composeTestRule.waitForIdle()
composeTestRule composeTestRule
.onNodeWithText( .onNodeWithText(
"continue", "continue",
@ -38,5 +53,155 @@ class HomeScreenTest {
) )
.assertExists() .assertExists()
.performClick() .performClick()
Assert.assertTrue(continueTask)
}
@Test
fun drawerTest() {
var homebuttontest = false
var timersbuttontest = false
var settingsbuttontest = false
var logoutbuttontest = false
var aboutbuttontest = false
composeTestRule.setContent {
HomeScreen(
open = {},
drawerActions = DrawerActions(
{homebuttontest = true},
{timersbuttontest = true},
{settingsbuttontest = true},
{logoutbuttontest = true},
{aboutbuttontest = true}
),
navigationBarActions = NavigationBarActions({false}, {}, {}, {}, {}, {}, {}, {}),
feedUiState = FeedUiState.Succes(mapOf()),
continueTask = {_, _ -> },
onEmptyFeedHelp = {}
)
}
composeTestRule.waitForIdle()
composeTestRule
.onAllNodesWithText(
"home",
substring = true,
ignoreCase = true
)[2] // Third node has the button
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
"timer",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
"settings",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
"log out",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
"about",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
Assert.assertTrue(homebuttontest)
Assert.assertTrue(timersbuttontest)
Assert.assertTrue(settingsbuttontest)
Assert.assertTrue(logoutbuttontest)
Assert.assertTrue(aboutbuttontest)
}
@Test
fun navigationbarTest() {
var hometest = false
var tasktest = false
var sessiontest = false
var profiletest = false
composeTestRule.setContent {
HomeScreen(
open = {},
drawerActions = DrawerActions({}, {}, {}, {}, {}),
navigationBarActions = NavigationBarActions(
{false},
{hometest = true},
{tasktest = true},
{sessiontest = true},
{profiletest = true},
{}, {}, {}
),
feedUiState = FeedUiState.Succes(mapOf()),
continueTask = {_, _ -> },
onEmptyFeedHelp = {}
)
}
composeTestRule.waitForIdle()
composeTestRule
.onAllNodesWithContentDescription(
"Home",
substring = true,
ignoreCase = true
)[0] // Third node has the button
.assertExists()
.performClick()
composeTestRule
.onNodeWithContentDescription(
"tasks",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithContentDescription(
"session",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithContentDescription(
"profile",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
Assert.assertTrue(hometest)
Assert.assertTrue(tasktest)
Assert.assertTrue(sessiontest)
Assert.assertTrue(profiletest)
} }
} }

View file

@ -0,0 +1,68 @@
package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.screens.log_in.LoginScreen
import be.ugent.sel.studeez.screens.log_in.LoginScreenActions
import be.ugent.sel.studeez.screens.log_in.LoginUiState
import org.junit.Rule
import org.junit.Test
class LoginScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun loginScreenTest() {
var login = false
var signup = false
var forgot_password = false
composeTestRule.setContent {
LoginScreen(
uiState = LoginUiState(),
loginScreenActions = LoginScreenActions(
{}, {},
{signup = true},
{login = true},
{forgot_password = true}
)
)
}
composeTestRule.waitForIdle()
composeTestRule
.onAllNodesWithText(
text = "Sign in",
substring = true,
ignoreCase = true
)[0] // The first object is the button
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
text = "Forgot",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
text = "Sign up",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(signup)
assert(login)
assert(forgot_password)
}
}

View file

@ -0,0 +1,68 @@
package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.screens.profile.EditProfileActions
import be.ugent.sel.studeez.screens.profile.EditProfileScreen
import be.ugent.sel.studeez.screens.profile.ProfileEditUiState
import org.junit.Rule
import org.junit.Test
class ProfileEditScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun profileEditScreenTest() {
var edit_save = false
var edit_cancel = false
var goback = false
composeTestRule.setContent {
EditProfileScreen(
goBack = {goback = true},
uiState = ProfileEditUiState(),
editProfileActions = EditProfileActions(
{},
{edit_save = true},
{edit_cancel = true}
)
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "save",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
text = "delete",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithContentDescription(
label = "go back",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(edit_cancel)
assert(edit_save)
assert(goback)
}
}

View file

@ -0,0 +1,42 @@
package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.common.composable.drawer.DrawerActions
import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions
import be.ugent.sel.studeez.screens.profile.ProfileActions
import be.ugent.sel.studeez.screens.profile.ProfileScreen
import org.junit.Rule
import org.junit.Test
class ProfileScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun profileScreenTest() {
var edit = false
composeTestRule.setContent {
ProfileScreen(
profileActions = ProfileActions({null}, {edit = true}),
drawerActions = DrawerActions({}, {}, {}, {}, {}),
navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {})
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithContentDescription(
label = "edit profile",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(edit)
}
}

View file

@ -0,0 +1,75 @@
package be.ugent.sel.studeez
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.data.local.models.SessionReport
import be.ugent.sel.studeez.screens.session_recap.SessionRecapActions
import be.ugent.sel.studeez.screens.session_recap.SessionRecapScreen
import com.google.firebase.Timestamp
import org.junit.Assert
import org.junit.Rule
import org.junit.Test
class SessionRecapScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun sessionRecapTest() {
var saveCalled = false
var discardCalled = false
composeTestRule.setContent {
SessionRecapScreen(
Modifier,
SessionRecapActions(
{
SessionReport(
"",
0,
Timestamp(0, 0),
"")
},
{ saveCalled = true },
{ discardCalled = true }
)
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
"You studied",
substring = true,
ignoreCase = true
)
.assertExists()
composeTestRule
.onNodeWithText(
"save",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
"discard",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
Assert.assertTrue(saveCalled)
Assert.assertTrue(discardCalled)
}
}

View file

@ -1,13 +1,15 @@
package be.ugent.sel.studeez package be.ugent.sel.studeez
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.data.local.models.SessionReport import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer
import be.ugent.sel.studeez.screens.session_recap.SessionRecapActions import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer
import be.ugent.sel.studeez.screens.session_recap.SessionRecapScreen import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer
import com.google.firebase.Timestamp import be.ugent.sel.studeez.screens.session.SessionActions
import be.ugent.sel.studeez.screens.session.sessionScreens.BreakSessionScreen
import be.ugent.sel.studeez.screens.session.sessionScreens.CustomSessionScreen
import be.ugent.sel.studeez.screens.session.sessionScreens.EndlessSessionScreen
import org.junit.Assert import org.junit.Assert
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -18,55 +20,100 @@ class SessionScreenTest {
val composeTestRule = createComposeRule() val composeTestRule = createComposeRule()
@Test @Test
fun sessionRecapTest() { fun customSessionScreenTest() {
var saveCalled = false var endSession = false
var discardCalled = false
composeTestRule.setContent { composeTestRule.setContent {
SessionRecapScreen( CustomSessionScreen(
Modifier, functionalTimer = FunctionalCustomTimer(0),
SessionRecapActions( mediaplayer = null
{ ).invoke(
SessionReport( open = {},
"", sessionActions = SessionActions(
0, {FunctionalCustomTimer(0)},
Timestamp(0, 0), { "" },
"") {}, {}, {endSession = true}
},
{ saveCalled = true },
{ discardCalled = true }
) )
) )
} }
composeTestRule
.onNodeWithText( composeTestRule.waitForIdle()
"You studied",
substring = true,
ignoreCase = true
)
.assertExists()
composeTestRule composeTestRule
.onNodeWithText( .onNodeWithText(
"save", "end session",
substring = true, substring = true,
ignoreCase = true ignoreCase = true
) )
.assertExists() .assertExists()
.performClick() .performClick()
composeTestRule
.onNodeWithText(
"discard",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
Assert.assertTrue(saveCalled) Assert.assertTrue(endSession)
Assert.assertTrue(discardCalled)
} }
@Test
fun endlessSessionScreenTest() {
var endSession = false
composeTestRule.setContent {
EndlessSessionScreen()
.invoke(
open = {},
sessionActions = SessionActions(
{FunctionalEndlessTimer()},
{ "" },
{}, {}, {endSession = true}
)
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
"end session",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
Assert.assertTrue(endSession)
}
@Test
fun breakSessionScreenTest() {
var endSession = false
composeTestRule.setContent {
BreakSessionScreen(
funPomoDoroTimer = FunctionalPomodoroTimer(0, 0, 0),
mediaplayer = null
)
.invoke(
open = {},
sessionActions = SessionActions(
{FunctionalPomodoroTimer(0, 0, 0)},
{ "" },
{}, {}, {endSession = true}
)
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
"end session",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
Assert.assertTrue(endSession)
}
} }

View file

@ -0,0 +1,52 @@
package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.screens.sign_up.SignUpActions
import be.ugent.sel.studeez.screens.sign_up.SignUpScreen
import be.ugent.sel.studeez.screens.sign_up.SignUpUiState
import org.junit.Rule
import org.junit.Test
class SignUpScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun signupScreenTest() {
var create = false
var login = false
composeTestRule.setContent {
SignUpScreen(
uiState = SignUpUiState(),
signUpActions = SignUpActions({}, {}, {}, {}, {create = true}, {login = true})
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "log in",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onAllNodesWithText(
text = "Create account",
substring = true,
ignoreCase = true
)[0] // First node has the button
.assertExists()
.performClick()
assert(login)
assert(create)
}
}

View file

@ -0,0 +1,40 @@
package be.ugent.sel.studeez
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.screens.splash.SplashScreen
import org.junit.Rule
import org.junit.Test
class SplashScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun splashScreenTest() {
var tryAgain = false
composeTestRule.setContent {
SplashScreen(
Modifier,
{tryAgain = true},
true
)
}
composeTestRule.waitForIdle()
composeTestRule
.onAllNodesWithText(
text = "try again",
substring = true,
ignoreCase = true
)[1] // Second node is the button
.assertExists()
.performClick()
assert(tryAgain)
}
}

View file

@ -0,0 +1,155 @@
package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.common.composable.DeleteButton
import be.ugent.sel.studeez.common.composable.drawer.DrawerActions
import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions
import be.ugent.sel.studeez.data.local.models.task.Subject
import be.ugent.sel.studeez.screens.subjects.SubjectScreen
import be.ugent.sel.studeez.screens.subjects.SubjectUiState
import be.ugent.sel.studeez.screens.subjects.form.SubjectForm
import be.ugent.sel.studeez.screens.subjects.form.SubjectFormUiState
import kotlinx.coroutines.flow.flowOf
import org.junit.Rule
import org.junit.Test
class SubjectScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun addSubjectScreenTest() {
var confirm = false
var goback = false
composeTestRule.setContent {
SubjectForm(
title = R.string.new_subject,
goBack = {goback = true},
uiState = SubjectFormUiState(),
onConfirm = {confirm = true},
onNameChange = {},
onColorChange = {},
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "confirm",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithContentDescription(
label = "go back",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(confirm)
assert(goback)
}
@Test
fun editSubjectScreenTest() {
var confirm = false
var delete = false
composeTestRule.setContent {
SubjectForm(
title = R.string.edit_subject,
goBack = {},
uiState = SubjectFormUiState(
name = "Test Subject",
),
onConfirm = {confirm = true},
onNameChange = {},
onColorChange = {},
)
DeleteButton(text = R.string.delete_subject) {
delete = true
}
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "confirm",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
text = "delete",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(confirm)
assert(delete)
}
@Test
fun subjectScreenTest() {
var view = false
var add = false
composeTestRule.setContent {
SubjectScreen(
drawerActions = DrawerActions({}, {}, {}, {}, {}),
navigationBarActions = NavigationBarActions({false}, {}, {}, {}, {}, {}, {}, {}),
onAddSubject = { add = true },
onViewSubject = { view = true },
getStudyTime = { flowOf() },
uiState = SubjectUiState.Succes(
listOf(
Subject(
name = "Test Subject",
argb_color = 0xFFFFD200,
taskCount = 5, taskCompletedCount = 2,
)
)
)
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "view",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
text = "new subject",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(add)
assert(view)
}
}

View file

@ -0,0 +1,160 @@
package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.common.composable.DeleteButton
import be.ugent.sel.studeez.data.local.models.task.Subject
import be.ugent.sel.studeez.data.local.models.task.Task
import be.ugent.sel.studeez.screens.tasks.TaskActions
import be.ugent.sel.studeez.screens.tasks.TaskScreen
import be.ugent.sel.studeez.screens.tasks.form.TaskForm
import be.ugent.sel.studeez.screens.tasks.form.TaskFormUiState
import kotlinx.coroutines.flow.flowOf
import org.junit.Rule
import org.junit.Test
class TaskScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun addTaskScreenTest() {
var confirm = false
var goback = false
composeTestRule.setContent {
TaskForm(
title = R.string.new_task,
goBack = {goback = true},
uiState = TaskFormUiState(),
onConfirm = {confirm = true},
onNameChange = {},
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "confirm",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithContentDescription(
label = "go back",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(confirm)
assert(goback)
}
@Test
fun editTaskScreenTest() {
var confirm = false
var delete = false
composeTestRule.setContent {
TaskForm(
title = R.string.edit_task,
goBack = {},
uiState = TaskFormUiState(
name = "Test Task",
),
onConfirm = {confirm = true},
onNameChange = {},
) {
DeleteButton(text = R.string.delete_task) {
delete = true
}
}
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "confirm",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
text = "delete",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(confirm)
assert(delete)
}
@Test
fun taskScreenTest() {
var add = false
var edit = false
var start = false
composeTestRule.setContent {
TaskScreen(
goBack = {},
taskActions = TaskActions(
{add = true},
{ Subject(name = "Test Subject") },
{ flowOf(listOf(Task())) },
{ _, _ -> run {} },
{edit = true},
{start = true},
{},
)
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithContentDescription(
label = "edit",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
text = "new",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
text = "start",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(add)
assert(edit)
assert(start)
}
}

View file

@ -0,0 +1,58 @@
package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.common.composable.drawer.DrawerActions
import be.ugent.sel.studeez.data.local.models.timer_info.EndlessTimerInfo
import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewActions
import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewScreen
import kotlinx.coroutines.flow.flowOf
import org.junit.Rule
import org.junit.Test
class TimerOverviewScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun timerOverviewScreenTest() {
var add = false
var edit = false
composeTestRule.setContent {
TimerOverviewScreen(
timerOverviewActions = TimerOverviewActions(
{ flowOf(listOf(EndlessTimerInfo("", ""))) },
{ listOf() },
{edit = true},
{add = true}
),
drawerActions = DrawerActions({}, {}, {}, {}, {})
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "add",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
composeTestRule
.onNodeWithText(
text = "edit",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(add)
assert(edit)
}
}

View file

@ -0,0 +1,37 @@
package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.data.local.models.timer_info.EndlessTimerInfo
import be.ugent.sel.studeez.screens.timer_form.form_screens.EndlessTimerFormScreen
import org.junit.Rule
import org.junit.Test
class TimerScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun timerFormScreenTest() {
var save = false
composeTestRule.setContent {
EndlessTimerFormScreen(EndlessTimerInfo("", ""))
.invoke(onSaveClick = {save = true})
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "save",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(save)
}
}

View file

@ -0,0 +1,40 @@
package be.ugent.sel.studeez
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionActions
import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionScreen
import kotlinx.coroutines.flow.flowOf
import org.junit.Rule
import org.junit.Test
class TimerSelectionScreenTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun timerOverviewScreenTest() {
var start = false
composeTestRule.setContent {
TimerSelectionScreen(
timerSelectionActions = TimerSelectionActions({ flowOf()}, {start = true}, 0),
popUp = {}
)
}
composeTestRule.waitForIdle()
composeTestRule
.onNodeWithText(
text = "start",
substring = true,
ignoreCase = true
)
.assertExists()
.performClick()
assert(start)
}
}

View file

@ -3,7 +3,9 @@ package be.ugent.sel.studeez.screens.timer_form
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
import be.ugent.sel.studeez.data.local.models.timer_info.PomodoroTimerInfo
import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo
import be.ugent.sel.studeez.R.string as AppText import be.ugent.sel.studeez.R.string as AppText
@ -40,3 +42,14 @@ fun TimerFormScreen(
timerFormScreen(onConfirmClick) timerFormScreen(onConfirmClick)
} }
} }
@Preview
@Composable
fun AddTimerPreview() {
TimerFormScreen(
popUp = { },
getTimerInfo = { PomodoroTimerInfo("", "", 0, 0, 0) },
label = AppText.add_timer,
onConfirmClick = {}
)
}

View file

@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate
import be.ugent.sel.studeez.data.local.models.timer_info.* import be.ugent.sel.studeez.data.local.models.timer_info.*
@ -43,4 +44,13 @@ fun TimerTypeSelectScreen(
} }
} }
} }
}
@Preview
@Composable
fun TimerTypeSelectScreenPreview() {
TimerTypeSelectScreen(
open = {},
popUp = {}
)
} }

View file

@ -2,6 +2,7 @@ package be.ugent.sel.studeez.timer_functional
import android.media.MediaPlayer import android.media.MediaPlayer
import be.ugent.sel.studeez.data.SelectedSessionReport import be.ugent.sel.studeez.data.SelectedSessionReport
import be.ugent.sel.studeez.data.SelectedTask
import be.ugent.sel.studeez.data.SelectedTimer import be.ugent.sel.studeez.data.SelectedTimer
import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer
import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer
@ -26,7 +27,7 @@ class InvisibleSessionManagerTest {
@Test @Test
fun InvisibleEndlessTimerTest() = runTest { fun InvisibleEndlessTimerTest() = runTest {
selectedTimer.set(FunctionalEndlessTimer()) selectedTimer.set(FunctionalEndlessTimer())
viewModel = SessionViewModel(selectedTimer, SelectedSessionReport(), mock(), LogServiceImpl()) viewModel = SessionViewModel(selectedTimer, SelectedSessionReport(), SelectedTask(), LogServiceImpl())
InvisibleSessionManager.setParameters(viewModel, mediaPlayer) InvisibleSessionManager.setParameters(viewModel, mediaPlayer)
val test = launch { val test = launch {
@ -48,7 +49,7 @@ class InvisibleSessionManagerTest {
val breakTime = 5 val breakTime = 5
val repeats = 1 val repeats = 1
selectedTimer.set(FunctionalPomodoroTimer(studyTime, breakTime, repeats)) selectedTimer.set(FunctionalPomodoroTimer(studyTime, breakTime, repeats))
viewModel = SessionViewModel(selectedTimer, SelectedSessionReport(), mock(), LogServiceImpl()) viewModel = SessionViewModel(selectedTimer, SelectedSessionReport(), SelectedTask(), LogServiceImpl())
InvisibleSessionManager.setParameters(viewModel, mediaPlayer) InvisibleSessionManager.setParameters(viewModel, mediaPlayer)
val test = launch { val test = launch {
@ -81,7 +82,7 @@ class InvisibleSessionManagerTest {
@Test @Test
fun InvisibleCustomTimerTest() = runTest { fun InvisibleCustomTimerTest() = runTest {
selectedTimer.set(FunctionalCustomTimer(5)) selectedTimer.set(FunctionalCustomTimer(5))
viewModel = SessionViewModel(selectedTimer, SelectedSessionReport(), mock(), LogServiceImpl()) viewModel = SessionViewModel(selectedTimer, SelectedSessionReport(), SelectedTask(), LogServiceImpl())
InvisibleSessionManager.setParameters(viewModel, mediaPlayer) InvisibleSessionManager.setParameters(viewModel, mediaPlayer)
val test = launch { val test = launch {

View file

@ -9,13 +9,13 @@ buildscript {
dependencies { dependencies {
classpath 'com.google.gms:google-services:4.3.15' classpath 'com.google.gms:google-services:4.3.15'
classpath 'com.android.tools.build:gradle:7.2.0' classpath 'com.android.tools.build:gradle:8.0.0'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.4' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.4'
} }
}// Top-level build file where you can add configuration options common to all sub-projects/modules. }// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id 'com.android.application' version '7.4.2' apply false id 'com.android.application' version '8.0.0' apply false
id 'com.android.library' version '7.4.2' apply false id 'com.android.library' version '8.0.0' apply false
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
// Hilt // Hilt