Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Ignacio García
Jetpack Compose Sample 1
Compare Revisions
0e69fcb9a7439f062b8620f8dee9a06d3bb0d5aa...6d1f16f8fdad5da53878cd8675de664eff91becd
Source
6d1f16f8fdad5da53878cd8675de664eff91becd
Select Git revision
...
Target
0e69fcb9a7439f062b8620f8dee9a06d3bb0d5aa
Select Git revision
Compare
Commits (2)
Add constants for test tags.
· 1414a2e3
Ignacio García
authored
Jan 14, 2021
1414a2e3
Add README file.
· 6d1f16f8
Ignacio García
authored
Feb 07, 2021
6d1f16f8
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
150 additions
and
70 deletions
+150
-70
README.md
README.md
+39
-0
app/src/androidTest/java/com/ignacio/composesample1/ui/MainScreenTest.kt
...Test/java/com/ignacio/composesample1/ui/MainScreenTest.kt
+21
-19
app/src/androidTest/java/com/ignacio/composesample1/ui/messagelist/DrawerTest.kt
...a/com/ignacio/composesample1/ui/messagelist/DrawerTest.kt
+12
-8
app/src/androidTest/java/com/ignacio/composesample1/ui/messagelist/MessageListTest.kt
.../ignacio/composesample1/ui/messagelist/MessageListTest.kt
+11
-8
app/src/androidTest/java/com/ignacio/composesample1/ui/messageview/MessageViewTest.kt
.../ignacio/composesample1/ui/messageview/MessageViewTest.kt
+14
-13
app/src/main/java/com/ignacio/composesample1/ui/Compose.kt
app/src/main/java/com/ignacio/composesample1/ui/Compose.kt
+32
-1
app/src/main/java/com/ignacio/composesample1/ui/MainScreen.kt
...src/main/java/com/ignacio/composesample1/ui/MainScreen.kt
+1
-1
app/src/main/java/com/ignacio/composesample1/ui/messagelist/MessageListUI.kt
...om/ignacio/composesample1/ui/messagelist/MessageListUI.kt
+14
-14
app/src/main/java/com/ignacio/composesample1/ui/messageview/MessageViewUI.kt
...om/ignacio/composesample1/ui/messageview/MessageViewUI.kt
+6
-6
No files found.
README.md
0 → 100644
View file @
6d1f16f8
# ComposeSample1
This project is a simplified mockup of two pEp's screens.
## Motivation
I created this project to learn and experiment with Jetpack Compose.
And as a learning project, if you follow the commits you can see some experiments.
There are also some logs as example that can help to understand how Jetpack Compose works.
## Some Conclusions
Jetpack Compose makes UI development and testing faster and easier.
One of the big points is decoupling UI from Activities and Fragments.
Another one of course, is using just one language for everything (Kotlin).
What would take several xml files when using traditional UI, can be done in a few lines of Kotlin code.
It is really useful to be able to test each UI component by itself, with mock data.
With this isolation, we can easily identify unwanted behaviors in that component,
without having our component's function depending on anything else in the app.
Of course the concepts change a little and we need to learn new patterns with Compose, but I think it's totally worth it :)
## Components
This project uses the following components and concepts:
*
[
MVVM architecture
][
MVVM
]
*
[
ViewModel
][
viewmodel
]
(presentation layer)
*
[
Kotlin Coroutines
][
coroutines
]
(background operations)
*
[
Kotlin StateFlow
][
stateflow
]
(communicate presentation and UI layer)
*
[
Room Database
][
room
]
(storage)
*
[
Jetpack Compose
][
compose
]
(UI layer)
*
[
Dagger Hilt
][
hilt
]
(dependency injection)
[
MVVM
]:
https://developer.android.com/jetpack/guide
[
viewmodel
]:
https://developer.android.com/topic/libraries/architecture/viewmodel
[
coroutines
]:
https://kotlinlang.org/docs/reference/coroutines-overview.html
[
stateflow
]:
https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
[
room
]:
https://developer.android.com/training/data-storage/room
[
compose
]:
https://developer.android.com/jetpack/compose
[
hilt
]:
https://developer.android.com/training/dependency-injection/hilt-android
app/src/androidTest/java/com/ignacio/composesample1/ui/MainScreenTest.kt
View file @
6d1f16f8
...
@@ -106,28 +106,29 @@ class MainScreenTest {
...
@@ -106,28 +106,29 @@ class MainScreenTest {
deleteMessage
()
deleteMessage
()
assertWeAreInMessageListScreen
()
assertWeAreInMessageListScreen
()
composeTestRule
composeTestRule
.
onNodeWithTag
(
"messageViewHolderTitleAndAbstract1"
)
.
onNodeWithTag
(
"
${TestTags.MessageList.
messageViewHolderTitleAndAbstract
}
1"
)
.
assertDoesNotExist
()
.
assertDoesNotExist
()
}
}
private
fun
deleteMessage
()
{
private
fun
deleteMessage
()
{
helper
.
assertNodeWithTag
(
"
messageViewDeleteMenuItem
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewDeleteMenuItem
).
performClick
()
}
}
private
fun
closeMessage
()
{
private
fun
closeMessage
()
{
helper
.
assertNodeWithTag
(
"
messageViewNavigationIcon
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewNavigationIcon
).
performClick
()
assertWeAreInMessageListScreen
()
assertWeAreInMessageListScreen
()
}
}
private
fun
assertMessageFlaggedInMessageView
(
flagged
:
Boolean
):
SemanticsNodeInteraction
{
private
fun
assertMessageFlaggedInMessageView
(
flagged
:
Boolean
):
SemanticsNodeInteraction
{
return
helper
.
assertInternalNodeWithTag
(
"messageViewFlagMenuItem"
).
assert
(
return
helper
.
assertInternalNodeWithTag
(
TestTags
.
MessageView
.
messageViewFlagMenuItem
)
hasContentDescription
(
.
assert
(
helper
.
context
.
getString
(
hasContentDescription
(
if
(
flagged
)
R
.
string
.
message_remove_star_action
helper
.
context
.
getString
(
else
R
.
string
.
message_add_star_action
if
(
flagged
)
R
.
string
.
message_remove_star_action
else
R
.
string
.
message_add_star_action
)
)
)
)
)
)
}
}
@Suppress
(
"SameParameterValue"
)
@Suppress
(
"SameParameterValue"
)
...
@@ -135,14 +136,15 @@ class MainScreenTest {
...
@@ -135,14 +136,15 @@ class MainScreenTest {
id
:
Int
,
id
:
Int
,
flagged
:
Boolean
flagged
:
Boolean
):
SemanticsNodeInteraction
{
):
SemanticsNodeInteraction
{
return
helper
.
assertInternalNodeWithTag
(
"messageViewHolderFlag$id"
).
assert
(
return
helper
.
assertInternalNodeWithTag
(
"${TestTags.MessageList.messageViewHolderFlag}$id"
)
hasContentDescription
(
.
assert
(
helper
.
context
.
getString
(
hasContentDescription
(
if
(
flagged
)
R
.
string
.
message_remove_star_action
helper
.
context
.
getString
(
else
R
.
string
.
message_add_star_action
if
(
flagged
)
R
.
string
.
message_remove_star_action
else
R
.
string
.
message_add_star_action
)
)
)
)
)
)
}
}
private
fun
assertWeAreInMessageListScreen
()
{
private
fun
assertWeAreInMessageListScreen
()
{
...
@@ -151,18 +153,18 @@ class MainScreenTest {
...
@@ -151,18 +153,18 @@ class MainScreenTest {
}
}
private
fun
assertWeAreInMessageViewScreen
()
{
private
fun
assertWeAreInMessageViewScreen
()
{
helper
.
assertNodeWithTag
(
"
messageViewTopBarBadge
"
)
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewTopBarBadge
)
helper
.
assertNodeWithText
(
R
.
string
.
secure_and_trusted
)
helper
.
assertNodeWithText
(
R
.
string
.
secure_and_trusted
)
}
}
private
fun
openMessage
(
id
:
Int
)
{
private
fun
openMessage
(
id
:
Int
)
{
helper
.
assertInternalNodeWithTag
(
"messageViewHolderTitleAndAbstract$id"
)
helper
.
assertInternalNodeWithTag
(
"
${TestTags.MessageList.
messageViewHolderTitleAndAbstract
}
$id"
)
.
performClick
()
.
performClick
()
assertWeAreInMessageViewScreen
()
assertWeAreInMessageViewScreen
()
}
}
private
fun
openOptionsMenu
()
{
private
fun
openOptionsMenu
()
{
helper
.
assertNodeWithTag
(
"
overflowMenu
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
overflowMenu
).
performClick
()
}
}
@Suppress
(
"SameParameterValue"
)
@Suppress
(
"SameParameterValue"
)
...
@@ -170,7 +172,7 @@ class MainScreenTest {
...
@@ -170,7 +172,7 @@ class MainScreenTest {
id
:
Int
,
id
:
Int
,
unread
:
Boolean
unread
:
Boolean
):
SemanticsNodeInteraction
{
):
SemanticsNodeInteraction
{
return
helper
.
assertNodeWithTag
(
"messageViewHolderTitleAndAbstract$id"
)
return
helper
.
assertNodeWithTag
(
"
${TestTags.MessageList.
messageViewHolderTitleAndAbstract
}
$id"
)
.
assert
(
.
assert
(
hasContentDescription
(
hasContentDescription
(
helper
.
context
.
getString
(
helper
.
context
.
getString
(
...
...
app/src/androidTest/java/com/ignacio/composesample1/ui/messagelist/DrawerTest.kt
View file @
6d1f16f8
...
@@ -5,8 +5,10 @@ import androidx.compose.ui.test.junit4.createComposeRule
...
@@ -5,8 +5,10 @@ import androidx.compose.ui.test.junit4.createComposeRule
import
androidx.compose.ui.test.performClick
import
androidx.compose.ui.test.performClick
import
com.ignacio.composesample1.R
import
com.ignacio.composesample1.R
import
com.ignacio.composesample1.ui.DrawerUser
import
com.ignacio.composesample1.ui.DrawerUser
import
com.ignacio.composesample1.ui.TestTags
import
com.ignacio.composesample1.ui.UITestHelper
import
com.ignacio.composesample1.ui.UITestHelper
import
com.nhaarman.mockitokotlin2.verify
import
com.nhaarman.mockitokotlin2.verify
import
kotlinx.coroutines.ExperimentalCoroutinesApi
import
org.junit.Before
import
org.junit.Before
import
org.junit.Rule
import
org.junit.Rule
import
org.junit.Test
import
org.junit.Test
...
@@ -18,6 +20,7 @@ class DrawerTest {
...
@@ -18,6 +20,7 @@ class DrawerTest {
private
val
drawerUser
=
DrawerUser
()
private
val
drawerUser
=
DrawerUser
()
@ExperimentalCoroutinesApi
@Before
@Before
fun
setUp
()
{
fun
setUp
()
{
helper
.
stubViewModel
(
null
,
false
)
helper
.
stubViewModel
(
null
,
false
)
...
@@ -39,14 +42,14 @@ class DrawerTest {
...
@@ -39,14 +42,14 @@ class DrawerTest {
@Test
@Test
fun
drawer_test
()
{
fun
drawer_test
()
{
openDrawer
()
openDrawer
()
helper
.
assertInternalNodeWithTag
(
"
currentAccountAvatar
"
)
helper
.
assertInternalNodeWithTag
(
TestTags
.
MessageList
.
currentAccountAvatar
)
helper
.
assertInternalNodeWithText
(
helper
.
username
)
helper
.
assertInternalNodeWithText
(
helper
.
username
)
helper
.
assertInternalNodeWithText
(
helper
.
email
)
helper
.
assertInternalNodeWithText
(
helper
.
email
)
helper
.
assertInternalNodeWithTag
(
"
otherAccountClicker1
"
).
performClick
()
helper
.
assertInternalNodeWithTag
(
TestTags
.
MessageList
.
otherAccountClicker1
).
performClick
()
verify
(
helper
.
drawerActionClickListener
).
onDrawerAccountCircleClicked
(
helper
.
allAccounts
[
1
])
verify
(
helper
.
drawerActionClickListener
).
onDrawerAccountCircleClicked
(
helper
.
allAccounts
[
1
])
helper
.
assertInternalNodeWithTag
(
"
otherAccountClicker2
"
).
performClick
()
helper
.
assertInternalNodeWithTag
(
TestTags
.
MessageList
.
otherAccountClicker2
).
performClick
()
verify
(
helper
.
drawerActionClickListener
).
onDrawerAccountCircleClicked
(
helper
.
allAccounts
[
2
])
verify
(
helper
.
drawerActionClickListener
).
onDrawerAccountCircleClicked
(
helper
.
allAccounts
[
2
])
assertSpecialFolderList
()
assertSpecialFolderList
()
...
@@ -64,7 +67,8 @@ class DrawerTest {
...
@@ -64,7 +67,8 @@ class DrawerTest {
}
}
private
fun
assertDrawerClosed
()
{
private
fun
assertDrawerClosed
()
{
helper
.
findInternalNodeWithTag
(
"currentAccountAvatar"
).
assertIsNotDisplayed
()
helper
.
findInternalNodeWithTag
(
TestTags
.
MessageList
.
currentAccountAvatar
)
.
assertIsNotDisplayed
()
helper
.
findInternalNodeWithText
(
helper
.
username
).
assertIsNotDisplayed
()
helper
.
findInternalNodeWithText
(
helper
.
username
).
assertIsNotDisplayed
()
helper
.
findInternalNodeWithText
(
helper
.
email
).
assertIsNotDisplayed
()
helper
.
findInternalNodeWithText
(
helper
.
email
).
assertIsNotDisplayed
()
}
}
...
@@ -78,12 +82,12 @@ class DrawerTest {
...
@@ -78,12 +82,12 @@ class DrawerTest {
}
}
private
fun
openDrawer
()
{
private
fun
openDrawer
()
{
helper
.
assertNodeWithTag
(
"
drawerIcon
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageList
.
drawerIcon
).
performClick
()
}
}
private
fun
assertSpecialFolderList
()
{
private
fun
assertSpecialFolderList
()
{
helper
.
assertScrollableList
(
helper
.
assertScrollableList
(
"
drawerSpecialFolderList
"
,
TestTags
.
MessageList
.
drawerSpecialFolderList
,
helper
.
specialFolders
,
helper
.
specialFolders
,
true
true
)
{
index
->
)
{
index
->
...
@@ -95,7 +99,7 @@ class DrawerTest {
...
@@ -95,7 +99,7 @@ class DrawerTest {
private
fun
assertNormalFolderList
()
{
private
fun
assertNormalFolderList
()
{
helper
.
assertScrollableList
(
helper
.
assertScrollableList
(
"
drawerFolderList
"
,
TestTags
.
MessageList
.
drawerFolderList
,
helper
.
folders
,
helper
.
folders
,
true
true
)
{
index
->
)
{
index
->
...
@@ -109,7 +113,7 @@ class DrawerTest {
...
@@ -109,7 +113,7 @@ class DrawerTest {
val
otherAccounts
=
helper
.
allAccounts
val
otherAccounts
=
helper
.
allAccounts
.
takeLast
(
helper
.
allAccounts
.
size
-
1
)
.
takeLast
(
helper
.
allAccounts
.
size
-
1
)
helper
.
assertScrollableList
(
helper
.
assertScrollableList
(
"
drawerAccountList
"
,
TestTags
.
MessageList
.
drawerAccountList
,
otherAccounts
,
otherAccounts
,
true
true
)
{
index
->
)
{
index
->
...
...
app/src/androidTest/java/com/ignacio/composesample1/ui/messagelist/MessageListTest.kt
View file @
6d1f16f8
...
@@ -6,6 +6,7 @@ import androidx.compose.ui.test.junit4.createComposeRule
...
@@ -6,6 +6,7 @@ import androidx.compose.ui.test.junit4.createComposeRule
import
androidx.compose.ui.test.onNodeWithSubstring
import
androidx.compose.ui.test.onNodeWithSubstring
import
androidx.compose.ui.test.performClick
import
androidx.compose.ui.test.performClick
import
com.ignacio.composesample1.R
import
com.ignacio.composesample1.R
import
com.ignacio.composesample1.ui.TestTags
import
com.ignacio.composesample1.ui.UITestHelper
import
com.ignacio.composesample1.ui.UITestHelper
import
com.nhaarman.mockitokotlin2.reset
import
com.nhaarman.mockitokotlin2.reset
import
com.nhaarman.mockitokotlin2.verify
import
com.nhaarman.mockitokotlin2.verify
...
@@ -30,15 +31,15 @@ class MessageListTest {
...
@@ -30,15 +31,15 @@ class MessageListTest {
helper
.
assertNodeWithText
(
R
.
string
.
app_name
)
helper
.
assertNodeWithText
(
R
.
string
.
app_name
)
helper
.
assertNodeWithText
(
R
.
string
.
subtitle_dummy
)
helper
.
assertNodeWithText
(
R
.
string
.
subtitle_dummy
)
helper
.
assertNodeWithTag
(
"
searchAction
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageList
.
searchAction
).
performClick
()
verify
(
helper
.
optionsMenuItemClickListener
).
onOptionsMenuItemClicked
(
R
.
string
.
search_action
)
verify
(
helper
.
optionsMenuItemClickListener
).
onOptionsMenuItemClicked
(
R
.
string
.
search_action
)
helper
.
assertNodeWithTag
(
"
overflowMenu
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
overflowMenu
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
option_1_action
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
option_1_action
).
performClick
()
verify
(
helper
.
optionsMenuItemClickListener
).
onOptionsMenuItemClicked
(
R
.
string
.
option_1_action
)
verify
(
helper
.
optionsMenuItemClickListener
).
onOptionsMenuItemClicked
(
R
.
string
.
option_1_action
)
helper
.
findNodeWithText
(
R
.
string
.
option_1_action
).
assertDoesNotExist
()
helper
.
findNodeWithText
(
R
.
string
.
option_1_action
).
assertDoesNotExist
()
helper
.
assertNodeWithTag
(
"
overflowMenu
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
overflowMenu
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
option_2_action
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
option_2_action
).
performClick
()
verify
(
helper
.
optionsMenuItemClickListener
).
onOptionsMenuItemClicked
(
R
.
string
.
option_2_action
)
verify
(
helper
.
optionsMenuItemClickListener
).
onOptionsMenuItemClicked
(
R
.
string
.
option_2_action
)
helper
.
findNodeWithText
(
R
.
string
.
option_2_action
).
assertDoesNotExist
()
helper
.
findNodeWithText
(
R
.
string
.
option_2_action
).
assertDoesNotExist
()
...
@@ -53,7 +54,7 @@ class MessageListTest {
...
@@ -53,7 +54,7 @@ class MessageListTest {
)
)
}
}
helper
.
assertScrollableList
(
helper
.
assertScrollableList
(
"
messageList
"
,
TestTags
.
MessageList
.
messageList
,
helper
.
allMessages
helper
.
allMessages
)
{
position
->
)
{
position
->
val
message
=
helper
.
allMessages
[
position
]
val
message
=
helper
.
allMessages
[
position
]
...
@@ -68,17 +69,19 @@ class MessageListTest {
...
@@ -68,17 +69,19 @@ class MessageListTest {
helper
.
assertInternalNodeWithText
(
"Subject${message.id}"
)
helper
.
assertInternalNodeWithText
(
"Subject${message.id}"
)
helper
.
assertInternalNodeWithText
(
"Body${message.id}"
)
helper
.
assertInternalNodeWithText
(
"Body${message.id}"
)
}
}
helper
.
assertNodeWithTag
(
"messageViewHolderContactBadge${message.id}"
).
performClick
()
helper
.
assertNodeWithTag
(
"${TestTags.MessageList.messageViewHolderContactBadge}${message.id}"
)
.
performClick
()
verify
(
helper
.
messageViewHolderActionListener
).
onContactClicked
(
message
.
from
.
first
())
verify
(
helper
.
messageViewHolderActionListener
).
onContactClicked
(
message
.
from
.
first
())
helper
.
assertNodeWithTag
(
"messageViewHolderTitleAndAbstract${message.id}"
)
helper
.
assertNodeWithTag
(
"
${TestTags.MessageList.
messageViewHolderTitleAndAbstract
}
${message.id}"
)
.
performClick
()
.
performClick
()
verify
(
helper
.
messageViewHolderActionListener
).
onMessageClicked
(
message
)
verify
(
helper
.
messageViewHolderActionListener
).
onMessageClicked
(
message
)
val
sdf
=
SimpleDateFormat
(
"MMM d"
,
Locale
.
getDefault
())
val
sdf
=
SimpleDateFormat
(
"MMM d"
,
Locale
.
getDefault
())
helper
.
assertNodeWithTag
(
"messageViewHolderDate${message.id}"
)
helper
.
assertNodeWithTag
(
"
${TestTags.MessageList.
messageViewHolderDate
}
${message.id}"
)
.
assertTextEquals
(
sdf
.
format
(
Date
()))
.
assertTextEquals
(
sdf
.
format
(
Date
()))
helper
.
assertNodeWithTag
(
"messageViewHolderFlag${message.id}"
).
performClick
()
helper
.
assertNodeWithTag
(
"${TestTags.MessageList.messageViewHolderFlag}${message.id}"
)
.
performClick
()
verify
(
helper
.
messageViewHolderActionListener
).
onFlagClicked
(
message
)
verify
(
helper
.
messageViewHolderActionListener
).
onFlagClicked
(
message
)
reset
(
helper
.
messageViewHolderActionListener
)
reset
(
helper
.
messageViewHolderActionListener
)
...
...
app/src/androidTest/java/com/ignacio/composesample1/ui/messageview/MessageViewTest.kt
View file @
6d1f16f8
...
@@ -3,6 +3,7 @@ package com.ignacio.composesample1.ui.messageview
...
@@ -3,6 +3,7 @@ package com.ignacio.composesample1.ui.messageview
import
androidx.compose.ui.test.junit4.createComposeRule
import
androidx.compose.ui.test.junit4.createComposeRule
import
androidx.compose.ui.test.performClick
import
androidx.compose.ui.test.performClick
import
com.ignacio.composesample1.R
import
com.ignacio.composesample1.R
import
com.ignacio.composesample1.ui.TestTags
import
com.ignacio.composesample1.ui.UITestHelper
import
com.ignacio.composesample1.ui.UITestHelper
import
com.nhaarman.mockitokotlin2.verify
import
com.nhaarman.mockitokotlin2.verify
import
kotlinx.coroutines.ExperimentalCoroutinesApi
import
kotlinx.coroutines.ExperimentalCoroutinesApi
...
@@ -24,23 +25,23 @@ class MessageViewTest {
...
@@ -24,23 +25,23 @@ class MessageViewTest {
messageInfo
=
MessageViewMenuMessageInfo
(
helper
.
allMessages
.
first
())
messageInfo
=
MessageViewMenuMessageInfo
(
helper
.
allMessages
.
first
())
)
)
}
}
helper
.
assertNodeWithTag
(
"
messageViewNavigationIcon
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewNavigationIcon
).
performClick
()
verify
(
helper
.
messageViewMenuActionListener
).
onNavigationClicked
()
verify
(
helper
.
messageViewMenuActionListener
).
onNavigationClicked
()
helper
.
assertNodeWithTag
(
"
messageViewTopBarBadge
"
)
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewTopBarBadge
)
helper
.
assertNodeWithText
(
R
.
string
.
secure_and_trusted
)
helper
.
assertNodeWithText
(
R
.
string
.
secure_and_trusted
)
helper
.
assertNodeWithTag
(
"
messageViewFlagMenuItem
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewFlagMenuItem
).
performClick
()
verify
(
helper
.
messageViewMenuActionListener
).
onFlagIconToggled
()
verify
(
helper
.
messageViewMenuActionListener
).
onFlagIconToggled
()
helper
.
assertNodeWithTag
(
"
messageViewDeleteMenuItem
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewDeleteMenuItem
).
performClick
()
verify
(
helper
.
messageViewMenuActionListener
).
onDeleteIconClicked
()
verify
(
helper
.
messageViewMenuActionListener
).
onDeleteIconClicked
()
helper
.
assertNodeWithTag
(
"
overflowMenu
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
overflowMenu
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
mark_as_read_action
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
mark_as_read_action
).
performClick
()
helper
.
findNodeWithText
(
R
.
string
.
mark_as_read_action
).
assertDoesNotExist
()
helper
.
findNodeWithText
(
R
.
string
.
mark_as_read_action
).
assertDoesNotExist
()
verify
(
helper
.
messageViewMenuActionListener
).
onUnreadToggleClicked
()
verify
(
helper
.
messageViewMenuActionListener
).
onUnreadToggleClicked
()
helper
.
assertNodeWithTag
(
"
overflowMenu
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
overflowMenu
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
option_3_action
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
option_3_action
).
performClick
()
helper
.
findNodeWithText
(
R
.
string
.
option_3_action
).
assertDoesNotExist
()
helper
.
findNodeWithText
(
R
.
string
.
option_3_action
).
assertDoesNotExist
()
verify
(
helper
.
optionsMenuItemClickListener
).
onOptionsMenuItemClicked
(
R
.
string
.
option_3_action
)
verify
(
helper
.
optionsMenuItemClickListener
).
onOptionsMenuItemClicked
(
R
.
string
.
option_3_action
)
...
@@ -57,24 +58,24 @@ class MessageViewTest {
...
@@ -57,24 +58,24 @@ class MessageViewTest {
homeviewModel
=
helper
.
viewModel
homeviewModel
=
helper
.
viewModel
)
)
}
}
helper
.
assertNodeWithTag
(
"
messageViewNavigationIcon
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewNavigationIcon
).
performClick
()
verify
(
helper
.
viewModel
).
closeMessage
()
verify
(
helper
.
viewModel
).
closeMessage
()
helper
.
assertNodeWithTag
(
"
messageViewTopBarBadge
"
)
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewTopBarBadge
)
helper
.
assertNodeWithText
(
R
.
string
.
secure_and_trusted
)
helper
.
assertNodeWithText
(
R
.
string
.
secure_and_trusted
)
helper
.
assertNodeWithTag
(
"
messageViewFlagMenuItem
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewFlagMenuItem
).
performClick
()
verify
(
helper
.
viewModel
).
toggleMessageFlag
(
message
)
verify
(
helper
.
viewModel
).
toggleMessageFlag
(
message
)
helper
.
assertNodeWithTag
(
"
messageViewDeleteMenuItem
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewDeleteMenuItem
).
performClick
()
verify
(
helper
.
viewModel
).
deleteMessage
(
message
)
verify
(
helper
.
viewModel
).
deleteMessage
(
message
)
helper
.
assertNodeWithTag
(
"
overflowMenu
"
).
performClick
()
helper
.
assertNodeWithTag
(
TestTags
.
overflowMenu
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
mark_as_read_action
).
performClick
()
helper
.
assertNodeWithText
(
R
.
string
.
mark_as_read_action
).
performClick
()
helper
.
findNodeWithText
(
R
.
string
.
mark_as_read_action
).
assertDoesNotExist
()
helper
.
findNodeWithText
(
R
.
string
.
mark_as_read_action
).
assertDoesNotExist
()
verify
(
helper
.
viewModel
).
toggleMessageUnread
(
message
)
verify
(
helper
.
viewModel
).
toggleMessageUnread
(
message
)
helper
.
assertNodeWithTag
(
"
messageViewAvatar
"
)
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewAvatar
)
helper
.
assertNodeWithText
(
message
.
subject
)
helper
.
assertNodeWithText
(
message
.
subject
)
helper
.
assertNodeWithText
(
message
.
body
)
helper
.
assertNodeWithText
(
message
.
body
)
helper
.
assertNodeWithText
(
helper
.
assertNodeWithText
(
...
@@ -87,6 +88,6 @@ class MessageViewTest {
...
@@ -87,6 +88,6 @@ class MessageViewTest {
helper
.
context
.
getString
(
R
.
string
.
message_to_field
,
helper
.
context
.
getString
(
R
.
string
.
message_to_field
,
message
.
recipients
.
joinToString
(
", "
)
{
it
.
name
})
message
.
recipients
.
joinToString
(
", "
)
{
it
.
name
})
)
)
helper
.
assertNodeWithTag
(
"
messageViewDate
"
)
helper
.
assertNodeWithTag
(
TestTags
.
MessageView
.
messageViewDate
)
}
}
}
}
\ No newline at end of file
app/src/main/java/com/ignacio/composesample1/ui/Compose.kt
View file @
6d1f16f8
...
@@ -26,4 +26,35 @@ fun LogCallbacksWithText(text: String) {
...
@@ -26,4 +26,35 @@ fun LogCallbacksWithText(text: String) {
fun
getViewModel
():
HomeViewModel
=
viewModel
<
HomeViewModelImpl
>()
fun
getViewModel
():
HomeViewModel
=
viewModel
<
HomeViewModelImpl
>()
val
AmbientProvidableMessage
:
ProvidableAmbient
<
MyMessage
>
=
val
AmbientProvidableMessage
:
ProvidableAmbient
<
MyMessage
>
=
ambientOf
{
MyMessage
.
emptyMessage
()
}
ambientOf
{
MyMessage
.
emptyMessage
()
}
\ No newline at end of file
object
TestTags
{
const
val
overflowMenu
=
"overflowMenu"
object
MessageList
{
const
val
drawerAccountList
=
"drawerAccountList"
const
val
drawerSpecialFolderList
=
"drawerSpecialFolderList"
const
val
drawerFolderList
=
"drawerFolderList"
const
val
messageList
=
"messageList"
const
val
searchAction
=
"searchAction"
const
val
messageViewHolder
=
"messageViewHolder"
const
val
messageViewHolderContactBadge
=
"messageViewHolderContactBadge"
const
val
messageViewHolderDate
=
"messageViewHolderDate"
const
val
messageViewHolderFlag
=
"messageViewHolderFlag"
const
val
messageViewHolderTitleAndAbstract
=
"messageViewHolderTitleAndAbstract"
const
val
drawerIcon
=
"drawerIcon"
const
val
currentAccountAvatar
=
"currentAccountAvatar"
const
val
otherAccountClicker1
=
"otherAccountClicker1"
const
val
otherAccountClicker2
=
"otherAccountClicker2"
}
object
MessageView
{
const
val
messageViewAvatar
=
"messageViewAvatar"
const
val
messageViewDate
=
"messageViewDate"
const
val
messageViewFlagMenuItem
=
"messageViewFlagMenuItem"
const
val
messageViewDeleteMenuItem
=
"messageViewDeleteMenuItem"
const
val
messageViewNavigationIcon
=
"messageViewNavigationIcon"
const
val
messageViewTopBarBadge
=
"messageViewTopBarBadge"
}
}
\ No newline at end of file
app/src/main/java/com/ignacio/composesample1/ui/MainScreen.kt
View file @
6d1f16f8
...
@@ -91,7 +91,7 @@ fun MyDropDownMenu(
...
@@ -91,7 +91,7 @@ fun MyDropDownMenu(
expanded
=
showMenu
.
value
,
expanded
=
showMenu
.
value
,
onDismissRequest
=
{
showMenu
.
value
=
false
},
onDismissRequest
=
{
showMenu
.
value
=
false
},
dropdownOffset
=
Position
((
screenWidth
).
dp
,
0
.
dp
),
dropdownOffset
=
Position
((
screenWidth
).
dp
,
0
.
dp
),
toggleModifier
=
Modifier
.
testTag
(
"
overflowMenu
"
)
toggleModifier
=
Modifier
.
testTag
(
TestTags
.
overflowMenu
)
)
{
)
{
myMenuScope
.
content
()
myMenuScope
.
content
()
}
}
...
...
app/src/main/java/com/ignacio/composesample1/ui/messagelist/MessageListUI.kt
View file @
6d1f16f8
...
@@ -145,7 +145,7 @@ fun MyTopBar(
...
@@ -145,7 +145,7 @@ fun MyTopBar(
navigationIcon
=
{
navigationIcon
=
{
IconButton
(
IconButton
(
onClick
=
{
onNavigationClicked
()
},
onClick
=
{
onNavigationClicked
()
},
modifier
=
Modifier
.
testTag
(
"
drawerIcon
"
)
modifier
=
Modifier
.
testTag
(
TestTags
.
MessageList
.
drawerIcon
)
)
{
)
{
Image
(
vectorResource
(
id
=
R
.
drawable
.
ic_baseline_menu_24
))
Image
(
vectorResource
(
id
=
R
.
drawable
.
ic_baseline_menu_24
))
}
}
...
@@ -168,7 +168,7 @@ fun MessageListOptionsMenu(
...
@@ -168,7 +168,7 @@ fun MessageListOptionsMenu(
onClick
=
{
onClick
=
{
optionsMenuItemClickListener
.
onOptionsMenuItemClicked
(
R
.
string
.
search_action
)
optionsMenuItemClickListener
.
onOptionsMenuItemClicked
(
R
.
string
.
search_action
)
},
},
modifier
=
Modifier
.
testTag
(
"
searchAction
"
)
modifier
=
Modifier
.
testTag
(
TestTags
.
MessageList
.
searchAction
)
)
{
)
{
Image
(
vectorResource
(
id
=
R
.
drawable
.
ic_baseline_search_24
))
Image
(
vectorResource
(
id
=
R
.
drawable
.
ic_baseline_search_24
))
}
}
...
@@ -229,7 +229,7 @@ fun DrawerBodyFolderMode(
...
@@ -229,7 +229,7 @@ fun DrawerBodyFolderMode(
DrawerFolderList
(
DrawerFolderList
(
folders
=
specialFolders
,
folders
=
specialFolders
,
drawerActionClickListener
=
drawerActionClickListener
,
drawerActionClickListener
=
drawerActionClickListener
,
modifier
=
Modifier
.
testTag
(
"
drawerSpecialFolderList
"
)
modifier
=
Modifier
.
testTag
(
TestTags
.
MessageList
.
drawerSpecialFolderList
)
)
)
Text
(
Text
(
stringResource
(
id
=
R
.
string
.
folders_title
),
stringResource
(
id
=
R
.
string
.
folders_title
),
...
@@ -238,7 +238,7 @@ fun DrawerBodyFolderMode(
...
@@ -238,7 +238,7 @@ fun DrawerBodyFolderMode(
DrawerFolderList
(
DrawerFolderList
(
folders
=
folders
,
folders
=
folders
,
drawerActionClickListener
=
drawerActionClickListener
,
drawerActionClickListener
=
drawerActionClickListener
,
modifier
=
Modifier
.
testTag
(
"
drawerFolderList
"
)
modifier
=
Modifier
.
testTag
(
TestTags
.
MessageList
.
drawerFolderList
)
)
)
}
}
}
}
...
@@ -263,7 +263,7 @@ private fun NavigationHeader(
...
@@ -263,7 +263,7 @@ private fun NavigationHeader(
.
preferredSize
(
50
.
dp
)
.
preferredSize
(
50
.
dp
)
.
clip
(
shape
=
CircleShape
)
.
clip
(
shape
=
CircleShape
)
.
background
(
colorResource
(
id
=
R
.
color
.
pep_green
))
.
background
(
colorResource
(
id
=
R
.
color
.
pep_green
))
.
testTag
(
"
currentAccountAvatar
"
),
.
testTag
(
TestTags
.
MessageList
.
currentAccountAvatar
),
contentScale
=
ContentScale
.
Crop
contentScale
=
ContentScale
.
Crop
)
)
Spacer
(
modifier
=
Modifier
.
weight
(
1f
))
Spacer
(
modifier
=
Modifier
.
weight
(
1f
))
...
@@ -272,7 +272,7 @@ private fun NavigationHeader(
...
@@ -272,7 +272,7 @@ private fun NavigationHeader(
image
=
R
.
drawable
.
ic_launcher_foreground
,
image
=
R
.
drawable
.
ic_launcher_foreground
,
account
=
accounts
[
1
],
account
=
accounts
[
1
],
drawerActionClickListener
=
drawerActionClickListener
,
drawerActionClickListener
=
drawerActionClickListener
,
modifier
=
Modifier
.
testTag
(
"
otherAccountClicker1
"
)
modifier
=
Modifier
.
testTag
(
TestTags
.
MessageList
.
otherAccountClicker1
)
)
)
}
}
if
(
accounts
.
size
>
2
)
{
if
(
accounts
.
size
>
2
)
{
...
@@ -281,7 +281,7 @@ private fun NavigationHeader(
...
@@ -281,7 +281,7 @@ private fun NavigationHeader(
image
=
R
.
drawable
.
ic_launcher_foreground
,
image
=
R
.
drawable
.
ic_launcher_foreground
,
account
=
accounts
[
2
],
account
=
accounts
[
2
],
drawerActionClickListener
=
drawerActionClickListener
,
drawerActionClickListener
=
drawerActionClickListener
,
modifier
=
Modifier
.
testTag
(
"
otherAccountClicker2
"
)
modifier
=
Modifier
.
testTag
(
TestTags
.
MessageList
.
otherAccountClicker2
)
)
)
}
}
}
}
...
@@ -344,7 +344,7 @@ fun MessageList(
...
@@ -344,7 +344,7 @@ fun MessageList(
messageViewHolderActionListener
:
MessageViewHolderActionListener
,
messageViewHolderActionListener
:
MessageViewHolderActionListener
,
modifier
:
Modifier
=
Modifier
modifier
:
Modifier
=
Modifier
)
{
)
{
LazyColumn
(
modifier
=
modifier
.
testTag
(
"
messageList
"
))
{
LazyColumn
(
modifier
=
modifier
.
testTag
(
TestTags
.
MessageList
.
messageList
))
{
items
(
items
=
messages
,
items
(
items
=
messages
,
itemContent
=
{
message
->
itemContent
=
{
message
->
MessageViewHolder
(
MessageViewHolder
(
...
@@ -371,7 +371,7 @@ fun MessageViewHolder(
...
@@ -371,7 +371,7 @@ fun MessageViewHolder(
Row
(
Row
(
modifier
=
modifier
modifier
=
modifier
.
clip
(
RoundedCornerShape
(
4
.
dp
))
.
clip
(
RoundedCornerShape
(
4
.
dp
))
.
testTag
(
"messageViewHolder${message.id}"
)
.
testTag
(
"
${TestTags.MessageList.
messageViewHolder
}
${message.id}"
)
)
{
)
{
MessageViewHolderContactBadge
(
message
,
messageViewHolderActionListener
)
MessageViewHolderContactBadge
(
message
,
messageViewHolderActionListener
)
Spacer
(
Spacer
(
...
@@ -405,7 +405,7 @@ fun MessageViewHolderContactBadge(
...
@@ -405,7 +405,7 @@ fun MessageViewHolderContactBadge(
.
clickable
(
onClick
=
{
.
clickable
(
onClick
=
{
messageViewHolderActionListener
.
onContactClicked
(
message
.
from
.
first
())
messageViewHolderActionListener
.
onContactClicked
(
message
.
from
.
first
())
})
})
.
testTag
(
"messageViewHolderContactBadge${message.id}"
),
.
testTag
(
"
${TestTags.MessageList.
messageViewHolderContactBadge
}
${message.id}"
),
shape
=
CircleShape
,
shape
=
CircleShape
,
color
=
MaterialTheme
.
colors
.
onSurface
.
copy
(
alpha
=
0.2f
)
color
=
MaterialTheme
.
colors
.
onSurface
.
copy
(
alpha
=
0.2f
)
)
{
)
{
...
@@ -430,7 +430,7 @@ fun RowScope.MessageViewHolderTitleAndAbstract(
...
@@ -430,7 +430,7 @@ fun RowScope.MessageViewHolderTitleAndAbstract(
if
(
message
.
read
)
context
.
getString
(
R
.
string
.
read_message_conent_description
)
if
(
message
.
read
)
context
.
getString
(
R
.
string
.
read_message_conent_description
)
else
context
.
getString
(
R
.
string
.
unread_message_conent_description
)
else
context
.
getString
(
R
.
string
.
unread_message_conent_description
)
}
}
.
testTag
(
"messageViewHolderTitleAndAbstract${message.id}"
)
.
testTag
(
"
${TestTags.MessageList.
messageViewHolderTitleAndAbstract
}
${message.id}"
)
)
{
)
{
Text
(
Text
(
text
=
message
.
subject
,
text
=
message
.
subject
,
...
@@ -466,7 +466,7 @@ fun MessageViewHolderDateAndFlag(
...
@@ -466,7 +466,7 @@ fun MessageViewHolderDateAndFlag(
val
sdf
=
SimpleDateFormat
(
"MMM d"
,
locale
)
val
sdf
=
SimpleDateFormat
(
"MMM d"
,
locale
)
Text
(
Text
(
sdf
.
format
(
Date
(
message
.
date
)),
sdf
.
format
(
Date
(
message
.
date
)),
modifier
=
Modifier
.
testTag
(
"messageViewHolderDate${message.id}"
)
modifier
=
Modifier
.
testTag
(
"
${TestTags.MessageList.
messageViewHolderDate
}
${message.id}"
)
)
)
Spacer
(
modifier
=
Modifier
.
weight
(
1f
))
Spacer
(
modifier
=
Modifier
.
weight
(
1f
))
Image
(
Image
(
...
@@ -485,7 +485,7 @@ fun MessageViewHolderDateAndFlag(
...
@@ -485,7 +485,7 @@ fun MessageViewHolderDateAndFlag(
if
(
message
.
flagged
)
context
.
getString
(
R
.
string
.
message_remove_star_action
)
if
(
message
.
flagged
)
context
.
getString
(
R
.
string
.
message_remove_star_action
)
else
context
.
getString
(
R
.
string
.
message_add_star_action
)
else
context
.
getString
(
R
.
string
.
message_add_star_action
)
}
}
.
testTag
(
"messageViewHolderFlag${message.id}"
)
.
testTag
(
"
${TestTags.MessageList.
messageViewHolderFlag
}
${message.id}"
)
)
)
}
}
}
}
...
@@ -545,7 +545,7 @@ fun DrawerBodyAccountMode(
...
@@ -545,7 +545,7 @@ fun DrawerBodyAccountMode(
DrawerAccountList
(
DrawerAccountList
(
accounts
=
accounts
,
accounts
=
accounts
,
drawerActionClickListener
=
drawerActionClickListener
,
drawerActionClickListener
=
drawerActionClickListener
,
modifier
=
Modifier
.
testTag
(
"
drawerAccountList
"
)
modifier
=
Modifier
.
testTag
(
TestTags
.
MessageList
.
drawerAccountList
)
)
)
DrawerActionRow
(
DrawerActionRow
(
image
=
R
.
drawable
.
ic_baseline_add_24
,
image
=
R
.
drawable
.
ic_baseline_add_24
,
...
...
app/src/main/java/com/ignacio/composesample1/ui/messageview/MessageViewUI.kt
View file @
6d1f16f8
...
@@ -107,7 +107,7 @@ fun MessageViewTopBar(
...
@@ -107,7 +107,7 @@ fun MessageViewTopBar(
vectorResource
(
id
=
R
.
drawable
.
pep_status_green
),
vectorResource
(
id
=
R
.
drawable
.
pep_status_green
),
modifier
=
Modifier
modifier
=
Modifier
.
preferredSize
(
32
.
dp
)
.
preferredSize
(
32
.
dp
)
.
testTag
(
"
messageViewTopBarBadge
"
)
.
testTag
(
TestTags
.
MessageView
.
messageViewTopBarBadge
)
)
)
Spacer
(
modifier
=
Modifier
.
preferredWidth
(
8
.
dp
))
Spacer
(
modifier
=
Modifier
.
preferredWidth
(
8
.
dp
))
Text
(
Text
(
...
@@ -122,7 +122,7 @@ fun MessageViewTopBar(
...
@@ -122,7 +122,7 @@ fun MessageViewTopBar(
navigationIcon
=
{
navigationIcon
=
{
IconButton
(
IconButton
(
onClick
=
{
messageViewMenuActionListener
.
onNavigationClicked
()
},
onClick
=
{
messageViewMenuActionListener
.
onNavigationClicked
()
},
modifier
=
Modifier
.
testTag
(
"
messageViewNavigationIcon
"
)
modifier
=
Modifier
.
testTag
(
TestTags
.
MessageView
.
messageViewNavigationIcon
)
)
{
)
{
Image
(
vectorResource
(
id
=
R
.
drawable
.
ic_clear_daynight
))
Image
(
vectorResource
(
id
=
R
.
drawable
.
ic_clear_daynight
))
}
}
...
@@ -156,7 +156,7 @@ fun MessageViewOptionsMenu(
...
@@ -156,7 +156,7 @@ fun MessageViewOptionsMenu(
if
(
menuMessageInfo
.
flagged
)
context
.
getString
(
R
.
string
.
message_remove_star_action
)
if
(
menuMessageInfo
.
flagged
)
context
.
getString
(
R
.
string
.
message_remove_star_action
)
else
context
.
getString
(
R
.
string
.
message_add_star_action
)
else
context
.
getString
(
R
.
string
.
message_add_star_action
)
}
}
.
testTag
(
"
messageViewFlagMenuItem
"
)
.
testTag
(
TestTags
.
MessageView
.
messageViewFlagMenuItem
)
)
{
)
{
Image
(
Image
(
vectorResource
(
vectorResource
(
...
@@ -170,7 +170,7 @@ fun MessageViewOptionsMenu(
...
@@ -170,7 +170,7 @@ fun MessageViewOptionsMenu(
onClick
=
{
onClick
=
{
messageViewMenuActionListener
.
onDeleteIconClicked
()
messageViewMenuActionListener
.
onDeleteIconClicked
()
},
},
modifier
=
Modifier
.
testTag
(
"
messageViewDeleteMenuItem
"
)
modifier
=
Modifier
.
testTag
(
TestTags
.
MessageView
.
messageViewDeleteMenuItem
)
)
{
)
{
Image
(
vectorResource
(
id
=
R
.
drawable
.
ic_trash_can_daynight
))
Image
(
vectorResource
(
id
=
R
.
drawable
.
ic_trash_can_daynight
))
}
}
...
@@ -241,7 +241,7 @@ fun ColumnScope.MessageViewBodyHeader() {
...
@@ -241,7 +241,7 @@ fun ColumnScope.MessageViewBodyHeader() {
.
preferredSize
(
48
.
dp
)
.
preferredSize
(
48
.
dp
)
.
clip
(
shape
=
CircleShape
)
.
clip
(
shape
=
CircleShape
)
.
background
(
colorResource
(
id
=
R
.
color
.
grey_scale_color
))
.
background
(
colorResource
(
id
=
R
.
color
.
grey_scale_color
))
.
testTag
(
"
messageViewAvatar
"
),
.
testTag
(
TestTags
.
MessageView
.
messageViewAvatar
),
contentScale
=
ContentScale
.
Crop
contentScale
=
ContentScale
.
Crop
)
)
Spacer
(
Modifier
.
preferredWidth
(
16
.
dp
))
Spacer
(
Modifier
.
preferredWidth
(
16
.
dp
))
...
@@ -254,7 +254,7 @@ fun ColumnScope.MessageViewBodyHeader() {
...
@@ -254,7 +254,7 @@ fun ColumnScope.MessageViewBodyHeader() {
Date
(
message
.
date
).
toString
(),
Date
(
message
.
date
).
toString
(),
Modifier
Modifier
.
align
(
Alignment
.
End
)
.
align
(
Alignment
.
End
)
.
testTag
(
"
messageViewDate
"
)
.
testTag
(
TestTags
.
MessageView
.
messageViewDate
)
)
)
}
}
...
...