book-reader/app/src/test/java/com/aryan/reader/AndroidSettingsHubModelsTest.kt
Aryan 9510293ac3
Update v1.0.49 (#330)
* Added PDF top tab strip visibility toggle and fixed WebView hit test NPE

* Refactored desktop reader screens and state management into specialized components

* Added image gallery to reader sidebar and refactored desktop PDF UI components

* Implemented EPUB image gallery

* Refactored reader and library models to use shared common types, centralizing file type resolution and texture management while removing redundant mapping logic

* Standardized UI styling and refactored app navigation layout

* Implemented auto-hiding reader chrome and activity tracking in desktop

* Refactored reader panels into distinct left and right modal layers with platform-specific sizing and keyboard navigation support.

* Added PPTX support for desktop and refactored parsing into a shared module

* Implement paid AI features and account management for the desktop application.

* Implement AI Hub and enhanced Cloud TTS integration for Desktop

* Implement streaming support for AI definition and summarization features

* Implement support for password-protected PDFs and file actions in the desktop reader.

* Implement cloud synchronization for desktop using Firestore and Google Drive

* Implement PDF reflow and "Text View" for the desktop reader

* Refactor OPDS logic to use SharedOpdsController

* Optimize PDF tile rendering performance

* Implement two-page spread support for PDF pagination

* Implement two-page spread support for the PDF viewer

* Improved shared spread zoom in PDF viewer

* Improve PDF spread navigation with fling support and configurable page gaps

* Add brightness control to PDF and EPUB readers

* Refactor folder synchronization to use shared logic engine

* Implement safe string formatting and validation for localized resources

* Implement TTS chunk skip navigation

* Implement deep-linking and playback controls for TTS media sessions

* Implement start index for TTS playback

* Improve TTS navigation, prefetching, and notification duration reporting

* Implement TTS mini playback bar for background reading

* Implement multi-window reader support for the desktop application

* Improve desktop modal window management and visibility syncing

* Implement localized string support for Desktop and shared UI

* Implement language selection and persistence for Desktop

* Implement plural string support for Desktop and migrate hardcoded counts to plurals.xml

* Implement localized banner messages and UI strings using resource-backed SharedText

* Implement compact badge styling for small book covers

* Refactor PDF native interaction and improve HTML import memory safety

* fix language persistence

* Refactor reader overflow menus to use section-based logic

* Refactor PDF layout remapping and improve text box interaction

* Improve CFI resolution and TTS resume accuracy using dynamic chunk offsets

* Centralize PDF annotation export mapping and improve metadata handling

* Add support for threaded comments in PDF highlight annotations

* Flatten highlight comments into a single thread for PDF export and allow author editing

* Integrate page slider into reader chrome and persist toggle state

* Handle fragments and queries in EPUB chapter paths

* Implement dynamic, theme-aware coloring for the reader slider

* Implement customizable app-wide font preference

* Implement one-hand zoom gestures in the PDF viewer

* Implement File Information dialog for PDF and EPUB readers

* Bump version to 1.0.49 (53)

* Refactor PDF reader logic into modular components

* Add ProGuard rules to prevent R8 optimization issues in EPUB reader screens

* Add option to use PDF filenames as display names

* Fix preservation of PDF filename display preference in library projection
2026-05-20 22:14:01 +05:30

198 lines
7.9 KiB
Kotlin

package com.aryan.reader
import com.aryan.reader.shared.SharedSettingsAction
import com.aryan.reader.shared.SharedSettingsDestination
import com.aryan.reader.shared.SharedSettingsHubModel
import com.aryan.reader.shared.SharedSettingsItemModel
import com.aryan.reader.shared.sharedSettingsHubModel
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
class AndroidSettingsHubModelsTest {
@Test
fun `offline android settings hide network backed sections`() {
val model = sharedSettingsHubModel(
androidSettingsHubInput(
uiState = ReaderScreenState(),
isOssBuild = true,
isOfflineBuild = true,
isDebugBuild = false
)
)
val actions = model.visibleNestedActions()
assertFalse(SharedSettingsAction.AI_SETTINGS in actions)
assertFalse(SharedSettingsAction.HIDE_READER_AI in actions)
assertFalse(SharedSettingsAction.SIGN_IN in actions)
assertFalse(SharedSettingsAction.CLOUD_SYNC in actions)
assertFalse(SharedSettingsAction.FOLDER_SYNC in actions)
assertFalse(SharedSettingsAction.HELP_FEEDBACK in actions)
assertFalse(SharedSettingsAction.SUPPORT in actions)
assertTrue(SharedSettingsAction.TTS_SETTINGS in actions)
assertTrue(SharedSettingsAction.CUSTOM_FONTS in actions)
}
@Test
fun `oss online settings hide sync rows but keep oss ai key settings`() {
val model = sharedSettingsHubModel(
androidSettingsHubInput(
uiState = ReaderScreenState(
currentUser = UserData(
uid = "user-id",
displayName = "Reader",
photoUrl = null,
email = "reader@example.com"
),
isProUser = true,
isSyncEnabled = true,
isFolderSyncEnabled = true
),
isOssBuild = true,
isOfflineBuild = false,
isDebugBuild = true
)
)
val actions = model.visibleNestedActions()
assertTrue(SharedSettingsAction.AI_SETTINGS in actions)
assertTrue(SharedSettingsAction.HIDE_READER_AI in actions)
assertFalse(SharedSettingsAction.SIGN_OUT in actions)
assertFalse(SharedSettingsAction.CLOUD_SYNC in actions)
assertFalse(SharedSettingsAction.FOLDER_SYNC in actions)
assertFalse(SharedSettingsAction.DEVICE_MANAGEMENT in actions)
assertFalse(SharedSettingsAction.CLEAR_CLOUD_LOCAL_DATA in actions)
assertTrue(SharedSettingsAction.SUPPORT in actions)
assertEquals(
"TTS & AI",
model.rootCategories.single { it.destination == SharedSettingsDestination.TTS_AI }.title
)
}
@Test
fun `non oss settings do not expose oss ai key settings`() {
val model = sharedSettingsHubModel(
androidSettingsHubInput(
uiState = ReaderScreenState(isProUser = true),
isOssBuild = false,
isOfflineBuild = false,
isDebugBuild = false
)
)
val actions = model.visibleNestedActions()
assertFalse(SharedSettingsAction.AI_SETTINGS in actions)
assertTrue(SharedSettingsAction.HIDE_READER_AI in actions)
assertTrue(SharedSettingsAction.CLOUD_SYNC in actions)
assertFalse(SharedSettingsAction.SUPPORT in actions)
assertEquals(
"TTS",
model.rootCategories.single { it.destination == SharedSettingsDestination.TTS_AI }.title
)
}
@Test
fun `android settings expose debug-only storage actions only in debug`() {
val releaseActions = sharedSettingsHubModel(
androidSettingsHubInput(
uiState = ReaderScreenState(),
isOssBuild = false,
isOfflineBuild = false,
isDebugBuild = false
)
).visibleNestedActions()
val debugActions = sharedSettingsHubModel(
androidSettingsHubInput(
uiState = ReaderScreenState(),
isOssBuild = false,
isOfflineBuild = false,
isDebugBuild = true
)
).visibleNestedActions()
assertFalse(SharedSettingsAction.EXPORT_LOGS in releaseActions)
assertTrue(SharedSettingsAction.EXPORT_LOGS in debugActions)
}
@Test
fun `android settings reflect global toggles from reader state`() {
val model = sharedSettingsHubModel(
androidSettingsHubInput(
uiState = ReaderScreenState(
isTabsEnabled = true,
useStrictFileFilter = true,
usePdfFileNameAsDisplayName = true,
isScreenCaptureProtectionEnabled = true
),
isOssBuild = false,
isOfflineBuild = false,
isDebugBuild = false
)
)
val toggles = model.visibleNestedItems().associateBy { it.action }
assertTrue(toggles.getValue(SharedSettingsAction.TABS_TOGGLE).checked == true)
assertTrue(toggles.getValue(SharedSettingsAction.STRICT_FILE_FILTER).checked == true)
assertTrue(toggles.getValue(SharedSettingsAction.PDF_FILENAME_DISPLAY_NAME).checked == true)
assertTrue(toggles.getValue(SharedSettingsAction.SCREEN_CAPTURE_PROTECTION).checked == true)
}
@Test
fun `android extra settings expose home overflow actions without settings duplicate`() {
val model = sharedSettingsHubModel(
androidSettingsHubInput(
uiState = ReaderScreenState(),
isOssBuild = false,
isOfflineBuild = false,
isDebugBuild = true
)
)
val extraActions = model.page(SharedSettingsDestination.EXTRA).items.map { it.action }
assertTrue(SharedSettingsAction.TABS_TOGGLE in extraActions)
assertTrue(SharedSettingsAction.LANGUAGE in extraActions)
assertTrue(SharedSettingsAction.EXTERNAL_FILE_BEHAVIOR in extraActions)
assertTrue(SharedSettingsAction.STRICT_FILE_FILTER in extraActions)
assertTrue(SharedSettingsAction.PDF_FILENAME_DISPLAY_NAME in extraActions)
assertTrue(SharedSettingsAction.CLEAR_BOOK_CACHE in extraActions)
assertTrue(SharedSettingsAction.CLEAR_REFLOW_CACHE in extraActions)
assertTrue(SharedSettingsAction.TEST_PANEL_DETECTION in extraActions)
assertTrue(SharedSettingsAction.TEST_SPEECH_BUBBLE_DETECTION in extraActions)
assertTrue(SharedSettingsAction.CLEAR_CLOUD_LOCAL_DATA in extraActions)
}
@Test
fun `cloud sync row is gated by pro state`() {
val freeSync = sharedSettingsHubModel(
androidSettingsHubInput(
uiState = ReaderScreenState(isProUser = false),
isOssBuild = false,
isOfflineBuild = false,
isDebugBuild = false
)
).visibleNestedItems().single { it.action == SharedSettingsAction.CLOUD_SYNC }
val proSync = sharedSettingsHubModel(
androidSettingsHubInput(
uiState = ReaderScreenState(isProUser = true),
isOssBuild = false,
isOfflineBuild = false,
isDebugBuild = false
)
).visibleNestedItems().single { it.action == SharedSettingsAction.CLOUD_SYNC }
assertFalse(freeSync.enabled)
assertTrue(proSync.enabled)
}
}
private fun SharedSettingsHubModel.visibleNestedItems(): List<SharedSettingsItemModel> {
return rootCategories.flatMap { category ->
page(category.destination).items
}
}
private fun SharedSettingsHubModel.visibleNestedActions(): List<SharedSettingsAction> {
return visibleNestedItems().map { it.action }
}