Skip to content

Commit e2a708a

Browse files
authored
Refactor: Move GutenbergKit configuration logic to appropriate locations (#22172)
* refactor: Move GutenbergKit configuration logic to appropriate locations Continues the refactoring effort to reduce GutenbergKitActivity responsibilities by moving fragment configuration logic closer to where it belongs. Changes: - Add companion object factory methods to SiteConfig.fromSiteModel() and PostConfig.fromPostModel() - Move buildAuthorizationData() method from activity to GutenbergKitSettingsBuilder - Add newInstanceWithBuilder() factory method to GutenbergKitEditorFragment - Consolidate configuration parameters into GutenbergKitConfig wrapper object - Remove duplicate configuration building methods from activity - Clean up unused imports The activity now delegates configuration building to the appropriate classes rather than handling detailed fragment setup logic itself. This improves separation of concerns and makes the fragment more self-contained. * refactor: Restore FeatureConfig data class and embed in AppConfig Maintains better separation of concerns by keeping feature-related configuration grouped together instead of scattering individual feature flags throughout AppConfig. Changes: - Restore FeatureConfig data class with feature flags - Add featureConfig property to AppConfig instead of individual flags - Update buildSettings method to use appConfig.featureConfig - Update activity to create FeatureConfig separately This preserves logical grouping while still consolidating parameters. * refactor: Keep FeatureConfig as separate parameter in buildSettings Restores the original API design where FeatureConfig remains a separate parameter to buildSettings method instead of being embedded in AppConfig. Changes: - Remove featureConfig from AppConfig data class - Restore featureConfig parameter to buildSettings method - Add featureConfig to GutenbergKitConfig wrapper - Update fragment to pass featureConfig separately - Update activity to create separate featureConfig This maintains better separation of concerns and preserves the logical grouping of related configuration parameters. * refactor: Simplify fromSiteModel to use single parameter Remove redundant siteId parameter and use SiteModel.siteId directly. This simplifies the factory method while maintaining the same functionality. * fix: Restore original webEditor and selfHostedSiteId logic Fixes logical changes in buildAuthorizationData to match original implementation: - Add webEditor and selfHostedSiteId fields to SiteConfig - Use original siteModel.selfHostedSiteId instead of calculated value - Use original siteModel.webEditor instead of empty string This ensures the authorization data matches the original behavior exactly. * fix: Use processed username/password in buildAuthorizationData Corrects the final logical difference to match original implementation: - Add apiRestUsernameProcessed and apiRestPasswordProcessed fields to SiteConfig - Use siteModel.getUserNameProcessed() and getPasswordProcessed() in factory - Update buildAuthorizationData to use processed versions This now exactly matches the original createGutenbergWebViewAuthorizationData method. * fix: Update test helper methods for new data class parameters Add missing required parameters to SiteConfig and AppConfig test helper methods to fix compilation errors after consolidating configuration logic. Changes: - Add selfHostedSiteId, webEditor, and processed credentials to SiteConfig - Add accountUserId, accountUserName, userAgent, and isJetpackSsoEnabled to AppConfig - Update test cases to use the new parameter structure * fix: Handle null context in UserAgent constructor Make UserAgent constructor safe when called with null context by using safe navigation operators and providing fallback values. Changes: - Use safe navigation for WebSettings.getDefaultUserAgent() call - Provide empty string fallback for defaultUserAgent when context is null - Use safe navigation for PackageUtils.getVersionName() call - Provide "0" fallback for versionName when context is null - Update test to use proper constructor parameters with import cleanup
1 parent 8a31c31 commit e2a708a

File tree

5 files changed

+161
-68
lines changed

5 files changed

+161
-68
lines changed

WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitActivity.kt

Lines changed: 16 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ import org.wordpress.android.editor.EditorImageSettingsListener
6565
import org.wordpress.android.editor.ExceptionLogger
6666
import org.wordpress.android.editor.gutenberg.DialogVisibility
6767
import org.wordpress.android.ui.posts.editor.GutenbergKitEditorFragment
68-
import org.wordpress.android.editor.gutenberg.GutenbergWebViewAuthorizationData
6968
import org.wordpress.android.editor.savedinstance.SavedInstanceDatabase
7069
import org.wordpress.android.editor.savedinstance.SavedInstanceDatabase.Companion.getDatabase
7170
import org.wordpress.android.fluxc.Dispatcher
@@ -105,8 +104,6 @@ import org.wordpress.android.fluxc.store.SiteStore.OnPrivateAtomicCookieFetched
105104
import org.wordpress.android.fluxc.store.UploadStore
106105
import org.wordpress.android.fluxc.store.bloggingprompts.BloggingPromptsStore
107106
import org.wordpress.android.fluxc.tools.FluxCImageLoader
108-
import org.wordpress.android.fluxc.utils.extensions.getPasswordProcessed
109-
import org.wordpress.android.fluxc.utils.extensions.getUserNameProcessed
110107
import org.wordpress.android.imageeditor.preview.PreviewImageFragment
111108
import org.wordpress.android.imageeditor.preview.PreviewImageFragment.Companion.EditImageData.InputData
112109
import org.wordpress.android.support.ZendeskHelper
@@ -2212,54 +2209,10 @@ class GutenbergKitActivity : BaseAppCompatActivity(), EditorImageSettingsListene
22122209
onXpostsSettingsCapability(isXpostsCapable)
22132210
}
22142211

