Merge backend-overhaul to master (#3198)

* Migrated logEvents to retrofit (#3087)

* Switched wikimedia-android-data-client for new features

* Added UserCLient and UserInterface

* Migrated ContributionsSyncAdapter to UserClient
Fixed sync related bugs

* Removed unused code

* Removed unused code

* Updated wikimedia-android-data-client to new version

* Update library for data client (#3131)

* Backend overhaul fetch media by filename (#3081)

* Added class MwParseResponse and MwParseResult for receiving parse output

* Migrated fetchMediaByFilename to retrofit

* Removed unused code

* Added tests

* Migrated isUserBlockedFromCommons to retrofit (#3085)

* Switched wikimedia-android-data-client for new features

* Added UserCLient and UserInterface

* Migrated isUserBlockedFromCommons to retrofit

* Added tests and removed dead code

* Implemented ban checking functionality in UploadActivity

* Removed unused class AuthenticatedActivity

* Fixed tests

* Fixed NullPointerException when a user accessed image details without logging in.

* * Login the login token way, handle LoginResult minutely, add account based on LoginResult (#3151)

* Added progress updater in UploadService to show upload progress in no… (#3156)

* added progress updater in UploadService to show upload progress in notification

* formatting changes

* [Dependency: Quadtree] Remove unused code from cache controller (#3163)

* Basic logging with redacted sensitive headers (#3159)

* As per #3026, removed the obsolete classes in package mwapi (#3150)

* fixed compile time error (#3165)

* [Dependency fluent]: Remove unused dependency fluent (#3164)

* Donot init quiz checker in onResume (#3167)

* clear image cache on logout (#3168)

* Fixed default locale and upload locales in descrptions (#3166)

* Fix 2FA login (#3170)

* Fix build (#3172)

* Localisation updates from https://translatewiki.net.

* Closes #3094 (#3095)

* BugFix in SpinnerDescriptionsAdapter and SpinnerLanguagesAdapter (use the langguage code provided by the spinner, donot set the language to the one returned by the locale)

* Update changelog.md

* Versioning for v2.11.0

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Center map on location clicked in nearby list and notification card(#2060) (#2366)

* center map on location clicked in nearby (#2060)

* improved animation

* Center map on location clicked in nearby list

* removed unnecessary methods

* center map on location clicked in nearby notification card

* some minor changes

* travis build error

* resolved errors

* Tidy up PR

* removed swipe to delete (#2589)

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* edited CREDITS file (#3145)

* Unused dependencies are removed (#3141)

Part of #3128

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Working with #3129 issue (#3146)

* Replace Hard-Coded strings with those from strings.xml.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* delete res/values-en-gb (#3153)

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* First commit (#3093)

Fixes info icon color is Review

* Solution #3126 (#3155)

Fixed wrong upload dates after image upload

* Bugfix/fix upload presenter tests (#3158)

* Revert "Merge branch 'backend-overhaul' into master"

This reverts commit 0090f24257, reversing
changes made to 9bccbfe443.

* * Fixed upload presenter tests
* Deleted app/src/main/res/values-en-gb/error.xml

* Localisation updates from https://translatewiki.net.

* Remove dependency on Exif parsing library. (#2947)

* Remove dependency on Exif parsing library.

* Fix test.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Refactor nearby classes mvp (#2969)

* Create parent contract

* Create map child contract and fill methods

* Add javadocs and specific interfaces for list

* Move general method to parent and add javadocs for parent

* Add explanation for keeping an emty View interface under NearbyListContract

* Move constracts under contract package

* Create presenters for map and list and implement user actions accordingly

* Add javadocs

* Add presenter, contract and fragment for parent Fragment of both NearyListFragment and NearbyMapFragment

* Implement missing methods

* Fix typo

* Add main views on fragment

* İmplement child fragment logic and their retain

* Relate parent presenter with parent fragment

* Add all location permission related methods to view contract and implement in fragment. Call them from presenter by passing locationServiceManager parameter

* Define refreshView method as updateMapAndList which is a better naming. Define it at presenter part.

* Define a presenter variable in fragment and call updateMapAndList method from there, if permissions are okay

* Add lock neabry method to unlisten nearby operations during updates

* Add network connection established check on view side, check it from presenter

* try to simplify previous method during refactor

* Add missing methods for NearbyMap

* Connect child fragment and prent fragment with presenter

* Change nearby design, first create views then register listeners

* AddnetworkBroadcatsReceiver on view side, call it from presenter

* Add comments

* Change the old NearbyFragment by our new NearbyParentFragment for first tests

* Prevent crash caused child fragment is actually null by checking if it is attached or not.

* Makes sure that initialize nearby operations method is called just after all views and fragments are ready and attached

* Make sure updateMAoAndList method is called when everything ready

* Rename a method with prepoer name

* Call update map and add required markers

* Find out zoom level problem

* Implement add nearby markers and add current marker methods

* remove unneeded codes copied from previous implementation

* Revert "remove unneeded codes copied from previous implementation"

This reverts commit 42539651de.

* add some commits and clear code

* Remove location listener implementation from view, handle them in presenter instead. And add timber debug notes and required method calls

* Style ,issues

* Refactor a variable name to camel case and bind search this area view

* Search this area button action is added

* Mostly implement search this area methods, not tested yet even once

* Make sure everything is called in required order and seach this area method basically works

* Rename methods accordingly and add Javadocs

* Add current location marker and remove circle around it

* Remove unused methods

* Add current location marker with object animator and remove previous marker is exists

* include clear map into add markers method and reorder methods

* Make search this area button appear at correct time

* Try to load un search this area is called

* Clear logs

* Add changes for permission made by Vivek to newly added fragments along with our nearby classes

* Add a view to nearby map ragment and insert map view as an item inside it

* Add logs to uınderstand why on meap ready callback is never called

* Add list item clicked and bottom sheet for list of nearby items is expanded

* Make nearby map ready callback came

* Add required methods to be called after map view is ready

* State: Map ready call is not called but permissions and methods are in correct order

* Remove unused logs

* Try to use SupportMapFragment instead, still no success...

* use SupportMapFragment instead

* Remove unused Near

* Upgrade mapbox sdk versions

* Remove Style import from fragment/NearbyMapFragment

* Remove Style import from **fragments/NearbyParentFragment

* Remove nearby/NearbyMapFragment

* Remove unused/old NearbyFragment and NearbyMapFragment

* Remove import of already removed class

* Make sure you removed everything related with mapbox implementation

* Update mapbox map

* Remove unused classes, do not forget centerMapToPlace doesn't work on this branch

* Remove Style class it required updated version of mapbox map

* Add base codes for new activity

* Prove that our mapbox sdk let us implement the map directly inside the activity

* Add base codes for testing mapbox activity in a single fragment inside activity

* Add codes from mapbox demo repository to test support fragment, map works in a single layer fragment

* Add base codes for test layered fragment activity

* Add Support fragment inside a fragment and proves that layered fragmentw with map works

* Test view pager and tab layout with support map fragment to see it works, it works!

* Move Contributions Fragment related codes to test activity

* Move nearby card methods

* Inject location manager and implement NerabyParentFragmentContract.View on test fragment

* Coppy the content of SupportMapFragment from mapbox repository, use this code to modify later. This method war suggested by mapbox team instead of extending the class

* Implement NearbyMapContract.View on our new SupportMapFragment

* Start to mplement logic of checking permissions

* Fix small dagger issue to inject location manager properly

* Request permission for nearby places if fragment is loaded and tab is selected

* Initialize map operations if map ready and tab is selected

* Markers loads at correct time

* Style the map according to new version of mapbox map

* Add some map elements like FABs and give their actions

* Implement map marker click actions

* Implement nearby Fabs logic with a small issue

* fix FABs are not closing problem

* Unkown problem occurs at map load when I try to use MainActivity again.

* Revert "Unkown problem occurs at map load when I try to use MainActivity again."

This reverts commit 3dc084415b.

* Search this area buttons are added but button function does not work and button visibility is problematic

* Fix issue with MainActivity with the help of Ashish

* Fix search this area button visibility issue

* Fix the issues with updating search nearby markers and camera position together

* Fix progress bar visibility issue

* Prevent loding map each time tab selected

* Take toolbar back

* Implement back button with presenter

* Add click actoion to bottom sheet details

* Add nearby list into bottom sheeet

* Make reuse existing fragments if there is any

* Code cleanup

* Cleanup

* Code cleanup

* Add lifecyle codes to prevent leaks

* Cleanup

* Code cleanup

* cleanup

* Make list item clicked and map focus to same place

* Add bookmark from list fragment

* Make nearby card click action work

* Revert "Fix conflicts"

This reverts commit f3451745d3, reversing
changes made to c5d4d5533d.

* Code cleanup

* Cleanup

* Make recenter button work when list sheet is expanded

* Cleanup

* Code cleanups

* NPE issue is not detected for now, can be solved on seperate PR

* Update map after Wikidata edit

* Cherry picked previously reverted merge, hoping this will fix enourmus amounts of diff files

* Previous merge bringed an file which should be deleted. Delete it.

* Revert irrelevant changes on build.gradle

* Revert irrelevant changes

* Jetbrains annotation is not included to build gradle, this issue caused build issues on my branch so I removed it to be able to build

* Rename ListView

* Use a singleton to access the presenter, instead of passing it to a variable inside fragment

* Fix code style issues

* Move hardcoded colors to colors.xml file

* Make larger methods smaller

* Make current location marker follow

* Do not track users position if user is searching around

* Revert irrelevant shanges at build gradle

* Remove unneeded variable

* Remove mvp directory, add sub directories directly under nearby directory instead

* Remove unneeded public definiton

* Remove unneeded namespace

* Add public defiiton, it is needed to reach the constructor.

* On Logout, fetch the CSRF token and then make the post logout call (#3182)

* Api call for logout

* call clear cached onCompleteSessionLogout

* Correction is passed file name to checkPageExistsUsingTitle, function expects file name prefixed with File: (#3194)

* Merge master (#3196)

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Localisation updates from https://translatewiki.net.

* Mapped values-en-gb to values-en-rGB (#3161)

Fixes "Error: Invalid resource directory name" bug.

* Localisation updates from https://translatewiki.net.

* Removes the "Other" deletion option mentioned in #3174 (#3183)

* Localisation updates from https://translatewiki.net.

* Renamed resource file to prevent build from failing (#3189)

* Localisation updates from https://translatewiki.net.

* Removed some jargon/slang from strings.xml (#3162)

* Localisation updates from https://translatewiki.net.

* solve issue Avoid 'form movements' in the login screen #1107 (#2936)

* Disabled review buttons while an image is being loaded (#3185)

* Disabled review buttons while an image is being loaded

* Added javadocs for the new methods

* Fix build
This commit is contained in:
Vivek Maskara 2019-11-06 18:05:12 +05:30 committed by Ashish Kumar
parent 2ed32162b7
commit 8ccad2277d
119 changed files with 2558 additions and 5016 deletions

View file

@ -1,8 +1,6 @@
package fr.free.nrw.commons
import fr.free.nrw.commons.mwapi.MediaResult
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
import fr.free.nrw.commons.media.MediaClient
import io.reactivex.Single
import org.junit.Assert.assertTrue
import org.junit.Before
@ -20,11 +18,7 @@ import org.mockito.MockitoAnnotations
class MediaDataExtractorTest {
@Mock
internal var mwApi: MediaWikiApi? = null
@Mock
internal var okHttpJsonApiClient: OkHttpJsonApiClient? = null
internal var mediaClient: MediaClient? = null
@InjectMocks
var mediaDataExtractor: MediaDataExtractor? = null
@ -42,19 +36,14 @@ class MediaDataExtractorTest {
*/
@Test
fun fetchMediaDetails() {
`when`(okHttpJsonApiClient?.getMedia(ArgumentMatchers.anyString(), ArgumentMatchers.anyBoolean()))
`when`(mediaClient?.getMedia(ArgumentMatchers.anyString()))
.thenReturn(Single.just(mock(Media::class.java)))
`when`(mwApi?.pageExists(ArgumentMatchers.anyString()))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val mediaResult = mock(MediaResult::class.java)
`when`(mediaResult.wikiSource).thenReturn("some wiki source")
`when`(mwApi?.fetchMediaByFilename(ArgumentMatchers.anyString()))
.thenReturn(Single.just(mediaResult))
`when`(mwApi?.parseWikicode(ArgumentMatchers.anyString()))
.thenReturn(Single.just("discussion text"))
`when`(mediaClient?.getPageHtml(ArgumentMatchers.anyString()))
.thenReturn(Single.just("Test"))
val fetchMediaDetails = mediaDataExtractor?.fetchMediaDetails("test.jpg")?.blockingGet()

View file

@ -13,6 +13,7 @@ import java.util.List;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.bookmarks.Bookmark;
import fr.free.nrw.commons.media.MediaClient;
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
import io.reactivex.Single;
@ -29,7 +30,7 @@ import static org.mockito.Mockito.when;
public class BookmarkPicturesControllerTest {
@Mock
OkHttpJsonApiClient okHttpJsonApiClient;
MediaClient mediaClient;
@Mock
BookmarkPicturesDao bookmarkDao;
@ -46,7 +47,7 @@ public class BookmarkPicturesControllerTest {
Media mockMedia = getMockMedia();
when(bookmarkDao.getAllBookmarks())
.thenReturn(getMockBookmarkList());
when(okHttpJsonApiClient.getMedia(anyString(), anyBoolean()))
when(mediaClient.getMedia(anyString()))
.thenReturn(Single.just(mockMedia));
}
@ -75,9 +76,9 @@ public class BookmarkPicturesControllerTest {
*/
@Test
public void loadBookmarkedPicturesForNullMedia() {
when(okHttpJsonApiClient.getMedia("File:Test1.jpg", false))
when(mediaClient.getMedia("File:Test1.jpg"))
.thenReturn(Single.error(new NullPointerException("Error occurred")));
when(okHttpJsonApiClient.getMedia("File:Test2.jpg", false))
when(mediaClient.getMedia("File:Test2.jpg"))
.thenReturn(Single.just(getMockMedia()));
List<Media> bookmarkedPictures = bookmarkPicturesController.loadBookmarkedPictures().blockingGet();
assertEquals(1, bookmarkedPictures.size());

View file

@ -0,0 +1,153 @@
package fr.free.nrw.commons.category
import io.reactivex.Observable
import junit.framework.Assert.*
import org.junit.Before
import org.junit.Test
import org.mockito.*
import org.wikipedia.dataclient.mwapi.MwQueryPage
import org.wikipedia.dataclient.mwapi.MwQueryResponse
import org.wikipedia.dataclient.mwapi.MwQueryResult
class CategoryClientTest {
@Mock
internal var categoryInterface: CategoryInterface? = null
@InjectMocks
var categoryClient: CategoryClient? = null
@Before
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun searchCategoriesFound() {
val mwQueryPage = Mockito.mock(MwQueryPage::class.java)
Mockito.`when`(mwQueryPage.title()).thenReturn("Category:Test")
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(categoryInterface!!.searchCategories(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt()))
.thenReturn(Observable.just(mockResponse))
val actualCategoryName = categoryClient!!.searchCategories("tes", 10).blockingFirst()
assertEquals("Test", actualCategoryName)
val actualCategoryName2 = categoryClient!!.searchCategories("tes", 10, 10).blockingFirst()
assertEquals("Test", actualCategoryName2)
}
@Test
fun searchCategoriesNull() {
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.pages()).thenReturn(null)
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(categoryInterface!!.searchCategories(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt()))
.thenReturn(Observable.just(mockResponse))
categoryClient!!.searchCategories("tes", 10).subscribe(
{ fail("SearchCategories returned element when it shouldn't have.") },
{ s -> throw s })
categoryClient!!.searchCategories("tes", 10, 10).subscribe(
{ fail("SearchCategories returned element when it shouldn't have.") },
{ s -> throw s })
}
@Test
fun searchCategoriesForPrefixFound() {
val mwQueryPage = Mockito.mock(MwQueryPage::class.java)
Mockito.`when`(mwQueryPage.title()).thenReturn("Category:Test")
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(categoryInterface!!.searchCategoriesForPrefix(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt()))
.thenReturn(Observable.just(mockResponse))
val actualCategoryName = categoryClient!!.searchCategoriesForPrefix("tes", 10).blockingFirst()
assertEquals("Test", actualCategoryName)
val actualCategoryName2 = categoryClient!!.searchCategoriesForPrefix("tes", 10, 10).blockingFirst()
assertEquals("Test", actualCategoryName2)
}
@Test
fun searchCategoriesForPrefixNull() {
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.pages()).thenReturn(null)
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(categoryInterface!!.searchCategoriesForPrefix(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt()))
.thenReturn(Observable.just(mockResponse))
categoryClient!!.searchCategoriesForPrefix("tes", 10).subscribe(
{ fail("SearchCategories returned element when it shouldn't have.") },
{ s -> throw s })
categoryClient!!.searchCategoriesForPrefix("tes", 10, 10).subscribe(
{ fail("SearchCategories returned element when it shouldn't have.") },
{ s -> throw s })
}
@Test
fun getParentCategoryListFound() {
val mwQueryPage = Mockito.mock(MwQueryPage::class.java)
Mockito.`when`(mwQueryPage.title()).thenReturn("Category:Test")
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(categoryInterface!!.getParentCategoryList(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
val actualCategoryName = categoryClient!!.getParentCategoryList("tes").blockingFirst()
assertEquals("Test", actualCategoryName)
}
@Test
fun getParentCategoryListNull() {
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.pages()).thenReturn(null)
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(categoryInterface!!.getParentCategoryList(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
categoryClient!!.getParentCategoryList("tes").subscribe(
{ fail("SearchCategories returned element when it shouldn't have.") },
{ s -> throw s })
}
@Test
fun getSubCategoryListFound() {
val mwQueryPage = Mockito.mock(MwQueryPage::class.java)
Mockito.`when`(mwQueryPage.title()).thenReturn("Category:Test")
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(categoryInterface!!.getSubCategoryList(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
val actualCategoryName = categoryClient!!.getSubCategoryList("tes").blockingFirst()
assertEquals("Test", actualCategoryName)
}
@Test
fun getSubCategoryListNull() {
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.pages()).thenReturn(null)
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(categoryInterface!!.getSubCategoryList(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
categoryClient!!.getSubCategoryList("tes").subscribe(
{ fail("SearchCategories returned element when it shouldn't have.") },
{ s -> throw s })
}
}

View file

@ -1,19 +1,22 @@
package fr.free.nrw.commons.delete
import android.accounts.Account
import android.content.Context
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.auth.SessionManager
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.actions.PageEditClient
import fr.free.nrw.commons.notification.NotificationHelper
import fr.free.nrw.commons.utils.ViewUtilWrapper
import io.reactivex.Observable
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentMatchers
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import org.wikipedia.AppAdapter
import javax.inject.Inject
import javax.inject.Named
/**
* Tests for delete helper
@ -21,17 +24,15 @@ import org.mockito.MockitoAnnotations
class DeleteHelperTest {
@Mock
internal var mwApi: MediaWikiApi? = null
@Mock
internal var sessionManager: SessionManager? = null
@Mock
internal var notificationHelper: NotificationHelper? = null
@field:[Inject Named("commons-page-edit")]
internal var pageEditClient: PageEditClient? = null
@Mock
internal var context: Context? = null
@Mock
internal var notificationHelper: NotificationHelper? = null
@Mock
internal var viewUtil: ViewUtilWrapper? = null
@ -54,9 +55,13 @@ class DeleteHelperTest {
*/
@Test
fun makeDeletion() {
`when`(mwApi?.editToken).thenReturn("token")
`when`(sessionManager?.authCookie).thenReturn("Mock cookie")
`when`(sessionManager?.currentAccount).thenReturn(Account("TestUser", "Test"))
`when`(pageEditClient?.prependEdit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(true))
`when`(pageEditClient?.appendEdit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(true))
`when`(pageEditClient?.edit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(true))
`when`(media?.displayTitle).thenReturn("Test file")
`when`(media?.filename).thenReturn("Test file.jpg")
@ -68,16 +73,45 @@ class DeleteHelperTest {
/**
* Test a failed deletion
*/
@Test
fun makeDeletionForNullToken() {
`when`(mwApi?.editToken).thenReturn(null)
`when`(sessionManager?.authCookie).thenReturn("Mock cookie")
`when`(sessionManager?.currentAccount).thenReturn(Account("TestUser", "Test"))
@Test(expected = RuntimeException::class)
fun makeDeletionForPrependEditFailure() {
`when`(pageEditClient?.prependEdit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(false))
`when`(pageEditClient?.appendEdit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(true))
`when`(pageEditClient?.edit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(true))
`when`(media?.displayTitle).thenReturn("Test file")
`when`(media?.filename).thenReturn("Test file.jpg")
val makeDeletion = deleteHelper?.makeDeletion(context, media, "Test reason")?.blockingGet()
assertNotNull(makeDeletion)
assertFalse(makeDeletion!!)
deleteHelper?.makeDeletion(context, media, "Test reason")?.blockingGet()
}
@Test(expected = RuntimeException::class)
fun makeDeletionForEditFailure() {
`when`(pageEditClient?.prependEdit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(true))
`when`(pageEditClient?.appendEdit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(true))
`when`(pageEditClient?.edit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(false))
`when`(media?.displayTitle).thenReturn("Test file")
`when`(media?.filename).thenReturn("Test file.jpg")
deleteHelper?.makeDeletion(context, media, "Test reason")?.blockingGet()
}
@Test(expected = RuntimeException::class)
fun makeDeletionForAppendEditFailure() {
`when`(pageEditClient?.prependEdit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(true))
`when`(pageEditClient?.appendEdit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(false))
`when`(pageEditClient?.edit(ArgumentMatchers.anyString(), ArgumentMatchers.anyString(), ArgumentMatchers.anyString()))
.thenReturn(Observable.just(true))
`when`(media?.displayTitle).thenReturn("Test file")
`when`(media?.filename).thenReturn("Test file.jpg")
deleteHelper?.makeDeletion(context, media, "Test reason")?.blockingGet()
}
}

View file

@ -0,0 +1,225 @@
package fr.free.nrw.commons.media
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.utils.CommonsDateUtil
import io.reactivex.Observable
import junit.framework.Assert.*
import org.junit.Before
import org.junit.Test
import org.mockito.*
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.wikipedia.dataclient.mwapi.ImageDetails
import org.wikipedia.dataclient.mwapi.MwQueryPage
import org.wikipedia.dataclient.mwapi.MwQueryResponse
import org.wikipedia.dataclient.mwapi.MwQueryResult
import org.wikipedia.gallery.ImageInfo
import org.mockito.ArgumentCaptor
import java.util.*
import org.mockito.Captor
class MediaClientTest {
@Mock
internal var mediaInterface: MediaInterface? = null
@InjectMocks
var mediaClient: MediaClient? = null
@Before
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun checkPageExistsUsingTitle() {
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.pageId()).thenReturn(10)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mediaInterface!!.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
val checkPageExistsUsingTitle = mediaClient!!.checkPageExistsUsingTitle("File:Test.jpg").blockingGet()
assertTrue(checkPageExistsUsingTitle)
}
@Test
fun checkPageNotExistsUsingTitle() {
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.pageId()).thenReturn(0)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
`when`(mwQueryResult.pages()).thenReturn(listOf())
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mediaInterface!!.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
val checkPageExistsUsingTitle = mediaClient!!.checkPageExistsUsingTitle("File:Test.jpg").blockingGet()
assertFalse(checkPageExistsUsingTitle)
}
@Test
fun checkFileExistsUsingSha() {
val mwQueryPage = mock(MwQueryPage::class.java)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.allImages()).thenReturn(listOf(mock(ImageDetails::class.java)))
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mediaInterface!!.checkFileExistsUsingSha(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
val checkFileExistsUsingSha = mediaClient!!.checkFileExistsUsingSha("abcde").blockingGet()
assertTrue(checkFileExistsUsingSha)
}
@Test
fun checkFileNotExistsUsingSha() {
val mwQueryPage = mock(MwQueryPage::class.java)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.allImages()).thenReturn(listOf())
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mediaInterface!!.checkFileExistsUsingSha(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
val checkFileExistsUsingSha = mediaClient!!.checkFileExistsUsingSha("abcde").blockingGet()
assertFalse(checkFileExistsUsingSha)
}
@Test
fun getMedia() {
val imageInfo = ImageInfo()
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.title()).thenReturn("Test")
`when`(mwQueryPage.imageInfo()).thenReturn(imageInfo)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mediaInterface!!.getMedia(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
assertEquals("Test", mediaClient!!.getMedia("abcde").blockingGet().filename)
}
@Test
fun getMediaNull() {
val imageInfo = ImageInfo()
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.title()).thenReturn("Test")
`when`(mwQueryPage.imageInfo()).thenReturn(imageInfo)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(null)
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mediaInterface!!.getMedia(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
assertEquals(Media.EMPTY, mediaClient!!.getMedia("abcde").blockingGet())
}
@Captor
private val filenameCaptor: ArgumentCaptor<String>? = null
@Test
fun getPictureOfTheDay() {
val template = "Template:Potd/" + CommonsDateUtil.getIso8601DateFormatShort().format(Date())
val imageInfo = ImageInfo()
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.title()).thenReturn("Test")
`when`(mwQueryPage.imageInfo()).thenReturn(imageInfo)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.firstPage()).thenReturn(mwQueryPage)
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mediaInterface!!.getMediaWithGenerator(filenameCaptor!!.capture()))
.thenReturn(Observable.just(mockResponse))
assertEquals("Test", mediaClient!!.getPictureOfTheDay().blockingGet().filename)
assertEquals(template, filenameCaptor.value);
}
@Captor
private val continuationCaptor: ArgumentCaptor<Map<String, String>>? = null
@Test
fun getMediaListFromCategoryTwice() {
val mockContinuation= mapOf(Pair("gcmcontinue", "test"))
val imageInfo = ImageInfo()
val mwQueryPage = mock(MwQueryPage::class.java)
`when`(mwQueryPage.title()).thenReturn("Test")
`when`(mwQueryPage.imageInfo()).thenReturn(imageInfo)
val mwQueryResult = mock(MwQueryResult::class.java)
`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage))
val mockResponse = mock(MwQueryResponse::class.java)
`when`(mockResponse.query()).thenReturn(mwQueryResult)
`when`(mockResponse.continuation()).thenReturn(mockContinuation)
`when`(mediaInterface!!.getMediaListFromCategory(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt(),
continuationCaptor!!.capture()))
.thenReturn(Observable.just(mockResponse))
val media1 = mediaClient!!.getMediaListFromCategory("abcde").blockingGet().get(0)
val media2 = mediaClient!!.getMediaListFromCategory("abcde").blockingGet().get(0)
assertEquals(continuationCaptor.allValues[0], emptyMap<String, String>())
assertEquals(continuationCaptor.allValues[1], mockContinuation)
assertEquals(media1.filename, "Test")
assertEquals(media2.filename, "Test")
}
@Test
fun getPageHtmlTest() {
val mwParseResult = mock(MwParseResult::class.java)
`when`(mwParseResult.text()).thenReturn("Test")
val mockResponse = MwParseResponse()
mockResponse.setParse(mwParseResult)
`when`(mediaInterface!!.getPageHtml(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
assertEquals("Test", mediaClient!!.getPageHtml("abcde").blockingGet())
}
@Test
fun getPageHtmlTestNull() {
val mockResponse = MwParseResponse()
mockResponse.setParse(null)
`when`(mediaInterface!!.getPageHtml(ArgumentMatchers.anyString()))
.thenReturn(Observable.just(mockResponse))
assertEquals("", mediaClient!!.getPageHtml("abcde").blockingGet())
}
}

View file

@ -1,156 +0,0 @@
package fr.free.nrw.commons.modifications
import android.content.ContentProviderClient
import android.content.ContentValues
import android.database.MatrixCursor
import android.database.sqlite.SQLiteDatabase
import android.net.Uri
import android.os.RemoteException
import com.nhaarman.mockito_kotlin.*
import fr.free.nrw.commons.BuildConfig
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.modifications.ModificationsContentProvider.BASE_URI
import fr.free.nrw.commons.modifications.ModifierSequenceDao.Table.*
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class ModifierSequenceDaoTest {
private val mediaUrl = "http://example.com/"
private val columns = arrayOf(COLUMN_ID, COLUMN_MEDIA_URI, COLUMN_DATA)
private val client: ContentProviderClient = mock()
private val database: SQLiteDatabase = mock()
private val contentValuesCaptor = argumentCaptor<ContentValues>()
private lateinit var testObject: ModifierSequenceDao
@Before
fun setUp() {
testObject = ModifierSequenceDao { client }
}
@Test
fun createFromCursorWithEmptyModifiers() {
testObject.fromCursor(createCursor("")).let {
assertEquals(mediaUrl, it.mediaUri.toString())
assertEquals(BASE_URI.buildUpon().appendPath("1").toString(), it.contentUri.toString())
assertTrue(it.modifiers.isEmpty())
}
}
@Test
fun createFromCursorWtihCategoryModifier() {
val cursor = createCursor("{\"name\": \"CategoriesModifier\", \"data\": {}}")
val seq = testObject.fromCursor(cursor)
assertEquals(1, seq.modifiers.size)
assertTrue(seq.modifiers[0] is CategoryModifier)
}
@Test
fun createFromCursorWithRemoveModifier() {
val cursor = createCursor("{\"name\": \"TemplateRemoverModifier\", \"data\": {}}")
val seq = testObject.fromCursor(cursor)
assertEquals(1, seq.modifiers.size)
assertTrue(seq.modifiers[0] is TemplateRemoveModifier)
}
@Test
fun deleteSequence() {
whenever(client.delete(isA(), isNull(), isNull())).thenReturn(1)
val seq = testObject.fromCursor(createCursor(""))
testObject.delete(seq)
verify(client).delete(eq(seq.contentUri), isNull(), isNull())
}
@Test(expected = RuntimeException::class)
fun deleteTranslatesRemoteExceptions() {
whenever(client.delete(isA(), isNull(), isNull())).thenThrow(RemoteException(""))
val seq = testObject.fromCursor(createCursor(""))
testObject.delete(seq)
}
@Test
fun saveExistingSequence() {
val modifierJson = "{\"name\":\"CategoriesModifier\",\"data\":{}}"
val expectedData = "{\"modifiers\":[$modifierJson]}"
val cursor = createCursor(modifierJson)
val seq = testObject.fromCursor(cursor)
testObject.save(seq)
verify(client).update(eq(seq.contentUri), contentValuesCaptor.capture(), isNull(), isNull())
contentValuesCaptor.firstValue.let {
assertEquals(2, it.size())
assertEquals(mediaUrl, it.get(COLUMN_MEDIA_URI))
assertEquals(expectedData, it.get(COLUMN_DATA))
}
}
@Test
fun saveNewSequence() {
val expectedContentUri = BASE_URI.buildUpon().appendPath("1").build()
whenever(client.insert(isA(), isA())).thenReturn(expectedContentUri)
val seq = ModifierSequence(Uri.parse(mediaUrl))
testObject.save(seq)
assertEquals(expectedContentUri.toString(), seq.contentUri.toString())
verify(client).insert(eq(ModificationsContentProvider.BASE_URI), contentValuesCaptor.capture())
contentValuesCaptor.firstValue.let {
assertEquals(2, it.size())
assertEquals(mediaUrl, it.get(COLUMN_MEDIA_URI))
assertEquals("{\"modifiers\":[]}", it.get(COLUMN_DATA))
}
}
@Test(expected = RuntimeException::class)
fun saveTranslatesRemoteExceptions() {
whenever(client.insert(isA(), isA())).thenThrow(RemoteException(""))
testObject.save(ModifierSequence(Uri.parse(mediaUrl)))
}
@Test
fun createTable() {
onCreate(database)
verify(database).execSQL(CREATE_TABLE_STATEMENT)
}
@Test
fun updateTable() {
onUpdate(database, 1, 2)
inOrder(database) {
verify<SQLiteDatabase>(database).execSQL(DROP_TABLE_STATEMENT)
verify<SQLiteDatabase>(database).execSQL(CREATE_TABLE_STATEMENT)
}
}
@Test
fun deleteTable() {
onDelete(database)
inOrder(database) {
verify<SQLiteDatabase>(database).execSQL(DROP_TABLE_STATEMENT)
verify<SQLiteDatabase>(database).execSQL(CREATE_TABLE_STATEMENT)
}
}
private fun createCursor(modifierJson: String) = MatrixCursor(columns, 1).apply {
addRow(listOf("1", mediaUrl, "{\"modifiers\": [$modifierJson]}"))
moveToFirst()
}
}

View file

@ -1,341 +0,0 @@
package fr.free.nrw.commons.mwapi
import android.os.Build
import androidx.test.core.app.ApplicationProvider
import com.google.gson.Gson
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.utils.ConfigUtils
import okhttp3.OkHttpClient
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okhttp3.mockwebserver.RecordedRequest
import org.junit.After
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.wikipedia.util.DateUtil
import java.net.URLDecoder
import java.util.*
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class ApacheHttpClientMediaWikiApiTest {
private lateinit var testObject: ApacheHttpClientMediaWikiApi
private lateinit var server: MockWebServer
private lateinit var wikidataServer: MockWebServer
private lateinit var sharedPreferences: JsonKvStore
private lateinit var okHttpClient: OkHttpClient
@Before
fun setUp() {
server = MockWebServer()
wikidataServer = MockWebServer()
okHttpClient = OkHttpClient()
sharedPreferences = mock(JsonKvStore::class.java)
testObject = ApacheHttpClientMediaWikiApi(ApplicationProvider.getApplicationContext(), "http://" + server.hostName + ":" + server.port + "/", "http://" + wikidataServer.hostName + ":" + wikidataServer.port + "/", sharedPreferences, Gson())
}
@After
fun teardown() {
server.shutdown()
}
@Test
fun authCookiesAreHandled() {
assertEquals("", testObject.authCookie)
testObject.authCookie = "cookie=chocolate-chip"
assertEquals("cookie=chocolate-chip", testObject.authCookie)
}
@Test
fun simpleLoginWithWrongPassword() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api batchcomplete=\"\"><query><tokens logintoken=\"baz\" /></query></api>"))
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><clientlogin status=\"FAIL\" message=\"Incorrect password entered.&#10;Please try again.\" messagecode=\"wrongpassword\" /></api>"))
val result = testObject.login("foo", "bar")
assertBasicRequestParameters(server, "POST").let { loginTokenRequest ->
parseBody(loginTokenRequest.body.readUtf8()).let { body ->
assertEquals("xml", body["format"])
assertEquals("query", body["action"])
assertEquals("login", body["type"])
assertEquals("tokens", body["meta"])
}
}
assertBasicRequestParameters(server, "POST").let { loginRequest ->
parseBody(loginRequest.body.readUtf8()).let { body ->
assertEquals("1", body["rememberMe"])
assertEquals("foo", body["username"])
assertEquals("bar", body["password"])
assertEquals("baz", body["logintoken"])
assertEquals("https://commons.wikimedia.org", body["loginreturnurl"])
assertEquals("xml", body["format"])
}
}
assertEquals("wrongpassword", result)
}
@Test
fun simpleLogin() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api batchcomplete=\"\"><query><tokens logintoken=\"baz\" /></query></api>"))
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><clientlogin status=\"PASS\" username=\"foo\" /></api>"))
val result = testObject.login("foo", "bar")
assertBasicRequestParameters(server, "POST").let { loginTokenRequest ->
parseBody(loginTokenRequest.body.readUtf8()).let { body ->
assertEquals("xml", body["format"])
assertEquals("query", body["action"])
assertEquals("login", body["type"])
assertEquals("tokens", body["meta"])
}
}
assertBasicRequestParameters(server, "POST").let { loginRequest ->
parseBody(loginRequest.body.readUtf8()).let { body ->
assertEquals("1", body["rememberMe"])
assertEquals("foo", body["username"])
assertEquals("bar", body["password"])
assertEquals("baz", body["logintoken"])
assertEquals("https://commons.wikimedia.org", body["loginreturnurl"])
assertEquals("xml", body["format"])
}
}
assertEquals("PASS", result)
}
@Test
fun twoFactorLogin() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api batchcomplete=\"\"><query><tokens logintoken=\"baz\" /></query></api>"))
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><clientlogin status=\"PASS\" username=\"foo\" /></api>"))
val result = testObject.login("foo", "bar", "2fa")
assertBasicRequestParameters(server, "POST").let { loginTokenRequest ->
parseBody(loginTokenRequest.body.readUtf8()).let { body ->
assertEquals("xml", body["format"])
assertEquals("query", body["action"])
assertEquals("login", body["type"])
assertEquals("tokens", body["meta"])
}
}
assertBasicRequestParameters(server, "POST").let { loginRequest ->
parseBody(loginRequest.body.readUtf8()).let { body ->
assertEquals("true", body["rememberMe"])
assertEquals("foo", body["username"])
assertEquals("bar", body["password"])
assertEquals("baz", body["logintoken"])
assertEquals("true", body["logincontinue"])
assertEquals("2fa", body["OATHToken"])
assertEquals("xml", body["format"])
}
}
assertEquals("PASS", result)
}
@Test
fun validateLoginForLoggedInUser() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"10\" name=\"foo\"/></query></api>"))
val result = testObject.validateLogin()
assertBasicRequestParameters(server, "GET").let { loginTokenRequest ->
parseQueryParams(loginTokenRequest).let { body ->
assertEquals("xml", body["format"])
assertEquals("query", body["action"])
assertEquals("userinfo", body["meta"])
}
}
assertTrue(result)
}
@Test
fun validateLoginForLoggedOutUser() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"0\" name=\"foo\"/></query></api>"))
val result = testObject.validateLogin()
assertBasicRequestParameters(server, "GET").let { loginTokenRequest ->
parseQueryParams(loginTokenRequest).let { params ->
assertEquals("xml", params["format"])
assertEquals("query", params["action"])
assertEquals("userinfo", params["meta"])
}
}
assertFalse(result)
}
@Test
fun editToken() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><tokens csrftoken=\"baz\" /></query></api>"))
val result = testObject.editToken
assertBasicRequestParameters(server, "POST").let { editTokenRequest ->
parseBody(editTokenRequest.body.readUtf8()).let { body ->
assertEquals("query", body["action"])
assertEquals("tokens", body["meta"])
}
}
assertEquals("baz", result)
}
@Test
fun getWikidataEditToken() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><centralauthtoken centralauthtoken=\"abc\" /></api>"))
wikidataServer.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><tokens csrftoken=\"baz\" /></query></api>"))
val result = testObject.wikidataCsrfToken
assertBasicRequestParameters(server, "GET").let { centralAuthTokenRequest ->
parseQueryParams(centralAuthTokenRequest).let { params ->
assertEquals("xml", params["format"])
assertEquals("centralauthtoken", params["action"])
}
}
assertBasicRequestParameters(wikidataServer, "POST").let { editTokenRequest ->
parseBody(editTokenRequest.body.readUtf8()).let { body ->
assertEquals("query", body["action"])
assertEquals("abc", body["centralauthtoken"])
assertEquals("tokens", body["meta"])
}
}
assertEquals("baz", result)
}
@Test
fun fileExistsWithName_FileNotFound() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api batchcomplete=\"\"><query> <normalized><n from=\"File:foo\" to=\"File:Foo\" /></normalized><pages><page _idx=\"-1\" ns=\"6\" title=\"File:Foo\" missing=\"\" imagerepository=\"\" /></pages></query></api>"))
val result = testObject.fileExistsWithName("foo")
assertBasicRequestParameters(server, "GET").let { request ->
parseQueryParams(request).let { params ->
assertEquals("xml", params["format"])
assertEquals("query", params["action"])
assertEquals("imageinfo", params["prop"])
assertEquals("File:foo", params["titles"])
}
}
assertFalse(result)
}
@Test
fun isUserBlockedFromCommonsForInfinitelyBlockedUser() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"1000\" name=\"testusername\" blockid=\"3000\" blockedby=\"blockerusername\" blockedbyid=\"1001\" blockreason=\"testing\" blockedtimestamp=\"2018-05-24T15:32:09Z\" blockexpiry=\"infinite\"></userinfo></query></api>"))
val result = testObject.isUserBlockedFromCommons()
assertBasicRequestParameters(server, "GET").let { userBlockedRequest ->
parseQueryParams(userBlockedRequest).let { body ->
assertEquals("xml", body["format"])
assertEquals("query", body["action"])
assertEquals("userinfo", body["meta"])
assertEquals("blockinfo", body["uiprop"])
}
}
assertTrue(result)
}
@Test
fun isUserBlockedFromCommonsForTimeBlockedUser() {
val currentDate = Date()
val expiredDate = Date(currentDate.time + 10000)
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"1000\" name=\"testusername\" blockid=\"3000\" blockedby=\"blockerusername\" blockedbyid=\"1001\" blockreason=\"testing\" blockedtimestamp=\"2018-05-24T15:32:09Z\" blockexpiry=\"" + DateUtil.iso8601DateFormat(expiredDate) + "\"></userinfo></query></api>"))
val result = testObject.isUserBlockedFromCommons()
assertBasicRequestParameters(server, "GET").let { userBlockedRequest ->
parseQueryParams(userBlockedRequest).let { body ->
assertEquals("xml", body["format"])
assertEquals("query", body["action"])
assertEquals("userinfo", body["meta"])
assertEquals("blockinfo", body["uiprop"])
}
}
assertTrue(result)
}
@Test
fun isUserBlockedFromCommonsForExpiredBlockedUser() {
val currentDate = Date()
val expiredDate = Date(currentDate.time - 10000)
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"1000\" name=\"testusername\" blockid=\"3000\" blockedby=\"blockerusername\" blockedbyid=\"1001\" blockreason=\"testing\" blockedtimestamp=\"2018-05-24T15:32:09Z\" blockexpiry=\"" + DateUtil.iso8601DateFormat(expiredDate) + "\"></userinfo></query></api>"))
val result = testObject.isUserBlockedFromCommons()
assertBasicRequestParameters(server, "GET").let { userBlockedRequest ->
parseQueryParams(userBlockedRequest).let { body ->
assertEquals("xml", body["format"])
assertEquals("query", body["action"])
assertEquals("userinfo", body["meta"])
assertEquals("blockinfo", body["uiprop"])
}
}
assertFalse(result)
}
@Test
fun isUserBlockedFromCommonsForNotBlockedUser() {
server.enqueue(MockResponse().setBody("<?xml version=\"1.0\"?><api><query><userinfo id=\"1000\" name=\"testusername\"></userinfo></query></api>"))
val result = testObject.isUserBlockedFromCommons()
assertBasicRequestParameters(server, "GET").let { userBlockedRequest ->
parseQueryParams(userBlockedRequest).let { body ->
assertEquals("xml", body["format"])
assertEquals("query", body["action"])
assertEquals("userinfo", body["meta"])
assertEquals("blockinfo", body["uiprop"])
}
}
assertFalse(result)
}
private fun assertBasicRequestParameters(server: MockWebServer, method: String): RecordedRequest = server.takeRequest().let {
assertEquals("/", it.requestUrl.encodedPath())
assertEquals(method, it.method)
assertEquals("Commons/${ConfigUtils.getVersionNameWithSha(ApplicationProvider.getApplicationContext())} (https://mediawiki.org/wiki/Apps/Commons) Android/${Build.VERSION.RELEASE}",
it.getHeader("User-Agent"))
if ("POST" == method) {
assertEquals("application/x-www-form-urlencoded", it.getHeader("Content-Type"))
}
return it
}
private fun parseQueryParams(request: RecordedRequest) = HashMap<String, String?>().apply {
request.requestUrl.let {
it.queryParameterNames().forEach { name -> put(name, it.queryParameter(name)) }
}
}
private fun parseBody(body: String): Map<String, String> = HashMap<String, String>().apply {
body.split("&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray().forEach { prop ->
val pair = prop.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
put(pair[0], URLDecoder.decode(pair[1], "utf-8"))
}
}
}

View file

@ -1,398 +0,0 @@
package fr.free.nrw.commons.mwapi
import com.google.gson.Gson
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient.mapType
import fr.free.nrw.commons.utils.CommonsDateUtil
import junit.framework.Assert.assertEquals
import okhttp3.HttpUrl
import okhttp3.OkHttpClient
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okhttp3.mockwebserver.RecordedRequest
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import java.util.*
import kotlin.random.Random
/**
* Mock web server based tests for ok http json api client
*/
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [23], application = TestCommonsApplication::class)
class OkHttpJsonApiClientTest {
private lateinit var testObject: OkHttpJsonApiClient
private lateinit var toolsForgeServer: MockWebServer
private lateinit var sparqlServer: MockWebServer
private lateinit var campaignsServer: MockWebServer
private lateinit var server: MockWebServer
private lateinit var sharedPreferences: JsonKvStore
private lateinit var okHttpClient: OkHttpClient
/**
* - make instances of mock web server
* - create instance of OkHttpJsonApiClient
*/
@Before
fun setUp() {
server = MockWebServer()
toolsForgeServer = MockWebServer()
sparqlServer = MockWebServer()
campaignsServer = MockWebServer()
okHttpClient = OkHttpClient.Builder().build()
sharedPreferences = Mockito.mock(JsonKvStore::class.java)
val toolsForgeUrl = "http://" + toolsForgeServer.hostName + ":" + toolsForgeServer.port + "/"
val sparqlUrl = "http://" + sparqlServer.hostName + ":" + sparqlServer.port + "/"
val campaignsUrl = "http://" + campaignsServer.hostName + ":" + campaignsServer.port + "/"
val serverUrl = "http://" + server.hostName + ":" + server.port + "/"
testObject = OkHttpJsonApiClient(okHttpClient, HttpUrl.get(toolsForgeUrl), sparqlUrl, campaignsUrl, serverUrl, sharedPreferences, Gson())
}
/**
* Shutdown server after tests
*/
@After
fun teardown() {
server.shutdown()
toolsForgeServer.shutdown()
sparqlServer.shutdown()
campaignsServer.shutdown()
}
/**
* Test response for category images
*/
@Test
fun getCategoryImages() {
server.enqueue(getFirstPageOfImages())
testFirstPageQuery()
}
/**
* test paginated response for category images
*/
@Test
fun getCategoryImagesWithContinue() {
server.enqueue(getFirstPageOfImages())
server.enqueue(getSecondPageOfImages())
testFirstPageQuery()
`when`(sharedPreferences.getJson<HashMap<String, String>>("query_continue_Watercraft moored off shore", mapType))
.thenReturn(hashMapOf(Pair("gcmcontinue", "testvalue"), Pair("continue", "gcmcontinue||")))
val categoryImagesContinued = testObject.getMediaList("category", "Watercraft moored off shore")!!.blockingGet()
assertBasicRequestParameters(server, "GET").let { request ->
parseQueryParams(request).let { body ->
Assert.assertEquals("json", body["format"])
Assert.assertEquals("2", body["formatversion"])
Assert.assertEquals("query", body["action"])
Assert.assertEquals("categorymembers", body["generator"])
Assert.assertEquals("file", body["gcmtype"])
Assert.assertEquals("Watercraft moored off shore", body["gcmtitle"])
Assert.assertEquals("timestamp", body["gcmsort"])
Assert.assertEquals("desc", body["gcmdir"])
Assert.assertEquals("testvalue", body["gcmcontinue"])
Assert.assertEquals("gcmcontinue||", body["continue"])
Assert.assertEquals("imageinfo", body["prop"])
Assert.assertEquals("url|extmetadata", body["iiprop"])
Assert.assertEquals("DateTime|Categories|GPSLatitude|GPSLongitude|ImageDescription|DateTimeOriginal|Artist|LicenseShortName|LicenseUrl", body["iiextmetadatafilter"])
}
}
assertEquals(categoryImagesContinued.size, 2)
}
/**
* Test response for search images
*/
@Test
fun getSearchImages() {
server.enqueue(getFirstPageOfImages())
testFirstPageSearchQuery()
}
/**
* Test response for paginated search
*/
@Test
fun getSearchImagesWithContinue() {
server.enqueue(getFirstPageOfSearchImages())
server.enqueue(getSecondPageOfSearchImages())
testFirstPageSearchQuery()
`when`(sharedPreferences.getJson<HashMap<String, String>>("query_continue_Watercraft moored off shore", mapType))
.thenReturn(hashMapOf(Pair("gsroffset", "25"), Pair("continue", "gsroffset||")))
val categoryImagesContinued = testObject.getMediaList("search", "Watercraft moored off shore")!!.blockingGet()
assertBasicRequestParameters(server, "GET").let { request ->
parseQueryParams(request).let { body ->
Assert.assertEquals("json", body["format"])
Assert.assertEquals("2", body["formatversion"])
Assert.assertEquals("query", body["action"])
Assert.assertEquals("search", body["generator"])
Assert.assertEquals("text", body["gsrwhat"])
Assert.assertEquals("6", body["gsrnamespace"])
Assert.assertEquals("25", body["gsrlimit"])
Assert.assertEquals("Watercraft moored off shore", body["gsrsearch"])
Assert.assertEquals("25", body["gsroffset"])
Assert.assertEquals("gsroffset||", body["continue"])
Assert.assertEquals("imageinfo", body["prop"])
Assert.assertEquals("url|extmetadata", body["iiprop"])
Assert.assertEquals("DateTime|Categories|GPSLatitude|GPSLongitude|ImageDescription|DateTimeOriginal|Artist|LicenseShortName|LicenseUrl", body["iiextmetadatafilter"])
}
}
assertEquals(categoryImagesContinued.size, 2)
}
/**
* Test response for getting media without generator
*/
@Test
fun getMedia() {
server.enqueue(getMediaList("", "", "", 1))
val media = testObject.getMedia("Test.jpg", false)!!.blockingGet()
assertBasicRequestParameters(server, "GET").let { request ->
parseQueryParams(request).let { body ->
Assert.assertEquals("json", body["format"])
Assert.assertEquals("2", body["formatversion"])
Assert.assertEquals("query", body["action"])
Assert.assertEquals("Test.jpg", body["titles"])
Assert.assertEquals("imageinfo", body["prop"])
Assert.assertEquals("url|extmetadata", body["iiprop"])
Assert.assertEquals("DateTime|Categories|GPSLatitude|GPSLongitude|ImageDescription|DateTimeOriginal|Artist|LicenseShortName|LicenseUrl", body["iiextmetadatafilter"])
}
}
assert(media is Media)
}
/**
* Test response for getting media with generator
* Equivalent of testing POTD
*/
@Test
fun getImageWithGenerator() {
val template = "Template:Potd/" + CommonsDateUtil.getIso8601DateFormatShort().format(Date())
server.enqueue(getMediaList("", "", "", 1))
val media = testObject.getMedia(template, true)!!.blockingGet()
assertBasicRequestParameters(server, "GET").let { request ->
parseQueryParams(request).let { body ->
Assert.assertEquals("json", body["format"])
Assert.assertEquals("2", body["formatversion"])
Assert.assertEquals("query", body["action"])
Assert.assertEquals(template, body["titles"])
Assert.assertEquals("images", body["generator"])
Assert.assertEquals("imageinfo", body["prop"])
Assert.assertEquals("url|extmetadata", body["iiprop"])
Assert.assertEquals("DateTime|Categories|GPSLatitude|GPSLongitude|ImageDescription|DateTimeOriginal|Artist|LicenseShortName|LicenseUrl", body["iiextmetadatafilter"])
}
}
assert(media is Media)
}
/**
* Test response for getting picture of the day
*/
@Test
fun getPictureOfTheDay() {
val template = "Template:Potd/" + CommonsDateUtil.getIso8601DateFormatShort().format(Date())
server.enqueue(getMediaList("", "", "", 1))
val media = testObject.pictureOfTheDay?.blockingGet()
assertBasicRequestParameters(server, "GET").let { request ->
parseQueryParams(request).let { body ->
Assert.assertEquals("json", body["format"])
Assert.assertEquals("2", body["formatversion"])
Assert.assertEquals("query", body["action"])
Assert.assertEquals(template, body["titles"])
Assert.assertEquals("images", body["generator"])
Assert.assertEquals("imageinfo", body["prop"])
Assert.assertEquals("url|extmetadata", body["iiprop"])
Assert.assertEquals("DateTime|Categories|GPSLatitude|GPSLongitude|ImageDescription|DateTimeOriginal|Artist|LicenseShortName|LicenseUrl", body["iiextmetadatafilter"])
}
}
assert(media is Media)
}
private fun testFirstPageSearchQuery() {
val categoryImages = testObject.getMediaList("search", "Watercraft moored off shore")!!.blockingGet()
assertBasicRequestParameters(server, "GET").let { request ->
parseQueryParams(request).let { body ->
Assert.assertEquals("json", body["format"])
Assert.assertEquals("2", body["formatversion"])
Assert.assertEquals("query", body["action"])
Assert.assertEquals("search", body["generator"])
Assert.assertEquals("text", body["gsrwhat"])
Assert.assertEquals("6", body["gsrnamespace"])
Assert.assertEquals("25", body["gsrlimit"])
Assert.assertEquals("Watercraft moored off shore", body["gsrsearch"])
Assert.assertEquals("imageinfo", body["prop"])
Assert.assertEquals("url|extmetadata", body["iiprop"])
Assert.assertEquals("DateTime|Categories|GPSLatitude|GPSLongitude|ImageDescription|DateTimeOriginal|Artist|LicenseShortName|LicenseUrl", body["iiextmetadatafilter"])
}
}
assertEquals(categoryImages.size, 2)
}
private fun testFirstPageQuery() {
val categoryImages = testObject.getMediaList("category", "Watercraft moored off shore")?.blockingGet()
assertBasicRequestParameters(server, "GET").let { request ->
parseQueryParams(request).let { body ->
Assert.assertEquals("json", body["format"])
Assert.assertEquals("2", body["formatversion"])
Assert.assertEquals("query", body["action"])
Assert.assertEquals("categorymembers", body["generator"])
Assert.assertEquals("file", body["gcmtype"])
Assert.assertEquals("Watercraft moored off shore", body["gcmtitle"])
Assert.assertEquals("timestamp", body["gcmsort"])
Assert.assertEquals("desc", body["gcmdir"])
Assert.assertEquals("imageinfo", body["prop"])
Assert.assertEquals("url|extmetadata", body["iiprop"])
Assert.assertEquals("DateTime|Categories|GPSLatitude|GPSLongitude|ImageDescription|DateTimeOriginal|Artist|LicenseShortName|LicenseUrl", body["iiextmetadatafilter"])
}
}
assertEquals(categoryImages?.size, 2)
}
private fun getFirstPageOfImages(): MockResponse {
return getMediaList("gcmcontinue", "testvalue", "gcmcontinue||", 2)
}
private fun getSecondPageOfImages(): MockResponse {
return getMediaList("gcmcontinue", "testvalue2", "gcmcontinue||", 2)
}
private fun getFirstPageOfSearchImages(): MockResponse {
return getMediaList("gsroffset", "25", "gsroffset||", 2)
}
private fun getSecondPageOfSearchImages(): MockResponse {
return getMediaList("gsroffset", "25", "gsroffset||", 2)
}
/**
* Generate a MockResponse object which contains a list of media pages
*/
private fun getMediaList(queryContinueType: String,
queryContinueValue: String,
continueVal: String,
numberOfPages: Int): MockResponse {
val mockResponse = MockResponse()
mockResponse.setResponseCode(200)
var continueJson = ""
if (queryContinueType != "" && queryContinueValue != "" && continueVal != "") {
continueJson = ",\"continue\":{\"$queryContinueType\":\"$queryContinueValue\",\"continue\":\"$continueVal\"}"
}
val mediaList = mutableListOf<String>()
val random = Random(1000)
for (i in 0 until numberOfPages) {
mediaList.add(getMediaPage(random))
}
val pagesString = mediaList.joinToString()
val responseBody = "{\"batchcomplete\":\"\"$continueJson,\"query\":{\"pages\":[$pagesString]}}"
mockResponse.setBody(responseBody)
return mockResponse
}
/**
* Generate test media json object
*/
private fun getMediaPage(random: Random): String {
val pageID = random.nextInt()
val id = random.nextInt()
val fileName = "Test$id"
val id1 = random.nextInt()
val id2 = random.nextInt()
val categories = "cat$id1|cat$id2"
return "{\"pageid\":$pageID,\"ns\":6,\"title\":\"File:$fileName\",\"imagerepository\":\"local\",\"imageinfo\":[{\"url\":\"https://upload.wikimedia.org/$fileName\",\"descriptionurl\":\"https://commons.wikimedia.org/wiki/File:$fileName\",\"descriptionshorturl\":\"https://commons.wikimedia.org/w/index.php?curid=4406048\",\"extmetadata\":{\"DateTime\":{\"value\":\"2013-04-13 15:12:11\",\"source\":\"mediawiki-metadata\",\"hidden\":\"\"},\"Categories\":{\"value\":\"$categories\",\"source\":\"commons-categories\",\"hidden\":\"\"},\"Artist\":{\"value\":\"<bdi><a href=\\\"https://en.wikipedia.org/wiki/en:Raphael\\\" class=\\\"extiw\\\" title=\\\"w:en:Raphael\\\">Raphael</a>\\n</bdi>\",\"source\":\"commons-desc-page\"},\"ImageDescription\":{\"value\":\"test desc\",\"source\":\"commons-desc-page\"},\"DateTimeOriginal\":{\"value\":\"1511<div style=\\\"display: none;\\\">date QS:P571,+1511-00-00T00:00:00Z/9</div>\",\"source\":\"commons-desc-page\"},\"LicenseShortName\":{\"value\":\"Public domain\",\"source\":\"commons-desc-page\",\"hidden\":\"\"}}}]}"
}
/**
* Check request params
*/
private fun assertBasicRequestParameters(server: MockWebServer, method: String): RecordedRequest = server.takeRequest().let {
Assert.assertEquals("/", it.requestUrl.encodedPath())
Assert.assertEquals(method, it.method)
return it
}
/**
* Check request params with encoded path
*/
private fun assertBasicRequestParameters(server: MockWebServer, method: String,encodedPath: String): RecordedRequest = server.takeRequest().let {
Assert.assertEquals(encodedPath, it.requestUrl.encodedPath())
Assert.assertEquals(method, it.method)
return it
}
/**
* Parse query params
*/
private fun parseQueryParams(request: RecordedRequest) = HashMap<String, String?>().apply {
request.requestUrl.let {
it.queryParameterNames().forEach { name -> put(name, it.queryParameter(name)) }
}
}
/**
* Test getUploadCount posititive and negative cases
*/
@Test
fun testGetUploadCount(){
//Positive
assertEquals(testBaseCasesAndGetUploadCount(true), 20)
//Negative
assertEquals(testBaseCasesAndGetUploadCount(false), 0)
}
/**
* Test getUploadCount base cases
*/
private fun testBaseCasesAndGetUploadCount(shouldAddResponse: Boolean): Int? {
val mockResponse = MockResponse()
mockResponse.setResponseCode(200)
if(shouldAddResponse) {
val responseBody = "20"
mockResponse.setBody(responseBody)
}
toolsForgeServer.enqueue(mockResponse)
val uploadCount=testObject.getUploadCount("ashishkumar294").blockingGet()
assertBasicRequestParameters(toolsForgeServer, "GET","/uploadsbyuser.py").let { request ->
parseQueryParams(request).let { body ->
Assert.assertEquals("ashishkumar294", body["user"])
}
}
return uploadCount
}
}

View file

@ -0,0 +1,77 @@
package fr.free.nrw.commons.mwapi
import io.reactivex.Observable
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.mockito.*
import org.wikipedia.dataclient.mwapi.MwQueryPage
import org.wikipedia.dataclient.mwapi.MwQueryResponse
import org.wikipedia.dataclient.mwapi.MwQueryResult
import org.wikipedia.dataclient.mwapi.UserInfo
import org.wikipedia.util.DateUtil
import java.util.*
class UserClientTest{
@Mock
internal var userInterface: UserInterface? = null
@InjectMocks
var userClient: UserClient? = null
@Before
@Throws(Exception::class)
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun isUserBlockedFromCommonsForInfinitelyBlockedUser() {
val userInfo = Mockito.mock(UserInfo::class.java)
Mockito.`when`(userInfo.blockexpiry()).thenReturn("infinite")
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.userInfo()).thenReturn(userInfo)
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(userInterface!!.userBlockInfo)
.thenReturn(Observable.just(mockResponse))
val isBanned = userClient!!.isUserBlockedFromCommons.blockingGet()
assertTrue(isBanned)
}
@Test
fun isUserBlockedFromCommonsForTimeBlockedUser() {
val currentDate = Date()
val expiredDate = Date(currentDate.time + 10000)
val userInfo = Mockito.mock(UserInfo::class.java)
Mockito.`when`(userInfo.blockexpiry()).thenReturn(DateUtil.iso8601DateFormat(expiredDate))
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.userInfo()).thenReturn(userInfo)
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(userInterface!!.userBlockInfo)
.thenReturn(Observable.just(mockResponse))
val isBanned = userClient!!.isUserBlockedFromCommons.blockingGet()
assertTrue(isBanned)
}
@Test
fun isUserBlockedFromCommonsForNeverBlockedUser() {
val userInfo = Mockito.mock(UserInfo::class.java)
Mockito.`when`(userInfo.blockexpiry()).thenReturn("")
val mwQueryResult = Mockito.mock(MwQueryResult::class.java)
Mockito.`when`(mwQueryResult.userInfo()).thenReturn(userInfo)
val mockResponse = Mockito.mock(MwQueryResponse::class.java)
Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult)
Mockito.`when`(userInterface!!.userBlockInfo)
.thenReturn(Observable.just(mockResponse))
val isBanned = userClient!!.isUserBlockedFromCommons.blockingGet()
assertFalse(isBanned)
}
}

View file

@ -1,8 +1,7 @@
package fr.free.nrw.commons.review
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
import fr.free.nrw.commons.media.MediaClient
import io.reactivex.Observable
import io.reactivex.Single
import junit.framework.Assert.assertNotNull
@ -28,9 +27,7 @@ class ReviewHelperTest {
@Mock
internal var reviewInterface: ReviewInterface? = null
@Mock
internal var okHttpJsonApiClient: OkHttpJsonApiClient? = null
@Mock
internal var mediaWikiApi: MediaWikiApi? = null
internal var mediaClient: MediaClient? = null
@InjectMocks
var reviewHelper: ReviewHelper? = null
@ -65,7 +62,7 @@ class ReviewHelperTest {
val media = mock(Media::class.java)
`when`(media.filename).thenReturn("File:Test.jpg")
`when`(okHttpJsonApiClient?.getMedia(ArgumentMatchers.anyString(), ArgumentMatchers.anyBoolean()))
`when`(mediaClient?.getMedia(ArgumentMatchers.anyString()))
.thenReturn(Single.just(media))
}
@ -74,7 +71,7 @@ class ReviewHelperTest {
*/
@Test
fun getRandomMedia() {
`when`(mediaWikiApi?.pageExists(ArgumentMatchers.anyString()))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(false))
val randomMedia = reviewHelper?.randomMedia?.blockingGet()
@ -89,7 +86,7 @@ class ReviewHelperTest {
*/
@Test(expected = RuntimeException::class)
fun getRandomMediaWithWithAllMediaNominatedForDeletion() {
`when`(mediaWikiApi?.pageExists(ArgumentMatchers.anyString()))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val media = reviewHelper?.randomMedia?.blockingGet()
assertNull(media)
@ -101,11 +98,11 @@ class ReviewHelperTest {
*/
@Test
fun getRandomMediaWithWithOneMediaNominatedForDeletion() {
`when`(mediaWikiApi?.pageExists("Commons:Deletion_requests/File:Test1.jpeg"))
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test1.jpeg"))
.thenReturn(Single.just(true))
`when`(mediaWikiApi?.pageExists("Commons:Deletion_requests/File:Test2.png"))
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test2.png"))
.thenReturn(Single.just(false))
`when`(mediaWikiApi?.pageExists("Commons:Deletion_requests/File:Test3.jpg"))
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test3.jpg"))
.thenReturn(Single.just(true))
val media = reviewHelper?.randomMedia?.blockingGet()

View file

@ -57,9 +57,7 @@ class CategoriesPresenterTest {
fun searchForCategoriesTest() {
Mockito.`when`(repository?.sortBySimilarity(ArgumentMatchers.anyString())).thenReturn(Comparator<CategoryItem> { _, _ -> 1 })
Mockito.`when`(repository?.selectedCategories).thenReturn(categoryItems)
Mockito.`when`(repository?.searchAll(ArgumentMatchers.anyString(), ArgumentMatchers.anyList())).thenReturn(testObservable)
Mockito.`when`(repository?.searchCategories(ArgumentMatchers.anyString(), ArgumentMatchers.anyList())).thenReturn(testObservable)
Mockito.`when`(repository?.getDefaultCategories(ArgumentMatchers.anyList())).thenReturn(testObservable)
Mockito.`when`(repository?.searchAll(ArgumentMatchers.anyString(), ArgumentMatchers.anyList())).thenReturn(Observable.empty())
categoriesPresenter?.searchForCategories("test")
verify(view)?.showProgress(true)
verify(view)?.showError(null)

View file

@ -2,7 +2,7 @@ package fr.free.nrw.commons.upload
import android.net.Uri
import fr.free.nrw.commons.location.LatLng
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.media.MediaClient
import fr.free.nrw.commons.nearby.Place
import fr.free.nrw.commons.utils.ImageUtils
import fr.free.nrw.commons.utils.ImageUtilsWrapper
@ -23,11 +23,11 @@ class u {
@Mock
internal var imageUtilsWrapper: ImageUtilsWrapper? = null
@Mock
internal var mwApi: MediaWikiApi? = null
@Mock
internal var readFBMD: ReadFBMD?=null
@Mock
internal var readEXIF: EXIFReader?=null
@Mock
internal var mediaClient: MediaClient? = null
@InjectMocks
var imageProcessingService: ImageProcessingService? = null
@ -55,6 +55,7 @@ class u {
`when`(uploadItem.title).thenReturn(mockTitle)
`when`(uploadItem.place).thenReturn(mockPlace)
`when`(uploadItem.fileName).thenReturn("File:jpg")
`when`(fileUtilsWrapper!!.getFileInputStream(ArgumentMatchers.anyString()))
.thenReturn(mock(FileInputStream::class.java))
@ -74,10 +75,10 @@ class u {
.thenReturn(mock(FileInputStream::class.java))
`when`(fileUtilsWrapper!!.getSHA1(any(FileInputStream::class.java)))
.thenReturn("fileSha")
`when`(mwApi!!.existingFile(ArgumentMatchers.anyString()))
.thenReturn(false)
`when`(mwApi!!.fileExistsWithName(ArgumentMatchers.anyString()))
.thenReturn(false)
`when`(mediaClient!!.checkFileExistsUsingSha(ArgumentMatchers.anyString()))
.thenReturn(Single.just(false))
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(false))
`when`(readFBMD?.processMetadata(ArgumentMatchers.any()))
.thenReturn(Single.just(ImageUtils.IMAGE_OK))
`when`(readEXIF?.processMetadata(ArgumentMatchers.anyString()))
@ -93,8 +94,8 @@ class u {
@Test
fun validateImageForDuplicateImage() {
`when`(mwApi!!.existingFile(ArgumentMatchers.anyString()))
.thenReturn(true)
`when`(mediaClient!!.checkFileExistsUsingSha(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val validateImage = imageProcessingService!!.validateImage(uploadItem, false)
assertEquals(ImageUtils.IMAGE_DUPLICATE, validateImage.blockingGet())
}
@ -123,16 +124,16 @@ class u {
@Test
fun validateImageForFileNameExistsWithCheckTitleOff() {
`when`(mwApi!!.fileExistsWithName(ArgumentMatchers.anyString()))
.thenReturn(true)
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val validateImage = imageProcessingService!!.validateImage(uploadItem, false)
assertEquals(ImageUtils.IMAGE_OK, validateImage.blockingGet())
}
@Test
fun validateImageForFileNameExistsWithCheckTitleOn() {
`when`(mwApi!!.fileExistsWithName(ArgumentMatchers.nullable(String::class.java)))
.thenReturn(true)
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
.thenReturn(Single.just(true))
val validateImage = imageProcessingService!!.validateImage(uploadItem, true)
assertEquals(ImageUtils.FILE_NAME_EXISTS, validateImage.blockingGet())
}

View file

@ -5,12 +5,10 @@ import android.content.Context
import fr.free.nrw.commons.auth.SessionManager
import fr.free.nrw.commons.filepicker.UploadableFile
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.nearby.Place
import fr.free.nrw.commons.utils.ImageUtils.IMAGE_OK
import io.reactivex.Single
import org.junit.After
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
@ -41,8 +39,6 @@ class UploadModelTest {
@Mock
internal var context: Context? = null
@Mock
internal var mwApi: MediaWikiApi? = null
@Mock
internal var sessionManage: SessionManager? = null
@Mock
internal var fileUtilsWrapper: FileUtilsWrapper? = null