Merge remote-tracking branch 'upstream/master' into refactorNearbyClassesMVP

This commit is contained in:
neslihanturan 2019-06-05 09:25:19 +03:00
commit c43b4949ed
33 changed files with 352 additions and 30 deletions

View file

@ -54,3 +54,6 @@ before_install:
- if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
openssl aes-256-cbc -K $encrypted_38ac1a5053f6_key -iv $encrypted_38ac1a5053f6_iv -in play.p12.enc -out play.p12 -d;
fi
notifications:
webhooks:
- https://wiki-commons.zulipchat.com/api/v1/external/travis?api_key=kn4a8YKNqHCBYp7EW2k463txMj35vReq&stream=travis-ci

View file

@ -60,7 +60,8 @@ dependencies {
testImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$KOTLIN_VERSION"
testImplementation "org.jetbrains.kotlin:kotlin-reflect:$KOTLIN_VERSION"
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:3.7.1'
testImplementation 'org.robolectric:robolectric:4.3'
testImplementation 'androidx.test:core:1.2.0'
testImplementation 'com.nhaarman:mockito-kotlin:1.5.0'
testImplementation 'com.squareup.okhttp3:mockwebserver:3.10.0'

View file

@ -70,7 +70,7 @@ public class NetworkingModule {
@Provides
@Singleton
public OkHttpJsonApiClient provideOkHttpJsonApiClient(OkHttpClient okHttpClient,
@Named("tools_force") HttpUrl toolsForgeUrl,
@Named("tools_forge") HttpUrl toolsForgeUrl,
@Named("default_preferences") JsonKvStore defaultKvStore,
Gson gson) {
return new OkHttpJsonApiClient(okHttpClient,
@ -91,7 +91,7 @@ public class NetworkingModule {
}
@Provides
@Named("tools_force")
@Named("tools_forge")
@NonNull
@SuppressWarnings("ConstantConditions")
public HttpUrl provideToolsForgeUrl() {

View file

@ -1,7 +1,9 @@
package fr.free.nrw.commons.mwapi;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@ -10,6 +12,7 @@ import org.wikipedia.dataclient.mwapi.MwQueryPage;
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
import org.wikipedia.dataclient.mwapi.RecentChange;
import org.wikipedia.util.DateUtil;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
@ -33,6 +36,7 @@ import fr.free.nrw.commons.nearby.model.NearbyResponse;
import fr.free.nrw.commons.nearby.model.NearbyResultItem;
import fr.free.nrw.commons.upload.FileUtils;
import fr.free.nrw.commons.utils.CommonsDateUtil;
import fr.free.nrw.commons.utils.ConfigUtils;
import fr.free.nrw.commons.wikidata.model.GetWikidataEditCountResponse;
import io.reactivex.Observable;
import io.reactivex.Single;
@ -84,6 +88,11 @@ public class OkHttpJsonApiClient {
urlBuilder
.addPathSegments("/uploadsbyuser.py")
.addQueryParameter("user", userName);
if (ConfigUtils.isBetaFlavour()) {
urlBuilder.addQueryParameter("labs", "commonswiki");
}
Request request = new Request.Builder()
.url(urlBuilder.build())
.build();
@ -91,8 +100,10 @@ public class OkHttpJsonApiClient {
return Single.fromCallable(() -> {
Response response = okHttpClient.newCall(request).execute();
if (response != null && response.isSuccessful()) {
if(!TextUtils.isEmpty(response.body().string().trim())){
return Integer.parseInt(response.body().string().trim());
}
}
return 0;
});
}
@ -103,6 +114,11 @@ public class OkHttpJsonApiClient {
urlBuilder
.addPathSegments("/wikidataedits.py")
.addQueryParameter("user", userName);
if (ConfigUtils.isBetaFlavour()) {
urlBuilder.addQueryParameter("labs", "commonswiki");
}
Request request = new Request.Builder()
.url(urlBuilder.build())
.build();
@ -131,7 +147,7 @@ public class OkHttpJsonApiClient {
*/
public Single<FeedbackResponse> getAchievements(String userName) {
final String fetchAchievementUrlTemplate =
wikiMediaToolforgeUrl + "/feedback.py";
wikiMediaToolforgeUrl + (ConfigUtils.isBetaFlavour() ? "/feedback.py?labs=commonswiki" : "/feedback.py");
return Single.fromCallable(() -> {
String url = String.format(
Locale.ENGLISH,

View file

@ -7,6 +7,7 @@ public class Prefs {
public static final String DEFAULT_LICENSE = "defaultLicense";
public static final String UPLOADS_SHOWING = "uploadsshowing";
public static final String IS_CONTRIBUTION_COUNT_CHANGED = "ccontributionCountChanged";
public static final String MANAGED_EXIF_TAGS = "managedExifTags";
public static class Licenses {
public static final String CC_BY_SA_3 = "CC BY-SA 3.0";

View file

@ -4,6 +4,7 @@ import android.Manifest;
import android.net.Uri;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.MultiSelectListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.SwitchPreference;
@ -14,6 +15,11 @@ import com.karumi.dexter.Dexter;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.single.BasePermissionListener;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
@ -59,6 +65,14 @@ public class SettingsFragment extends PreferenceFragment {
return true;
});
MultiSelectListPreference multiSelectListPref = (MultiSelectListPreference) findPreference("manageExifTags");
if (multiSelectListPref != null) {
multiSelectListPref.setOnPreferenceChangeListener((preference, newValue) -> {
defaultKvStore.putJson(Prefs.MANAGED_EXIF_TAGS, newValue);
return true;
});
}
final EditTextPreference uploadLimit = (EditTextPreference) findPreference("uploads");
int currentUploadLimit = defaultKvStore.getInt(Prefs.UPLOADS_SHOWING, 100);
uploadLimit.setText(Integer.toString(currentUploadLimit));

View file

@ -0,0 +1,38 @@
package fr.free.nrw.commons.ui.LongTitlePreferences;
import android.content.Context;
import android.preference.MultiSelectListPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
public class LongTitleMultiSelectListPreference extends MultiSelectListPreference {
/*
public LongTitleMultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public LongTitleMultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
*/
public LongTitleMultiSelectListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LongTitleMultiSelectListPreference(Context context) {
super(context);
}
@Override
protected void onBindView(View view)
{
super.onBindView(view);
TextView title= view.findViewById(android.R.id.title);
if (title != null) {
title.setSingleLine(false);
}
}
}

View file

@ -0,0 +1,43 @@
package fr.free.nrw.commons.upload;
import timber.log.Timber;
import static androidx.exifinterface.media.ExifInterface.*;
/**
* Support utils for EXIF metadata handling
*
*/
public class FileMetadataUtils {
/**
* Takes EXIF label from sharedPreferences as input and returns relevant EXIF tags
*
* @param pref EXIF sharedPreference label
* @return EXIF tags
*/
public static String[] getTagsFromPref(String pref) {
Timber.d("Retuning tags for pref:%s", pref);
switch (pref) {
case "Author":
return new String[]{TAG_ARTIST, TAG_CAMARA_OWNER_NAME};
case "Copyright":
return new String[]{TAG_COPYRIGHT};
case "Location":
return new String[]{TAG_GPS_LATITUDE, TAG_GPS_LATITUDE_REF,
TAG_GPS_LONGITUDE, TAG_GPS_LONGITUDE_REF,
TAG_GPS_ALTITUDE, TAG_GPS_ALTITUDE_REF};
case "Camera Model":
return new String[]{TAG_MAKE, TAG_MODEL};
case "Lens Model":
return new String[]{TAG_LENS_MAKE, TAG_LENS_MODEL, TAG_LENS_SPECIFICATION};
case "Serial Numbers":
return new String[]{TAG_BODY_SERIAL_NUMBER, TAG_LENS_SERIAL_NUMBER};
case "Software":
return new String[]{TAG_SOFTWARE};
default:
return new String[]{};
}
}
}

View file

@ -2,22 +2,34 @@ package fr.free.nrw.commons.upload;
import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import androidx.annotation.NonNull;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import androidx.exifinterface.media.ExifInterface;
import com.google.gson.reflect.TypeToken;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.caching.CacheController;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.mwapi.CategoryApi;
import fr.free.nrw.commons.settings.Prefs;
import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
@ -66,7 +78,10 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
/**
* Processes filePath coordinates, either from EXIF data or user location
*/
GPSExtractor processFileCoordinates(SimilarImageInterface similarImageInterface) {
GPSExtractor processFileCoordinates(SimilarImageInterface similarImageInterface, Context context) {
// Redact EXIF data as indicated in preferences.
redactExifTags(exifInterface, getExifTagsToRedact(context));
Timber.d("Calling GPSExtractor");
imageObj = new GPSExtractor(exifInterface);
decimalCoords = imageObj.getCoords();
@ -81,6 +96,55 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
return imageObj;
}
/**
* Gets EXIF Tags from preferences to be redacted.
*
* @param context application context
* @return tags to be redacted
*/
private Set<String> getExifTagsToRedact(Context context) {
Type setType = new TypeToken<Set<String>>() {}.getType();
Set<String> prefManageEXIFTags = defaultKvStore.getJson(Prefs.MANAGED_EXIF_TAGS, setType);
Set<String> redactTags = new HashSet<>(Arrays.asList(
context.getResources().getStringArray(R.array.pref_exifTag_values)));
Timber.d(redactTags.toString());
if (prefManageEXIFTags != null) redactTags.removeAll(prefManageEXIFTags);
return redactTags;
}
/**
* Redacts EXIF metadata as indicated in preferences.
*
* @param exifInterface ExifInterface object
* @param redactTags tags to be redacted
*/
public static void redactExifTags(ExifInterface exifInterface, Set<String> redactTags) {
if(redactTags.isEmpty()) return;
Disposable disposable = Observable.fromIterable(redactTags)
.flatMap(tag -> Observable.fromArray(FileMetadataUtils.getTagsFromPref(tag)))
.forEach(tag -> {
Timber.d("Checking for tag: %s", tag);
String oldValue = exifInterface.getAttribute(tag);
if (oldValue != null && !oldValue.isEmpty()) {
Timber.d("Exif tag %s with value %s redacted.", tag, oldValue);
exifInterface.setAttribute(tag, null);
}
});
CompositeDisposable disposables = new CompositeDisposable();
disposables.add(disposable);
disposables.clear();
try {
exifInterface.saveAttributes();
} catch (IOException e) {
Timber.w("EXIF redaction failed: %s", e.toString());
}
}
/**
* Find other images around the same location that were taken within the last 20 sec
* @param similarImageInterface

View file

@ -109,7 +109,7 @@ public class UploadModel {
createdTimestampSource = dateTimeWithSource.getSource();
}
Timber.d("File created date is %d", fileCreatedDate);
GPSExtractor gpsExtractor = fileProcessor.processFileCoordinates(similarImageInterface);
GPSExtractor gpsExtractor = fileProcessor.processFileCoordinates(similarImageInterface, context);
return new UploadItem(uploadableFile.getContentUri(), Uri.parse(uploadableFile.getFilePath()), uploadableFile.getMimeType(context), source, gpsExtractor, place, fileCreatedDate, createdTimestampSource);
}

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Authors:
* 4nn1l2
* Abijeet Patro
* Amirsara
* Arash.pt
@ -175,13 +176,15 @@
<string name="detail_discussion_empty">بدون بحث</string>
<string name="detail_license_empty">مجوز ناشناخته</string>
<string name="menu_refresh">تازه‌کردن</string>
<string name="storage_permission_title">درخواست اجازهٔ ذخیره‌سازی</string>
<string name="read_storage_permission_rationale">اجازه‌های مورد نیاز: مطالعهٔ حافظهٔ خارجی. اپلیکیشن بدون آن نمی‌تواند کار کند.</string>
<string name="write_storage_permission_rationale" fuzzy="true">اجازه‌های مورد نیاز: نوشتن در حافظهٔ خارجی. اپلیکیشن نمیتواند به دبین دسترسی داشته باشد.</string>
<string name="write_storage_permission_rationale">اجازه‌های مورد نیاز: نوشتن در حافظهٔ خارجی. اپلیکیشن نمیتواند به دوربین/گالری دسترسی داشته باشد.</string>
<string name="location_permission_rationale">اجازه‌های اختیاری: دریافت موقعیت برای پیشنهاد رده</string>
<string name="ok">تأیید</string>
<string name="title_activity_nearby">مکان‌‌های اطراف</string>
<string name="no_nearby">مکانی در نزدیکی یافت نشد</string>
<string name="warning">هشدار</string>
<string name="upload_image_duplicate">پرونده در ویکی‌انبار موجود است. آیا مطمئنید که می‌خواهید ادامه دهید؟</string>
<string name="yes">بله</string>
<string name="no">خیر</string>
<string name="media_detail_title">عنوان</string>
@ -201,7 +204,8 @@
<string name="invalid_input">ورودی نامعتبر</string>
<string name="maximum_limit_alert">عدم توانایی در نمایش بیش از ۵۰۰ مورد</string>
<string name="enter_valid">عدد معتبر را وارد کنید</string>
<string name="set_limit" fuzzy="true">تنظیم محدودیت بارگذاری‌های اخیر</string>
<string name="cannot_be_zero">حد بارگذاری نمی‌تواند ۰ باشد</string>
<string name="set_limit">محدودیت بارگذاری اخیر</string>
<string name="login_failed_2fa_not_supported">تأیید دومرحله‌ای الان پشتیبانی نمی‌شود.</string>
<string name="logout_verification">آیا واقعاً قصد خروج از سامانه را دارید؟</string>
<string name="commons_logo">نشان ویکی‌انبار</string>
@ -245,11 +249,16 @@
<string name="error_while_cache">خطا در زمان دریافت تصاویر</string>
<string name="title_info">عنوانی توصیفی و یکتا برای پرونده که به عنوان نام پرونده در نظر گرفته خواهد شد. ترجیحاً به زبان ساده باشد، می‌توانید فاصله هم به کار ببرید. پسوند پرونده را ننویسید.</string>
<string name="description_info">لطفاً تصویر را تا حد توان شرح دهید. کجا گرفته شده‌است؟ شامل چه چیزی می‌شود؟ لطفاً اشیا یا افراد را شرح دهید. اطلاعاتی که به راحتی قابل مشاهده هستند را صرفه‌نظر کنید. اگر چیزی در تصویر غیر طبیعی به نظر می‌رسد آن را شرح دهید.</string>
<string name="upload_image_too_dark">این تصویر خیلی تار است. آیا مطمئنید که می‌خواهید آن را بارگذاری کنید؟ ویکی‌انبار فقط برای نگهداری از تصاویری است که ارزش دانشنامه‌ای داشته باشند.</string>
<string name="upload_image_blurry">این تصویر خیلی محو است. آیا مطمئنید که می‌خواهید آن را بارگذاری کنید؟ ویکی‌انبار فقط برای نگهداری از تصاویری است که ارزش دانشنامه‌ای داشته باشند.</string>
<string name="upload_problem_exist">مشکلات احتمالی با این تصویر :</string>
<string name="upload_problem_image_dark">تصویر بیش از حد تاریک است.</string>
<string name="upload_problem_image_blurry">تصویر تار است.</string>
<string name="upload_problem_image_duplicate">تصویر اکنون در انبار موجود است.</string>
<string name="upload_problem_different_geolocation">این تصویر در مکان متفاوتی گرفته شده است.</string>
<string name="upload_problem_fbmd">لطفاً فقط تصاویری را بارگذاری کنید که خودتان گرفته‌اید. تصاویری را که در فیس‌بوک دیگران پیدا کرده‌اید بارگذاری نکنید.</string>
<string name="upload_problem_do_you_continue">هنوزم می خوای این عکس رو آپلود کنی؟</string>
<string name="internet_downloaded">لطفاً فقط تصاویری را بارگذاری کنید که خودتان گرفته‌اید. تصاویری را که از اینترنت بارگیری کرده‌اید بارگذاری نکنید.</string>
<string name="give_permission">اجازه بده</string>
<string name="use_external_storage">استفاده از حافظهٔ خارجی</string>
<string name="use_external_storage_summary">ذخیرهٔ تصویرهای گرفته شده توسط دوربین درونکار اپلیکیشن بر روی دستگاه شما</string>
@ -261,6 +270,8 @@
<string name="nominate_deletion">نامزد شده برای حذف</string>
<string name="nominated_for_deletion">این تصویر برای حذف شدن علامت گذاری شده.</string>
<string name="nominated_see_more"> .</string>
<string name="nominating_file_for_deletion">نامزد حذف کردن %1$s.</string>
<string name="nominating_for_deletion_status">نامزد حذف کردن: %1$s</string>
<string name="view_browser">مشاهده در مرورگر</string>
<string name="skip_login">رها کردن</string>
<string name="navigation_item_login">ورود به سامانه</string>
@ -268,6 +279,7 @@
<string name="skip_login_message">برای بارگذاری تصاویر در آینده شما باید وارد حساب کاربری خود شوید.</string>
<string name="login_alert_message">لطفا برای استفاده از این ویژگی وارد شوید</string>
<string name="copy_wikicode">از ویکی واژه به کلیپ برد کپی کنید.</string>
<string name="wikicode_copied">ویکی‌متن در کلیپ‌بورد کپی شد</string>
<string name="nearby_location_has_not_changed">مکان تغییر نکرده‌است.</string>
<string name="nearby_location_not_available">مکان موجود نیست.</string>
<string name="location_permission_rationale_nearby">برای نمایش مکان‌ّای اطراف نیاز به اجازه است.</string>
@ -404,4 +416,5 @@
<string name="menu_option_unread">مشاهده خوانده نشده ها</string>
<string name="image_chooser_title">انتخاب تصویر برای بارگذاری</string>
<string name="please_wait">لطفاً صبر کنید...</string>
<string name="image_info">اطلاعات عکس</string>
</resources>

View file

@ -65,7 +65,7 @@
<string name="provider_categories">حالیہ ورتیاں ڳیاں ونکیاں</string>
<string name="menu_retry_upload">ولدا کوشش کرو</string>
<string name="menu_cancel_upload">منسوخ</string>
<string name="menu_download">ڈاؤن لوڈ ، لہاوݨ</string>
<string name="menu_download">ڈاؤن لوڈ کرو ، لہاؤ</string>
<string name="preference_license">پہلے طے تھیا لائسنس</string>
<string name="preference_theme">رات آلا مزاج</string>
<string name="preference_theme_summary">گھاٹا تھیم ورتو</string>

View file

@ -14,4 +14,25 @@
<item>@string/license_pref_cc_by_sa_3_0</item>
<item>@string/license_pref_cc_by_sa_4_0</item>
</array>
<!--TODO add more EXIF tags-->
<array name="pref_exifTag_entries">
<item>@string/exif_tag_name_author</item>
<item>@string/exif_tag_name_copyright</item>
<item>@string/exif_tag_name_location</item>
<item>@string/exif_tag_name_cameraModel</item>
<item>@string/exif_tag_name_lensModel</item>
<item>@string/exif_tag_name_serialNumbers</item>
<item>@string/exif_tag_name_software</item>
</array>
<array name="pref_exifTag_values">
<item>@string/exif_tag_author</item>
<item>@string/exif_tag_copyright</item>
<item>@string/exif_tag_location</item>
<item>@string/exif_tag_cameraModel</item>
<item>@string/exif_tag_lensModel</item>
<item>@string/exif_tag_serialNumbers</item>
<item>@string/exif_tag_software</item>
</array>
</resources>

View file

@ -5,4 +5,13 @@
<string name="license_pref_cc_by_sa_3_0" translatable="false">CC BY-SA 3.0</string>
<string name="license_pref_cc_by_4_0" translatable="false">CC BY 4.0</string>
<string name="license_pref_cc_by_sa_4_0" translatable="false">CC BY-SA 4.0</string>
<string name="exif_tag_author" translatable="false">Author</string>
<string name="exif_tag_copyright" translatable="false">Copyright</string>
<string name="exif_tag_location" translatable="false">Location</string>
<string name="exif_tag_cameraModel" translatable="false">Camera Model</string>
<string name="exif_tag_lensModel" translatable="false">Lens Model</string>
<string name="exif_tag_serialNumbers" translatable="false">Serial Numbers</string>
<string name="exif_tag_software" translatable="false">Software</string>
</resources>

View file

@ -5,6 +5,7 @@
<string name="preference_category_appearance">Appearance</string>
<string name="preference_category_general">General</string>
<string name="preference_category_feedback">Feedback</string>
<string name="preference_category_privacy">Privacy</string>
<string name="preference_category_location">Location</string>
<string name="app_name">Commons</string>
<string name="bullet">&#8226; </string>
@ -537,6 +538,18 @@ Upload your first media by tapping on the add button.</string>
<string name="welcome_dont_upload_content_description">Examples of images not to upload</string>
<string name="skip_image">SKIP THIS IMAGE</string>
<string name="download_failed_we_cannot_download_the_file_without_storage_permission">Download Failed!!. We cannot download the file without external storage permission.</string>
<string name="manage_exif_tags">Manage EXIF Tags</string>
<string name="manage_exif_tags_summary">Select which EXIF tags to keep in uploads</string>
<string name="exif_tag_name_author">Author</string>
<string name="exif_tag_name_copyright">Copyright</string>
<string name="exif_tag_name_location">Location</string>
<string name="exif_tag_name_cameraModel">Camera Model</string>
<string name="exif_tag_name_lensModel">Lens Model</string>
<string name="exif_tag_name_serialNumbers">Serial Numbers</string>
<string name="exif_tag_name_software">Software</string>
<string name="share_text">Upload photos to Wikimedia Commons on your phone Download the Commons app: %1$s</string>
<string name="share_via">Share app via...</string>
<string name="image_info">Image Info</string>

View file

@ -59,6 +59,18 @@
</fr.free.nrw.commons.ui.LongTitlePreferences.LongTitlePreferenceCategory>
<fr.free.nrw.commons.ui.LongTitlePreferences.LongTitlePreferenceCategory
android:title="@string/preference_category_privacy">
<fr.free.nrw.commons.ui.LongTitlePreferences.LongTitleMultiSelectListPreference
android:entries="@array/pref_exifTag_entries"
android:entryValues="@array/pref_exifTag_values"
android:key="manageExifTags"
android:title="@string/manage_exif_tags"
android:summary="@string/manage_exif_tags_summary"/>
</fr.free.nrw.commons.ui.LongTitlePreferences.LongTitlePreferenceCategory>
<!-- The key 'allowGps' was used before and has since been removed based on the discussion at #1599.
Do not reuse this key unless you revive the same feature with the changes mentioned at #1599.-->

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

View file

@ -4,7 +4,7 @@ import fr.free.nrw.commons.mwapi.MediaResult
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
import io.reactivex.Single
import junit.framework.Assert.assertTrue
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentMatchers

View file

@ -7,7 +7,7 @@ import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = intArrayOf(21), application = TestCommonsApplication::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class MediaTest {
@Test
fun displayTitleShouldStripExtension() {

View file

@ -2,15 +2,15 @@ package fr.free.nrw.commons
import fr.free.nrw.commons.location.LatLng
import fr.free.nrw.commons.nearby.NearbyController.loadAttractionsFromLocationToBaseMarkerOptions
import androidx.test.core.app.ApplicationProvider
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class NearbyControllerTest {
@Test
@ -18,7 +18,7 @@ class NearbyControllerTest {
val location = LatLng(0.0, 0.0, 0f)
val options = loadAttractionsFromLocationToBaseMarkerOptions(
location, null, RuntimeEnvironment.application, null)
location, null, ApplicationProvider.getApplicationContext(), null)
assertEquals(0, options.size.toLong())
}
@ -28,7 +28,7 @@ class NearbyControllerTest {
val location = LatLng(0.0, 0.0, 0f)
val options = loadAttractionsFromLocationToBaseMarkerOptions(
location, emptyList(), RuntimeEnvironment.application, emptyList())
location, emptyList(), ApplicationProvider.getApplicationContext(), emptyList())
assertEquals(0, options.size.toLong())
}

View file

@ -24,7 +24,7 @@ import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class BookMarkLocationDaoTest {
private val columns = arrayOf(COLUMN_NAME,
COLUMN_DESCRIPTION,

View file

@ -21,7 +21,7 @@ import org.junit.Before
import org.junit.Test
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class BookmarkPictureDaoTest {
private val columns = arrayOf(COLUMN_MEDIA_NAME, COLUMN_CREATOR)

View file

@ -21,7 +21,7 @@ import org.robolectric.annotation.Config
import java.util.*
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class CategoryDaoTest {
private val columns = arrayOf(COLUMN_ID, COLUMN_NAME, COLUMN_LAST_USED, COLUMN_TIMES_USED)

View file

@ -23,7 +23,7 @@ import org.robolectric.annotation.Config
import java.util.*
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class ContributionDaoTest {
private val localUri = "http://example.com/"
private val client: ContentProviderClient = mock()

View file

@ -7,7 +7,7 @@ import fr.free.nrw.commons.auth.SessionManager
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.notification.NotificationHelper
import fr.free.nrw.commons.utils.ViewUtilWrapper
import junit.framework.Assert.*
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.mockito.InjectMocks

View file

@ -21,7 +21,7 @@ import org.robolectric.annotation.Config
import java.util.*
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class RecentSearchesDaoTest {
private val columns = arrayOf(COLUMN_ID, COLUMN_NAME, COLUMN_LAST_USED)

View file

@ -20,7 +20,7 @@ import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [21], application = TestCommonsApplication::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class ModifierSequenceDaoTest {
private val mediaUrl = "http://example.com/"

View file

@ -1,8 +1,8 @@
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.BuildConfig
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.utils.ConfigUtils
@ -17,14 +17,13 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
import org.wikipedia.util.DateUtil
import java.net.URLDecoder
import java.util.*
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = intArrayOf(21), application = TestCommonsApplication::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class ApacheHttpClientMediaWikiApiTest {
private lateinit var testObject: ApacheHttpClientMediaWikiApi
@ -39,7 +38,7 @@ class ApacheHttpClientMediaWikiApiTest {
wikidataServer = MockWebServer()
okHttpClient = OkHttpClient()
sharedPreferences = mock(JsonKvStore::class.java)
testObject = ApacheHttpClientMediaWikiApi(RuntimeEnvironment.application, "http://" + server.hostName + ":" + server.port + "/", "http://" + wikidataServer.hostName + ":" + wikidataServer.port + "/", sharedPreferences, Gson())
testObject = ApacheHttpClientMediaWikiApi(ApplicationProvider.getApplicationContext(), "http://" + server.hostName + ":" + server.port + "/", "http://" + wikidataServer.hostName + ":" + wikidataServer.port + "/", sharedPreferences, Gson())
}
@After
@ -319,7 +318,7 @@ class ApacheHttpClientMediaWikiApiTest {
private fun assertBasicRequestParameters(server: MockWebServer, method: String): RecordedRequest = server.takeRequest().let {
assertEquals("/", it.requestUrl.encodedPath())
assertEquals(method, it.method)
assertEquals("Commons/${ConfigUtils.getVersionNameWithSha(RuntimeEnvironment.application)} (https://mediawiki.org/wiki/Apps/Commons) Android/${Build.VERSION.RELEASE}",
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"))

View file

@ -29,7 +29,7 @@ import kotlin.random.Random
* Mock web server based tests for ok http json api client
*/
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class, sdk = [23], application = TestCommonsApplication::class)
@Config(sdk = [23], application = TestCommonsApplication::class)
class OkHttpJsonApiClientTest {
private lateinit var testObject: OkHttpJsonApiClient

View file

@ -4,7 +4,7 @@ import fr.free.nrw.commons.Media
import fr.free.nrw.commons.mwapi.MediaWikiApi
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient
import io.reactivex.Single
import junit.framework.Assert.assertTrue
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.mockito.ArgumentMatchers

View file

@ -0,0 +1,23 @@
package fr.free.nrw.commons.upload
import androidx.exifinterface.media.ExifInterface.*
import junit.framework.Assert.assertTrue
import org.junit.Test
import java.util.*
/**
* Test cases for FileMetadataUtils
*/
class FileMetadataUtilsTest {
/**
* Test method to verify EXIF tags
*/
@Test
fun getTagsFromPref() {
val author = FileMetadataUtils.getTagsFromPref("Author")
val authorRef = arrayOf(TAG_ARTIST, TAG_CAMARA_OWNER_NAME);
assertTrue(Arrays.deepEquals(author, authorRef))
}
}

View file

@ -1,6 +1,7 @@
package fr.free.nrw.commons.upload
import android.content.SharedPreferences
import androidx.exifinterface.media.ExifInterface
import fr.free.nrw.commons.caching.CacheController
import fr.free.nrw.commons.mwapi.CategoryApi
import org.junit.Before
@ -11,6 +12,9 @@ import org.mockito.MockitoAnnotations
import javax.inject.Inject
import javax.inject.Named
import java.io.FileInputStream
import java.io.FileOutputStream
class FileProcessorTest {
@Mock
@ -35,4 +39,51 @@ class FileProcessorTest {
fun processFileCoordinates() {
}
/**
* Test method to verify redaction Exif metadata
*/
@Test
fun redactExifTags() {
/*
val filePathRef: String? = "src/test/data/exif_redact_sample.jpg"
val filePathTmp: String? = "" + System.getProperty("java.io.tmpdir") + "exif_redact_sample_tmp.jpg"
val inStream = FileInputStream(filePathRef)
val outStream = FileOutputStream(filePathTmp)
val inChannel = inStream.getChannel()
val outChannel = outStream.getChannel()
inChannel.transferTo(0, inChannel.size(), outChannel)
inStream.close()
outStream.close()
val redactTags = mutableSetOf("Author", "Copyright", "Location", "Camera Model",
"Lens Model", "Serial Numbers", "Software")
val exifInterface : ExifInterface? = ExifInterface(filePathTmp.toString())
var nonEmptyTag = false
for (redactTag in redactTags) {
for (tag in FileMetadataUtils.getTagsFromPref(redactTag)) {
val tagValue = exifInterface?.getAttribute(tag)
if(tagValue != null) {
nonEmptyTag = true
break
}
}
if (nonEmptyTag) break
}
// all tags are empty, can't test redaction
assert(nonEmptyTag)
FileProcessor.redactExifTags(exifInterface, redactTags)
for (redactTag in redactTags) {
for (tag in FileMetadataUtils.getTagsFromPref(redactTag)) {
val oldValue = exifInterface?.getAttribute(tag)
assert(oldValue == null)
}
}
*/
}
}

View file

@ -15,6 +15,7 @@
#Thu Mar 01 15:28:48 IST 2018
org.gradle.jvmargs=-Xmx1536M
android.enableBuildCache=true
android.enableUnitTestBinaryResources=true
KOTLIN_VERSION=1.3.21
BUTTERKNIFE_VERSION=10.1.0