2215-
val isWpCom = site.isWPCom || siteModel.isWPComAtomic
2216-
val gutenbergWebViewAuthorizationData = createGutenbergWebViewAuthorizationData(isWpCom)
2217-
val settings = createGutenbergKitSettings()
2212+
val siteConfig = GutenbergKitSettingsBuilder.SiteConfig.fromSiteModel(siteModel)
22182213

2219-
return GutenbergKitEditorFragment.newInstance(
2220-
getContext(),
2221-
isNewPost,
2222-
gutenbergWebViewAuthorizationData,
2223-
jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(),
2224-
settings
2225-
)
2226-
}
2227-
2228-
private fun createGutenbergWebViewAuthorizationData(isWpCom: Boolean): GutenbergWebViewAuthorizationData {
2229-
return GutenbergWebViewAuthorizationData(
2230-
siteModel.url,
2231-
isWpCom,
2232-
accountStore.account.userId,
2233-
accountStore.account.userName,
2234-
accountStore.accessToken,
2235-
siteModel.selfHostedSiteId,
2236-
siteModel.getUserNameProcessed(),
2237-
siteModel.getPasswordProcessed(),
2238-
siteModel.isUsingWpComRestApi,
2239-
siteModel.webEditor,
2240-
userAgent.toString(),
2241-
isJetpackSsoEnabled
2242-
)
2243-
}
2244-
2245-
private fun createGutenbergKitSettings(): MutableMap<String, Any?> {
2246-
val siteConfig = GutenbergKitSettingsBuilder.SiteConfig(
2247-
url = siteModel.url,
2248-
siteId = site.siteId,
2249-
isWPCom = site.isWPCom,
2250-
isWPComAtomic = siteModel.isWPComAtomic,
2251-
isJetpackConnected = site.isJetpackConnected,
2252-
isUsingWpComRestApi = siteModel.isUsingWpComRestApi,
2253-
wpApiRestUrl = siteModel.wpApiRestUrl,
2254-
apiRestUsernamePlain = site.apiRestUsernamePlain,
2255-
apiRestPasswordPlain = siteModel.apiRestPasswordPlain
2256-
)
2257-
2258-
val postConfig = GutenbergKitSettingsBuilder.PostConfig(
2259-
remotePostId = editPostRepository.getPost()?.remotePostId,
2260-
isPage = editPostRepository.isPage,
2261-
title = editPostRepository.getPost()?.title,
2262-
content = editPostRepository.getPost()?.content
2214+
val postConfig = GutenbergKitSettingsBuilder.PostConfig.fromPostModel(
2215+
editPostRepository.getPost()
22632216
)
22642217

22652218
val featureConfig = GutenbergKitSettingsBuilder.FeatureConfig(
@@ -2272,15 +2225,26 @@ class GutenbergKitActivity : BaseAppCompatActivity(), EditorImageSettingsListene
22722225
val appConfig = GutenbergKitSettingsBuilder.AppConfig(
22732226
accessToken = accountStore.accessToken,
22742227
locale = perAppLocaleManager.getCurrentLocaleLanguageCode(),
2275-
cookies = editPostAuthViewModel.getCookiesForPrivateSites(site, privateAtomicCookie)
2228+
cookies = editPostAuthViewModel.getCookiesForPrivateSites(site, privateAtomicCookie),
2229+
accountUserId = accountStore.account.userId,
2230+
accountUserName = accountStore.account.userName,
2231+
userAgent = userAgent,
2232+
isJetpackSsoEnabled = isJetpackSsoEnabled
22762233
)
22772234

2278-
return GutenbergKitSettingsBuilder.buildSettings(
2235+
val config = GutenbergKitSettingsBuilder.GutenbergKitConfig(
22792236
siteConfig = siteConfig,
22802237
postConfig = postConfig,
22812238
appConfig = appConfig,
22822239
featureConfig = featureConfig
22832240
)
2241+
2242+
return GutenbergKitEditorFragment.newInstanceWithBuilder(
2243+
getContext(),
2244+
isNewPost,
2245+
jetpackFeatureRemovalPhaseHelper.shouldShowJetpackPoweredEditorFeatures(),
2246+
config
2247+
)
22842248
}
22852249

22862250
override fun instantiateItem(container: ViewGroup, position: Int): Any {

WordPress/src/main/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilder.kt

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package org.wordpress.android.ui.posts
22

33
import android.util.Base64
4+
import org.wordpress.android.editor.gutenberg.GutenbergWebViewAuthorizationData
5+
import org.wordpress.android.fluxc.model.PostImmutableModel
6+
import org.wordpress.android.fluxc.model.SiteModel
7+
import org.wordpress.android.fluxc.network.UserAgent
8+
import org.wordpress.android.fluxc.utils.extensions.getPasswordProcessed
9+
import org.wordpress.android.fluxc.utils.extensions.getUserNameProcessed
410
import org.wordpress.android.util.AppLog
511
import org.wordpress.android.util.UrlUtils
612

@@ -17,15 +23,50 @@ object GutenbergKitSettingsBuilder {
1723
val isUsingWpComRestApi: Boolean,
1824
val wpApiRestUrl: String?,
1925
val apiRestUsernamePlain: String?,
20-
val apiRestPasswordPlain: String?
21-
)
26+
val apiRestPasswordPlain: String?,
27+
val selfHostedSiteId: Long,
28+
val webEditor: String,
29+
val apiRestUsernameProcessed: String?,
30+
val apiRestPasswordProcessed: String?
31+
) {
32+
companion object {
33+
fun fromSiteModel(site: SiteModel): SiteConfig {
34+
return SiteConfig(
35+
url = site.url,
36+
siteId = site.siteId,
37+
isWPCom = site.isWPCom,
38+
isWPComAtomic = site.isWPComAtomic,
39+
isJetpackConnected = site.isJetpackConnected,
40+
isUsingWpComRestApi = site.isUsingWpComRestApi,
41+
wpApiRestUrl = site.wpApiRestUrl,
42+
apiRestUsernamePlain = site.apiRestUsernamePlain,
43+
apiRestPasswordPlain = site.apiRestPasswordPlain,
44+
selfHostedSiteId = site.selfHostedSiteId,
45+
webEditor = site.webEditor,
46+
apiRestUsernameProcessed = site.getUserNameProcessed(),
47+
apiRestPasswordProcessed = site.getPasswordProcessed()
48+
)
49+
}
50+
}
51+
}
2252

2353
data class PostConfig(
2454
val remotePostId: Long?,
2555
val isPage: Boolean,
2656
val title: String?,
2757
val content: String?
28-
)
58+
) {
59+
companion object {
60+
fun fromPostModel(postModel: PostImmutableModel?): PostConfig {
61+
return PostConfig(
62+
remotePostId = postModel?.remotePostId,
63+
isPage = postModel?.isPage ?: false,
64+
title = postModel?.title,
65+
content = postModel?.content
66+
)
67+
}
68+
}
69+
}
2970

3071
data class FeatureConfig(
3172
val isPluginsFeatureEnabled: Boolean,
@@ -35,7 +76,18 @@ object GutenbergKitSettingsBuilder {
3576
data class AppConfig(
3677
val accessToken: String?,
3778
val locale: String,
38-
val cookies: Any?
79+
val cookies: Any?,
80+
val accountUserId: Long,
81+
val accountUserName: String?,
82+
val userAgent: UserAgent,
83+
val isJetpackSsoEnabled: Boolean
84+
)
85+
86+
data class GutenbergKitConfig(
87+
val siteConfig: SiteConfig,
88+
val postConfig: PostConfig,
89+
val appConfig: AppConfig,
90+
val featureConfig: FeatureConfig
3991
)
4092

4193
/**
@@ -147,4 +199,27 @@ object GutenbergKitSettingsBuilder {
147199
return isFeatureEnabled &&
148200
(isWPComSite || (isJetpackConnected && !applicationPassword.isNullOrEmpty()))
149201
}
202+
203+
/**
204+
* Builds Gutenberg WebView authorization data for the fragment.
205+
*/
206+
fun buildAuthorizationData(
207+
siteConfig: SiteConfig,
208+
appConfig: AppConfig
209+
): GutenbergWebViewAuthorizationData {
210+
return GutenbergWebViewAuthorizationData(
211+
siteConfig.url,
212+
siteConfig.isWPCom || siteConfig.isWPComAtomic,
213+
appConfig.accountUserId,
214+
appConfig.accountUserName,
215+
appConfig.accessToken,
216+
siteConfig.selfHostedSiteId,
217+
siteConfig.apiRestUsernameProcessed,
218+
siteConfig.apiRestPasswordProcessed,
219+
siteConfig.isUsingWpComRestApi,
220+
siteConfig.webEditor,
221+
appConfig.userAgent.toString(),
222+
appConfig.isJetpackSsoEnabled
223+
)
224+
}
150225
}

WordPress/src/main/java/org/wordpress/android/ui/posts/editor/GutenbergKitEditorFragment.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import org.wordpress.android.editor.EditorImagePreviewListener
2525
import org.wordpress.android.editor.LiveTextWatcher
2626
import org.wordpress.android.editor.gutenberg.GutenbergWebViewAuthorizationData
2727
import org.wordpress.android.editor.savedinstance.SavedInstanceDatabase.Companion.getDatabase
28+
import org.wordpress.android.ui.posts.GutenbergKitSettingsBuilder
2829
import org.wordpress.android.util.AppLog
2930
import org.wordpress.android.util.PermissionUtils
3031
import org.wordpress.android.util.ProfilingUtils
@@ -538,5 +539,36 @@ class GutenbergKitEditorFragment : GutenbergKitEditorFragmentBase() {
538539
db?.addParcel(ARG_GUTENBERG_WEB_VIEW_AUTH_DATA, webViewAuthorizationData)
539540
return fragment
540541
}
542+
543+
/**
544+
* Simplified factory method that uses GutenbergKitSettingsBuilder for configuration.
545+
* This reduces the activity's responsibility for detailed fragment setup.
546+
*/
547+
fun newInstanceWithBuilder(
548+
context: Context,
549+
isNewPost: Boolean,
550+
jetpackFeaturesEnabled: Boolean,
551+
config: GutenbergKitSettingsBuilder.GutenbergKitConfig
552+
): GutenbergKitEditorFragment {
553+
val authorizationData = GutenbergKitSettingsBuilder.buildAuthorizationData(
554+
siteConfig = config.siteConfig,
555+
appConfig = config.appConfig
556+
)
557+
558+
val settings = GutenbergKitSettingsBuilder.buildSettings(
559+
siteConfig = config.siteConfig,
560+
postConfig = config.postConfig,
561+
appConfig = config.appConfig,
562+
featureConfig = config.featureConfig
563+
)
564+
565+
return newInstance(
566+
context,
567+
isNewPost,
568+
authorizationData,
569+
jetpackFeaturesEnabled,
570+
settings
571+
)
572+
}
541573
}
542574
}

WordPress/src/test/java/org/wordpress/android/ui/posts/GutenbergKitSettingsBuilderTest.kt

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import org.assertj.core.api.Assertions.assertThat
44
import org.junit.Test
55
import org.junit.runner.RunWith
66
import org.mockito.junit.MockitoJUnitRunner
7+
import org.wordpress.android.fluxc.network.UserAgent
78

89
@RunWith(MockitoJUnitRunner::class)
910
@Suppress("LargeClass")
@@ -393,7 +394,11 @@ class GutenbergKitSettingsBuilderTest {
393394
isUsingWpComRestApi = true,
394395
wpApiRestUrl = null,
395396
apiRestUsernamePlain = null,
396-
apiRestPasswordPlain = null
397+
apiRestPasswordPlain = null,
398+
selfHostedSiteId = 0,
399+
webEditor = "gutenberg",
400+
apiRestUsernameProcessed = null,
401+
apiRestPasswordProcessed = null
397402
)
398403

399404
val postConfig = GutenbergKitSettingsBuilder.PostConfig(
@@ -441,7 +446,11 @@ class GutenbergKitSettingsBuilderTest {
441446
isUsingWpComRestApi = false,
442447
wpApiRestUrl = "https://jetpack-site.com/wp-json/",
443448
apiRestUsernamePlain = "admin",
444-
apiRestPasswordPlain = "securepass"
449+
apiRestPasswordPlain = "securepass",
450+
selfHostedSiteId = 999,
451+
webEditor = "gutenberg",
452+
apiRestUsernameProcessed = "admin",
453+
apiRestPasswordProcessed = "securepass"
445454
)
446455

447456
val postConfig = GutenbergKitSettingsBuilder.PostConfig(
@@ -601,7 +610,11 @@ class GutenbergKitSettingsBuilderTest {
601610
) = GutenbergKitSettingsBuilder.AppConfig(
602611
accessToken = accessToken,
603612
locale = locale,
604-
cookies = cookies
613+
cookies = cookies,
614+
accountUserId = 123L,
615+
accountUserName = "testuser",
616+
userAgent = UserAgent(appContext = null, appName = "foo"),
617+
isJetpackSsoEnabled = false
605618
)
606619

607620
private fun createSiteConfig(
@@ -623,7 +636,11 @@ class GutenbergKitSettingsBuilderTest {
623636
isUsingWpComRestApi = isUsingWpComRestApi,
624637
wpApiRestUrl = wpApiRestUrl,
625638
apiRestUsernamePlain = apiRestUsernamePlain,
626-
apiRestPasswordPlain = apiRestPasswordPlain
639+
apiRestPasswordPlain = apiRestPasswordPlain,
640+
selfHostedSiteId = siteId,
641+
webEditor = "gutenberg",
642+
apiRestUsernameProcessed = apiRestUsernamePlain,
643+
apiRestPasswordProcessed = apiRestPasswordPlain
627644
)
628645

629646
private fun createPostConfig(

libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/UserAgent.kt

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,25 @@ class UserAgent(appContext: Context?, appName: String) {
1616
// E.g.:
1717
// "Mozilla/5.0 (Linux; Android 6.0; Android SDK built for x86_64 Build/MASTER; wv)
1818
// AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.119 Mobile Safari/537.36"
19-
val defaultUserAgent = try {
20-
WebSettings.getDefaultUserAgent(appContext)
21-
} catch (e: RuntimeException) {
22-
// `getDefaultUserAgent()` can throw an Exception
23-
// see: https://github.com/wordpress-mobile/WordPress-Android/issues/20147#issuecomment-1961238187
24-
""
25-
}
19+
val defaultUserAgent = appContext?.let {
20+
try {
21+
WebSettings.getDefaultUserAgent(appContext)
22+
} catch (_: RuntimeException) {
23+
// `getDefaultUserAgent()` can throw an Exception
24+
// see: https://github.com/wordpress-mobile/WordPress-Android/issues/20147#issuecomment-1961238187
25+
""
26+
}
27+
} ?: ""
2628
// User-Agent string when making HTTP connections, for both API traffic and WebViews.
2729
// Appends "wp-android/version" to WebView's default User-Agent string for the webservers
2830
// to get the full feature list of the browser and serve content accordingly, e.g.:
2931
// "Mozilla/5.0 (Linux; Android 6.0; Android SDK built for x86_64 Build/MASTER; wv)
3032
// AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.119 Mobile Safari/537.36
3133
// wp-android/4.7"
32-
val appWithVersion = "$appName/${PackageUtils.getVersionName(appContext)}"
34+
val versionName = appContext?.let {
35+
PackageUtils.getVersionName(appContext)
36+
} ?: "0" // PackageUtils.getVersionName will also return "0" if it can't find packageInfo
37+
val appWithVersion = "$appName/$versionName"
3338
userAgent = if (defaultUserAgent.isNotEmpty()) "$defaultUserAgent $appWithVersion" else appWithVersion
3439
}
3540

0 commit comments

Comments
 (0)