Skip to content

Commit

Permalink
Merge pull request #2867 from wordpress-mobile/task/add-fetch-all-dom…
Browse files Browse the repository at this point in the history
…ains-call

Adds fetch all-domains api call
  • Loading branch information
Antonis Lilis authored Oct 12, 2023
2 parents ee1af4f + 397b911 commit ae6a6e7
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,24 @@ class DomainsFragment : StoreSelectingFragment() {
}
}
}

fetch_all_domains.setOnClickListener {
lifecycleScope.launch {
val result = store.fetchAllDomains(noWpCom = false) // fetching wpcom too for debugging purposes
when {
result.isError -> {
prependToLog("Error fetching all domains: ${result.error.message}")
}
else -> {
prependToLog("All domains count: ${result.domains?.size}")
val domains = result.domains
?.joinToString(separator = "\n") {
"${it.domain} (type: ${it.type}), expiry: ${it.expiry}"
}
prependToLog("Domains:\n$domains")
}
}
}
}
}
}
6 changes: 6 additions & 0 deletions example/src/main/res/layout/fragment_domains.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,11 @@
android:layout_height="wrap_content"
android:text="Fetch domain price" />

<Button
android:id="@+id/fetch_all_domains"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Fetch all domain" />

</LinearLayout>
</ScrollView>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package org.wordpress.android.fluxc.network.rest.wpcom.site

import com.android.volley.RequestQueue
import com.android.volley.VolleyError
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
Expand All @@ -16,6 +18,7 @@ import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.wordpress.android.fluxc.Dispatcher
import org.wordpress.android.fluxc.UnitTestUtils
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.fluxc.network.BaseRequest.BaseNetworkError
import org.wordpress.android.fluxc.network.BaseRequest.GenericErrorType
Expand Down Expand Up @@ -526,6 +529,66 @@ class SiteRestClientTest {
assertThat(options).containsEntry("site_creation_flow", siteCreationFlow)
}

@Test
fun `when all domains are requested, then the correct response is built`() = test {
val allDomainsJson = "wp/all-domains/all-domains.json"
val json = UnitTestUtils.getStringFromResourceFile(javaClass, allDomainsJson)
val responseType = object : TypeToken<AllDomainsResponse>() {}.type
val response = GsonBuilder().create().fromJson(json, responseType) as AllDomainsResponse

initAllDomainsResponse(data = response)

val responseModel = restClient.fetchAllDomains(noWpCom = true)
assert(responseModel is Success)
with((responseModel as Success).data) {
assertThat(domains).hasSize(2)
assertThat(domains[0].domain).isEqualTo("some.test.domain")
assertThat(domains[0].wpcomDomain).isFalse
assertThat(domains[1].domain).isEqualTo("some.test.domain 2")
assertThat(domains[1].wpcomDomain).isTrue
}
}

@Test
fun `given a network error, when all domains are requested, then return api error`() = test {
val error = WPComGsonNetworkError(BaseNetworkError(GenericErrorType.NETWORK_ERROR))
initAllDomainsResponse(error = error)

val response = restClient.fetchAllDomains(noWpCom = true)
assert(response is Response.Error)
with((response as Response.Error).error) {
assertThat(type).isEqualTo(GenericErrorType.NETWORK_ERROR)
assertThat(message).isNull()
}
}

@Test
fun `given timeout, when all domains are requested, then return timeout error`() = test {
val error = WPComGsonNetworkError(BaseNetworkError(GenericErrorType.TIMEOUT))
initAllDomainsResponse(error = error)

val response = restClient.fetchAllDomains(noWpCom = true)
assert(response is Response.Error)
with((response as Response.Error).error) {
assertThat(type).isEqualTo(GenericErrorType.TIMEOUT)
assertThat(message).isNull()
}
}

@Test
fun `given not authenticated, when all domains are requested, then retun auth required error`() = test {
val tokenErrorMessage = "An active access token must be used to query information about the current user."
val error = WPComGsonNetworkError(BaseNetworkError(GenericErrorType.NOT_AUTHENTICATED, tokenErrorMessage))
initAllDomainsResponse(error = error)

val response = restClient.fetchAllDomains(noWpCom = true)
assert(response is Response.Error)
with((response as Response.Error).error) {
assertThat(type).isEqualTo(GenericErrorType.NOT_AUTHENTICATED)
assertThat(message).isEqualTo(tokenErrorMessage)
}
}

