NodeInfo: replace Int by Long in upload limits, add test cases
This commit is contained in:
parent
25b57f3db4
commit
930e05be27
|
@ -122,7 +122,8 @@ class ComposeActivity : BaseActivity(),
|
|||
var maximumTootCharacters = DEFAULT_CHARACTER_LIMIT
|
||||
|
||||
private var composeOptions: ComposeOptions? = null
|
||||
private val viewModel: ComposeViewModel by viewModels { viewModelFactory }
|
||||
@VisibleForTesting
|
||||
val viewModel: ComposeViewModel by viewModels { viewModelFactory }
|
||||
private var suggestFormattingSyntax: String = "text/markdown"
|
||||
|
||||
private var mediaCount = 0
|
||||
|
@ -346,8 +347,9 @@ class ComposeActivity : BaseActivity(),
|
|||
enableButton(composeAddMediaButton, true, true)
|
||||
enablePollButton(true)
|
||||
}
|
||||
|
||||
private var supportedFormattingSyntax = arrayListOf<String>()
|
||||
|
||||
@VisibleForTesting
|
||||
var supportedFormattingSyntax = arrayListOf<String>()
|
||||
|
||||
private fun subscribeToUpdates(mediaAdapter: MediaPreviewAdapter) {
|
||||
withLifecycleContext {
|
||||
|
|
|
@ -560,8 +560,8 @@ fun <T> mutableLiveData(default: T) = MutableLiveData<T>().apply { value = defau
|
|||
const val DEFAULT_CHARACTER_LIMIT = 500
|
||||
private const val DEFAULT_MAX_OPTION_COUNT = 4
|
||||
private const val DEFAULT_MAX_OPTION_LENGTH = 25
|
||||
private const val STATUS_VIDEO_SIZE_LIMIT = 41943040 // 40MiB
|
||||
private const val STATUS_IMAGE_SIZE_LIMIT = 8388608 // 8MiB
|
||||
private const val STATUS_VIDEO_SIZE_LIMIT : Long = 41943040 // 40MiB
|
||||
private const val STATUS_IMAGE_SIZE_LIMIT : Long = 8388608 // 8MiB
|
||||
|
||||
|
||||
data class ComposeInstanceParams(
|
||||
|
@ -576,6 +576,6 @@ data class ComposeInstanceMetadata(
|
|||
val supportsMarkdown: Boolean,
|
||||
val supportsBBcode: Boolean,
|
||||
val supportsHTML: Boolean,
|
||||
val videoLimit: Int,
|
||||
val imageLimit: Int
|
||||
val videoLimit: Long,
|
||||
val imageLimit: Long
|
||||
)
|
||||
|
|
|
@ -75,7 +75,7 @@ public class DownsizeImageTask extends AsyncTask<Uri, Void, Boolean> {
|
|||
super.onPostExecute(successful);
|
||||
}
|
||||
|
||||
public static boolean resize(Uri[] uris, int sizeLimit, ContentResolver contentResolver,
|
||||
public static boolean resize(Uri[] uris, long sizeLimit, ContentResolver contentResolver,
|
||||
File tempFile) {
|
||||
for (Uri uri : uris) {
|
||||
InputStream inputStream;
|
||||
|
|
|
@ -59,8 +59,8 @@ fun createNewImageFile(context: Context): File {
|
|||
data class PreparedMedia(val type: Int, val uri: Uri, val size: Long)
|
||||
|
||||
interface MediaUploader {
|
||||
fun prepareMedia(inUri: Uri, videoLimit: Int, imageLimit: Int, filename: String?): Single<PreparedMedia>
|
||||
fun uploadMedia(media: QueuedMedia, videoLimit: Int, imageLimit: Int): Observable<UploadEvent>
|
||||
fun prepareMedia(inUri: Uri, videoLimit: Long, imageLimit: Long, filename: String?): Single<PreparedMedia>
|
||||
fun uploadMedia(media: QueuedMedia, videoLimit: Long, imageLimit: Long): Observable<UploadEvent>
|
||||
}
|
||||
|
||||
class AudioSizeException : Exception()
|
||||
|
@ -73,14 +73,14 @@ class MediaUploaderImpl(
|
|||
private val context: Context,
|
||||
private val mastodonApi: MastodonApi
|
||||
) : MediaUploader {
|
||||
override fun uploadMedia(media: QueuedMedia, videoLimit: Int, imageLimit: Int): Observable<UploadEvent> {
|
||||
override fun uploadMedia(media: QueuedMedia, videoLimit: Long, imageLimit: Long): Observable<UploadEvent> {
|
||||
return Observable
|
||||
.fromCallable {
|
||||
if (shouldResizeMedia(media, imageLimit)) {
|
||||
downsize(media, imageLimit)
|
||||
} else media
|
||||
}
|
||||
.switchMap { upload(it, videoLimit, imageLimit) }
|
||||
.switchMap { upload(it) }
|
||||
.subscribeOn(Schedulers.io())
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ class MediaUploaderImpl(
|
|||
}
|
||||
}
|
||||
|
||||
override fun prepareMedia(inUri: Uri, videoLimit: Int, imageLimit: Int, filename: String?): Single<PreparedMedia> {
|
||||
override fun prepareMedia(inUri: Uri, videoLimit: Long, imageLimit: Long, filename: String?): Single<PreparedMedia> {
|
||||
return Single.fromCallable {
|
||||
var mediaSize = getMediaSize(contentResolver, inUri)
|
||||
var uri = inUri
|
||||
|
@ -159,7 +159,7 @@ class MediaUploaderImpl(
|
|||
|
||||
private val contentResolver = context.contentResolver
|
||||
|
||||
private fun upload(media: QueuedMedia, videoLimit: Int, imageLimit: Int): Observable<UploadEvent> {
|
||||
private fun upload(media: QueuedMedia): Observable<UploadEvent> {
|
||||
return Observable.create { emitter ->
|
||||
var (mimeType, fileExtension) = getMimeTypeAndSuffixFromFilenameOrUri(media.uri, media.originalFileName)
|
||||
val filename = String.format("%s_%s_%s%s",
|
||||
|
@ -196,13 +196,13 @@ class MediaUploaderImpl(
|
|||
}
|
||||
}
|
||||
|
||||
private fun downsize(media: QueuedMedia, imageLimit: Int): QueuedMedia {
|
||||
private fun downsize(media: QueuedMedia, imageLimit: Long): QueuedMedia {
|
||||
val file = createNewImageFile(context)
|
||||
DownsizeImageTask.resize(arrayOf(media.uri), imageLimit, context.contentResolver, file)
|
||||
return media.copy(uri = file.toUri(), mediaSize = file.length())
|
||||
}
|
||||
|
||||
private fun shouldResizeMedia(media: QueuedMedia, imageLimit: Int): Boolean {
|
||||
private fun shouldResizeMedia(media: QueuedMedia, imageLimit: Long): Boolean {
|
||||
// resize only images
|
||||
if(media.type == QueuedMedia.Type.IMAGE) {
|
||||
// resize when exceed image limit
|
||||
|
|
|
@ -25,7 +25,7 @@ data class NodeInfoLink(
|
|||
)
|
||||
|
||||
data class NodeInfoLinks(
|
||||
val links: ArrayList<NodeInfoLink>
|
||||
val links: List<NodeInfoLink>
|
||||
)
|
||||
|
||||
// we care only about supported postFormats
|
||||
|
@ -41,14 +41,14 @@ data class NodeInfoSoftware(
|
|||
)
|
||||
|
||||
data class NodeInfoPleromaUploadLimits(
|
||||
val avatar: Int?,
|
||||
val background: Int?,
|
||||
val banner: Int?,
|
||||
val general: Int?
|
||||
val avatar: Long?,
|
||||
val background: Long?,
|
||||
val banner: Long?,
|
||||
val general: Long?
|
||||
)
|
||||
|
||||
data class NodeInfoPixelfedUploadLimits(
|
||||
@SerializedName("max_photo_size") val maxPhotoSize: Int?
|
||||
@SerializedName("max_photo_size") val maxPhotoSize: Long?
|
||||
)
|
||||
|
||||
data class NodeInfoPixelfedConfig(
|
||||
|
@ -56,7 +56,7 @@ data class NodeInfoPixelfedConfig(
|
|||
)
|
||||
|
||||
data class NodeInfoMetadata(
|
||||
val postFormats: ArrayList<String>?,
|
||||
val postFormats: List<String>?,
|
||||
val uploadLimits: NodeInfoPleromaUploadLimits?,
|
||||
val config: NodeInfoPixelfedConfig?
|
||||
)
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.mockito.Mockito.mock
|
|||
import org.robolectric.Robolectric
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.fakes.RoboMenuItem
|
||||
import java.lang.Math.pow
|
||||
|
||||
/**
|
||||
* Created by charlag on 3/7/18.
|
||||
|
@ -75,9 +76,7 @@ class ComposeActivityTest {
|
|||
notificationLight = true
|
||||
)
|
||||
var instanceResponseCallback: (()->Instance)? = null
|
||||
private val nodeinfoLinks = NodeInfoLinks(
|
||||
links = arrayListOf<NodeInfoLink>()
|
||||
)
|
||||
var nodeinfoResponseCallback: (()->NodeInfo)? = null
|
||||
|
||||
@Before
|
||||
fun setupActivity() {
|
||||
|
@ -89,7 +88,27 @@ class ComposeActivityTest {
|
|||
|
||||
apiMock = mock(MastodonApi::class.java)
|
||||
`when`(apiMock.getCustomEmojis()).thenReturn(Single.just(emptyList()))
|
||||
`when`(apiMock.getNodeinfoLinks()).thenReturn(Single.just(nodeinfoLinks))
|
||||
`when`(apiMock.getNodeinfoLinks()).thenReturn(object: Single<NodeInfoLinks>() {
|
||||
override fun subscribeActual(observer: SingleObserver<in NodeInfoLinks>) {
|
||||
if (nodeinfoResponseCallback == null) {
|
||||
observer.onError(Throwable())
|
||||
} else {
|
||||
observer.onSuccess(NodeInfoLinks(
|
||||
listOf( NodeInfoLink( "", "" ) )
|
||||
))
|
||||
}
|
||||
}
|
||||
})
|
||||
`when`(apiMock.getNodeinfo("")).thenReturn(object: Single<NodeInfo>() {
|
||||
override fun subscribeActual(observer: SingleObserver< in NodeInfo>) {
|
||||
val nodeinfo = nodeinfoResponseCallback?.invoke()
|
||||
if (nodeinfo == null) {
|
||||
observer.onError(Throwable())
|
||||
} else {
|
||||
observer.onSuccess(nodeinfo)
|
||||
}
|
||||
}
|
||||
})
|
||||
`when`(apiMock.getInstance()).thenReturn(object: Single<Instance>() {
|
||||
override fun subscribeActual(observer: SingleObserver<in Instance>) {
|
||||
val instance = instanceResponseCallback?.invoke()
|
||||
|
@ -164,12 +183,66 @@ class ComposeActivityTest {
|
|||
|
||||
@Test
|
||||
fun whenMaximumTootCharsIsPopulated_customLimitIsUsed() {
|
||||
val customMaximum = 1000
|
||||
val customMaximum = 2147483647
|
||||
instanceResponseCallback = { getInstanceWithMaximumTootCharacters(customMaximum) }
|
||||
setupActivity()
|
||||
assertEquals(customMaximum, activity.maximumTootCharacters)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenPleromaInNodeinfo_attachmentLimitsRemoved() {
|
||||
nodeinfoResponseCallback = { getPleromaNodeinfo(
|
||||
null,
|
||||
NodeInfoPleromaUploadLimits( 100, 100, 100, 100 ))
|
||||
}
|
||||
setupActivity()
|
||||
assertEquals(true, activity.viewModel.hasNoAttachmentLimits)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenPleromaInNodeinfo_haveFormatting() {
|
||||
nodeinfoResponseCallback = { getPleromaNodeinfo(
|
||||
listOf("text/plain", "text/markdown", "text/bbcode"),
|
||||
NodeInfoPleromaUploadLimits( 100, 100, 100, 100 ))
|
||||
}
|
||||
setupActivity()
|
||||
assertArrayEquals(arrayOf("text/markdown", "text/bbcode"), activity.supportedFormattingSyntax.toTypedArray())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenPleromaInNodeinfo_haveCustomUploadLimits() {
|
||||
nodeinfoResponseCallback = { getPleromaNodeinfo(
|
||||
null,
|
||||
NodeInfoPleromaUploadLimits( Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE ))
|
||||
}
|
||||
setupActivity()
|
||||
assertEquals(Long.MAX_VALUE, activity.viewModel.instanceMetadata.value!!.imageLimit)
|
||||
assertEquals(Long.MAX_VALUE, activity.viewModel.instanceMetadata.value!!.videoLimit)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenPixelfedInNodeInfo_haveCustomUploadLimits() {
|
||||
nodeinfoResponseCallback = { getPixelfedNodeinfo( 1024 * 1024 ) }
|
||||
setupActivity()
|
||||
assertEquals(1024 * 1024 * 1024, activity.viewModel.instanceMetadata.value!!.imageLimit)
|
||||
assertEquals(1024 * 1024 * 1024, activity.viewModel.instanceMetadata.value!!.videoLimit)
|
||||
assertArrayEquals(emptyArray(), activity.supportedFormattingSyntax.toTypedArray()) // pixelfed has no formatting
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMastodonInNodeinfo_butItsAGlitch() {
|
||||
nodeinfoResponseCallback = { getMastodonNodeinfo( "3.1.0+glitch" ) }
|
||||
setupActivity()
|
||||
assertArrayEquals(arrayOf("text/markdown", "text/html"), activity.supportedFormattingSyntax.toTypedArray())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMastodonInNodeinfo_butItsBoringVanilla() {
|
||||
nodeinfoResponseCallback = { getMastodonNodeinfo( "3.1.0" ) }
|
||||
setupActivity()
|
||||
assertArrayEquals(emptyArray(), activity.supportedFormattingSyntax.toTypedArray())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenTextContainsNoUrl_everyCharacterIsCounted() {
|
||||
val content = "This is test content please ignore thx "
|
||||
|
@ -361,6 +434,43 @@ class ComposeActivityTest {
|
|||
activity.findViewById<EditText>(R.id.composeEditField).setText(text ?: "Some text")
|
||||
}
|
||||
|
||||
private fun getPleromaNodeinfo(postFormats: List<String>?, limits: NodeInfoPleromaUploadLimits) : NodeInfo
|
||||
{
|
||||
return NodeInfo(
|
||||
NodeInfoMetadata(
|
||||
postFormats,
|
||||
limits,
|
||||
null
|
||||
),
|
||||
NodeInfoSoftware(
|
||||
"pleroma",
|
||||
"2.0.0"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getPixelfedNodeinfo(maxPhotoSize: Long) : NodeInfo {
|
||||
return NodeInfo(
|
||||
NodeInfoMetadata(
|
||||
null, null, NodeInfoPixelfedConfig( NodeInfoPixelfedUploadLimits( maxPhotoSize ) )
|
||||
),
|
||||
NodeInfoSoftware(
|
||||
"pixelfed",
|
||||
"2.0.0"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getMastodonNodeinfo(version: String) : NodeInfo {
|
||||
return NodeInfo(
|
||||
null,
|
||||
NodeInfoSoftware(
|
||||
"mastodon",
|
||||
version
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getInstanceWithMaximumTootCharacters(maximumTootCharacters: Int?): Instance
|
||||
{
|
||||
return Instance(
|
||||
|
|
Loading…
Reference in New Issue