Skip to content

Commit

Permalink
feat: use lc when querying server.
Browse files Browse the repository at this point in the history
Closes #3848

ref: renamed AbstractProductSearch to Search

fix: fixed Unit Tests using robolectric
  • Loading branch information
VaiTon committed Apr 7, 2021
1 parent 43b051c commit 2d9add6
Show file tree
Hide file tree
Showing 16 changed files with 216 additions and 196 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Expand Up @@ -175,6 +175,7 @@ dependencies {

// Unit Testing
testImplementation("junit:junit:4.13.2")
testImplementation("org.robolectric:robolectric:4.4")
testImplementation("org.mockito:mockito-core:3.8.0")
testImplementation("net.javacrumbs.json-unit:json-unit-fluent:2.24.0")
testImplementation("com.google.truth:truth:1.1.2")
Expand Down
Expand Up @@ -48,7 +48,6 @@ import openfoodfacts.github.scrachx.openfood.models.Product
import openfoodfacts.github.scrachx.openfood.models.ProductImageField
import openfoodfacts.github.scrachx.openfood.network.ApiFields
import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient
import openfoodfacts.github.scrachx.openfood.network.services.ProductsAPI
import openfoodfacts.github.scrachx.openfood.utils.*
import openfoodfacts.github.scrachx.openfood.utils.FileDownloader.download
import openfoodfacts.github.scrachx.openfood.utils.LocaleHelper.LanguageData
Expand Down Expand Up @@ -79,9 +78,6 @@ class ImagesManageActivity : BaseActivity() {
@Inject
lateinit var picasso: Picasso

@Inject
lateinit var productsApi: ProductsAPI

private val disp = CompositeDisposable()

private var lastViewedImage: File? = null
Expand Down Expand Up @@ -466,7 +462,7 @@ class ImagesManageActivity : BaseActivity() {

private fun editPhoto(productImageField: ProductImageField?, transformation: ImageTransformation) {
if (transformation.isNotEmpty()) {
download(this, transformation.imageUrl!!, productsApi)
download(this, transformation.imageUrl!!, client)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { file: File? ->
//to delete the file after:
Expand Down
Expand Up @@ -4,15 +4,15 @@ import android.content.Context
import android.widget.ArrayAdapter
import android.widget.Filter
import android.widget.Filterable
import openfoodfacts.github.scrachx.openfood.network.services.ProductsAPI
import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient
import org.apache.commons.lang3.StringUtils
import java.util.*

class EmbCodeAutoCompleteAdapter(
context: Context?,
context: Context,
textViewResourceId: Int,
private val productsApi: ProductsAPI
) : ArrayAdapter<String>(context!!, textViewResourceId), Filterable {
private val productsApi: OpenFoodAPIClient
) : ArrayAdapter<String>(context, textViewResourceId), Filterable {
private val codeList: MutableList<String> = arrayListOf()


Expand All @@ -28,7 +28,7 @@ class EmbCodeAutoCompleteAdapter(
if (constraint == null) return FilterResults().apply { count = 0 }

// Retrieve the autocomplete results from server.
val list = productsApi.getEMBCodeSuggestions(constraint.toString()).blockingGet()
val list = productsApi.rawApi.getEMBCodeSuggestions(constraint.toString()).blockingGet()

// Assign the data to the FilterResults
return FilterResults().apply {
Expand Down
Expand Up @@ -4,14 +4,14 @@ import android.content.Context
import android.widget.ArrayAdapter
import android.widget.Filter
import android.widget.Filterable
import openfoodfacts.github.scrachx.openfood.network.services.ProductsAPI
import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient
import org.apache.commons.lang3.StringUtils
import java.util.*

class PeriodAfterOpeningAutoCompleteAdapter(
context: Context?,
textViewResourceId: Int,
private val productsApi: ProductsAPI
private val client: OpenFoodAPIClient
) : ArrayAdapter<String>(context!!, textViewResourceId), Filterable {
private val periodsList = mutableListOf<String>()

Expand All @@ -26,7 +26,7 @@ class PeriodAfterOpeningAutoCompleteAdapter(
if (constraint == null) return FilterResults().apply { count = 0 }

// Retrieve the autocomplete results from server.
val list = productsApi.getPeriodAfterOpeningSuggestions(constraint.toString()).blockingGet()
val list = client.rawApi.getPeriodAfterOpeningSuggestions(constraint.toString()).blockingGet()

// Assign the data to the FilterResults
return FilterResults().apply {
Expand Down
Expand Up @@ -47,7 +47,7 @@ import openfoodfacts.github.scrachx.openfood.models.entities.allergen.AllergenNa
import openfoodfacts.github.scrachx.openfood.models.entities.allergen.AllergenNameDao
import openfoodfacts.github.scrachx.openfood.network.ApiFields
import openfoodfacts.github.scrachx.openfood.network.ApiFields.Keys.lcIngredientsKey
import openfoodfacts.github.scrachx.openfood.network.services.ProductsAPI
import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient
import openfoodfacts.github.scrachx.openfood.utils.*
import openfoodfacts.github.scrachx.openfood.utils.FileDownloader.download
import openfoodfacts.github.scrachx.openfood.utils.LocaleHelper.getLanguage
Expand All @@ -73,7 +73,7 @@ class ProductEditIngredientsFragment : ProductEditFragment() {
lateinit var picasso: Picasso

@Inject
lateinit var productsApi: ProductsAPI
lateinit var client: OpenFoodAPIClient

@Inject
lateinit var matomoAnalytics: MatomoAnalytics
Expand Down Expand Up @@ -324,7 +324,7 @@ class ProductEditIngredientsFragment : ProductEditFragment() {
imagePath == null -> editIngredientsImage()
photoFile != null -> cropRotateImage(photoFile, getString(R.string.ingredients_picture))
else -> {
download(requireContext(), imagePath!!, productsApi)
download(requireContext(), imagePath!!, client)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { file ->
photoFile = file
Expand Down
Expand Up @@ -54,7 +54,7 @@ import openfoodfacts.github.scrachx.openfood.models.entities.OfflineSavedProduct
import openfoodfacts.github.scrachx.openfood.network.ApiFields
import openfoodfacts.github.scrachx.openfood.network.ApiFields.Defaults.NUTRITION_DATA_PER_100G
import openfoodfacts.github.scrachx.openfood.network.ApiFields.Defaults.NUTRITION_DATA_PER_SERVING
import openfoodfacts.github.scrachx.openfood.network.services.ProductsAPI
import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient
import openfoodfacts.github.scrachx.openfood.utils.*
import openfoodfacts.github.scrachx.openfood.utils.FileDownloader.download
import openfoodfacts.github.scrachx.openfood.utils.UnitUtils.UNIT_IU
Expand Down Expand Up @@ -106,7 +106,7 @@ class ProductEditNutritionFactsFragment : ProductEditFragment() {
lateinit var picasso: Picasso

@Inject
lateinit var productsApi: ProductsAPI
lateinit var client: OpenFoodAPIClient

@Inject
lateinit var matomoAnalytics: MatomoAnalytics
Expand Down Expand Up @@ -409,7 +409,7 @@ class ProductEditNutritionFactsFragment : ProductEditFragment() {
if (photoFile != null) {
cropRotateImage(photoFile, getString(R.string.nutrition_facts_picture))
} else {
download(requireContext(), path, productsApi)
download(requireContext(), path, client)
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
photoFile = it
Expand Down
Expand Up @@ -38,7 +38,6 @@ import com.theartofdev.edmodo.cropper.CropImage
import dagger.hilt.android.AndroidEntryPoint
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.rxkotlin.addTo
import io.reactivex.schedulers.Schedulers
import openfoodfacts.github.scrachx.openfood.AppFlavors.OBF
import openfoodfacts.github.scrachx.openfood.AppFlavors.OFF
import openfoodfacts.github.scrachx.openfood.AppFlavors.OPF
Expand Down Expand Up @@ -72,7 +71,7 @@ import openfoodfacts.github.scrachx.openfood.models.entities.store.StoreNameDao
import openfoodfacts.github.scrachx.openfood.models.entities.tag.TagDao
import openfoodfacts.github.scrachx.openfood.network.ApiFields
import openfoodfacts.github.scrachx.openfood.network.ApiFields.Keys.lcProductNameKey
import openfoodfacts.github.scrachx.openfood.network.services.ProductsAPI
import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient
import openfoodfacts.github.scrachx.openfood.utils.*
import openfoodfacts.github.scrachx.openfood.utils.FileDownloader.download
import openfoodfacts.github.scrachx.openfood.utils.LocaleHelper.getLCOrDefault
Expand All @@ -97,7 +96,7 @@ class ProductEditOverviewFragment : ProductEditFragment() {
lateinit var picasso: Picasso

@Inject
lateinit var productsApi: ProductsAPI
lateinit var client: OpenFoodAPIClient

@Inject
lateinit var matomoAnalytics: MatomoAnalytics
Expand Down Expand Up @@ -530,7 +529,7 @@ class ProductEditOverviewFragment : ProductEditFragment() {
(operation.result as List<CountryName>).mapTo(countries) { it.name }

val adapter = ArrayAdapter(requireActivity(), android.R.layout.simple_dropdown_item_1line, countries)
val embAdapter = EmbCodeAutoCompleteAdapter(activity, android.R.layout.simple_dropdown_item_1line, productsApi)
val embAdapter = EmbCodeAutoCompleteAdapter(requireContext(), android.R.layout.simple_dropdown_item_1line, client)

binding.originOfIngredients.setAdapter(adapter)
binding.countryWherePurchased.setAdapter(adapter)
Expand Down Expand Up @@ -576,8 +575,11 @@ class ProductEditOverviewFragment : ProductEditFragment() {

if (isFlavors(OBF)) {
binding.periodOfTimeAfterOpeningTil.visibility = View.VISIBLE
val customAdapter = PeriodAfterOpeningAutoCompleteAdapter(activity,
android.R.layout.simple_dropdown_item_1line, productsApi)
val customAdapter = PeriodAfterOpeningAutoCompleteAdapter(
activity,
android.R.layout.simple_dropdown_item_1line,
client
)
binding.periodOfTimeAfterOpening.setAdapter(customAdapter)
}
}
Expand All @@ -598,8 +600,7 @@ class ProductEditOverviewFragment : ProductEditFragment() {
if (editionMode) {
loadFrontImage(lang)
val fields = "ingredients_text_$lang,product_name_$lang"
productsApi.getProductByBarcode(product!!.code, fields, getUserAgent(Utils.HEADER_USER_AGENT_SEARCH))
.subscribeOn(Schedulers.io())
client.getProductStateFull(product!!.code, fields)
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe {
binding.name.setText(getString(R.string.txtLoading))
Expand Down Expand Up @@ -652,7 +653,7 @@ class ProductEditOverviewFragment : ProductEditFragment() {
// Image found, download it if necessary and edit it
isFrontImagePresent = true
if (photoFile == null) {
download(requireContext(), frontImageUrl!!, productsApi)
download(requireContext(), frontImageUrl!!, client)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { file: File? ->
photoFile = file
Expand Down
Expand Up @@ -9,6 +9,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.text.HtmlCompat
import androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT
import androidx.core.text.bold
import com.squareup.picasso.Picasso
import dagger.hilt.android.AndroidEntryPoint
Expand All @@ -26,6 +27,7 @@ import openfoodfacts.github.scrachx.openfood.models.Nutriments
import openfoodfacts.github.scrachx.openfood.models.Product
import openfoodfacts.github.scrachx.openfood.models.ProductImageField
import openfoodfacts.github.scrachx.openfood.models.ProductState
import openfoodfacts.github.scrachx.openfood.network.ApiFields
import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient
import openfoodfacts.github.scrachx.openfood.utils.*
import java.io.File
Expand Down Expand Up @@ -99,15 +101,15 @@ class EnvironmentProductFragment : BaseFragment() {
if (carbonFootprintNutriment != null) {
binding.textCarbonFootprint.text = SpannableStringBuilder()
.bold { append(getString(R.string.textCarbonFootprint)) }
binding.textCarbonFootprint.append(carbonFootprintNutriment.for100gInUnits)
binding.textCarbonFootprint.append(carbonFootprintNutriment.unit)
.append(carbonFootprintNutriment.for100gInUnits)
.append(carbonFootprintNutriment.unit)
} else {
binding.carbonFootprintCv.visibility = View.GONE
}

val environmentInfoCard = product.environmentInfoCard
if (!environmentInfoCard.isNullOrEmpty()) {
binding.environmentInfoText.append(HtmlCompat.fromHtml(environmentInfoCard, HtmlCompat.FROM_HTML_MODE_COMPACT))
binding.environmentInfoText.append(HtmlCompat.fromHtml(environmentInfoCard, FROM_HTML_MODE_COMPACT))
binding.environmentInfoText.movementMethod = LinkMovementMethod.getInstance()
} else {
binding.environmentInfoCv.visibility = View.GONE
Expand All @@ -117,8 +119,8 @@ class EnvironmentProductFragment : BaseFragment() {
if (!packaging.isNullOrEmpty()) {
binding.packagingText.text = SpannableStringBuilder()
.bold { append(getString(R.string.packaging_environmentTab)) }
binding.packagingText.append(" ")
binding.packagingText.append(packaging.split(',').toString().removeSurrounding("[", "]"))
.append(" ")
.append(packaging.replace(",", ", "))
} else {
binding.packagingCv.visibility = View.GONE
}
Expand All @@ -128,7 +130,7 @@ class EnvironmentProductFragment : BaseFragment() {
// TODO: 02/03/2021 i18n
binding.recyclingInstructionToDiscard.text = SpannableStringBuilder()
.bold { append("Recycling instructions - To discard: ") }
binding.recyclingInstructionToDiscard.append(recyclingInstructionsToDiscard)
.append(recyclingInstructionsToDiscard)
} else {
binding.recyclingInstructionsDiscardCv.visibility = View.GONE
}
Expand All @@ -138,7 +140,7 @@ class EnvironmentProductFragment : BaseFragment() {
// TODO: 02/03/2021 i18n
binding.recyclingInstructionToRecycle.text = SpannableStringBuilder()
.bold { append("Recycling instructions - To recycle: ") }
binding.recyclingInstructionToRecycle.append(recyclingInstructionsToRecycle)
.append(recyclingInstructionsToRecycle)
} else {
binding.recyclingInstructionsRecycleCv.visibility = View.GONE
}
Expand Down Expand Up @@ -188,7 +190,7 @@ class EnvironmentProductFragment : BaseFragment() {
// Load into view
binding.addPhotoLabel.visibility = View.GONE
mUrlImage = photoFile.absolutePath
Picasso.get()
picasso
.load(photoFile)
.fit()
.into(binding.imageViewPackaging)
Expand All @@ -197,21 +199,18 @@ class EnvironmentProductFragment : BaseFragment() {
//checks the product states_tags to determine which prompt to be shown
private fun refreshTagsPrompt() {
val statesTags = product.statesTags
showLabelsPrompt = statesTags.contains("en:labels-to-be-completed")
showOriginsPrompt = statesTags.contains("en:origins-to-be-completed")
showLabelsPrompt = ApiFields.StateTags.LABELS_TO_BE_COMPLETED in statesTags
showOriginsPrompt = ApiFields.StateTags.ORIGINS_TO_BE_COMPLETED in statesTags

binding.addLabelOriginPrompt.visibility = View.VISIBLE
when {
showLabelsPrompt && showOriginsPrompt -> {
// showLabelsPrompt and showOriginsPrompt true
binding.addLabelOriginPrompt.text = getString(R.string.add_labels_origins_prompt_text)
}
showLabelsPrompt -> {
// showLabelsPrompt true
binding.addLabelOriginPrompt.text = getString(R.string.add_labels_prompt_text)
}
showOriginsPrompt -> {
// showOriginsPrompt true
binding.addLabelOriginPrompt.text = getString(R.string.add_origins_prompt_text)
}
else -> binding.addLabelOriginPrompt.visibility = View.GONE
Expand Down
Expand Up @@ -38,7 +38,7 @@ import openfoodfacts.github.scrachx.openfood.features.listeners.EndlessRecyclerV
import openfoodfacts.github.scrachx.openfood.features.listeners.RecyclerItemClickListener
import openfoodfacts.github.scrachx.openfood.features.scan.ContinuousScanActivity
import openfoodfacts.github.scrachx.openfood.features.shared.BaseActivity
import openfoodfacts.github.scrachx.openfood.models.AbstractProductSearch
import openfoodfacts.github.scrachx.openfood.models.Search
import openfoodfacts.github.scrachx.openfood.models.SearchInfo
import openfoodfacts.github.scrachx.openfood.models.SearchProduct
import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient
Expand Down Expand Up @@ -344,7 +344,7 @@ class ProductSearchActivity : BaseActivity() {
}


private fun Single<AbstractProductSearch>.startSearch(@StringRes noMatchMsg: Int, @StringRes extendedMsg: Int = -1) {
private fun Single<Search>.startSearch(@StringRes noMatchMsg: Int, @StringRes extendedMsg: Int = -1) {
observeOn(AndroidSchedulers.mainThread()).subscribe { search, throwable ->
displaySearch(throwable == null, search, noMatchMsg, extendedMsg)
}.addTo(disp)
Expand Down Expand Up @@ -372,15 +372,15 @@ class ProductSearchActivity : BaseActivity() {
}
}

private fun showResponse(isResponseOk: Boolean, response: AbstractProductSearch?) {
private fun showResponse(isResponseOk: Boolean, response: Search?) {
if (isResponseOk && response != null) {
showSuccessfulResponse(response)
} else {
showOfflineCloud()
}
}

private fun showSuccessfulResponse(response: AbstractProductSearch) {
private fun showSuccessfulResponse(response: Search) {
mCountProducts = response.count.toInt()
if (pageAddress == 1) {
val number = NumberFormat.getInstance(Locale.getDefault()).format(response.count.toLong())
Expand Down Expand Up @@ -447,7 +447,7 @@ class ProductSearchActivity : BaseActivity() {
*/
private fun displaySearch(
isResponseSuccessful: Boolean,
response: AbstractProductSearch?,
response: Search?,
@StringRes emptyMessage: Int,
@StringRes extendedMessage: Int = -1
) = if (response == null) {
Expand Down
Expand Up @@ -5,7 +5,7 @@ import java.io.Serializable

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder("page_size", "count", "skip", "page", "products")
data class AbstractProductSearch(
data class Search(
@JsonProperty("page_size") val pageSize: String,
@JsonProperty("count") val count: String,
@JsonProperty("skip") val skip: Int,
Expand Down
Expand Up @@ -28,6 +28,8 @@ object ApiFields {
object StateTags {
const val CATEGORIES_TO_BE_COMPLETED = "en:categories-to-be-completed"
const val NUTRITION_FACTS_TO_BE_COMPLETED = "en:nutrition-facts-to-be-completed"
const val LABELS_TO_BE_COMPLETED = "en:labels-to-be-completed"
const val ORIGINS_TO_BE_COMPLETED = "en:origins-to-be-completed"

const val INGREDIENTS_COMPLETED = "en:ingredients-completed"
}
Expand Down

0 comments on commit 2d9add6

Please sign in to comment.