Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.woocommerce.android.applicationpasswords

import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.ApplicationPasswordsConfiguration
import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.JetpackApplicationPasswordsSupport
import javax.inject.Inject

class IsAppPasswordsSupportedForJetpackSite @Inject constructor(
private val applicationPasswordsConfiguration: ApplicationPasswordsConfiguration,
private val jetpackApplicationPasswordsSupport: JetpackApplicationPasswordsSupport
) {
suspend operator fun invoke(site: SiteModel): Boolean {
return applicationPasswordsConfiguration.isEnabledForJetpackAccess() &&
jetpackApplicationPasswordsSupport.supportsAppPasswords(site)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.woocommerce.android.support.zendesk

import android.content.Context
import android.os.Parcelable
import com.woocommerce.android.applicationpasswords.IsAppPasswordsSupportedForJetpackSite
import com.woocommerce.android.extensions.formatResult
import com.woocommerce.android.support.help.HelpOrigin
import com.woocommerce.android.support.zendesk.RequestConstants.requestCreationIdentityNotSetErrorMessage
Expand Down Expand Up @@ -35,7 +36,8 @@ class ZendeskTicketRepository @Inject constructor(
private val siteStore: SiteStore,
private val dispatchers: CoroutineDispatchers,
private val wooLog: WooLog,
private val ssrFetcher: WCSSRModelCachingFetcher
private val ssrFetcher: WCSSRModelCachingFetcher,
private val isAppPasswordsSupportedForJetpackSite: IsAppPasswordsSupportedForJetpackSite
) {
/**
* This function creates a new customer Support Request through the Zendesk API Providers.
Expand Down Expand Up @@ -140,16 +142,21 @@ class ZendeskTicketRepository @Inject constructor(
* This is a helper function which returns a set of pre-defined tags depending on some conditions. It accepts a list of
* custom tags to be added for special cases.
*/
private fun buildZendeskTags(
private suspend fun buildZendeskTags(
selectedSite: SiteModel?,
allSites: List<SiteModel>?,
origin: HelpOrigin,
extraTags: List<String>
): List<String> {
val tags = ArrayList<String>()
if (selectedSite?.connectionType == SiteConnectionType.ApplicationPasswords) {
tags.add(ZendeskTags.applicationPasswordAuthenticated)
selectedSite?.let {
if (selectedSite.connectionType == SiteConnectionType.ApplicationPasswords) {
tags.add(ZendeskTags.applicationPasswordAuthenticated)
} else if (isAppPasswordsSupportedForJetpackSite(it)) {
tags.add(ZendeskTags.jetpackSiteUsingAppPasswords)
}
}

allSites?.let { it ->
// Add wpcom tag if at least one site is WordPress.com site
if (it.any { it.isWPCom }) {
Expand Down Expand Up @@ -181,14 +188,16 @@ sealed class TicketType(
val tags: List<String> = emptyList(),
val excludedTags: List<String> = emptyList()
) : Parcelable {
@Parcelize object MobileApp : TicketType(
@Parcelize
object MobileApp : TicketType(
form = TicketCustomField.wooMobileFormID,
categoryName = ZendeskConstants.mobileAppCategory,
subcategoryName = ZendeskConstants.mobileSubcategoryValue,
tags = listOf(ZendeskTags.mobileApp)
)

@Parcelize object InPersonPayments : TicketType(
@Parcelize
object InPersonPayments : TicketType(
form = TicketCustomField.wooMobileFormID,
categoryName = ZendeskConstants.mobileAppCategory,
subcategoryName = ZendeskConstants.mobileSubcategoryValue,
Expand All @@ -198,7 +207,8 @@ sealed class TicketType(
)
)

@Parcelize object Payments : TicketType(
@Parcelize
object Payments : TicketType(
form = TicketCustomField.wooFormID,
categoryName = ZendeskConstants.supportCategory,
subcategoryName = ZendeskConstants.paymentsSubcategoryValue,
Expand All @@ -212,7 +222,8 @@ sealed class TicketType(
excludedTags = listOf(ZendeskTags.jetpackTag)
)

@Parcelize object WooPlugin : TicketType(
@Parcelize
object WooPlugin : TicketType(
form = TicketCustomField.wooFormID,
categoryName = ZendeskConstants.supportCategory,
subcategoryName = "",
Expand All @@ -224,7 +235,8 @@ sealed class TicketType(
excludedTags = listOf(ZendeskTags.jetpackTag)
)

@Parcelize object OtherPlugins : TicketType(
@Parcelize
object OtherPlugins : TicketType(
form = TicketCustomField.wooFormID,
categoryName = ZendeskConstants.supportCategory,
subcategoryName = ZendeskConstants.storeSubcategoryValue,
Expand Down Expand Up @@ -267,6 +279,7 @@ object TicketCustomField {

object ZendeskTags {
const val applicationPasswordAuthenticated = "application_password_authenticated"
const val jetpackSiteUsingAppPasswords = "jetpack_site_using_app_passwords"
const val mobileApp = "mobile_app"
const val woocommerceCore = "woocommerce_core"
const val paymentsProduct = "woocommerce_payments"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.woocommerce.android.support

import com.woocommerce.android.applicationpasswords.IsAppPasswordsSupportedForJetpackSite
import com.woocommerce.android.support.help.HelpOrigin
import com.woocommerce.android.support.zendesk.TicketCustomField
import com.woocommerce.android.support.zendesk.TicketType
Expand All @@ -25,6 +26,7 @@ import org.junit.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.given
import org.mockito.kotlin.mock
import org.mockito.kotlin.stub
import org.mockito.kotlin.verify
Expand All @@ -46,7 +48,10 @@ internal class ZendeskTicketRepositoryTest : BaseUnitTest() {
private lateinit var requestProvider: RequestProvider
private lateinit var envDataSource: ZendeskEnvironmentDataSource
private lateinit var siteStore: SiteStore
private val ssrFetcher: WCSSRModelCachingFetcher = mock()
private val ssrFetcher: WCSSRModelCachingFetcher = mock {
onBlocking { load(any()) } doReturn WooResult(model = null)
}
private val isAppPasswordsSupportedForJetpackSite: IsAppPasswordsSupportedForJetpackSite = mock()

@Before
fun setup() {
Expand Down Expand Up @@ -693,14 +698,45 @@ internal class ZendeskTicketRepositoryTest : BaseUnitTest() {
}
}

@Test
fun `given jetpack site supports app passwords, when creating the request, then include corresponding tag`() =
testBlocking {
val site = SiteModel().apply {
origin = SiteModel.ORIGIN_WPCOM_REST
setIsJetpackConnected(true)
}
given(isAppPasswordsSupportedForJetpackSite.invoke(site)).willReturn(true)

val captor = argumentCaptor<CreateRequest>()
createSUT()

// when
sut.createRequest(
context = mock(),
origin = HelpOrigin.LOGIN_HELP_NOTIFICATION,
ticketType = TicketType.MobileApp,
selectedSite = site,
subject = "subject",
description = "description",
extraTags = emptyList(),
siteAddress = "siteAddress"
).first()

// then
verify(requestProvider).createRequest(captor.capture(), any())
val tags = captor.firstValue.tags
assertThat(tags).contains(ZendeskTags.jetpackSiteUsingAppPasswords)
}

private fun createSUT() {
sut = ZendeskTicketRepository(
zendeskSettings = zendeskSettings,
envDataSource = envDataSource,
siteStore = siteStore,
dispatchers = coroutinesTestRule.testDispatchers,
mock(),
ssrFetcher
ssrFetcher,
isAppPasswordsSupportedForJetpackSite = isAppPasswordsSupportedForJetpackSite
)
}

Expand Down