Skip to content

Commit 566870d

Browse files
authored
CMM-779 migrate add categories to wordpress-rs (#22227)
* Add creating action * Minor fix * Minor fix * Adding tests * typo * Minor fixes
1 parent 01ebcb1 commit 566870d

File tree

3 files changed

+136
-2
lines changed

3 files changed

+136
-2
lines changed

libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpapi/taxonomy/TaxonomyRsApiRestClient.kt

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpApiClientProvider
1212
import org.wordpress.android.fluxc.store.TaxonomyStore
1313
import org.wordpress.android.fluxc.store.TaxonomyStore.DEFAULT_TAXONOMY_TAG
1414
import org.wordpress.android.fluxc.store.TaxonomyStore.FetchTermsResponsePayload
15+
import org.wordpress.android.fluxc.store.TaxonomyStore.RemoteTermPayload
1516
import org.wordpress.android.fluxc.store.TaxonomyStore.TaxonomyError
1617
import org.wordpress.android.fluxc.store.TaxonomyStore.TaxonomyErrorType
1718
import org.wordpress.android.fluxc.utils.AppLogWrapper
1819
import org.wordpress.android.util.AppLog
1920
import rs.wordpress.api.kotlin.WpRequestResult
21+
import uniffi.wp_api.CategoryCreateParams
2022
import uniffi.wp_api.CategoryListParams
2123
import uniffi.wp_api.TagListParams
2224
import javax.inject.Inject
@@ -30,6 +32,52 @@ class TaxonomyRsApiRestClient @Inject constructor(
3032
private val appLogWrapper: AppLogWrapper,
3133
private val wpApiClientProvider: WpApiClientProvider,
3234
) {
35+
fun createPostCategory(site: SiteModel, term: TermModel) {
36+
scope.launch {
37+
val client = wpApiClientProvider.getWpApiClient(site)
38+
39+
val categoriesResponse = client.request { requestBuilder ->
40+
requestBuilder.categories().create(
41+
CategoryCreateParams(
42+
name = term.name,
43+
description = term.description,
44+
slug = term.slug,
45+
parent = term.parentRemoteId
46+
)
47+
)
48+
}
49+
50+
when (categoriesResponse) {
51+
is WpRequestResult.Success -> {
52+
val category = categoriesResponse.response.data
53+
appLogWrapper.d(AppLog.T.POSTS, "Created category: ${category.name}")
54+
val payload = RemoteTermPayload(
55+
TermModel(
56+
category.id.toInt(),
57+
site.id,
58+
category.id,
59+
TaxonomyStore.DEFAULT_TAXONOMY_CATEGORY,
60+
category.name,
61+
category.slug,
62+
category.description,
63+
category.parent,
64+
category.count.toInt()
65+
),
66+
site
67+
)
68+
notifyTermCreated(payload)
69+
}
70+
71+
else -> {
72+
appLogWrapper.e(AppLog.T.POSTS, "Failed creating category: $categoriesResponse")
73+
val payload = RemoteTermPayload(term, site)
74+
payload.error = TaxonomyError(TaxonomyErrorType.GENERIC_ERROR, "")
75+
notifyTermCreated(payload)
76+
}
77+
}
78+
}
79+
}
80+
3381
fun fetchPostCategories(site: SiteModel) {
3482
scope.launch {
3583
val client = wpApiClientProvider.getWpApiClient(site)
@@ -124,6 +172,12 @@ class TaxonomyRsApiRestClient @Inject constructor(
124172
dispatcher.dispatch(TaxonomyActionBuilder.newFetchedTermsAction(payload))
125173
}
126174

175+
private fun notifyTermCreated(
176+
payload: RemoteTermPayload,
177+
) {
178+
dispatcher.dispatch(TaxonomyActionBuilder.newPushedTermAction(payload))
179+
}
180+
127181
private fun createTermsResponsePayload(
128182
terms: List<TermModel>,
129183
site: SiteModel,

libs/fluxc/src/main/java/org/wordpress/android/fluxc/store/TaxonomyStore.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,11 @@ private void handlePushTermCompleted(@NonNull RemoteTermPayload payload) {
426426
}
427427

428428
private void pushTerm(@NonNull RemoteTermPayload payload) {
429-
if (payload.site.isUsingWpComRestApi()) {
429+
if (payload.site.isUsingSelfHostedRestApi() && DEFAULT_TAXONOMY_CATEGORY.equals(payload.term.getTaxonomy())) {
430+
mTaxonomyRsApiRestClient.createPostCategory(payload.site, payload.term);
431+
} else if (payload.site.isUsingWpComRestApi()) {
430432
mTaxonomyRestClient.pushTerm(payload.term, payload.site);
431433
} else {
432-
// TODO: check for WP-REST-API plugin and use it here
433434
mTaxonomyXMLRPCClient.pushTerm(payload.term, payload.site);
434435
}
435436
}

libs/fluxc/src/test/java/org/wordpress/android/fluxc/network/rest/wpapi/taxonomy/TaxonomyRsApiRestClientTest.kt

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@ import org.wordpress.android.fluxc.action.TaxonomyAction
2424
import org.wordpress.android.fluxc.annotations.action.Action
2525
import org.wordpress.android.fluxc.model.SiteModel
2626
import org.wordpress.android.fluxc.network.rest.wpapi.rs.WpApiClientProvider
27+
import org.wordpress.android.fluxc.model.TermModel
2728
import org.wordpress.android.fluxc.store.TaxonomyStore.FetchTermsResponsePayload
29+
import org.wordpress.android.fluxc.store.TaxonomyStore.RemoteTermPayload
2830
import org.wordpress.android.fluxc.store.TaxonomyStore.TaxonomyErrorType
2931
import org.wordpress.android.fluxc.utils.AppLogWrapper
3032
import rs.wordpress.api.kotlin.WpApiClient
3133
import rs.wordpress.api.kotlin.WpRequestResult
3234
import uniffi.wp_api.CategoryWithEditContext
35+
import uniffi.wp_api.CategoriesRequestCreateResponse
3336
import uniffi.wp_api.CategoriesRequestListWithEditContextResponse
3437
import uniffi.wp_api.TagWithEditContext
3538
import uniffi.wp_api.TagsRequestListWithEditContextResponse
@@ -56,6 +59,18 @@ class TaxonomyRsApiRestClientTest {
5659
url = "https://test.wordpress.com"
5760
}
5861

62+
private val testTermModel = TermModel(
63+
1, // id
64+
123, // localSiteId
65+
2L, // remoteTermId
66+
"category", // taxonomy
67+
"Test Category", // name
68+
"test-category", // slug
69+
"Test category description", // description
70+
0L, // parentRemoteId
71+
0 // postCount
72+
)
73+
5974
private val testTagTaxonomyName = "post_tag"
6075
private val testCategoryTaxonomyName = "category"
6176

@@ -199,6 +214,70 @@ class TaxonomyRsApiRestClientTest {
199214
assertNull(payload.error)
200215
}
201216

217+
@Test
218+
fun `createPostCategory with error response dispatches error action`() = runTest {
219+
// Use a concrete error type that we can create - UnknownError requires statusCode and response
220+
val errorResponse = WpRequestResult.UnknownError<Any>(
221+
statusCode = 500u,
222+
response = "Internal Server Error"
223+
)
224+
225+
whenever(wpApiClient.request<Any>(any())).thenReturn(errorResponse)
226+
227+
taxonomyClient.createPostCategory(testSite, testTermModel)
228+
229+
// Verify dispatcher was called with error action
230+
val actionCaptor = ArgumentCaptor.forClass(Action::class.java)
231+
verify(dispatcher).dispatch(actionCaptor.capture())
232+
233+
val capturedAction = actionCaptor.value
234+
val payload = capturedAction.payload as RemoteTermPayload
235+
assertEquals(capturedAction.type, TaxonomyAction.PUSHED_TERM)
236+
assertEquals(testSite, payload.site)
237+
assertEquals(testTermModel, payload.term)
238+
assertNotNull(payload.error)
239+
assertEquals(TaxonomyErrorType.GENERIC_ERROR, payload.error?.type)
240+
}
241+
242+
@Test
243+
fun `createPostCategory with success response dispatches success action`() = runTest {
244+
val categoryWithEditContext = createTestCategoryWithEditContext()
245+
246+
// Create the correct response structure following the MediaRSApiRestClientTest pattern
247+
val categoryResponse = CategoriesRequestCreateResponse(
248+
categoryWithEditContext,
249+
mock<WpNetworkHeaderMap>()
250+
)
251+
252+
val successResponse: WpRequestResult<CategoriesRequestCreateResponse> = WpRequestResult.Success(
253+
response = categoryResponse
254+
)
255+
256+
whenever(wpApiClient.request<CategoriesRequestCreateResponse>(any())).thenReturn(successResponse)
257+
258+
taxonomyClient.createPostCategory(testSite, testTermModel)
259+
260+
// Verify dispatcher was called with success action
261+
val actionCaptor = ArgumentCaptor.forClass(Action::class.java)
262+
verify(dispatcher).dispatch(actionCaptor.capture())
263+
264+
val capturedAction = actionCaptor.value
265+
val payload = capturedAction.payload as RemoteTermPayload
266+
assertEquals(capturedAction.type, TaxonomyAction.PUSHED_TERM)
267+
assertEquals(testSite, payload.site)
268+
assertNotNull(payload.term)
269+
// Verify the created term has the correct properties
270+
assertEquals(categoryWithEditContext.id.toInt(), payload.term.id)
271+
assertEquals(testSite.id, payload.term.localSiteId)
272+
assertEquals(categoryWithEditContext.id, payload.term.remoteTermId)
273+
assertEquals(testCategoryTaxonomyName, payload.term.taxonomy)
274+
assertEquals(categoryWithEditContext.name, payload.term.name)
275+
assertEquals(categoryWithEditContext.slug, payload.term.slug)
276+
assertEquals(categoryWithEditContext.description, payload.term.description)
277+
assertEquals(categoryWithEditContext.count.toInt(), payload.term.postCount)
278+
assertNull(payload.error)
279+
}
280+
202281
private fun createTestCategoryWithEditContext(): CategoryWithEditContext {
203282
return CategoryWithEditContext(
204283
id = 2L,

0 commit comments

Comments
 (0)