private suspend fun initSiteResponse(
data: SiteWPComRestResponse? = null,
error: WPComGsonNetworkError? = null
Expand Down Expand Up @@ -561,6 +624,13 @@ class SiteRestClientTest {
return initGetResponse(SitesFeaturesRestResponse::class.java, data ?: mock(), error)
}

private suspend fun initAllDomainsResponse(
data: AllDomainsResponse? = null,
error: WPComGsonNetworkError? = null
): Response<AllDomainsResponse> {
return initGetResponse(AllDomainsResponse::class.java, data ?: mock(), error)
}

private suspend fun <T> initGetResponse(
clazz: Class<T>,
data: T,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import org.wordpress.android.fluxc.network.BaseRequest.GenericErrorType.PARSE_ER
import org.wordpress.android.fluxc.network.rest.wpapi.site.SiteWPAPIRestClient
import org.wordpress.android.fluxc.network.rest.wpcom.WPComGsonRequest.WPComGsonNetworkError
import org.wordpress.android.fluxc.network.rest.wpcom.WPComGsonRequestBuilder.Response
import org.wordpress.android.fluxc.network.rest.wpcom.site.AllDomainsResponse
import org.wordpress.android.fluxc.network.rest.wpcom.site.Domain
import org.wordpress.android.fluxc.network.rest.wpcom.site.DomainsResponse
import org.wordpress.android.fluxc.network.rest.wpcom.site.PlansResponse
Expand All @@ -38,7 +39,10 @@ import org.wordpress.android.fluxc.persistence.PostSqlUtils
import org.wordpress.android.fluxc.persistence.SiteSqlUtils
import org.wordpress.android.fluxc.persistence.domains.DomainDao
import org.wordpress.android.fluxc.persistence.jetpacksocial.JetpackSocialDao
import org.wordpress.android.fluxc.store.SiteStore.AllDomainsError
import org.wordpress.android.fluxc.store.SiteStore.AllDomainsErrorType
import org.wordpress.android.fluxc.store.SiteStore.FetchSitesPayload
import org.wordpress.android.fluxc.store.SiteStore.FetchedAllDomainsPayload
import org.wordpress.android.fluxc.store.SiteStore.FetchedDomainsPayload
import org.wordpress.android.fluxc.store.SiteStore.FetchedPlansPayload
import org.wordpress.android.fluxc.store.SiteStore.FetchedPostFormatsPayload
Expand Down Expand Up @@ -72,8 +76,10 @@ class SiteStoreTest {
@Mock lateinit var jetpackSocialDao: JetpackSocialDao
@Mock lateinit var jetpackSocialMapper: JetpackSocialMapper
@Mock lateinit var domainsSuccessResponse: Response.Success<DomainsResponse>
@Mock lateinit var allDomainsSuccessResponse: Response.Success<AllDomainsResponse>
@Mock lateinit var plansSuccessResponse: Response.Success<PlansResponse>
@Mock lateinit var domainsErrorResponse: Response.Error<DomainsResponse>
@Mock lateinit var allDomainsErrorResponse: Response.Error<AllDomainsResponse>
@Mock lateinit var plansErrorResponse: Response.Error<PlansResponse>
private lateinit var siteStore: SiteStore

Expand Down Expand Up @@ -487,4 +493,30 @@ class SiteStoreTest {

assertThat(onSitePlansFetched.error.type).isEqualTo(PlansError(PlansErrorType.GENERIC_ERROR, null).type)
}

@Test
fun `fetchAllDomains from WPCom endpoint`() = test {
whenever(siteRestClient.fetchAllDomains()).thenReturn(allDomainsSuccessResponse)
whenever(allDomainsSuccessResponse.data).thenReturn(AllDomainsResponse(listOf()))

val onAllDomainsFetched = siteStore.fetchAllDomains()

assertThat(onAllDomainsFetched.domains).isNotNull
assertThat(onAllDomainsFetched.error).isNull()
assertThat(onAllDomainsFetched).isEqualTo(FetchedAllDomainsPayload(onAllDomainsFetched.domains))
}

@Test
fun `fetchAllDomains error from WPCom endpoint returns error`() = test {
val site = SiteModel()
site.setIsWPCom(true)

whenever(siteRestClient.fetchAllDomains()).thenReturn(allDomainsErrorResponse)
whenever(allDomainsErrorResponse.error).thenReturn(WPComGsonNetworkError(BaseNetworkError(NETWORK_ERROR)))

val onAllDomainsFetched = siteStore.fetchAllDomains()

val expectedErrorType = AllDomainsError(AllDomainsErrorType.GENERIC_ERROR, null).type
assertThat(onAllDomainsFetched.error.type).isEqualTo(expectedErrorType)
}
}
32 changes: 32 additions & 0 deletions example/src/test/resources/wp/all-domains/all-domains.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"domains": [
{
"domain": "some.test.domain",
"blog_id": 11111,
"blog_name": "some test blog",
"type": "mapping",
"is_domain_only_site": false,
"is_wpcom_staging_domain": false,
"has_registration": false,
"registration_date": "2009-03-26T21:20:53+00:00",
"expiry": "2024-03-24T00:00:00+00:00",
"wpcom_domain": false,
"current_user_is_owner": true,
"site_slug": "test slug"
},
{
"domain": "some.test.domain 2",
"blog_id": 22222,
"blog_name": "some test blog 2",
"type": "mapping",
"is_domain_only_site": false,
"is_wpcom_staging_domain": false,
"has_registration": false,
"registration_date": "2009-03-26T21:20:53+00:00",
"expiry": "2024-03-24T00:00:00+00:00",
"wpcom_domain": true,
"current_user_is_owner": false,
"site_slug": "test slug 2"
}
]
}
2 changes: 2 additions & 0 deletions fluxc-processor/src/main/resources/wp-com-endpoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
/read/site/$site#String/post_email_subscriptions/$action#String
/read/site/$site#String/post_email_subscriptions/update

/all-domains

/domains/suggestions
/domains/supported-countries/
/domains/supported-states/$countryCode#String
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.wordpress.android.fluxc.network.rest.wpcom.site

import com.google.gson.annotations.JsonAdapter
import com.google.gson.annotations.SerializedName

data class AllDomainsResponse(val domains: List<AllDomainsDomain>)

data class AllDomainsDomain(
@SerializedName("domain")
val domain: String? = null,
@SerializedName("blog_id")
val blogId: Long = 0,
@SerializedName("blog_name")
val blogName: String? = null,
@SerializedName("type")
val type: String? = null,
@SerializedName("is_domain_only_site")
@JsonAdapter(BooleanTypeAdapter::class)
val isDomainOnlySite: Boolean = false,
@SerializedName("is_wpcom_staging_domain")
@JsonAdapter(BooleanTypeAdapter::class)
val isWpcomStagingDomain: Boolean = false,
@SerializedName("has_registration")
@JsonAdapter(BooleanTypeAdapter::class)
val hasRegistration: Boolean = false,
@SerializedName("registration_date")
val registrationDate: String? = null,
@SerializedName("expiry")
val expiry: String? = null,
@SerializedName("wpcom_domain")
@JsonAdapter(BooleanTypeAdapter::class)
val wpcomDomain: Boolean = false,
@SerializedName("current_user_is_owner")
@JsonAdapter(BooleanTypeAdapter::class)
val currentUserIsOwner: Boolean = false,
@SerializedName("site_slug")
val siteSlug: String? = null,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.wordpress.android.fluxc.network.rest.wpcom.site

import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import java.lang.reflect.Type
import java.util.Locale

internal class BooleanTypeAdapter : JsonDeserializer<Boolean?> {
@Suppress("VariableNaming") private val TRUE_STRINGS: Set<String> = HashSet(listOf("true", "1", "yes"))

@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Boolean {
val jsonPrimitive = json.asJsonPrimitive
return when {
jsonPrimitive.isBoolean -> jsonPrimitive.asBoolean
jsonPrimitive.isNumber -> jsonPrimitive.asNumber.toInt() == 1
jsonPrimitive.isString -> TRUE_STRINGS.contains(jsonPrimitive.asString.toLowerCase(
Locale.getDefault()
))
else -> false
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
package org.wordpress.android.fluxc.network.rest.wpcom.site

import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import com.google.gson.annotations.JsonAdapter
import com.google.gson.annotations.SerializedName
import java.lang.reflect.Type
import java.util.Locale

data class DomainsResponse(val domains: List<Domain>)

Expand Down Expand Up @@ -155,17 +150,3 @@ data class TitanMailSubscription(
val status: String? = null
)

internal class BooleanTypeAdapter : JsonDeserializer<Boolean?> {
@Suppress("VariableNaming") private val TRUE_STRINGS: Set<String> = HashSet(listOf("true", "1", "yes"))

@Throws(JsonParseException::class)
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Boolean {
val jsonPrimitive = json.asJsonPrimitive
return when {
jsonPrimitive.isBoolean -> jsonPrimitive.asBoolean
jsonPrimitive.isNumber -> jsonPrimitive.asNumber.toInt() == 1
jsonPrimitive.isString -> TRUE_STRINGS.contains(jsonPrimitive.asString.toLowerCase(Locale.getDefault()))
else -> false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,11 @@ class SiteRestClient @Inject constructor(
add(request)
}

suspend fun fetchAllDomains(noWpCom: Boolean = true): Response<AllDomainsResponse> {
val url = WPCOMREST.all_domains.urlV1_1
val params = mapOf("no_wpcom" to noWpCom.toString())
return wpComGsonRequestBuilder.syncGetRequest(this, url, params, AllDomainsResponse::class.java)
}
suspend fun fetchSiteDomains(site: SiteModel): Response<DomainsResponse> {
val url = WPCOMREST.sites.site(site.siteId).domains.urlV1_1
return wpComGsonRequestBuilder.syncGetRequest(this, url, mapOf(), DomainsResponse::class.java)
Expand Down
Loading

0 comments on commit ae6a6e7

Please sign in to comment.