mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 10:46:53 -04:00
64 Custom apps should validate their expansion files and re-download if corrupt/missing - unit test custom download
This commit is contained in:
parent
c05742d02a
commit
f92664ca5f
@ -32,7 +32,7 @@ import kotlinx.android.synthetic.main.activity_language.language_recycler_view
|
||||
import kotlinx.android.synthetic.main.activity_language.toolbar
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.extensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
|
||||
import org.kiwix.kiwixmobile.kiwixActivityComponent
|
||||
import org.kiwix.kiwixmobile.language.adapter.LanguageAdapter
|
||||
import org.kiwix.kiwixmobile.language.adapter.LanguageDelegate.HeaderDelegate
|
||||
|
@ -27,7 +27,7 @@ import androidx.core.net.toFile
|
||||
import androidx.core.net.toUri
|
||||
import org.json.JSONArray
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.extensions.start
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start
|
||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
import org.kiwix.kiwixmobile.core.main.WebViewCallback
|
||||
|
@ -17,12 +17,9 @@
|
||||
*/
|
||||
package org.kiwix.kiwixmobile.zim_manager
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings.System
|
||||
import android.util.Log
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.widget.SearchView
|
||||
@ -32,17 +29,15 @@ import kotlinx.android.synthetic.main.zim_manager.tabs
|
||||
import kotlinx.android.synthetic.main.zim_manager.toolbar
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.extensions.start
|
||||
import org.kiwix.kiwixmobile.core.extensions.startWithActionFrom
|
||||
import org.kiwix.kiwixmobile.core.extensions.viewModel
|
||||
import org.kiwix.kiwixmobile.language.LanguageActivity
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
|
||||
import org.kiwix.kiwixmobile.core.utils.Constants.TAG_KIWIX
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.startWithActionFrom
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
import org.kiwix.kiwixmobile.core.utils.LanguageUtils
|
||||
import org.kiwix.kiwixmobile.local_file_transfer.LocalFileTransferActivity
|
||||
import org.kiwix.kiwixmobile.kiwixActivityComponent
|
||||
import java.io.File
|
||||
import org.kiwix.kiwixmobile.language.LanguageActivity
|
||||
import org.kiwix.kiwixmobile.local_file_transfer.LocalFileTransferActivity
|
||||
import javax.inject.Inject
|
||||
|
||||
class ZimManageActivity : BaseActivity() {
|
||||
@ -144,20 +139,6 @@ class ZimManageActivity : BaseActivity() {
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
// Set zim file and return
|
||||
fun finishResult(path: String?) {
|
||||
if (path != null) {
|
||||
val file = File(path)
|
||||
val uri = Uri.fromFile(file)
|
||||
Log.i(TAG_KIWIX, "Opening Zim File: $uri")
|
||||
setResult(Activity.RESULT_OK, Intent().setData(uri))
|
||||
finish()
|
||||
} else {
|
||||
setResult(Activity.RESULT_CANCELED)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAB_EXTRA = "TAB"
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
||||
import org.kiwix.kiwixmobile.core.downloader.Downloader
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadItem
|
||||
import org.kiwix.kiwixmobile.core.extensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.utils.DialogShower
|
||||
import org.kiwix.kiwixmobile.core.utils.KiwixDialog.YesNoDialog.StopDownload
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
|
@ -37,8 +37,8 @@ import kotlinx.android.synthetic.main.zim_list.zimfilelist
|
||||
import org.kiwix.kiwixmobile.R
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
import org.kiwix.kiwixmobile.core.extensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.utils.Constants.REQUEST_STORAGE_PERMISSION
|
||||
import org.kiwix.kiwixmobile.core.utils.LanguageUtils
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
|
@ -21,7 +21,7 @@ import android.app.Activity
|
||||
import androidx.core.net.toUri
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.extensions.start
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start
|
||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem.BookOnDisk
|
||||
import org.kiwix.kiwixmobile.main.KiwixMainActivity
|
||||
|
@ -23,7 +23,7 @@ import android.view.ActionMode
|
||||
import io.reactivex.processors.PublishProcessor
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.extensions.startActionMode
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.startActionMode
|
||||
import org.kiwix.kiwixmobile.core.zim_manager.fileselect_view.adapter.BooksOnDiskListItem
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions
|
||||
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestDeleteMultiSelection
|
||||
|
@ -39,9 +39,9 @@ import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.base.BaseFragment
|
||||
import org.kiwix.kiwixmobile.core.downloader.Downloader
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.extensions.snack
|
||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
import org.kiwix.kiwixmobile.core.extensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
import org.kiwix.kiwixmobile.core.settings.StorageCalculator
|
||||
import org.kiwix.kiwixmobile.core.utils.BookUtils
|
||||
|
@ -1 +0,0 @@
|
||||
relaxUnitFun=true
|
@ -1 +0,0 @@
|
||||
junit.jupiter.testinstance.lifecycle.default=per_class
|
@ -1,104 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metalink xmlns="urn:ietf:params:xml:ns:metalink">
|
||||
<generator>MirrorBrain/2.18.1</generator>
|
||||
<origin dynamic="true">http://download.kiwix.org/zim/wikipedia/wikipedia_af_all_nopic_2016-05.zim.meta4</origin>
|
||||
<published>2016-06-08T08:59:18Z</published>
|
||||
<publisher>
|
||||
<name>Kiwix project</name>
|
||||
<url>http://www.kiwix.org</url>
|
||||
</publisher>
|
||||
|
||||
<file name="wikipedia_af_all_nopic_2016-05.zim">
|
||||
<size>63973123</size>
|
||||
|
||||
<!-- <mtime>1462622396</mtime> -->
|
||||
|
||||
<!-- internal id: 756021 -->
|
||||
<hash type="md5">6f06866b61c4a921b57f28cfd4307220</hash>
|
||||
<hash type="sha-1">8aac4c7f89e3cdd45b245695e19ecde5aac59593</hash>
|
||||
<hash type="sha-256">83126775538cf588a85edb10db04d6e012321a2025278a08a084b258849b3a5c</hash>
|
||||
<pieces length="1048576" type="sha-1">
|
||||
<hash>f36815d904d4fd563aaef4ee6ef2600fb1fd70b2</hash>
|
||||
<hash>cd34a8a85ed1dd275417ce224ff0cd8d9893d101</hash>
|
||||
<hash>7702114faf59441937c9075ad695fad61cdb13f3</hash>
|
||||
<hash>532553bfb04c870375a53368b17838e50b169ab8</hash>
|
||||
<hash>fcda3eba296502965015ef3f07b05adeb4d95dfc</hash>
|
||||
<hash>97af1a7b1327a6f13dfc63524c63077c4aaa1278</hash>
|
||||
<hash>4c02b16d3d0cb1acc5b0eb02a46e3047245ca65c</hash>
|
||||
<hash>163927a9e7405b20c0544d06243baecfdf3c13d3</hash>
|
||||
<hash>1d4ccf5570fecefc93793aa1ebb73d95eb46cf03</hash>
|
||||
<hash>a0e5200bde74ba58c7318e15a34d5f891fb36841</hash>
|
||||
<hash>e862a19ce5a4066efdcc15bf3c74462292251171</hash>
|
||||
<hash>1c964b3029b6eda5ddff6815bf5298ca9a4c4196</hash>
|
||||
<hash>29f52efd444b496fc55c99541de62823605bdce7</hash>
|
||||
<hash>d5ae5e610f0b2f102bc16d7eeea55cacf259dda8</hash>
|
||||
<hash>b7e0102f182a84d76c3a8ca02d0e9319a320eed6</hash>
|
||||
<hash>bd63b665f1ac5620226481bacbe4dee1d31d48ba</hash>
|
||||
<hash>54393351f78e24c4ebb4dbfd22fcdfff279f39fb</hash>
|
||||
<hash>8845733b1da2876ad81aa1f7596dfd0e49bcc293</hash>
|
||||
<hash>94c2bb5e297a1c61bd1e4a3b47a2ffa8457dc9aa</hash>
|
||||
<hash>b2c1229eb3ffa88c71f0584c9714b7cf2d7df091</hash>
|
||||
<hash>d0978cf7aaba0320442673fc47f400e43df84a99</hash>
|
||||
<hash>5b8e68db7197089a78e92eb77f1c63859d098b1b</hash>
|
||||
<hash>d4ff1f37c101735c81a06ebd98e1c3be465e0314</hash>
|
||||
<hash>e9399f2c1f883816d3007765443cd38a1b4c6f9f</hash>
|
||||
<hash>b6fa56a9dc6893bd67deebd14e9f2ccd42d63355</hash>
|
||||
<hash>73efed5e8fd6480fece063826d62241783126b63</hash>
|
||||
<hash>b24ec4bd6f1f6ad2de9724275ac141c92692edd2</hash>
|
||||
<hash>3d35dee6ee7e1add3e8f30fe601f4f74ed11e704</hash>
|
||||
<hash>9af07844246402bc6e28f37f8eb8c0329033a874</hash>
|
||||
<hash>1be6178907a740670d8e61f72ebc8d47860015ce</hash>
|
||||
<hash>6e954cc098392cf7f515e07f4d666d8b0a5fe329</hash>
|
||||
<hash>e9f09f347f07585338073fea96f8d009a5aa3e0d</hash>
|
||||
<hash>a48801add4c60733a023bdcce5e62aacb33becf0</hash>
|
||||
<hash>90ca6abeeb08fbc136f1d0234741ca6b506869bc</hash>
|
||||
<hash>7c426983069ea0556168f9e7343426f79d233bc1</hash>
|
||||
<hash>18e893707d86bb778f9be3957e2645502ae1469d</hash>
|
||||
<hash>c7a984439cb7e7fbbc805ea9eb77bebcfbaa25a5</hash>
|
||||
<hash>9614ca49b5611494e4aaa0a3ffd3e23f5bfae86a</hash>
|
||||
<hash>d344c4cd8db6c0859eb00ba90cdeb1e12b9922c4</hash>
|
||||
<hash>ef777338b04c4b638721e1a043c3ae433a885c82</hash>
|
||||
<hash>04504c63113f7719f5ac13c8e30f1feec4648268</hash>
|
||||
<hash>1411ad174573f8c2a9a2d33c33f77f776db40f35</hash>
|
||||
<hash>bc771262c4abf687b49321c83fd4613dbdcc1aa3</hash>
|
||||
<hash>6762c76f99280283fa73037a0358efe5fd903eee</hash>
|
||||
<hash>8ba56ea08fe4c2f9e76ee8273ce9dad4c4bd977a</hash>
|
||||
<hash>97d8246b1db42afb9048109f920811fb5e723e71</hash>
|
||||
<hash>6c59c23baeb706f6902f5a8dc822bcf932721cdc</hash>
|
||||
<hash>1dff0732d971bc25af5afa9768493f435e5ab5d0</hash>
|
||||
<hash>133ff15a2992b0d5337eeddc62da839f86cee1e0</hash>
|
||||
<hash>0590bc490e4f12782849b8b36b87e1b68becdb83</hash>
|
||||
<hash>705e5c62c96c6b41a9cfea97796ebdcc981145a6</hash>
|
||||
<hash>e03ba6cf2deba1dfc8d781e4b8d0c602e033eea4</hash>
|
||||
<hash>a5c46e2093d7c138df4553bfc92604de91b8fe89</hash>
|
||||
<hash>035f0bd63b253c88a5ef7efaea96b3ee664e6f91</hash>
|
||||
<hash>3b4732487b464d6164d9e460d990dcf8de8b499c</hash>
|
||||
<hash>3453494c2188f5bee8a86a7b3626129e61a8bb21</hash>
|
||||
<hash>47a062cdd2f7024f6f6ebffe6ade5ca9474932ea</hash>
|
||||
<hash>5c30eee23b5b75680958760472c5c39aaaab108c</hash>
|
||||
<hash>c93ae5c2faf3f3a898e01f5c9aef1d57f2969990</hash>
|
||||
<hash>debf6ed9bbfbc9db4505d89dc74f871049d5c918</hash>
|
||||
<hash>3d0c0800396e5305ff1ddabba2371f817ec4839c</hash>
|
||||
<hash>8055e515aa6e78f2810bbb0e0cd07330838b8920</hash>
|
||||
</pieces>
|
||||
|
||||
|
||||
<!-- Found 7 mirrors: 0 in the same network prefix, 0 in the same autonomous system,
|
||||
0 handling this country, 0 in the same region, 5 elsewhere -->
|
||||
|
||||
<!-- Mirrors in the same network (unknown): -->
|
||||
|
||||
<!-- Mirrors in the same AS (unknown): -->
|
||||
|
||||
<!-- Mirrors which handle this country (unknown): -->
|
||||
|
||||
<!-- Mirrors in the same continent (unknown): -->
|
||||
|
||||
<!-- Mirrors in the rest of the world: -->
|
||||
<url location="us" priority="1">http://ftpmirror.your.org/pub/kiwix/zim/wikipedia/wikipedia_af_all_nopic_2016-05.zim</url>
|
||||
<url location="gb" priority="2">http://www.mirrorservice.org/sites/download.kiwix.org/zim/wikipedia/wikipedia_af_all_nopic_2016-05.zim</url>
|
||||
<url location="us" priority="3">http://download.wikimedia.org/kiwix/zim/wikipedia/wikipedia_af_all_nopic_2016-05.zim</url>
|
||||
<url location="de" priority="4">http://mirror.netcologne.de/kiwix/zim/wikipedia/wikipedia_af_all_nopic_2016-05.zim</url>
|
||||
<url location="fr" priority="5">http://mirror3.kiwix.org/zim/wikipedia/wikipedia_af_all_nopic_2016-05.zim</url>
|
||||
</file>
|
||||
</metalink>
|
@ -87,7 +87,7 @@ class AllProjectConfigurer {
|
||||
lintOptions {
|
||||
isAbortOnError = true
|
||||
isCheckAllWarnings = true
|
||||
isCheckAllWarnings = true
|
||||
isWarningsAsErrors = true
|
||||
|
||||
ignore(
|
||||
"SyntheticAccessor",
|
||||
@ -102,7 +102,8 @@ class AllProjectConfigurer {
|
||||
warning(
|
||||
"UnknownNullness",
|
||||
"SelectableText",
|
||||
"IconDensities"
|
||||
"IconDensities",
|
||||
"ContentDescription"
|
||||
)
|
||||
baseline("${path}/lint-baseline.xml")
|
||||
}
|
||||
@ -121,6 +122,7 @@ class AllProjectConfigurer {
|
||||
sourceSets {
|
||||
getByName("test") {
|
||||
java.srcDir("${target.rootDir}/core/src/sharedTestFunctions/java")
|
||||
resources.srcDir("${target.rootDir}/core/src/test/resources")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,55 +30,60 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import org.kiwix.kiwixmobile.core.Intents
|
||||
|
||||
fun Activity.startActionMode(
|
||||
menuId: Int,
|
||||
idsToClickActions: Map<Int, () -> Any>,
|
||||
onDestroyAction: () -> Unit
|
||||
): ActionMode? {
|
||||
return startActionMode(object : Callback {
|
||||
override fun onActionItemClicked(
|
||||
mode: ActionMode,
|
||||
item: MenuItem
|
||||
) = idsToClickActions[item.itemId]?.let {
|
||||
it()
|
||||
mode.finish()
|
||||
true
|
||||
} ?: false
|
||||
object ActivityExtensions {
|
||||
|
||||
override fun onCreateActionMode(
|
||||
mode: ActionMode,
|
||||
menu: Menu?
|
||||
): Boolean {
|
||||
mode.menuInflater
|
||||
.inflate(menuId, menu)
|
||||
return true
|
||||
}
|
||||
fun Activity.startActionMode(
|
||||
menuId: Int,
|
||||
idsToClickActions: Map<Int, () -> Any>,
|
||||
onDestroyAction: () -> Unit
|
||||
): ActionMode? {
|
||||
return startActionMode(object : Callback {
|
||||
override fun onActionItemClicked(
|
||||
mode: ActionMode,
|
||||
item: MenuItem
|
||||
) = idsToClickActions[item.itemId]?.let {
|
||||
it()
|
||||
mode.finish()
|
||||
true
|
||||
} ?: false
|
||||
|
||||
override fun onPrepareActionMode(
|
||||
mode: ActionMode?,
|
||||
menu: Menu?
|
||||
) = false
|
||||
override fun onCreateActionMode(
|
||||
mode: ActionMode,
|
||||
menu: Menu?
|
||||
): Boolean {
|
||||
mode.menuInflater
|
||||
.inflate(menuId, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
onDestroyAction()
|
||||
}
|
||||
})
|
||||
override fun onPrepareActionMode(
|
||||
mode: ActionMode?,
|
||||
menu: Menu?
|
||||
) = false
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
onDestroyAction()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
inline fun <reified T : Activity> Activity.start(
|
||||
noinline intentFunc: (Intent.() -> Unit)? = null
|
||||
) {
|
||||
startActivity(
|
||||
Intent(this, T::class.java).apply {
|
||||
intentFunc?.invoke(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
inline fun <reified T : Activity> Activity.startWithActionFrom() {
|
||||
startActivity(Intents.internal(T::class.java))
|
||||
}
|
||||
|
||||
inline fun <reified T : ViewModel> FragmentActivity.viewModel(
|
||||
viewModelFactory: ViewModelProvider.Factory
|
||||
) =
|
||||
ViewModelProviders.of(this, viewModelFactory)
|
||||
.get(T::class.java)
|
||||
}
|
||||
|
||||
inline fun <reified T : Activity> Activity.start(noinline intentFunc: (Intent.() -> Unit)? = null) {
|
||||
startActivity(
|
||||
Intent(this, T::class.java).apply {
|
||||
intentFunc?.invoke(this)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
inline fun <reified T : Activity> Activity.startWithActionFrom() {
|
||||
startActivity(Intents.internal(T::class.java))
|
||||
}
|
||||
|
||||
inline fun <reified T : ViewModel> FragmentActivity.viewModel(
|
||||
viewModelFactory: ViewModelProvider.Factory
|
||||
) =
|
||||
ViewModelProviders.of(this, viewModelFactory)
|
||||
.get(T::class.java)
|
||||
|
@ -9,14 +9,12 @@
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="SdCardPath"
|
||||
message="Do not hardcode "`/data/`"; use `Context.getFilesDir().getPath()` instead"
|
||||
errorLine1=" "/data/data/%s/lib/%s", packageName,"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
|
||||
id="ObsoleteLintCustomCheck"
|
||||
message="Lint found an issue registry (`butterknife.lint.LintRegistry`) which is older than the current API level; these checks may not work correctly.

Recompile the checks against the latest version. Custom check API version is 2 (3.2), current lint API level is 5 (3.5+)"
|
||||
includedVariants="customexampleDebug"
|
||||
excludedVariants="customexampleRelease">
|
||||
<location
|
||||
file="src\main\java\org\kiwix\kiwixmobile\custom\main\CustomMainActivity.kt"
|
||||
line="109"
|
||||
column="12"/>
|
||||
file="..\..\..\.gradle\caches\transforms-2\files-2.1\6dca90c1110a5ba8556122fc8f89395f\butterknife-runtime-10.1.0\jars\lint.jar"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
@ -58,9 +56,17 @@
|
||||
|
||||
<issue
|
||||
id="UnusedResources"
|
||||
message="The resource `R.drawable.kiwix_icon_with_title` appears to be unused">
|
||||
message="The resource `R.mipmap.kiwix_icon` appears to be unused">
|
||||
<location
|
||||
file="src\customexample\res\drawable\kiwix_icon_with_title.png"/>
|
||||
file="src\customexample\res\mipmap-hdpi\kiwix_icon.png"/>
|
||||
<location
|
||||
file="src\customexample\res\mipmap-mdpi\kiwix_icon.png"/>
|
||||
<location
|
||||
file="src\customexample\res\mipmap-xhdpi\kiwix_icon.png"/>
|
||||
<location
|
||||
file="src\customexample\res\mipmap-xxhdpi\kiwix_icon.png"/>
|
||||
<location
|
||||
file="src\customexample\res\mipmap-xxxhdpi\kiwix_icon.png"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
@ -74,6 +80,13 @@
|
||||
column="11"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="UnusedResources"
|
||||
message="The resource `R.raw.wikipedia_fr_test_2017_07` appears to be unused">
|
||||
<location
|
||||
file="src\customexample\res\raw\wikipedia_fr_test_2017_07.zim"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="IconDipSize"
|
||||
message="The image `ic_kiwix_widget.png` varies significantly in its density-independent (dip) size across the various density versions: drawable-hdpi\\ic_kiwix_widget.png: 48x48 dp (72x72 px), drawable-mdpi\\ic_kiwix_widget.png: 72x72 dp (72x72 px), drawable-xhdpi\\ic_kiwix_widget.png: 48x48 dp (96x96 px), drawable-xxhdpi\\ic_kiwix_widget.png: 48x48 dp (144x144 px), drawable-xxxhdpi\\ic_kiwix_widget.png: 48x48 dp (192x192 px)">
|
||||
@ -156,6 +169,39 @@
|
||||
file="src\customexample\res\drawable-xxxhdpi\ic_kiwix_widget.png"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="SelectableText"
|
||||
message="Consider making the text value selectable by specifying `android:textIsSelectable="true"`"
|
||||
errorLine1=" <TextView"
|
||||
errorLine2=" ~~~~~~~~">
|
||||
<location
|
||||
file="src\main\res\layout\layout_custom_download_error.xml"
|
||||
line="10"
|
||||
column="4"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="SelectableText"
|
||||
message="Consider making the text value selectable by specifying `android:textIsSelectable="true"`"
|
||||
errorLine1=" <TextView"
|
||||
errorLine2=" ~~~~~~~~">
|
||||
<location
|
||||
file="src\main\res\layout\layout_custom_download_in_progress.xml"
|
||||
line="8"
|
||||
column="4"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="SelectableText"
|
||||
message="Consider making the text value selectable by specifying `android:textIsSelectable="true"`"
|
||||
errorLine1=" <TextView"
|
||||
errorLine2=" ~~~~~~~~">
|
||||
<location
|
||||
file="src\main\res\layout\layout_custom_download_in_progress.xml"
|
||||
line="28"
|
||||
column="4"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="GoogleAppIndexingApiWarning"
|
||||
message="Missing support for Firebase App Indexing API"
|
||||
@ -167,4 +213,26 @@
|
||||
column="7"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="ContentDescription"
|
||||
message="Missing `contentDescription` attribute on image"
|
||||
errorLine1=" <ImageView"
|
||||
errorLine2=" ~~~~~~~~~">
|
||||
<location
|
||||
file="src\main\res\layout\activity_custom_download.xml"
|
||||
line="9"
|
||||
column="4"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="UnknownNullness"
|
||||
message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://android.github.io/kotlin-guides/interop.html#nullability-annotations"
|
||||
errorLine1=" public CustomViewModelFactory(Map<Class<? extends ViewModel>, Provider<ViewModel>> creators) {"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="src\main\java\org\kiwix\kiwixmobile\custom\CustomViewModelFactory.java"
|
||||
line="32"
|
||||
column="33"/>
|
||||
</issue>
|
||||
|
||||
</issues>
|
||||
|
@ -31,8 +31,8 @@ import kotlinx.android.synthetic.main.layout_custom_download_in_progress.cd_prog
|
||||
import kotlinx.android.synthetic.main.layout_custom_download_required.cd_download_button
|
||||
import org.kiwix.kiwixmobile.core.base.BaseActivity
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadItem
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel
|
||||
import org.kiwix.kiwixmobile.core.extensions.setDistinctDisplayedChild
|
||||
import org.kiwix.kiwixmobile.core.extensions.viewModel
|
||||
import org.kiwix.kiwixmobile.custom.R
|
||||
import org.kiwix.kiwixmobile.custom.customActivityComponent
|
||||
import org.kiwix.kiwixmobile.custom.download.Action.ClickedDownload
|
||||
|
@ -41,7 +41,8 @@ import javax.inject.Inject
|
||||
class CustomDownloadViewModel @Inject constructor(
|
||||
downloadDao: FetchDownloadDao,
|
||||
setPreferredStorageWithMostSpace: SetPreferredStorageWithMostSpace,
|
||||
private val downloadCustom: DownloadCustom
|
||||
private val downloadCustom: DownloadCustom,
|
||||
private val finishAndStartMain: FinishAndStartMain
|
||||
) : ViewModel() {
|
||||
|
||||
val state = MutableLiveData<State>().apply { value = DownloadRequired }
|
||||
@ -90,7 +91,7 @@ class CustomDownloadViewModel @Inject constructor(
|
||||
else
|
||||
DownloadInProgress(action.downloads)
|
||||
else
|
||||
DownloadComplete.also { _effects.offer(FinishAndStartMain()) }
|
||||
DownloadComplete.also { _effects.offer(finishAndStartMain) }
|
||||
DownloadComplete -> state
|
||||
}
|
||||
}
|
||||
|
@ -20,10 +20,11 @@ package org.kiwix.kiwixmobile.custom.download.effects
|
||||
|
||||
import android.app.Activity
|
||||
import org.kiwix.kiwixmobile.core.base.SideEffect
|
||||
import org.kiwix.kiwixmobile.core.extensions.start
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start
|
||||
import org.kiwix.kiwixmobile.custom.main.CustomMainActivity
|
||||
import javax.inject.Inject
|
||||
|
||||
class FinishAndStartMain() : SideEffect<Unit> {
|
||||
class FinishAndStartMain @Inject constructor() : SideEffect<Unit> {
|
||||
override fun invokeWith(activity: Activity) {
|
||||
activity.finish()
|
||||
activity.start<CustomMainActivity>()
|
||||
|
@ -24,7 +24,7 @@ import android.util.Log
|
||||
import android.view.Menu
|
||||
import org.kiwix.kiwixmobile.core.CoreApp
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.extensions.start
|
||||
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.start
|
||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||
import org.kiwix.kiwixmobile.core.main.WebViewCallback
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
|
||||
|
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.custom.download
|
||||
|
||||
import com.jraska.livedata.test
|
||||
import com.tonyodev.fetch2.Error.NONE
|
||||
import io.mockk.clearAllMocks
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.reactivex.processors.PublishProcessor
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadState
|
||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadState.Failed
|
||||
import org.kiwix.kiwixmobile.custom.download.Action.ClickedDownload
|
||||
import org.kiwix.kiwixmobile.custom.download.Action.ClickedRetry
|
||||
import org.kiwix.kiwixmobile.custom.download.Action.DatabaseEmission
|
||||
import org.kiwix.kiwixmobile.custom.download.State.DownloadComplete
|
||||
import org.kiwix.kiwixmobile.custom.download.State.DownloadFailed
|
||||
import org.kiwix.kiwixmobile.custom.download.State.DownloadInProgress
|
||||
import org.kiwix.kiwixmobile.custom.download.State.DownloadRequired
|
||||
import org.kiwix.kiwixmobile.custom.download.effects.DownloadCustom
|
||||
import org.kiwix.kiwixmobile.custom.download.effects.FinishAndStartMain
|
||||
import org.kiwix.kiwixmobile.custom.download.effects.SetPreferredStorageWithMostSpace
|
||||
import org.kiwix.sharedFunctions.InstantExecutorExtension
|
||||
import org.kiwix.sharedFunctions.downloadItem
|
||||
|
||||
@ExtendWith(InstantExecutorExtension::class)
|
||||
internal class CustomDownloadViewModelTest {
|
||||
private val fetchDownloadDao: FetchDownloadDao = mockk()
|
||||
private val setPreferredStorageWithMostSpace: SetPreferredStorageWithMostSpace = mockk()
|
||||
private val downloadCustom: DownloadCustom = mockk()
|
||||
private val finishAndStartMain: FinishAndStartMain = mockk()
|
||||
|
||||
private val downloads: PublishProcessor<List<DownloadModel>> = PublishProcessor.create()
|
||||
private lateinit var customDownloadViewModel: CustomDownloadViewModel
|
||||
|
||||
@BeforeEach
|
||||
internal fun setUp() {
|
||||
clearAllMocks()
|
||||
every { fetchDownloadDao.downloads() } returns downloads
|
||||
customDownloadViewModel = CustomDownloadViewModel(
|
||||
fetchDownloadDao,
|
||||
setPreferredStorageWithMostSpace,
|
||||
downloadCustom,
|
||||
finishAndStartMain
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `effects emits SetPreferred on Subscribe`() {
|
||||
customDownloadViewModel.effects.test().assertValue(setPreferredStorageWithMostSpace)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `initial State is DownloadRequired`() {
|
||||
customDownloadViewModel.state.test().assertValue(State.DownloadRequired)
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class DownloadEmissions {
|
||||
@Test
|
||||
internal fun `Emission with data moves state from Required to InProgress`() {
|
||||
assertStateTransition(
|
||||
DownloadRequired,
|
||||
DatabaseEmission(listOf(downloadItem())),
|
||||
State.DownloadInProgress(listOf(downloadItem()))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `Emission without data moves state from Required to Required`() {
|
||||
assertStateTransition(DownloadRequired, DatabaseEmission(listOf()), DownloadRequired)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `Emission with data moves state from Failed to InProgress`() {
|
||||
assertStateTransition(
|
||||
DownloadFailed(DownloadState.Pending),
|
||||
DatabaseEmission(listOf(downloadItem())),
|
||||
State.DownloadInProgress(listOf(downloadItem()))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `Emission without data moves state from Failed to Failed`() {
|
||||
assertStateTransition(
|
||||
DownloadFailed(DownloadState.Pending),
|
||||
DatabaseEmission(listOf()),
|
||||
DownloadFailed(DownloadState.Pending)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `Emission with data+failure moves state from InProgress to Failed`() {
|
||||
assertStateTransition(
|
||||
DownloadInProgress(listOf()),
|
||||
DatabaseEmission(listOf(downloadItem(state = Failed(NONE)))),
|
||||
DownloadFailed(Failed(NONE))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `Emission with data moves state from InProgress to InProgress`() {
|
||||
assertStateTransition(
|
||||
DownloadInProgress(listOf(downloadItem(downloadId = 1L))),
|
||||
DatabaseEmission(listOf(downloadItem(downloadId = 2L))),
|
||||
DownloadInProgress(listOf(downloadItem(downloadId = 2L)))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `Emission without data moves state from InProgress to Complete`() {
|
||||
val sideEffects = customDownloadViewModel.effects.test()
|
||||
assertStateTransition(
|
||||
DownloadInProgress(listOf()),
|
||||
DatabaseEmission(listOf()),
|
||||
DownloadComplete
|
||||
)
|
||||
sideEffects.assertValues(setPreferredStorageWithMostSpace, finishAndStartMain)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `Any emission does not change state from Complete`() {
|
||||
assertStateTransition(
|
||||
DownloadComplete,
|
||||
DatabaseEmission(listOf(downloadItem())),
|
||||
DownloadComplete
|
||||
)
|
||||
}
|
||||
|
||||
private fun assertStateTransition(
|
||||
initialState: State,
|
||||
action: DatabaseEmission,
|
||||
endState: State
|
||||
) {
|
||||
customDownloadViewModel.state.value = initialState
|
||||
customDownloadViewModel.actions.offer(action)
|
||||
customDownloadViewModel.state.test().assertValue(endState)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `clicking Retry triggers DownloadCustom`() {
|
||||
val sideEffects = customDownloadViewModel.effects.test()
|
||||
customDownloadViewModel.actions.offer(ClickedRetry)
|
||||
sideEffects.assertValues(setPreferredStorageWithMostSpace, downloadCustom)
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `clicking Download triggers DownloadCustom`() {
|
||||
val sideEffects = customDownloadViewModel.effects.test()
|
||||
customDownloadViewModel.actions.offer(ClickedDownload)
|
||||
sideEffects.assertValues(setPreferredStorageWithMostSpace, downloadCustom)
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.custom.download.effects
|
||||
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.kiwix.kiwixmobile.core.downloader.Downloader
|
||||
import org.kiwix.sharedFunctions.book
|
||||
|
||||
internal class DownloadCustomTest {
|
||||
|
||||
@Test
|
||||
fun `invokeWith queues download with ZimUrl`() {
|
||||
val downloader = mockk<Downloader>()
|
||||
DownloadCustom(downloader).invokeWith(mockk())
|
||||
verify {
|
||||
downloader.download(expectedBook())
|
||||
}
|
||||
}
|
||||
|
||||
private fun expectedBook() = book(
|
||||
"custom",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
)
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.custom.download.effects
|
||||
|
||||
import android.app.Activity
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
internal class FinishAndStartMainTest {
|
||||
|
||||
@Test
|
||||
fun `invokeWith finishes activity and starts main`() {
|
||||
val activity = mockk<Activity>()
|
||||
// Inline functions cannot be mocked
|
||||
// mockkObject(ActivityExtensions)
|
||||
// every { start<CustomMainActivity>(null) } just Runs issues with inline extension functions
|
||||
FinishAndStartMain().invokeWith(activity)
|
||||
verify {
|
||||
activity.finish()
|
||||
activity.startActivity(any())
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.custom.download.effects
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.core.content.ContextCompat
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.verify
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.kiwix.kiwixmobile.core.settings.StorageCalculator
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import java.io.File
|
||||
|
||||
internal class SetPreferredStorageWithMostSpaceTest {
|
||||
|
||||
@Test
|
||||
fun `invokeWith sets the storage with the most space as preferred`() {
|
||||
val storageCalculator = mockk<StorageCalculator>()
|
||||
val sharedPreferenceUtil = mockk<SharedPreferenceUtil>()
|
||||
val activity = mockk<Activity>()
|
||||
mockkStatic(ContextCompat::class)
|
||||
val directoryWithMoreStorage = mockk<File>()
|
||||
val directoryWithLessStorage = mockk<File>()
|
||||
every { ContextCompat.getExternalFilesDirs(activity, null) } returns arrayOf(
|
||||
directoryWithMoreStorage, null, directoryWithLessStorage
|
||||
)
|
||||
every { storageCalculator.availableBytes(directoryWithMoreStorage) } returns 1
|
||||
every { storageCalculator.availableBytes(directoryWithLessStorage) } returns 0
|
||||
val expectedStorage = "expectedStorage"
|
||||
every { directoryWithMoreStorage.path } returns expectedStorage
|
||||
SetPreferredStorageWithMostSpace(storageCalculator, sharedPreferenceUtil).invokeWith(activity)
|
||||
verify {
|
||||
sharedPreferenceUtil.putPrefStorage(expectedStorage)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user