mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Convert API clients to kotlin (#5567)
* Convert UserClient to kotlin * Added tests for WikiBaseClient * Removed superfluous dao tests in review helper and got the proper ReviewDaoTest running in the unit test suite * Improved tests for ReviewHelper * Convert the ReviewHelper to kotlin * Convert the WikiBaseClient to kotlin * Convert the WikidataClient to kotlin
This commit is contained in:
parent
c43405267a
commit
728712c4e1
15 changed files with 496 additions and 526 deletions
|
|
@ -1,74 +0,0 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.room.Room;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import fr.free.nrw.commons.db.AppDatabase;
|
||||
import fr.free.nrw.commons.review.ReviewDao;
|
||||
import fr.free.nrw.commons.review.ReviewEntity;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ReviewDaoTest {
|
||||
|
||||
private ReviewDao reviewDao;
|
||||
private AppDatabase database;
|
||||
|
||||
/**
|
||||
* Set up the application database
|
||||
*/
|
||||
@Before
|
||||
public void createDb() {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
database = Room.inMemoryDatabaseBuilder(
|
||||
context, AppDatabase.class)
|
||||
.allowMainThreadQueries()
|
||||
.build();
|
||||
reviewDao = database.ReviewDao();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the database
|
||||
*/
|
||||
@After
|
||||
public void closeDb() {
|
||||
database.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test insertion
|
||||
* Also checks isReviewedAlready():
|
||||
* Case 1: When image has been reviewed/skipped by the user
|
||||
*/
|
||||
@Test
|
||||
public void insert() {
|
||||
// Insert data
|
||||
String imageId = "1234";
|
||||
ReviewEntity reviewEntity = new ReviewEntity(imageId);
|
||||
reviewDao.insert(reviewEntity);
|
||||
|
||||
// Check insertion
|
||||
// Covers the case where the image exists in the database
|
||||
// And isReviewedAlready() returns true
|
||||
Boolean isInserted = reviewDao.isReviewedAlready(imageId);
|
||||
assertThat(isInserted, equalTo(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test review status of the image
|
||||
* Case 2: When image has not been reviewed/skipped
|
||||
*/
|
||||
@Test
|
||||
public void isReviewedAlready(){
|
||||
String imageId = "5856";
|
||||
Boolean isInserted = reviewDao.isReviewedAlready(imageId);
|
||||
assertThat(isInserted, equalTo(false));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
package fr.free.nrw.commons.mwapi;
|
||||
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse;
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResult;
|
||||
import fr.free.nrw.commons.wikidata.mwapi.UserInfo;
|
||||
import fr.free.nrw.commons.utils.DateUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
|
||||
public class UserClient {
|
||||
private final UserInterface userInterface;
|
||||
|
||||
@Inject
|
||||
public UserClient(UserInterface userInterface) {
|
||||
this.userInterface = userInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a user is currently blocked from Commons
|
||||
*
|
||||
* @return whether or not the user is blocked from Commons
|
||||
*/
|
||||
public Single<Boolean> isUserBlockedFromCommons() {
|
||||
return userInterface.getUserBlockInfo()
|
||||
.map(MwQueryResponse::query)
|
||||
.map(MwQueryResult::userInfo)
|
||||
.map(UserInfo::blockexpiry)
|
||||
.map(blockExpiry -> {
|
||||
if (blockExpiry.isEmpty())
|
||||
return false;
|
||||
else if ("infinite".equals(blockExpiry))
|
||||
return true;
|
||||
else {
|
||||
Date endDate = DateUtil.iso8601DateParse(blockExpiry);
|
||||
Date current = new Date();
|
||||
return endDate.after(current);
|
||||
}
|
||||
}).single(false);
|
||||
}
|
||||
}
|
||||
36
app/src/main/java/fr/free/nrw/commons/mwapi/UserClient.kt
Normal file
36
app/src/main/java/fr/free/nrw/commons/mwapi/UserClient.kt
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package fr.free.nrw.commons.mwapi
|
||||
|
||||
import fr.free.nrw.commons.utils.DateUtil
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResult
|
||||
import fr.free.nrw.commons.wikidata.mwapi.UserInfo
|
||||
import io.reactivex.Single
|
||||
import java.text.ParseException
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
||||
class UserClient @Inject constructor(private val userInterface: UserInterface) {
|
||||
/**
|
||||
* Checks to see if a user is currently blocked from Commons
|
||||
*
|
||||
* @return whether or not the user is blocked from Commons
|
||||
*/
|
||||
fun isUserBlockedFromCommons(): Single<Boolean> =
|
||||
userInterface.getUserBlockInfo()
|
||||
.map(::processBlockExpiry)
|
||||
.single(false)
|
||||
|
||||
@Throws(ParseException::class)
|
||||
private fun processBlockExpiry(response: MwQueryResponse): Boolean {
|
||||
val blockExpiry = response.query()?.userInfo()?.blockexpiry()
|
||||
return when {
|
||||
blockExpiry.isNullOrEmpty() -> false
|
||||
"infinite" == blockExpiry -> true
|
||||
else -> {
|
||||
val endDate = DateUtil.iso8601DateParse(blockExpiry)
|
||||
val current = Date()
|
||||
endDate.after(current)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
package fr.free.nrw.commons.review;
|
||||
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.media.MediaClient;
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import java.util.Collections;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage;
|
||||
import timber.log.Timber;
|
||||
|
||||
@Singleton
|
||||
public class ReviewHelper {
|
||||
|
||||
private static final String[] imageExtensions = new String[]{".jpg", ".jpeg", ".png"};
|
||||
|
||||
private final MediaClient mediaClient;
|
||||
private final ReviewInterface reviewInterface;
|
||||
|
||||
@Inject
|
||||
ReviewDao dao;
|
||||
|
||||
@Inject
|
||||
public ReviewHelper(MediaClient mediaClient, ReviewInterface reviewInterface) {
|
||||
this.mediaClient = mediaClient;
|
||||
this.reviewInterface = reviewInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches recent changes from MediaWiki API
|
||||
* Calls the API to get the latest 50 changes
|
||||
* When more results are available, the query gets continued beyond this range
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Observable<MwQueryPage> getRecentChanges() {
|
||||
return reviewInterface.getRecentChanges()
|
||||
.map(mwQueryResponse -> mwQueryResponse.query().pages())
|
||||
.map(recentChanges -> {
|
||||
Collections.shuffle(recentChanges);
|
||||
return recentChanges;
|
||||
})
|
||||
.flatMapIterable(changes -> changes)
|
||||
.filter(recentChange -> isChangeReviewable(recentChange));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a random file change for review.
|
||||
* - Picks a random file from those changes
|
||||
* - Checks if the file is nominated for deletion
|
||||
* - Retries upto 5 times for getting a file which is not nominated for deletion
|
||||
*
|
||||
* @return Random file change
|
||||
*/
|
||||
public Single<Media> getRandomMedia() {
|
||||
return getRecentChanges()
|
||||
.flatMapSingle(change -> getRandomMediaFromRecentChange(change))
|
||||
.filter(media -> !StringUtils.isBlank(media.getFilename())
|
||||
&& !getReviewStatus(media.getPageId()) // Check if the image has already been shown to the user
|
||||
)
|
||||
.firstOrError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a proper Media object if the file is not already nominated for deletion
|
||||
* Else it returns an empty Media object
|
||||
*
|
||||
* @param recentChange
|
||||
* @return
|
||||
*/
|
||||
private Single<Media> getRandomMediaFromRecentChange(MwQueryPage recentChange) {
|
||||
return Single.just(recentChange)
|
||||
.flatMap(change -> mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/" + change.title()))
|
||||
.flatMap(isDeleted -> {
|
||||
if (isDeleted) {
|
||||
return Single.error(new Exception(recentChange.title() + " is deleted"));
|
||||
}
|
||||
return mediaClient.getMedia(recentChange.title());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the image exists in the reviewed images entity
|
||||
*
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
@VisibleForTesting
|
||||
Boolean getReviewStatus(String image){
|
||||
if(dao == null){
|
||||
return false;
|
||||
}
|
||||
return Observable.fromCallable(()-> dao.isReviewedAlready(image))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread()).blockingSingle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first revision of the file from filename
|
||||
*
|
||||
* @param filename
|
||||
* @return
|
||||
*/
|
||||
public Observable<MwQueryPage.Revision> getFirstRevisionOfFile(String filename) {
|
||||
return reviewInterface.getFirstRevisionOfFile(filename)
|
||||
.map(response -> response.query().firstPage().revisions().get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks Whether Given File is used in any Wiki page or not
|
||||
* by calling api for given file
|
||||
*
|
||||
* @param filename
|
||||
* @return
|
||||
*/
|
||||
Observable<Boolean> checkFileUsage(final String filename) {
|
||||
return reviewInterface.getGlobalUsageInfo(filename)
|
||||
.map(mwQueryResponse -> mwQueryResponse.query().firstPage()
|
||||
.checkWhetherFileIsUsedInWikis());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the change is reviewable or not.
|
||||
* - checks the type and revisionId of the change
|
||||
* - checks supported image extensions
|
||||
*
|
||||
* @param recentChange
|
||||
* @return
|
||||
*/
|
||||
private boolean isChangeReviewable(MwQueryPage recentChange) {
|
||||
for (String extension : imageExtensions) {
|
||||
if (recentChange.title().endsWith(extension)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds reviewed/skipped images to the database
|
||||
*
|
||||
* @param imageId
|
||||
*/
|
||||
public void addViewedImagesToDB(String imageId) {
|
||||
Completable.fromAction(() -> dao.insert(new ReviewEntity(imageId)))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(() -> {
|
||||
// Inserted successfully
|
||||
Timber.i("Image inserted successfully.");
|
||||
},
|
||||
throwable -> {
|
||||
Timber.e("Image not inserted into the reviewed images database");
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
138
app/src/main/java/fr/free/nrw/commons/review/ReviewHelper.kt
Normal file
138
app/src/main/java/fr/free/nrw/commons/review/ReviewHelper.kt
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
package fr.free.nrw.commons.review
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.media.MediaClient
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage.Revision
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
import timber.log.Timber
|
||||
import java.util.Collections
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class ReviewHelper @Inject constructor(
|
||||
private val mediaClient: MediaClient,
|
||||
private val reviewInterface: ReviewInterface
|
||||
) {
|
||||
@JvmField @Inject var dao: ReviewDao? = null
|
||||
|
||||
/**
|
||||
* Fetches recent changes from MediaWiki API
|
||||
* Calls the API to get the latest 50 changes
|
||||
* When more results are available, the query gets continued beyond this range
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private fun getRecentChanges() = reviewInterface.getRecentChanges()
|
||||
.map { it.query()?.pages() }
|
||||
.map(MutableList<MwQueryPage>::shuffled)
|
||||
.flatMapIterable { changes: List<MwQueryPage>? -> changes }
|
||||
.filter { isChangeReviewable(it) }
|
||||
|
||||
/**
|
||||
* Gets a random file change for review. Checks if the image has already been shown to the user
|
||||
* - Picks a random file from those changes
|
||||
* - Checks if the file is nominated for deletion
|
||||
* - Retries upto 5 times for getting a file which is not nominated for deletion
|
||||
*
|
||||
* @return Random file change
|
||||
*/
|
||||
fun getRandomMedia(): Single<Media> = getRecentChanges()
|
||||
.flatMapSingle(::getRandomMediaFromRecentChange)
|
||||
.filter { !it.filename.isNullOrBlank() && !getReviewStatus(it.pageId) }
|
||||
.firstOrError()
|
||||
|
||||
/**
|
||||
* Returns a proper Media object if the file is not already nominated for deletion
|
||||
* Else it returns an empty Media object
|
||||
*
|
||||
* @param recentChange
|
||||
* @return
|
||||
*/
|
||||
private fun getRandomMediaFromRecentChange(recentChange: MwQueryPage) =
|
||||
Single.just(recentChange)
|
||||
.flatMap { mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/${it.title()}") }
|
||||
.flatMap {
|
||||
if (it) {
|
||||
Single.error(Exception("${recentChange.title()} is deleted"))
|
||||
} else {
|
||||
mediaClient.getMedia(recentChange.title())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the image exists in the reviewed images entity
|
||||
*
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
fun getReviewStatus(image: String?): Boolean =
|
||||
dao?.isReviewedAlready(image) ?: false
|
||||
|
||||
/**
|
||||
* Gets the first revision of the file from filename
|
||||
*
|
||||
* @param filename
|
||||
* @return
|
||||
*/
|
||||
fun getFirstRevisionOfFile(filename: String?): Observable<Revision> =
|
||||
reviewInterface.getFirstRevisionOfFile(filename)
|
||||
.map { it.query()?.firstPage()?.revisions()?.get(0) }
|
||||
|
||||
/**
|
||||
* Checks Whether Given File is used in any Wiki page or not
|
||||
* by calling api for given file
|
||||
*
|
||||
* @param filename
|
||||
* @return
|
||||
*/
|
||||
fun checkFileUsage(filename: String?): Observable<Boolean> =
|
||||
reviewInterface.getGlobalUsageInfo(filename)
|
||||
.map { it.query()?.firstPage()?.checkWhetherFileIsUsedInWikis() }
|
||||
|
||||
/**
|
||||
* Checks if the change is reviewable or not.
|
||||
* - checks the type and revisionId of the change
|
||||
* - checks supported image extensions
|
||||
*
|
||||
* @param recentChange
|
||||
* @return
|
||||
*/
|
||||
private fun isChangeReviewable(recentChange: MwQueryPage): Boolean {
|
||||
for (extension in imageExtensions) {
|
||||
if (recentChange.title().endsWith(extension)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds reviewed/skipped images to the database
|
||||
*
|
||||
* @param imageId
|
||||
*/
|
||||
fun addViewedImagesToDB(imageId: String?) {
|
||||
Completable.fromAction { dao!!.insert(ReviewEntity(imageId)) }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{
|
||||
// Inserted successfully
|
||||
Timber.i("Image inserted successfully.")
|
||||
}
|
||||
) { throwable: Throwable? -> Timber.e("Image not inserted into the reviewed images database") }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val imageExtensions = arrayOf(".jpg", ".jpeg", ".png")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
package fr.free.nrw.commons.wikidata;
|
||||
|
||||
import static fr.free.nrw.commons.di.NetworkingModule.NAMED_COMMONS_CSRF;
|
||||
import static fr.free.nrw.commons.media.MediaClientKt.PAGE_ID_PREFIX;
|
||||
|
||||
import fr.free.nrw.commons.upload.UploadResult;
|
||||
import fr.free.nrw.commons.upload.WikiBaseInterface;
|
||||
import io.reactivex.Observable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient;
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwPostResponse;
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Wikibase Client for calling WikiBase APIs
|
||||
*/
|
||||
@Singleton
|
||||
public class WikiBaseClient {
|
||||
|
||||
private final WikiBaseInterface wikiBaseInterface;
|
||||
private final CsrfTokenClient csrfTokenClient;
|
||||
|
||||
@Inject
|
||||
public WikiBaseClient(WikiBaseInterface wikiBaseInterface,
|
||||
@Named(NAMED_COMMONS_CSRF) CsrfTokenClient csrfTokenClient) {
|
||||
this.wikiBaseInterface = wikiBaseInterface;
|
||||
this.csrfTokenClient = csrfTokenClient;
|
||||
}
|
||||
|
||||
public Observable<Boolean> postEditEntity(String fileEntityId, String data) {
|
||||
return csrfToken()
|
||||
.switchMap(editToken -> wikiBaseInterface.postEditEntity(fileEntityId, editToken, data)
|
||||
.map(response -> (response.getSuccessVal() == 1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the server call for posting new depicts
|
||||
*
|
||||
* @param filename name of the file
|
||||
* @param data data of the depicts to be uploaded
|
||||
* @return Observable<Boolean>
|
||||
*/
|
||||
public Observable<Boolean> postEditEntityByFilename(final String filename, final String data) {
|
||||
return csrfToken()
|
||||
.switchMap(editToken -> wikiBaseInterface.postEditEntityByFilename(filename,
|
||||
editToken, data)
|
||||
.map(response -> (response.getSuccessVal() == 1)));
|
||||
}
|
||||
|
||||
public Observable<Long> getFileEntityId(UploadResult uploadResult) {
|
||||
return wikiBaseInterface.getFileEntityId(uploadResult.createCanonicalFileName())
|
||||
.map(response -> (long) (response.query().pages().get(0).pageId()));
|
||||
}
|
||||
|
||||
public Observable<MwPostResponse> addLabelstoWikidata(long fileEntityId,
|
||||
String languageCode, String captionValue) {
|
||||
return csrfToken()
|
||||
.switchMap(editToken -> wikiBaseInterface
|
||||
.addLabelstoWikidata(PAGE_ID_PREFIX + fileEntityId, editToken, languageCode,
|
||||
captionValue));
|
||||
|
||||
}
|
||||
|
||||
private Observable<String> csrfToken() {
|
||||
return Observable.fromCallable(() -> {
|
||||
try {
|
||||
return csrfTokenClient.getTokenBlocking();
|
||||
} catch (Throwable throwable) {
|
||||
Timber.e(throwable);
|
||||
return "";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package fr.free.nrw.commons.wikidata
|
||||
|
||||
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient
|
||||
import fr.free.nrw.commons.di.NetworkingModule
|
||||
import fr.free.nrw.commons.media.PAGE_ID_PREFIX
|
||||
import fr.free.nrw.commons.upload.UploadResult
|
||||
import fr.free.nrw.commons.upload.WikiBaseInterface
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwPostResponse
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
|
||||
import io.reactivex.Observable
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Wikibase Client for calling WikiBase APIs
|
||||
*/
|
||||
@Singleton
|
||||
class WikiBaseClient @Inject constructor(
|
||||
private val wikiBaseInterface: WikiBaseInterface,
|
||||
@param:Named(NetworkingModule.NAMED_COMMONS_CSRF) private val csrfTokenClient: CsrfTokenClient
|
||||
) {
|
||||
fun postEditEntity(fileEntityId: String?, data: String?): Observable<Boolean> {
|
||||
return csrfToken().switchMap { editToken ->
|
||||
wikiBaseInterface.postEditEntity(fileEntityId!!, editToken, data!!)
|
||||
.map { response: MwPostResponse -> response.successVal == 1 }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the server call for posting new depicts
|
||||
*
|
||||
* @param filename name of the file
|
||||
* @param data data of the depicts to be uploaded
|
||||
* @return Observable<Boolean>
|
||||
</Boolean> */
|
||||
fun postEditEntityByFilename(filename: String?, data: String?): Observable<Boolean> {
|
||||
return csrfToken().switchMap { editToken ->
|
||||
wikiBaseInterface.postEditEntityByFilename(filename!!, editToken, data!!)
|
||||
.map { response: MwPostResponse -> response.successVal == 1 }
|
||||
}
|
||||
}
|
||||
|
||||
fun getFileEntityId(uploadResult: UploadResult): Observable<Long> {
|
||||
return wikiBaseInterface.getFileEntityId(uploadResult.createCanonicalFileName())
|
||||
.map { response: MwQueryResponse -> response.query()!!.pages()!![0].pageId().toLong() }
|
||||
}
|
||||
|
||||
fun addLabelstoWikidata(fileEntityId: Long, languageCode: String?, captionValue: String?): Observable<MwPostResponse> {
|
||||
return csrfToken().switchMap { editToken ->
|
||||
wikiBaseInterface.addLabelstoWikidata(
|
||||
PAGE_ID_PREFIX + fileEntityId,
|
||||
editToken,
|
||||
languageCode,
|
||||
captionValue
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun csrfToken(): Observable<String> = Observable.fromCallable {
|
||||
try {
|
||||
csrfTokenClient.getTokenBlocking()
|
||||
} catch (throwable: Throwable) {
|
||||
Timber.e(throwable)
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
package fr.free.nrw.commons.wikidata;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import fr.free.nrw.commons.wikidata.model.AddEditTagResponse;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.ObservableSource;
|
||||
import fr.free.nrw.commons.wikidata.model.Statement_partial;
|
||||
|
||||
@Singleton
|
||||
public class WikidataClient {
|
||||
|
||||
|
||||
private final WikidataInterface wikidataInterface;
|
||||
private final Gson gson;
|
||||
|
||||
@Inject
|
||||
public WikidataClient(WikidataInterface wikidataInterface, final Gson gson) {
|
||||
this.wikidataInterface = wikidataInterface;
|
||||
this.gson = gson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create wikidata claim to add P18 value
|
||||
*
|
||||
* @return revisionID of the edit
|
||||
*/
|
||||
Observable<Long> setClaim(Statement_partial claim, String tags) {
|
||||
return getCsrfToken()
|
||||
.flatMap(
|
||||
csrfToken -> wikidataInterface.postSetClaim(gson.toJson(claim), tags, csrfToken))
|
||||
.map(mwPostResponse -> mwPostResponse.getPageinfo().getLastrevid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get csrf token for wikidata edit
|
||||
*/
|
||||
@NotNull
|
||||
private Observable<String> getCsrfToken() {
|
||||
return wikidataInterface.getCsrfToken()
|
||||
.map(mwQueryResponse -> mwQueryResponse.query().csrfToken());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package fr.free.nrw.commons.wikidata
|
||||
|
||||
import com.google.gson.Gson
|
||||
import fr.free.nrw.commons.wikidata.model.Statement_partial
|
||||
import fr.free.nrw.commons.wikidata.model.WbCreateClaimResponse
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
|
||||
import io.reactivex.Observable
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class WikidataClient @Inject constructor(
|
||||
private val wikidataInterface: WikidataInterface,
|
||||
private val gson: Gson
|
||||
) {
|
||||
/**
|
||||
* Create wikidata claim to add P18 value
|
||||
*
|
||||
* @return revisionID of the edit
|
||||
*/
|
||||
fun setClaim(claim: Statement_partial?, tags: String?): Observable<Long> {
|
||||
return csrfToken().flatMap { csrfToken: String? ->
|
||||
wikidataInterface.postSetClaim(gson.toJson(claim), tags!!, csrfToken!!)
|
||||
}.map { mwPostResponse: WbCreateClaimResponse -> mwPostResponse.pageinfo.lastrevid }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get csrf token for wikidata edit
|
||||
*/
|
||||
private fun csrfToken(): Observable<String?> =
|
||||
wikidataInterface.getCsrfToken().map { it.query()?.csrfToken() }
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ class UserClientTest{
|
|||
Mockito.`when`(userInterface!!.getUserBlockInfo())
|
||||
.thenReturn(Observable.just(mockResponse))
|
||||
|
||||
val isBanned = userClient!!.isUserBlockedFromCommons.blockingGet()
|
||||
val isBanned = userClient!!.isUserBlockedFromCommons().blockingGet()
|
||||
assertTrue(isBanned)
|
||||
}
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ class UserClientTest{
|
|||
Mockito.`when`(userInterface!!.getUserBlockInfo())
|
||||
.thenReturn(Observable.just(mockResponse))
|
||||
|
||||
val isBanned = userClient!!.isUserBlockedFromCommons.blockingGet()
|
||||
val isBanned = userClient!!.isUserBlockedFromCommons().blockingGet()
|
||||
assertTrue(isBanned)
|
||||
}
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ class UserClientTest{
|
|||
Mockito.`when`(userInterface!!.getUserBlockInfo())
|
||||
.thenReturn(Observable.just(mockResponse))
|
||||
|
||||
val isBanned = userClient!!.isUserBlockedFromCommons.blockingGet()
|
||||
val isBanned = userClient!!.isUserBlockedFromCommons().blockingGet()
|
||||
assertFalse(isBanned)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,10 +111,10 @@ class ReviewActivityTest {
|
|||
val media = mock(Media::class.java)
|
||||
|
||||
doReturn(mapOf<String, Boolean>("test" to false)).`when`(media).categoriesHiddenStatus
|
||||
doReturn(Single.just(media)).`when`(reviewHelper)?.randomMedia
|
||||
Assert.assertNotNull(reviewHelper?.randomMedia)
|
||||
doReturn(Single.just(media)).`when`(reviewHelper)?.getRandomMedia()
|
||||
Assert.assertNotNull(reviewHelper?.getRandomMedia())
|
||||
reviewHelper
|
||||
?.randomMedia
|
||||
?.getRandomMedia()
|
||||
?.test()
|
||||
?.assertValue(media);
|
||||
activity.swipeToNext()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
package fr.free.nrw.commons.review
|
||||
|
||||
import androidx.room.Room.inMemoryDatabaseBuilder
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import fr.free.nrw.commons.TestCommonsApplication
|
||||
import fr.free.nrw.commons.db.AppDatabase
|
||||
import org.hamcrest.CoreMatchers
|
||||
import org.hamcrest.MatcherAssert
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.LooperMode
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@Config(sdk = [21], application = TestCommonsApplication::class)
|
||||
@LooperMode(LooperMode.Mode.PAUSED)
|
||||
class ReviewDaoTest {
|
||||
private lateinit var reviewDao: ReviewDao
|
||||
private lateinit var database: AppDatabase
|
||||
|
||||
/**
|
||||
* Set up the application database
|
||||
*/
|
||||
@Before
|
||||
fun createDb() {
|
||||
database = inMemoryDatabaseBuilder(
|
||||
context = ApplicationProvider.getApplicationContext(),
|
||||
klass = AppDatabase::class.java
|
||||
).allowMainThreadQueries().build()
|
||||
reviewDao = database.ReviewDao()
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the database
|
||||
*/
|
||||
@After
|
||||
fun closeDb() {
|
||||
database.close()
|
||||
}
|
||||
|
||||
/**
|
||||
* Test insertion
|
||||
* Also checks isReviewedAlready():
|
||||
* Case 1: When image has been reviewed/skipped by the user
|
||||
*/
|
||||
@Test
|
||||
fun insert() {
|
||||
// Insert data
|
||||
val imageId = "1234"
|
||||
val reviewEntity = ReviewEntity(imageId)
|
||||
reviewDao.insert(reviewEntity)
|
||||
|
||||
// Check insertion
|
||||
// Covers the case where the image exists in the database
|
||||
// And isReviewedAlready() returns true
|
||||
val isInserted = reviewDao.isReviewedAlready(imageId)
|
||||
MatcherAssert.assertThat(isInserted, CoreMatchers.equalTo(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isReviewedAlready() {
|
||||
/**
|
||||
* Test review status of the image
|
||||
* Case 2: When image has not been reviewed/skipped
|
||||
*/
|
||||
val imageId = "5856"
|
||||
val isInserted = reviewDao.isReviewedAlready(imageId)
|
||||
MatcherAssert.assertThat(isInserted, CoreMatchers.equalTo(false))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +1,32 @@
|
|||
package fr.free.nrw.commons.review
|
||||
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.media.MediaClient
|
||||
import io.reactivex.Completable
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResult
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers
|
||||
import org.mockito.InjectMocks
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.*
|
||||
import org.mockito.MockitoAnnotations
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResult
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
/**
|
||||
* Test class for ReviewHelper
|
||||
*/
|
||||
class ReviewHelperTest {
|
||||
|
||||
@Mock
|
||||
internal var reviewInterface: ReviewInterface? = null
|
||||
@Mock
|
||||
internal var mediaClient: MediaClient? = null
|
||||
private val reviewInterface = mock<ReviewInterface>()
|
||||
private val mediaClient = mock<MediaClient>()
|
||||
private val reviewHelper = ReviewHelper(mediaClient, reviewInterface)
|
||||
|
||||
@InjectMocks
|
||||
var reviewHelper: ReviewHelper? = null
|
||||
|
||||
val dao = mock(ReviewDao::class.java)
|
||||
private val mwQueryResult = mock<MwQueryResult>()
|
||||
private val mockResponse = mock<MwQueryResponse>()
|
||||
|
||||
/**
|
||||
* Init mocks
|
||||
|
|
@ -42,28 +34,8 @@ class ReviewHelperTest {
|
|||
@Before
|
||||
@Throws(Exception::class)
|
||||
fun setUp() {
|
||||
MockitoAnnotations.openMocks(this)
|
||||
|
||||
val mwQueryPage = mock(MwQueryPage::class.java)
|
||||
val mockRevision = mock(MwQueryPage.Revision::class.java)
|
||||
`when`(mockRevision.user).thenReturn("TestUser")
|
||||
`when`(mwQueryPage.revisions()).thenReturn(listOf(mockRevision))
|
||||
|
||||
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`(reviewInterface?.getRecentChanges())
|
||||
.thenReturn(Observable.just(mockResponse))
|
||||
|
||||
`when`(reviewInterface?.getFirstRevisionOfFile(ArgumentMatchers.anyString()))
|
||||
.thenReturn(Observable.just(mockResponse))
|
||||
|
||||
val media = mock(Media::class.java)
|
||||
whenever(media.filename).thenReturn("Test file.jpg")
|
||||
`when`(mediaClient?.getMedia(ArgumentMatchers.anyString()))
|
||||
.thenReturn(Single.just(media))
|
||||
whenever(mockResponse.query()).thenReturn(mwQueryResult)
|
||||
whenever(reviewInterface.getRecentChanges()).thenReturn(Observable.just(mockResponse))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -71,14 +43,19 @@ class ReviewHelperTest {
|
|||
*/
|
||||
@Test
|
||||
fun getRandomMedia() {
|
||||
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
|
||||
.thenReturn(Single.just(false))
|
||||
whenever(mediaClient.checkPageExistsUsingTitle(any())).thenReturn(Single.just(false))
|
||||
|
||||
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
|
||||
.thenReturn(Single.just(false))
|
||||
val page1 = setupMedia("one.jpg")
|
||||
val page2 = setupMedia("two.jpeg")
|
||||
val page3 = setupMedia("three.png")
|
||||
val ignored = setupMedia("ignored.txt")
|
||||
whenever(mwQueryResult.pages()).thenReturn(listOf(page1, page2, page3, ignored))
|
||||
|
||||
reviewHelper?.randomMedia
|
||||
verify(reviewInterface, times(1))!!.getRecentChanges()
|
||||
val random = reviewHelper.getRandomMedia().test()
|
||||
|
||||
random.assertNoErrors()
|
||||
assertEquals(1, random.valueCount())
|
||||
assertTrue(setOf("one.jpg", "two.jpeg", "three.png").contains(random.values().first().filename))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -86,9 +63,12 @@ class ReviewHelperTest {
|
|||
*/
|
||||
@Test(expected = RuntimeException::class)
|
||||
fun getRandomMediaWithWithAllMediaNominatedForDeletion() {
|
||||
`when`(mediaClient?.checkPageExistsUsingTitle(ArgumentMatchers.anyString()))
|
||||
.thenReturn(Single.just(true))
|
||||
val media = reviewHelper?.randomMedia?.blockingGet()
|
||||
whenever(mediaClient.checkPageExistsUsingTitle(any())).thenReturn(Single.just(true))
|
||||
|
||||
val page1 = setupMedia("one.jpg")
|
||||
whenever(mwQueryResult.pages()).thenReturn(listOf(page1))
|
||||
|
||||
val media = reviewHelper.getRandomMedia().blockingGet()
|
||||
assertNull(media)
|
||||
verify(reviewInterface, times(1))!!.getRecentChanges()
|
||||
}
|
||||
|
|
@ -98,15 +78,14 @@ class ReviewHelperTest {
|
|||
*/
|
||||
@Test
|
||||
fun getRandomMediaWithWithOneMediaNominatedForDeletion() {
|
||||
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test1.jpeg"))
|
||||
.thenReturn(Single.just(true))
|
||||
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test2.png"))
|
||||
.thenReturn(Single.just(false))
|
||||
`when`(mediaClient?.checkPageExistsUsingTitle("Commons:Deletion_requests/File:Test3.jpg"))
|
||||
.thenReturn(Single.just(true))
|
||||
whenever(mediaClient.checkPageExistsUsingTitle("Commons:Deletion_requests/one.jpg")).thenReturn(Single.just(true))
|
||||
|
||||
reviewHelper?.randomMedia
|
||||
verify(reviewInterface, times(1))!!.getRecentChanges()
|
||||
val page1 = setupMedia("one.jpg")
|
||||
whenever(mwQueryResult.pages()).thenReturn(listOf(page1))
|
||||
|
||||
val random = reviewHelper.getRandomMedia().test()
|
||||
|
||||
assertEquals("one.jpg is deleted", random.errors().first().message)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,57 +93,55 @@ class ReviewHelperTest {
|
|||
*/
|
||||
@Test
|
||||
fun getFirstRevisionOfFile() {
|
||||
val firstRevisionOfFile = reviewHelper?.getFirstRevisionOfFile("Test.jpg")?.blockingFirst()
|
||||
val rev1 = mock<MwQueryPage.Revision>()
|
||||
whenever(rev1.user).thenReturn("TestUser")
|
||||
whenever(rev1.revisionId).thenReturn(1L)
|
||||
val rev2 = mock<MwQueryPage.Revision>()
|
||||
whenever(rev2.user).thenReturn("TestUser")
|
||||
whenever(rev2.revisionId).thenReturn(2L)
|
||||
|
||||
assertTrue(firstRevisionOfFile is MwQueryPage.Revision)
|
||||
val page = setupMedia("Test.jpg", rev1, rev2)
|
||||
whenever(mwQueryResult.firstPage()).thenReturn(page)
|
||||
whenever(reviewInterface.getFirstRevisionOfFile(any())).thenReturn(Observable.just(mockResponse))
|
||||
|
||||
val firstRevisionOfFile = reviewHelper.getFirstRevisionOfFile("Test.jpg").blockingFirst()
|
||||
|
||||
assertEquals(1, firstRevisionOfFile.revisionId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the review status of the image
|
||||
* Case 1: Image identifier exists in the database
|
||||
*/
|
||||
@Test
|
||||
fun getReviewStatusWhenImageHasBeenReviewedAlready() {
|
||||
val testImageId1 = "123456"
|
||||
`when`(dao.isReviewedAlready(testImageId1)).thenReturn(true)
|
||||
fun checkFileUsage() {
|
||||
whenever(reviewInterface.getGlobalUsageInfo(any())).thenReturn(Observable.just(mockResponse))
|
||||
val page = setupMedia("Test.jpg")
|
||||
whenever(mwQueryResult.firstPage()).thenReturn(page)
|
||||
whenever(page.checkWhetherFileIsUsedInWikis()).thenReturn(true)
|
||||
|
||||
val observer = io.reactivex.observers.TestObserver<Boolean>()
|
||||
Observable.fromCallable(Callable<Boolean> {
|
||||
dao.isReviewedAlready(testImageId1)
|
||||
}).subscribeWith(observer)
|
||||
observer.assertValue(true)
|
||||
observer.dispose()
|
||||
val result = reviewHelper.checkFileUsage("Test.jpg").test()
|
||||
|
||||
assertTrue(result.values().first())
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the review status of the image
|
||||
* Case 2: Image identifier does not exist in the database
|
||||
*/
|
||||
@Test
|
||||
fun getReviewStatusWhenImageHasBeenNotReviewedAlready() {
|
||||
val testImageId2 = "789101"
|
||||
`when`(dao.isReviewedAlready(testImageId2)).thenReturn(false)
|
||||
fun testReviewStatus() {
|
||||
val reviewDao = mock<ReviewDao>()
|
||||
whenever(reviewDao.isReviewedAlready("Test.jpg")).thenReturn(true)
|
||||
|
||||
val observer = io.reactivex.observers.TestObserver<Boolean>()
|
||||
Observable.fromCallable(Callable<Boolean> {
|
||||
dao.isReviewedAlready(testImageId2)
|
||||
}).subscribeWith(observer)
|
||||
observer.assertValue(false)
|
||||
observer.dispose()
|
||||
reviewHelper.dao = reviewDao
|
||||
val result = reviewHelper.getReviewStatus("Test.jpg")
|
||||
|
||||
assertTrue(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the successful insertion of the image identifier into the database
|
||||
*/
|
||||
@Test
|
||||
fun addViewedImagesToDB() {
|
||||
val testImageId = "123456"
|
||||
private fun setupMedia(file: String, vararg revision: MwQueryPage.Revision): MwQueryPage = mock<MwQueryPage>().apply {
|
||||
whenever(title()).thenReturn(file)
|
||||
if (revision.isNotEmpty()) {
|
||||
whenever(revisions()).thenReturn(*revision.toMutableList())
|
||||
}
|
||||
|
||||
val observer = io.reactivex.observers.TestObserver<Boolean>()
|
||||
Completable.fromAction {
|
||||
dao.insert(ReviewEntity(testImageId))
|
||||
}.subscribeWith(observer)
|
||||
observer.assertComplete()
|
||||
observer.dispose()
|
||||
val media = mock<Media>().apply {
|
||||
whenever(filename).thenReturn(file)
|
||||
whenever(pageId).thenReturn(file.split(".").first())
|
||||
}
|
||||
whenever(mediaClient.getMedia(file)).thenReturn(Single.just(media))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,84 @@
|
|||
package fr.free.nrw.commons.wikidata
|
||||
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient
|
||||
import fr.free.nrw.commons.upload.UploadResult
|
||||
import fr.free.nrw.commons.upload.WikiBaseInterface
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwPostResponse
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse
|
||||
import fr.free.nrw.commons.wikidata.mwapi.MwQueryResult
|
||||
import io.reactivex.Observable
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import junit.framework.TestCase.assertSame
|
||||
import junit.framework.TestCase.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.InjectMocks
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.MockitoAnnotations
|
||||
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient
|
||||
import org.mockito.Mockito.mock
|
||||
|
||||
class WikiBaseClientUnitTest {
|
||||
|
||||
@Mock
|
||||
internal var csrfTokenClient: CsrfTokenClient? = null
|
||||
|
||||
@InjectMocks
|
||||
var wikiBaseClient: WikiBaseClient? = null
|
||||
private val csrfTokenClient: CsrfTokenClient = mock()
|
||||
private val wikiBaseInterface: WikiBaseInterface = mock()
|
||||
private val wikiBaseClient = WikiBaseClient(wikiBaseInterface, csrfTokenClient)
|
||||
|
||||
@Before
|
||||
@Throws(Exception::class)
|
||||
fun setUp() {
|
||||
MockitoAnnotations.openMocks(this)
|
||||
Mockito.`when`(csrfTokenClient!!.getTokenBlocking())
|
||||
.thenReturn("test")
|
||||
whenever(csrfTokenClient.getTokenBlocking()).thenReturn("test")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPostEditEntity() {
|
||||
val response = mock<MwPostResponse>()
|
||||
whenever(response.successVal).thenReturn(1)
|
||||
whenever(wikiBaseInterface.postEditEntity("the-id", "test", "the-data"))
|
||||
.thenReturn(Observable.just(response))
|
||||
|
||||
val result = wikiBaseClient.postEditEntity("the-id", "the-data").blockingFirst()
|
||||
|
||||
assertTrue(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPostEditEntityByFilename() {
|
||||
wikiBaseClient?.postEditEntityByFilename("File:Example.jpg", "data")
|
||||
val response = mock<MwPostResponse>()
|
||||
whenever(response.successVal).thenReturn(1)
|
||||
whenever(wikiBaseInterface.postEditEntityByFilename("File:Example.jpg", "test", "the-data"))
|
||||
.thenReturn(Observable.just(response))
|
||||
|
||||
val result = wikiBaseClient.postEditEntityByFilename("File:Example.jpg", "the-data").blockingFirst()
|
||||
|
||||
assertTrue(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getFileEntityId() {
|
||||
val upload = UploadResult("result", "key", 0, "Example.jpg")
|
||||
|
||||
val response = mock<MwQueryResponse>()
|
||||
val query = mock<MwQueryResult>()
|
||||
val page = mock<MwQueryPage>()
|
||||
whenever(response.query()).thenReturn(query)
|
||||
whenever(query.pages()).thenReturn(mutableListOf(page))
|
||||
whenever(page.pageId()).thenReturn(123)
|
||||
whenever(wikiBaseInterface.getFileEntityId("File:Example.jpg"))
|
||||
.thenReturn(Observable.just(response))
|
||||
|
||||
val result = wikiBaseClient.getFileEntityId(upload).blockingFirst()
|
||||
|
||||
assertEquals(123L, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun addLabelstoWikidata() {
|
||||
val mwPostResponse = mock<MwPostResponse>()
|
||||
whenever(wikiBaseInterface.addLabelstoWikidata(
|
||||
"M123", "test", "en", "caption"
|
||||
)).thenReturn(Observable.just(mwPostResponse))
|
||||
|
||||
val result = wikiBaseClient.addLabelstoWikidata(123L, "en", "caption").blockingFirst()
|
||||
|
||||
assertSame(mwPostResponse, result)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package fr.free.nrw.commons.wikidata
|
|||
|
||||
import android.content.Context
|
||||
import com.google.gson.Gson
|
||||
import com.nhaarman.mockitokotlin2.anyOrNull
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.whenever
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore
|
||||
|
|
@ -61,7 +62,7 @@ class WikidataEditServiceTest {
|
|||
fun createImageClaim() {
|
||||
whenever(directKvStore.getBoolean("Picture_Has_Correct_Location", true))
|
||||
.thenReturn(true)
|
||||
whenever(wikibaseClient.getFileEntityId(any())).thenReturn(Observable.just(1L))
|
||||
whenever(wikibaseClient.getFileEntityId(anyOrNull())).thenReturn(Observable.just(1L))
|
||||
whenever(wikidataClient.setClaim(any(), anyString()))
|
||||
.thenReturn(Observable.just(1L))
|
||||
val wikidataPlace: WikidataPlace = mock()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue