Skip to content

Commit

Permalink
Merge branch 'main' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanbarrossilva committed Jan 9, 2024
2 parents 0d00a54 + d1c877d commit 490cd93
Show file tree
Hide file tree
Showing 136 changed files with 2,168 additions and 445 deletions.
7 changes: 4 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ android {
compileSdk = libs.versions.android.sdk.target.get().toInt()
composeOptions.kotlinCompilerExtensionVersion = libs.versions.android.compose.compiler.get()
flavorDimensions += Dimensions.VERSION
lintOptions.disable += "Instantiatable"
lint.disable += "Instantiatable"
namespace = namespaceFor("app")

buildFeatures {
Expand Down Expand Up @@ -71,6 +71,7 @@ android {

dependencies {
"androidTestDemoImplementation"(project(":core:sample-test"))
"androidTestDemoImplementation"(project(":feature:gallery-test"))
"androidTestDemoImplementation"(project(":platform:ui"))
"androidTestDemoImplementation"(libs.android.activity.ktx)
"androidTestDemoImplementation"(libs.android.compose.ui.test.junit)
Expand Down Expand Up @@ -103,6 +104,6 @@ dependencies {
implementation(libs.android.constraintlayout)
implementation(libs.android.fragment.ktx)
implementation(libs.android.material)
implementation(libs.kotlin.reflect)
implementation(libs.time4j)

releaseImplementation(libs.kotlin.reflect)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.swipeDown
import com.jeanbarrossilva.orca.app.demo.test.onSearchAction
import com.jeanbarrossilva.orca.app.demo.test.performScrollToPostPreviewWithGalleryPreview
import com.jeanbarrossilva.orca.app.demo.test.performScrollToPostPreviewWithLinkCard
import com.jeanbarrossilva.orca.core.feed.profile.post.content.highlight.Highlight
Expand All @@ -30,7 +31,11 @@ import com.jeanbarrossilva.orca.ext.intents.intendBrowsingTo
import com.jeanbarrossilva.orca.ext.intents.intendStartingOf
import com.jeanbarrossilva.orca.feature.composer.ComposerActivity
import com.jeanbarrossilva.orca.feature.feed.FEED_FLOATING_ACTION_BUTTON_TAG
import com.jeanbarrossilva.orca.feature.feed.FeedFragment
import com.jeanbarrossilva.orca.feature.gallery.GalleryActivity
import com.jeanbarrossilva.orca.feature.gallery.test.ui.onCloseActionButton
import com.jeanbarrossilva.orca.feature.search.SearchActivity
import com.jeanbarrossilva.orca.platform.ui.test.assertIsAtFragment
import com.jeanbarrossilva.orca.platform.ui.test.component.timeline.onRefreshIndicator
import com.jeanbarrossilva.orca.platform.ui.test.component.timeline.onTimeline
import com.jeanbarrossilva.orca.platform.ui.test.component.timeline.post.figure.gallery.thumbnail.onThumbnails
Expand All @@ -42,6 +47,11 @@ import org.junit.Test
internal class FeedTests {
@get:Rule val composeRule = createAndroidComposeRule<DemoOrcaActivity>()

@Test
fun navigatesToSearch() {
intendStartingOf<SearchActivity> { composeRule.onSearchAction().performClick() }
}

@Test
fun refreshes() {
composeRule.onTimeline().performTouchInput(TouchInjectionScope::swipeDown)
Expand All @@ -67,6 +77,17 @@ internal class FeedTests {
}
}

@Test
fun navigatesToGalleryAndGoesBackToFeedWhenClosingIt() {
with(composeRule) {
onTimeline().performScrollToPostPreviewWithGalleryPreview {
onThumbnails().onFirst().performClick()
onCloseActionButton().performClick()
assertIsAtFragment(composeRule.activity, FeedFragment.ROUTE)
}
}
}

@Test
fun navigatesToComposerOnFabClick() {
intendStartingOf<ComposerActivity> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
import com.jeanbarrossilva.orca.app.R
import com.jeanbarrossilva.orca.app.demo.test.performScrollToPostPreviewWithLinkCard
import com.jeanbarrossilva.orca.app.demo.test.performStartClick
import com.jeanbarrossilva.orca.core.feed.profile.post.Post
import com.jeanbarrossilva.orca.core.feed.profile.post.content.highlight.Highlight
import com.jeanbarrossilva.orca.core.sample.feed.profile.post.Posts
import com.jeanbarrossilva.orca.core.sample.test.feed.profile.post.content.highlight.sample
import com.jeanbarrossilva.orca.core.sample.test.feed.profile.post.samples
import com.jeanbarrossilva.orca.core.sample.test.feed.profile.post.withSamples
import com.jeanbarrossilva.orca.ext.intents.intendBrowsingTo
import com.jeanbarrossilva.orca.feature.postdetails.PostDetailsFragment
import com.jeanbarrossilva.orca.platform.ui.test.assertIsAtFragment
Expand All @@ -51,6 +51,9 @@ internal class ProfileDetailsTests {
fun navigatesToPostDetailsOnPostPreviewClick() {
onView(withId(R.id.profile_details)).perform(click())
composeRule.onPostPreviews().onFirst().performStartClick()
assertIsAtFragment(composeRule.activity, PostDetailsFragment.getRoute(Post.samples.first().id))
assertIsAtFragment(
composeRule.activity,
PostDetailsFragment.getRoute(Posts.withSamples.first().id)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright © 2024 Orca
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If
* not, see https://www.gnu.org/licenses.
*/

package com.jeanbarrossilva.orca.app.demo

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import com.jeanbarrossilva.orca.app.demo.test.onSearchAction
import org.junit.Rule
import org.junit.Test

internal class SemanticsNodeInteractionsProviderExtensionsTests {
@get:Rule val composeRule = createAndroidComposeRule<DemoOrcaActivity>()

@Test
fun findsSearchAction() {
composeRule.onSearchAction().assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright © 2024 Orca
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If
* not, see https://www.gnu.org/licenses.
*/

package com.jeanbarrossilva.orca.app.demo.test

import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
import androidx.compose.ui.test.onNodeWithTag
import com.jeanbarrossilva.orca.feature.feed.FEED_SEARCH_ACTION_TAG

/** [SemanticsNodeInteraction] of the feed's search action. */
internal fun SemanticsNodeInteractionsProvider.onSearchAction(): SemanticsNodeInteraction {
return onNodeWithTag(FEED_SEARCH_ACTION_TAG)
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ open class OrcaActivity : NavigationActivity(), OnBottomAreaAvailabilityChangeLi
register<PostDetailsModule>(MainPostDetailsModule(this@OrcaActivity))
register<ProfileDetailsModule>(MainProfileDetailsModule(this@OrcaActivity))
register<SearchModule>(MainSearchModule(navigator))
register<SettingsModule>(MainSettingsModule(navigator))
register<TermMutingModule>(MainTermMutingModule(navigator))
register<SettingsModule>(MainSettingsModule(this@OrcaActivity))
register<TermMutingModule>(MainTermMutingModule)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import com.jeanbarrossilva.orca.feature.composer.ComposerActivity
import com.jeanbarrossilva.orca.feature.feed.FeedBoundary
import com.jeanbarrossilva.orca.feature.gallery.GalleryActivity
import com.jeanbarrossilva.orca.feature.postdetails.PostDetailsFragment
import com.jeanbarrossilva.orca.feature.search.SearchFragment
import com.jeanbarrossilva.orca.feature.search.SearchActivity
import com.jeanbarrossilva.orca.platform.ui.core.browseTo
import com.jeanbarrossilva.orca.platform.ui.core.navigation.Navigator
import java.net.URL
Expand All @@ -33,7 +33,7 @@ internal class NavigatorFeedBoundary(
private val navigator: Navigator
) : FeedBoundary {
override fun navigateToSearch() {
SearchFragment.navigate(navigator)
SearchActivity.start(context)
}

override fun navigateTo(url: URL) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,4 @@ internal class NavigatorGalleryBoundary(private val navigator: Navigator) : Gall
override fun navigateToPostDetails(id: String) {
PostDetailsFragment.navigate(navigator, id)
}

override fun pop() {
navigator.pop()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,4 @@ internal class NavigatorSearchBoundary(private val navigator: Navigator) : Searc
override fun navigateToProfileDetails(id: String) {
ProfileDetailsFragment.navigate(navigator, id)
}

override fun pop() {
navigator.pop()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@

package com.jeanbarrossilva.orca.app.module.feature.settings

import android.content.Context
import com.jeanbarrossilva.orca.feature.settings.SettingsBoundary
import com.jeanbarrossilva.orca.feature.settings.termmuting.TermMutingFragment
import com.jeanbarrossilva.orca.platform.ui.core.navigation.Navigator
import com.jeanbarrossilva.orca.feature.settings.termmuting.TermMutingActivity

internal class NavigatorSettingsBoundary(private val navigator: Navigator) : SettingsBoundary {
internal class ContextualSettingsBoundary(private val context: Context) : SettingsBoundary {
override fun navigateToTermMuting() {
TermMutingFragment.navigate(navigator)
TermMutingActivity.start(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@

package com.jeanbarrossilva.orca.app.module.feature.settings

import android.content.Context
import com.jeanbarrossilva.orca.core.module.CoreModule
import com.jeanbarrossilva.orca.core.module.termMuter
import com.jeanbarrossilva.orca.feature.settings.SettingsModule
import com.jeanbarrossilva.orca.platform.ui.core.navigation.Navigator
import com.jeanbarrossilva.orca.std.injector.Injector

internal class MainSettingsModule(private val navigator: Navigator) :
internal class MainSettingsModule(private val context: Context) :
SettingsModule(
{ Injector.from<CoreModule>().termMuter() },
{ NavigatorSettingsBoundary(navigator) }
{ ContextualSettingsBoundary(context) }
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ package com.jeanbarrossilva.orca.app.module.feature.settings.termmuting
import com.jeanbarrossilva.orca.core.module.CoreModule
import com.jeanbarrossilva.orca.core.module.termMuter
import com.jeanbarrossilva.orca.feature.settings.termmuting.TermMutingModule
import com.jeanbarrossilva.orca.platform.ui.core.navigation.Navigator
import com.jeanbarrossilva.orca.std.injector.Injector

internal class MainTermMutingModule(private val navigator: Navigator) :
TermMutingModule(
{ Injector.from<CoreModule>().termMuter() },
{ NavigatorTermMutingBoundary(navigator) }
)
internal object MainTermMutingModule :
TermMutingModule({ Injector.from<CoreModule>().termMuter() })
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ internal enum class BottomNavigation {
override val id = R.id.feed

override suspend fun getDestination(): Navigator.Navigation.Destination<*> {
return authenticationLock.requestUnlock {
Navigator.Navigation.Destination("feed") { FeedFragment(it.id) }
return authenticationLock.scheduleUnlock {
Navigator.Navigation.Destination(FeedFragment.ROUTE) { FeedFragment(it.id) }
}
}
},
PROFILE_DETAILS {
override val id = R.id.profile_details

override suspend fun getDestination(): Navigator.Navigation.Destination<*> {
return authenticationLock.requestUnlock {
return authenticationLock.scheduleUnlock {
Navigator.Navigation.Destination(ProfileDetailsFragment.createRoute(it.id)) {
ProfileDetailsFragment(BackwardsNavigationState.Unavailable, it.id)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import com.jeanbarrossilva.orca.core.auth.actor.Actor
* [AuthenticationLock] with test-specific default structures.
*
* @param authenticator [TestAuthenticator] through which the [Actor] will be authenticated if it
* isn't and [requestUnlock][AuthenticationLock.requestUnlock] is called.
* isn't and [requestUnlock][AuthenticationLock.scheduleUnlock] is called.
* @param actorProvider [TestActorProvider] whose provided [Actor] will be ensured to be either
* [unauthenticated][Actor.Unauthenticated] or [authenticated][Actor.Authenticated].
*/
Expand Down
2 changes: 1 addition & 1 deletion core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dependencies {
testImplementation(project(":core:sample"))
testImplementation(project(":core:sample-test"))
testImplementation(project(":core-test"))
testImplementation(libs.assertk)
testImplementation(project(":ext:testing"))
testImplementation(libs.kotlin.coroutines.test)
testImplementation(libs.kotlin.test)
testImplementation(libs.turbine)
Expand Down
2 changes: 2 additions & 0 deletions core/mastodon/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ android {
dependencies {
androidTestImplementation(project(":platform:autos-test"))
androidTestImplementation(project(":platform:intents"))
androidTestImplementation(project(":platform:testing"))
androidTestImplementation(project(":std:injector-test"))
androidTestImplementation(libs.android.compose.ui.test.junit)
androidTestImplementation(libs.android.test.core)
Expand All @@ -54,6 +55,7 @@ dependencies {
ksp(project(":std:injector-processor"))

implementation(project(":core:sample"))
implementation(project(":ext:coroutines"))
implementation(project(":platform:autos"))
implementation(project(":platform:cache"))
implementation(project(":platform:ui"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performImeAction
import androidx.compose.ui.test.performTextInput
import androidx.test.platform.app.InstrumentationRegistry
import com.jeanbarrossilva.orca.core.instance.Instance
import com.jeanbarrossilva.orca.core.instance.InstanceProvider
import com.jeanbarrossilva.orca.core.instance.domain.Domain
Expand All @@ -33,15 +32,14 @@ import com.jeanbarrossilva.orca.core.sample.feed.profile.post.content.SampleTerm
import com.jeanbarrossilva.orca.core.sample.instance.domain.sample
import com.jeanbarrossilva.orca.ext.intents.intendBrowsingTo
import com.jeanbarrossilva.orca.platform.autos.test.kit.input.text.onTextFieldErrors
import com.jeanbarrossilva.orca.platform.testing.asString
import com.jeanbarrossilva.orca.platform.testing.context
import com.jeanbarrossilva.orca.platform.ui.core.sample
import com.jeanbarrossilva.orca.std.injector.test.InjectorTestRule
import org.junit.Rule
import org.junit.Test

internal class MastodonAuthorizationActivityTests {
private val context
get() = InstrumentationRegistry.getInstrumentation().context

@get:Rule
val injectorRule = InjectorTestRule {
register(
Expand All @@ -58,51 +56,45 @@ internal class MastodonAuthorizationActivityTests {
@Test
fun showsErrorWhenSigningInWithBlankDomain() {
composeRule
.onNodeWithText(context.getString(R.string.core_http_authorization_domain))
.onNodeWithText(R.string.core_http_authorization_domain.asString())
.apply { performTextInput(" ") }
.performImeAction()
composeRule
.onTextFieldErrors()
.assertTextEquals(
context.getString(
com.jeanbarrossilva.orca.platform.autos.R.string
.platform_ui_text_field_consecutive_error_message,
context.getString(R.string.core_http_authorization_empty_domain)
)
com.jeanbarrossilva.orca.platform.autos.R.string
.platform_ui_text_field_consecutive_error_message
.asString(R.string.core_http_authorization_empty_domain.asString())
)
}

@Test
fun showsErrorWhenSigningInWithInvalidDomain() {
composeRule
.onNodeWithText(context.getString(R.string.core_http_authorization_domain))
.onNodeWithText(R.string.core_http_authorization_domain.asString())
.apply { performTextInput("1️⃣🏛️🖼️") }
.performImeAction()
composeRule
.onTextFieldErrors()
.assertTextEquals(
context.getString(
com.jeanbarrossilva.orca.platform.autos.R.string
.platform_ui_text_field_consecutive_error_message,
context.getString(R.string.core_http_authorization_invalid_domain)
)
com.jeanbarrossilva.orca.platform.autos.R.string
.platform_ui_text_field_consecutive_error_message
.asString(R.string.core_http_authorization_invalid_domain.asString())
)
}

@Test
fun browsesToHelpArticle() {
intendBrowsingTo("${MastodonAuthorizationActivity.helpUri}") {
composeRule
.onNodeWithText(context.getString(R.string.core_http_authorization_help))
.performClick()
composeRule.onNodeWithText(R.string.core_http_authorization_help.asString()).performClick()
}
}

@Test
fun browsesToInstanceWhenSigningInWithValidDomain() {
intendBrowsingTo("${MastodonAuthorizationViewModel.createURL(context, Domain.sample)}") {
composeRule
.onNodeWithText(context.getString(R.string.core_http_authorization_domain))
.onNodeWithText(R.string.core_http_authorization_domain.asString())
.apply { performTextInput("${Domain.sample}") }
.performImeAction()
}
Expand Down
Loading

0 comments on commit 490cd93

Please sign in to comment.