Compare commits

..

13 Commits

Author SHA1 Message Date
Sylvia van Os
7ba1f56c46 Add barcode encoding support
- Add new barcodeencoding field to database
- Read barcode encoding from pkpass file
- Add barcodeencoding to import/export
- Add barcodeencoding to share URI
- On default, use zxing's GuessEncoding function in StringUtils (this
  should not use UTF-8 unless needed)
- Allow manually forcing ISO-8859-1 or UTF-8
2025-12-21 21:34:49 +01:00
Sylvia van Os
b895a9bc48 Merge pull request #2884 from CatimaLoyalty/create-pull-request/patch-1766291750
Update contributors
2025-12-21 12:12:49 +01:00
TheLastProject
0d33319ad4 Update contributors 2025-12-21 04:35:50 +00:00
Sylvia van Os
2af9d58f06 Merge pull request #2883 from Iamlooker/fix/jvm-configuration
build: Fix conflicting JVM setup
2025-12-20 12:55:58 +01:00
LooKeR
427e9d6482 build: Fix conflicting JVM setup 2025-12-20 13:44:21 +05:30
Sylvia van Os
e21fd954d3 Merge pull request #2881 from CatimaLoyalty/create-pull-request/patch-1766097757
Update locales
2025-12-19 00:12:25 +01:00
TheLastProject
e7f47c7a5a Update locales 2025-12-18 22:42:36 +00:00
Sylvia van Os
54c6dac322 Merge pull request #2880 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2025-12-18 23:42:24 +01:00
امیرضا
cf64958562 Added translation using Weblate (Persian (Old)) 2025-12-18 23:02:46 +01:00
Sylvia van Os
ea31a3b42a Merge pull request #2879 from weblate/weblate-catima-catima
Translations update from Hosted Weblate
2025-12-18 21:32:08 +01:00
B o d o
353dbedbb9 Translated using Weblate (German)
Currently translated at 100.0% (155 of 155 strings)

Translation: Catima/Android (Fastlane)
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/de/
2025-12-18 21:01:29 +01:00
Sylvia van Os
a87c446c31 Merge pull request #2877 from CatimaLoyalty/dependabot/github_actions/peter-evans/create-pull-request-8.0.0
Bump peter-evans/create-pull-request from 7.0.11 to 8.0.0
2025-12-18 10:30:48 +01:00
dependabot[bot]
85f1d06b02 Bump peter-evans/create-pull-request from 7.0.11 to 8.0.0
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.11 to 8.0.0.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v7.0.11...v8.0.0)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-18 02:02:26 +00:00
45 changed files with 1114 additions and 615 deletions

View File

@@ -27,7 +27,7 @@ jobs:
- name: Run converter script
run: python .scripts/changelog_to_fastlane.py
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7.0.11
uses: peter-evans/create-pull-request@v8.0.0
with:
title: "Update Fastlane changelogs"
commit-message: "Update Fastlane changelogs"

View File

@@ -25,7 +25,7 @@ jobs:
file_in_repo: app/src/main/res/raw/contributors.txt
min_commit_count: 5
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7.0.11
uses: peter-evans/create-pull-request@v8.0.0
with:
title: "Update contributors"
commit-message: "Update contributors"

View File

@@ -31,7 +31,7 @@ jobs:
- name: Generate featureGraphic.png for each language
run: .scripts/generate_feature_graphic/generate_feature_graphic.sh
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7.0.11
uses: peter-evans/create-pull-request@v8.0.0
with:
title: "Update feature graphic"
commit-message: "Update feature graphic"

View File

@@ -23,7 +23,7 @@ jobs:
- name: Update locales
run: .scripts/locales.py
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7.0.11
uses: peter-evans/create-pull-request@v8.0.0
with:
title: "Update locales"
commit-message: "Update locales"

View File

@@ -1,9 +1,9 @@
import com.android.build.gradle.internal.tasks.factory.dependsOn
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
alias(libs.plugins.com.android.application)
alias(libs.plugins.org.jetbrains.kotlin.android)
alias(libs.plugins.org.jetbrains.kotlin.plugin.compose)
}
kotlin {
@@ -48,7 +48,6 @@ android {
buildFeatures {
buildConfig = true
compose = true
viewBinding = true
}
@@ -76,16 +75,6 @@ android {
}
}
compileOptions {
encoding = "UTF-8"
// Flag to enable support for the new language APIs
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
sourceSets {
getByName("test") {
resources.srcDirs("src/test/res")
@@ -104,8 +93,18 @@ android {
lint {
lintConfig = file("lint.xml")
}
kotlinOptions {
jvmTarget = "17"
kotlin {
compilerOptions {
jvmTarget = JvmTarget.JVM_21
}
}
compileOptions {
encoding = "UTF-8"
// Flag to enable support for the new language APIs
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
}
@@ -122,19 +121,6 @@ dependencies {
implementation(libs.com.google.android.material.material)
coreLibraryDesugaring(libs.com.android.tools.desugar.jdk.libs)
// Compose
implementation(libs.androidx.activity.activity.compose)
val composeBom = platform(libs.androidx.compose.compose.bom)
implementation(composeBom)
implementation(libs.androidx.compose.foundation.foundation)
implementation(libs.androidx.compose.material3.material3)
implementation(libs.androidx.compose.material.material.icons.extended)
implementation(libs.androidx.compose.ui.ui.tooling.preview.android)
debugImplementation(libs.androidx.compose.ui.ui.test.manifest)
androidTestImplementation(composeBom)
androidTestImplementation(libs.androidx.compose.ui.ui.test.junit4)
// Third-party
implementation(libs.com.journeyapps.zxing.android.embedded)
implementation(libs.com.github.yalantis.ucrop)
@@ -154,8 +140,6 @@ dependencies {
androidTestImplementation(libs.bundles.androidx.test)
androidTestImplementation(libs.junit.junit)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.androidx.test.rules)
androidTestImplementation(libs.androidx.test.runner)
androidTestImplementation(libs.androidx.test.uiautomator.uiautomator)
androidTestImplementation(libs.androidx.test.espresso.espresso.core)
}

View File

@@ -1,89 +0,0 @@
package protect.card_locker
import android.app.Instrumentation
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performScrollTo
import androidx.compose.ui.test.runComposeUiTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import protect.card_locker.compose.theme.CatimaTheme
@OptIn(ExperimentalTestApi::class)
@RunWith(AndroidJUnit4::class)
class AboutActivityTest {
@get:Rule
private val rule: ComposeContentTestRule = createComposeRule()
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val content: AboutContent = AboutContent(instrumentation.targetContext)
@Test
fun testInitialState(): Unit = runComposeUiTest {
setContent {
AboutScreenContent(content = content)
}
onNodeWithTag("topbar_catima").assertIsDisplayed()
onNodeWithTag("card_version_history").assertIsDisplayed()
onNodeWithText(content.versionHistory).assertIsDisplayed()
onNodeWithTag("card_credits").assertIsDisplayed()
onNodeWithText(content.copyrightShort).assertIsDisplayed()
onNodeWithTag("card_translate").assertIsDisplayed()
onNodeWithTag("card_license").assertIsDisplayed()
// We might be off the screen so start scrolling
onNodeWithTag("card_source_github").performScrollTo().assertIsDisplayed()
onNodeWithTag("card_privacy_policy").performScrollTo().assertIsDisplayed()
onNodeWithTag("card_donate").performScrollTo().assertIsDisplayed()
// Dont scroll to this, since its not displayed
onNodeWithTag("card_rate_google").assertIsNotDisplayed()
onNodeWithTag("card_report_error").performScrollTo().assertIsDisplayed()
}
@Test
fun testDonateAndGoogleCardVisible(): Unit = runComposeUiTest {
setContent {
CatimaTheme {
AboutScreenContent(
content = content,
showDonate = true,
showRateOnGooglePlay = true,
)
}
}
onNodeWithTag("card_donate").performScrollTo().assertIsDisplayed()
onNodeWithTag("card_rate_google").performScrollTo().assertIsDisplayed()
}
@Test
fun testDonateAndGoogleCardHidden(): Unit = runComposeUiTest {
setContent {
CatimaTheme {
AboutScreenContent(
content = content,
showDonate = false,
showRateOnGooglePlay = false,
)
}
}
onNodeWithTag("card_privacy_policy").performScrollTo().assertIsDisplayed()
onNodeWithTag("card_donate").assertIsNotDisplayed()
onNodeWithTag("card_rate_google").assertIsNotDisplayed()
onNodeWithTag("card_report_error").performScrollTo().assertIsDisplayed()
}
}

View File

@@ -1,167 +1,149 @@
package protect.card_locker
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.fromHtml
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import protect.card_locker.compose.CatimaAboutSection
import protect.card_locker.compose.CatimaTopAppBar
import protect.card_locker.compose.theme.CatimaTheme
import android.text.Spanned
import android.view.MenuItem
import android.view.View
import android.widget.ScrollView
import android.widget.TextView
class AboutActivity : ComponentActivity() {
import androidx.annotation.StringRes
import androidx.core.view.isVisible
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import protect.card_locker.databinding.AboutActivityBinding
class AboutActivity : CatimaAppCompatActivity() {
private companion object {
private const val TAG = "Catima"
}
private lateinit var binding: AboutActivityBinding
private lateinit var content: AboutContent
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = AboutActivityBinding.inflate(layoutInflater)
content = AboutContent(this)
title = content.pageTitle
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
enableToolbarBackButton()
setContent {
CatimaTheme {
AboutScreenContent(
content = content,
showDonate = BuildConfig.showDonate,
showRateOnGooglePlay = BuildConfig.showRateOnGooglePlay,
onBackPressedDispatcher = onBackPressedDispatcher
)
binding.apply {
creditsSub.text = content.copyrightShort
versionHistorySub.text = content.versionHistory
versionHistory.tag = "https://catima.app/changelog/"
translate.tag = "https://hosted.weblate.org/engage/catima/"
license.tag = "https://github.com/CatimaLoyalty/Android/blob/main/LICENSE"
repo.tag = "https://github.com/CatimaLoyalty/Android/"
privacy.tag = "https://catima.app/privacy-policy/"
reportError.tag = "https://github.com/CatimaLoyalty/Android/issues"
rate.tag = "https://play.google.com/store/apps/details?id=me.hackerchick.catima"
donate.tag = "https://catima.app/donate"
// Hide Google Play rate button if not on Google Play
rate.isVisible = BuildConfig.showRateOnGooglePlay
// Hide donate button on Google Play (Google Play doesn't allow donation links)
donate.isVisible = BuildConfig.showDonate
}
bindClickListeners()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
finish()
true
}
else -> super.onOptionsItemSelected(item)
}
}
override fun onDestroy() {
super.onDestroy()
content.destroy()
clearClickListeners()
}
private fun bindClickListeners() {
binding.apply {
versionHistory.setOnClickListener { showHistory(it) }
translate.setOnClickListener { openExternalBrowser(it) }
license.setOnClickListener { showLicense(it) }
repo.setOnClickListener { openExternalBrowser(it) }
privacy.setOnClickListener { showPrivacy(it) }
reportError.setOnClickListener { openExternalBrowser(it) }
rate.setOnClickListener { openExternalBrowser(it) }
donate.setOnClickListener { openExternalBrowser(it) }
credits.setOnClickListener { showCredits() }
}
}
private fun clearClickListeners() {
binding.apply {
versionHistory.setOnClickListener(null)
translate.setOnClickListener(null)
license.setOnClickListener(null)
repo.setOnClickListener(null)
privacy.setOnClickListener(null)
reportError.setOnClickListener(null)
rate.setOnClickListener(null)
donate.setOnClickListener(null)
credits.setOnClickListener(null)
}
}
private fun showCredits() {
showHTML(R.string.credits, content.contributorInfo, null)
}
private fun showHistory(view: View) {
showHTML(R.string.version_history, content.historyInfo, view)
}
private fun showLicense(view: View) {
showHTML(R.string.license, content.licenseInfo, view)
}
private fun showPrivacy(view: View) {
showHTML(R.string.privacy_policy, content.privacyInfo, view)
}
private fun showHTML(@StringRes title: Int, text: Spanned, view: View?) {
val dialogContentPadding = resources.getDimensionPixelSize(R.dimen.alert_dialog_content_padding)
val textView = TextView(this).apply {
setText(text)
Utils.makeTextViewLinksClickable(this, text)
}
val scrollView = ScrollView(this).apply {
addView(textView)
setPadding(dialogContentPadding, dialogContentPadding / 2, dialogContentPadding, 0)
}
MaterialAlertDialogBuilder(this).apply {
setTitle(title)
setView(scrollView)
setPositiveButton(R.string.ok, null)
// Add View online button if an URL is linked to this view
view?.tag?.let {
setNeutralButton(R.string.view_online) { _, _ -> openExternalBrowser(view) }
}
show()
}
}
private fun openExternalBrowser(view: View) {
val tag = view.tag
if (tag is String && tag.startsWith("https://")) {
OpenWebLinkHandler().openBrowser(this, tag)
}
}
}
@Composable
fun AboutScreenContent(
content: AboutContent,
showDonate: Boolean = true,
showRateOnGooglePlay: Boolean = false,
onBackPressedDispatcher: OnBackPressedDispatcher? = null,
) {
Scaffold(
topBar = { CatimaTopAppBar(content.pageTitle.toString(), onBackPressedDispatcher) }
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding)
.verticalScroll(rememberScrollState())
) {
CatimaAboutSection(
stringResource(R.string.version_history),
content.versionHistory,
modifier = Modifier.testTag("card_version_history"),
onClickUrl = "https://catima.app/changelog/",
onClickDialogText = AnnotatedString.fromHtml(
htmlString = content.historyHtml,
linkStyles = TextLinkStyles(
style = SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colorScheme.primary
)
)
)
)
CatimaAboutSection(
stringResource(R.string.credits),
content.copyrightShort,
modifier = Modifier.testTag("card_credits"),
onClickDialogText = AnnotatedString.fromHtml(
htmlString = content.contributorInfoHtml,
linkStyles = TextLinkStyles(
style = SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colorScheme.primary
)
)
)
)
CatimaAboutSection(
stringResource(R.string.help_translate_this_app),
stringResource(R.string.translate_platform),
modifier = Modifier.testTag("card_translate"),
onClickUrl = "https://hosted.weblate.org/engage/catima/"
)
CatimaAboutSection(
stringResource(R.string.license),
stringResource(R.string.app_license),
modifier = Modifier.testTag("card_license"),
onClickUrl = "https://github.com/CatimaLoyalty/Android/blob/main/LICENSE",
onClickDialogText = AnnotatedString.fromHtml(
htmlString = content.licenseHtml,
linkStyles = TextLinkStyles(
style = SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colorScheme.primary
)
)
)
)
CatimaAboutSection(
stringResource(R.string.source_repository),
stringResource(R.string.on_github),
modifier = Modifier.testTag("card_source_github"),
onClickUrl = "https://github.com/CatimaLoyalty/Android/"
)
CatimaAboutSection(
stringResource(R.string.privacy_policy),
stringResource(R.string.and_data_usage),
modifier = Modifier.testTag("card_privacy_policy"),
onClickUrl = "https://catima.app/privacy-policy/",
onClickDialogText = AnnotatedString.fromHtml(
htmlString = content.privacyHtml,
linkStyles = TextLinkStyles(
style = SpanStyle(
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colorScheme.primary
)
)
)
)
if (showDonate) {
CatimaAboutSection(
stringResource(R.string.donate),
"",
modifier = Modifier.testTag("card_donate"),
onClickUrl = "https://catima.app/donate"
)
}
if (showRateOnGooglePlay) {
CatimaAboutSection(
stringResource(R.string.rate_this_app),
stringResource(R.string.on_google_play),
modifier = Modifier.testTag("card_rate_google"),
onClickUrl = "https://play.google.com/store/apps/details?id=me.hackerchick.catima"
)
}
CatimaAboutSection(
stringResource(R.string.report_error),
stringResource(R.string.on_github),
modifier = Modifier.testTag("card_report_error"),
onClickUrl = "https://github.com/CatimaLoyalty/Android/issues"
)
}
}
}
@Preview
@Composable
private fun AboutActivityPreview() {
AboutScreenContent(AboutContent(LocalContext.current))
}

View File

@@ -3,8 +3,11 @@ package protect.card_locker;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.text.Spanned;
import android.util.Log;
import androidx.core.text.HtmlCompat;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
@@ -52,7 +55,7 @@ public class AboutContent {
return context.getString(R.string.app_copyright_short);
}
public String getContributorsHtml() {
public String getContributors() {
String contributors;
try {
contributors = "<br/>" + Utils.readTextFile(context, R.raw.contributors);
@@ -62,7 +65,7 @@ public class AboutContent {
return contributors.replace("\n", "<br />");
}
public String getHistoryHtml() {
public String getHistory() {
String versionHistory;
try {
versionHistory = Utils.readTextFile(context, R.raw.changelog)
@@ -74,7 +77,7 @@ public class AboutContent {
.replace("\n", "<br />");
}
public String getLicenseHtml() {
public String getLicense() {
try {
return Utils.readTextFile(context, R.raw.license);
} catch (IOException ignored) {
@@ -82,7 +85,7 @@ public class AboutContent {
}
}
public String getPrivacyHtml() {
public String getPrivacy() {
String privacyPolicy;
try {
privacyPolicy = Utils.readTextFile(context, R.raw.privacy)
@@ -94,7 +97,7 @@ public class AboutContent {
.replace("\n", "<br />");
}
public String getThirdPartyLibrariesHtml() {
public String getThirdPartyLibraries() {
final List<ThirdPartyInfo> usedLibraries = new ArrayList<>();
usedLibraries.add(new ThirdPartyInfo("ACRA", "https://github.com/ACRA/acra", "Apache 2.0"));
usedLibraries.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0"));
@@ -113,7 +116,7 @@ public class AboutContent {
return result.toString();
}
public String getUsedThirdPartyAssetsHtml() {
public String getUsedThirdPartyAssets() {
final List<ThirdPartyInfo> usedAssets = new ArrayList<>();
usedAssets.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0"));
@@ -126,19 +129,31 @@ public class AboutContent {
return result.toString();
}
public String getContributorInfoHtml() {
public Spanned getContributorInfo() {
StringBuilder contributorInfo = new StringBuilder();
contributorInfo.append(getCopyright());
contributorInfo.append("<br/><br/>");
contributorInfo.append(context.getString(R.string.app_copyright_old));
contributorInfo.append("<br/><br/>");
contributorInfo.append(String.format(context.getString(R.string.app_contributors), getContributorsHtml()));
contributorInfo.append(String.format(context.getString(R.string.app_contributors), getContributors()));
contributorInfo.append("<br/><br/>");
contributorInfo.append(String.format(context.getString(R.string.app_libraries), getThirdPartyLibrariesHtml()));
contributorInfo.append(String.format(context.getString(R.string.app_libraries), getThirdPartyLibraries()));
contributorInfo.append("<br/><br/>");
contributorInfo.append(String.format(context.getString(R.string.app_resources), getUsedThirdPartyAssetsHtml()));
contributorInfo.append(String.format(context.getString(R.string.app_resources), getUsedThirdPartyAssets()));
return contributorInfo.toString();
return HtmlCompat.fromHtml(contributorInfo.toString(), HtmlCompat.FROM_HTML_MODE_COMPACT);
}
public Spanned getHistoryInfo() {
return HtmlCompat.fromHtml(getHistory(), HtmlCompat.FROM_HTML_MODE_COMPACT);
}
public Spanned getLicenseInfo() {
return HtmlCompat.fromHtml(getLicense(), HtmlCompat.FROM_HTML_MODE_LEGACY);
}
public Spanned getPrivacyInfo() {
return HtmlCompat.fromHtml(getPrivacy(), HtmlCompat.FROM_HTML_MODE_COMPACT);
}
public String getVersionHistory() {

View File

@@ -4,17 +4,24 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.util.ArrayMap;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.StringUtils;
import java.lang.ref.WeakReference;
import java.nio.charset.Charset;
import java.util.Map;
import protect.card_locker.async.CompatCallable;
@@ -39,6 +46,7 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
private final WeakReference<TextView> textViewReference;
private String cardId;
private final CatimaBarcode format;
private final Charset encoding;
private final int imageHeight;
private final int imageWidth;
private final int imagePadding;
@@ -48,7 +56,7 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
BarcodeImageWriterTask(
Context context, ImageView imageView, String cardIdString,
CatimaBarcode barcodeFormat, TextView textView,
CatimaBarcode barcodeFormat, @Nullable Charset barcodeEncoding, TextView textView,
boolean showFallback, BarcodeImageWriterResultCallback callback, boolean roundCornerPadding, boolean isFullscreen
) {
mContext = context;
@@ -62,6 +70,7 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
cardId = cardIdString;
format = barcodeFormat;
encoding = barcodeEncoding;
int imageViewHeight = imageView.getHeight();
int imageViewWidth = imageView.getWidth();
@@ -172,10 +181,22 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
}
MultiFormatWriter writer = new MultiFormatWriter();
Map<EncodeHintType, Object> encodeHints = new ArrayMap<>();
// Use charset if defined or guess otherwise
if (encoding != null) {
Log.d(TAG, "Encoding explicitly set, " + encoding.name());
encodeHints.put(EncodeHintType.CHARACTER_SET, encoding);
} else {
String guessedEncoding = StringUtils.guessEncoding(cardId.getBytes(), new ArrayMap<>());
Log.d(TAG, "Guessed encoding: " + guessedEncoding);
encodeHints.put(EncodeHintType.CHARACTER_SET, Charset.forName(guessedEncoding));
}
BitMatrix bitMatrix;
try {
try {
bitMatrix = writer.encode(cardId, format.format(), imageWidth, imageHeight, null);
bitMatrix = writer.encode(cardId, format.format(), imageWidth, imageHeight, encodeHints);
} catch (Exception e) {
// Cast a wider net here and catch any exception, as there are some
// cases where an encoder may fail if the data is invalid for the

View File

@@ -92,13 +92,13 @@ public class BarcodeSelectorAdapter extends ArrayAdapter<CatimaBarcodeWithValue>
Log.d(TAG, "Generating barcode for type " + formatType);
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getContext(), image, cardId, format, text, true, null, true, false);
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getContext(), image, cardId, format, null, text, true, null, true, false);
mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
}
});
} else {
Log.d(TAG, "Generating barcode for type " + formatType);
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getContext(), image, cardId, format, text, true, null, true, false);
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getContext(), image, cardId, format, null, text, true, null, true, false);
mTasks.executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
}
}

View File

@@ -10,8 +10,11 @@ import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.Nullable;
import java.io.FileNotFoundException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Currency;
@@ -23,7 +26,7 @@ import java.util.Set;
public class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Catima.db";
public static final int ORIGINAL_DATABASE_VERSION = 1;
public static final int DATABASE_VERSION = 17;
public static final int DATABASE_VERSION = 18;
// NB: changing these values requires a migration
public static final int DEFAULT_ZOOM_LEVEL = 100;
@@ -49,6 +52,7 @@ public class DBHelper extends SQLiteOpenHelper {
public static final String CARD_ID = "cardid";
public static final String BARCODE_ID = "barcodeid";
public static final String BARCODE_TYPE = "barcodetype";
public static final String BARCODE_ENCODING = "barcodeencoding";
public static final String STAR_STATUS = "starstatus";
public static final String LAST_USED = "lastused";
public static final String ZOOM_LEVEL = "zoomlevel";
@@ -112,6 +116,7 @@ public class DBHelper extends SQLiteOpenHelper {
LoyaltyCardDbIds.CARD_ID + " TEXT not null," +
LoyaltyCardDbIds.BARCODE_ID + " TEXT," +
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT," +
LoyaltyCardDbIds.BARCODE_ENCODING + " TEXT," +
LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0'," +
LoyaltyCardDbIds.LAST_USED + " INTEGER DEFAULT '0', " +
LoyaltyCardDbIds.ZOOM_LEVEL + " INTEGER DEFAULT '" + DEFAULT_ZOOM_LEVEL + "', " +
@@ -335,6 +340,11 @@ public class DBHelper extends SQLiteOpenHelper {
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
+ " ADD COLUMN " + LoyaltyCardDbIds.ZOOM_LEVEL_WIDTH + " INTEGER DEFAULT '100' ");
}
if (oldVersion < 18 && newVersion >= 18) {
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
+ " ADD COLUMN " + LoyaltyCardDbIds.BARCODE_ENCODING + " TEXT");
}
}
public static Set<String> imageFiles(Context context, final SQLiteDatabase database) {
@@ -396,7 +406,8 @@ public class DBHelper extends SQLiteOpenHelper {
public static long insertLoyaltyCard(
final SQLiteDatabase database, final String store, final String note, final Date validFrom,
final Date expiry, final BigDecimal balance, final Currency balanceType, final String cardId,
final String barcodeId, final CatimaBarcode barcodeType, final Integer headerColor,
final String barcodeId, final CatimaBarcode barcodeType, final @Nullable Charset barcodeEncoding,
final Integer headerColor,
final int starStatus, final Long lastUsed, final int archiveStatus) {
database.beginTransaction();
@@ -411,6 +422,7 @@ public class DBHelper extends SQLiteOpenHelper {
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.name() : null);
contentValues.put(LoyaltyCardDbIds.BARCODE_ENCODING, barcodeEncoding != null ? barcodeEncoding.name() : null);
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
contentValues.put(LoyaltyCardDbIds.STAR_STATUS, starStatus);
contentValues.put(LoyaltyCardDbIds.LAST_USED, lastUsed != null ? lastUsed : Utils.getUnixTime());
@@ -430,7 +442,8 @@ public class DBHelper extends SQLiteOpenHelper {
final SQLiteDatabase database, final int id, final String store, final String note,
final Date validFrom, final Date expiry, final BigDecimal balance,
final Currency balanceType, final String cardId, final String barcodeId,
final CatimaBarcode barcodeType, final Integer headerColor, final int starStatus,
final CatimaBarcode barcodeType, final @Nullable Charset barcodeEncoding,
final Integer headerColor, final int starStatus,
final Long lastUsed, final int archiveStatus) {
database.beginTransaction();
@@ -446,6 +459,7 @@ public class DBHelper extends SQLiteOpenHelper {
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.name() : null);
contentValues.put(LoyaltyCardDbIds.BARCODE_ENCODING, barcodeEncoding != null ? barcodeEncoding.name() : null);
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
contentValues.put(LoyaltyCardDbIds.STAR_STATUS, starStatus);
contentValues.put(LoyaltyCardDbIds.LAST_USED, lastUsed != null ? lastUsed : Utils.getUnixTime());
@@ -465,7 +479,8 @@ public class DBHelper extends SQLiteOpenHelper {
SQLiteDatabase database, final int id, final String store, final String note,
final Date validFrom, final Date expiry, final BigDecimal balance,
final Currency balanceType, final String cardId, final String barcodeId,
final CatimaBarcode barcodeType, final Integer headerColor, final int starStatus,
final CatimaBarcode barcodeType, final @Nullable Charset barcodeEncoding,
final Integer headerColor, final int starStatus,
final Long lastUsed, final int archiveStatus) {
database.beginTransaction();
@@ -480,6 +495,7 @@ public class DBHelper extends SQLiteOpenHelper {
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.name() : null);
contentValues.put(LoyaltyCardDbIds.BARCODE_ENCODING, barcodeEncoding != null ? barcodeEncoding.name() : null);
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
contentValues.put(LoyaltyCardDbIds.STAR_STATUS, starStatus);
contentValues.put(LoyaltyCardDbIds.LAST_USED, lastUsed != null ? lastUsed : Utils.getUnixTime());

View File

@@ -4,11 +4,14 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import androidx.annotation.Nullable;
import java.io.InvalidObjectException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Currency;
import java.util.Date;
@@ -25,6 +28,7 @@ public class ImportURIHelper {
private static final String CARD_ID = DBHelper.LoyaltyCardDbIds.CARD_ID;
private static final String BARCODE_ID = DBHelper.LoyaltyCardDbIds.BARCODE_ID;
private static final String BARCODE_TYPE = DBHelper.LoyaltyCardDbIds.BARCODE_TYPE;
private static final String BARCODE_ENCODING = DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING;
private static final String HEADER_COLOR = DBHelper.LoyaltyCardDbIds.HEADER_COLOR;
private final Context context;
@@ -66,6 +70,7 @@ public class ImportURIHelper {
try {
// These values are allowed to be null
CatimaBarcode barcodeType = null;
Charset barcodeEncoding = null;
Date validFrom = null;
Date expiry = null;
BigDecimal balance = new BigDecimal("0");
@@ -103,6 +108,11 @@ public class ImportURIHelper {
barcodeType = CatimaBarcode.fromName(unparsedBarcodeType);
}
String unparsedBarcodeEncoding = kv.get(BARCODE_ENCODING);
if (unparsedBarcodeEncoding != null && !unparsedBarcodeEncoding.equals("")) {
barcodeEncoding = Charset.forName(unparsedBarcodeEncoding);
}
String unparsedBalance = kv.get(BALANCE);
if (unparsedBalance != null && !unparsedBalance.equals("")) {
balance = new BigDecimal(unparsedBalance);
@@ -136,6 +146,7 @@ public class ImportURIHelper {
cardId,
barcodeId,
barcodeType,
barcodeEncoding,
headerColor,
0,
Utils.getUnixTime(),
@@ -195,6 +206,9 @@ public class ImportURIHelper {
if (loyaltyCard.barcodeType != null) {
fragment = appendFragment(fragment, BARCODE_TYPE, loyaltyCard.barcodeType.name());
}
if (loyaltyCard.barcodeEncoding != null) {
fragment = appendFragment(fragment, BARCODE_ENCODING, loyaltyCard.barcodeEncoding.name());
}
if (loyaltyCard.headerColor != null) {
fragment = appendFragment(fragment, HEADER_COLOR, loyaltyCard.headerColor.toString());
}

View File

@@ -9,6 +9,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.Currency;
import java.util.Date;
import java.util.List;
@@ -31,6 +32,8 @@ public class LoyaltyCard {
@Nullable
public CatimaBarcode barcodeType;
@Nullable
public Charset barcodeEncoding;
@Nullable
public Integer headerColor;
public int starStatus;
public long lastUsed;
@@ -62,6 +65,7 @@ public class LoyaltyCard {
public static final String BUNDLE_LOYALTY_CARD_CARD_ID = "loyaltyCardCardId";
public static final String BUNDLE_LOYALTY_CARD_BARCODE_ID = "loyaltyCardBarcodeId";
public static final String BUNDLE_LOYALTY_CARD_BARCODE_TYPE = "loyaltyCardBarcodeType";
public static final String BUNDLE_LOYALTY_CARD_BARCODE_ENCODING = "loyaltyCardBarcodeEncoding";
public static final String BUNDLE_LOYALTY_CARD_HEADER_COLOR = "loyaltyCardHeaderColor";
public static final String BUNDLE_LOYALTY_CARD_STAR_STATUS = "loyaltyCardStarStatus";
public static final String BUNDLE_LOYALTY_CARD_LAST_USED = "loyaltyCardLastUsed";
@@ -90,6 +94,7 @@ public class LoyaltyCard {
setCardId("");
setBarcodeId(null);
setBarcodeType(null);
setBarcodeEncoding(null);
setHeaderColor(null);
setStarStatus(0);
setLastUsed(Utils.getUnixTime());
@@ -124,7 +129,7 @@ public class LoyaltyCard {
public LoyaltyCard(final int id, final String store, final String note, @Nullable final Date validFrom,
@Nullable final Date expiry, final BigDecimal balance, @Nullable final Currency balanceType,
final String cardId, @Nullable final String barcodeId, @Nullable final CatimaBarcode barcodeType,
@Nullable final Integer headerColor, final int starStatus,
@Nullable final Charset barcodeEncoding, @Nullable final Integer headerColor, final int starStatus,
final long lastUsed, final int zoomLevel, final int zoomLevelWidth, final int archiveStatus,
@Nullable Bitmap imageThumbnail, @Nullable String imageThumbnailPath,
@Nullable Bitmap imageFront, @Nullable String imageFrontPath,
@@ -139,6 +144,7 @@ public class LoyaltyCard {
setCardId(cardId);
setBarcodeId(barcodeId);
setBarcodeType(barcodeType);
setBarcodeEncoding(barcodeEncoding);
setHeaderColor(headerColor);
setStarStatus(starStatus);
setLastUsed(lastUsed);
@@ -244,6 +250,10 @@ public class LoyaltyCard {
this.barcodeType = barcodeType;
}
public void setBarcodeEncoding(@Nullable Charset barcodeEncoding) {
this.barcodeEncoding = barcodeEncoding;
}
public void setHeaderColor(@Nullable Integer headerColor) {
this.headerColor = headerColor;
}
@@ -379,6 +389,11 @@ public class LoyaltyCard {
} else if (requireFull) {
throw new IllegalArgumentException("Missing key " + BUNDLE_LOYALTY_CARD_BARCODE_TYPE);
}
if (bundle.containsKey(BUNDLE_LOYALTY_CARD_BARCODE_ENCODING)) {
setBarcodeEncoding(Charset.forName(bundle.getString(BUNDLE_LOYALTY_CARD_BARCODE_ENCODING)));
} else if (requireFull) {
throw new IllegalArgumentException("Missing key " + BUNDLE_LOYALTY_CARD_BARCODE_ENCODING);
}
if (bundle.containsKey(BUNDLE_LOYALTY_CARD_HEADER_COLOR)) {
int tmpHeaderColor = bundle.getInt(BUNDLE_LOYALTY_CARD_HEADER_COLOR);
setHeaderColor(tmpHeaderColor != -1 ? tmpHeaderColor : null);
@@ -462,6 +477,9 @@ public class LoyaltyCard {
if (!exportIsLimited || exportLimit.contains(BUNDLE_LOYALTY_CARD_BARCODE_TYPE)) {
bundle.putString(BUNDLE_LOYALTY_CARD_BARCODE_TYPE, barcodeType != null ? barcodeType.name() : null);
}
if (!exportIsLimited || exportLimit.contains(BUNDLE_LOYALTY_CARD_BARCODE_ENCODING)) {
bundle.putString(BUNDLE_LOYALTY_CARD_BARCODE_ENCODING, barcodeEncoding != null ? barcodeEncoding.name() : null);
}
if (!exportIsLimited || exportLimit.contains(BUNDLE_LOYALTY_CARD_HEADER_COLOR)) {
bundle.putInt(BUNDLE_LOYALTY_CARD_HEADER_COLOR, headerColor != null ? headerColor : -1);
}
@@ -539,6 +557,9 @@ public class LoyaltyCard {
// barcodeType
int barcodeTypeColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE);
CatimaBarcode barcodeType = !cursor.isNull(barcodeTypeColumn) ? CatimaBarcode.fromName(cursor.getString(barcodeTypeColumn)) : null;
// barcodeEncoding
int barcodeEncodingColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING);
Charset barcodeEncoding = !cursor.isNull(barcodeEncodingColumn) ? Charset.forName(cursor.getString(barcodeEncodingColumn)) : null;
// headerColor
int headerColorColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR);
Integer headerColor = !cursor.isNull(headerColorColumn) ? cursor.getInt(headerColorColumn) : null;
@@ -564,6 +585,7 @@ public class LoyaltyCard {
cardId,
barcodeId,
barcodeType,
barcodeEncoding,
headerColor,
starStatus,
lastUsed,
@@ -593,6 +615,7 @@ public class LoyaltyCard {
Utils.equals(a.barcodeId, b.barcodeId) && // nullable String
Utils.equals(a.barcodeType == null ? null : a.barcodeType.format(),
b.barcodeType == null ? null : b.barcodeType.format()) && // nullable CatimaBarcode with no overridden .equals(), so we need to check .format()
Utils.equals(a.barcodeEncoding, b.barcodeEncoding) && // nullable String
Utils.equals(a.headerColor, b.headerColor) && // nullable Integer
a.starStatus == b.starStatus && // non-nullable int
a.archiveStatus == b.archiveStatus && // non-nullable int
@@ -619,7 +642,7 @@ public class LoyaltyCard {
public String toString() {
return String.format(
"LoyaltyCard{%n id=%s,%n store=%s,%n note=%s,%n validFrom=%s,%n expiry=%s,%n"
+ " balance=%s,%n balanceType=%s,%n cardId=%s,%n barcodeId=%s,%n barcodeType=%s,%n"
+ " balance=%s,%n balanceType=%s,%n cardId=%s,%n barcodeId=%s,%n barcodeType=%s,%n barcodeEncoding=%s,%n"
+ " headerColor=%s,%n starStatus=%s,%n lastUsed=%s,%n zoomLevel=%s,%n zoomLevelWidth=%s,%n archiveStatus=%s%n"
+ " imageThumbnail=%s,%n imageThumbnailPath=%s,%n imageFront=%s,%n imageFrontPath=%s,%n imageBack=%s,%n imageBackPath=%s,%n}",
this.id,
@@ -632,6 +655,7 @@ public class LoyaltyCard {
this.cardId,
this.barcodeId,
this.barcodeType != null ? this.barcodeType.format() : null,
this.barcodeEncoding != null ? this.barcodeEncoding.name() : null,
this.headerColor,
this.starStatus,
this.lastUsed,

View File

@@ -70,6 +70,8 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
@@ -128,6 +130,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
TextView cardIdFieldView;
AutoCompleteTextView barcodeIdField;
AutoCompleteTextView barcodeTypeField;
AutoCompleteTextView barcodeEncodingField;
ImageView barcodeImage;
View barcodeImageLayout;
View barcodeCaptureLayout;
@@ -229,6 +232,14 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
viewModel.setHasChanged(true);
}
protected void setLoyaltyCardBarcodeEncoding(@Nullable Charset barcodeEncoding) {
viewModel.getLoyaltyCard().setBarcodeEncoding(barcodeEncoding);
generateBarcode();
viewModel.setHasChanged(true);
}
protected void setLoyaltyCardHeaderColor(@Nullable Integer headerColor) {
viewModel.getLoyaltyCard().setHeaderColor(headerColor);
@@ -334,6 +345,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
cardIdFieldView = binding.cardIdView;
barcodeIdField = binding.barcodeIdField;
barcodeTypeField = binding.barcodeTypeField;
barcodeEncodingField = binding.barcodeEncodingField;
barcodeImage = binding.barcode;
barcodeImage.setClipToOutline(true);
barcodeImageLayout = binding.barcodeLayout;
@@ -577,6 +589,30 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
}
});
barcodeEncodingField.addTextChangedListener(new SimpleTextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!s.toString().isEmpty()) {
Log.d(TAG, "Setting barcode encoding to " + s.toString());
if (s.toString().equals(getString(R.string.automatic))) {
setLoyaltyCardBarcodeEncoding(null);
} else {
setLoyaltyCardBarcodeEncoding(Charset.forName(s.toString()));
}
}
}
@Override
public void afterTextChanged(Editable s) {
ArrayList<String> barcodeEncodingList = new ArrayList<>();
barcodeEncodingList.add(getString(R.string.automatic));
barcodeEncodingList.add(StandardCharsets.ISO_8859_1.name());
barcodeEncodingList.add(StandardCharsets.UTF_8.name());
ArrayAdapter<String> barcodeEncodingAdapter = new ArrayAdapter<>(LoyaltyCardEditActivity.this, android.R.layout.select_dialog_item, barcodeEncodingList);
barcodeEncodingField.setAdapter(barcodeEncodingAdapter);
}
});
binding.tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
@@ -773,6 +809,8 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
barcodeIdField.setText(barcodeId != null && !barcodeId.isEmpty() ? barcodeId : getString(R.string.sameAsCardId));
CatimaBarcode barcodeType = viewModel.getLoyaltyCard().barcodeType;
barcodeTypeField.setText(barcodeType != null ? barcodeType.prettyName() : getString(R.string.noBarcode));
Charset barcodeEncoding = viewModel.getLoyaltyCard().barcodeEncoding;
barcodeEncodingField.setText(barcodeEncoding != null ? barcodeEncoding.name() : getString(R.string.automatic));
// We set the balance here (with onResuming/onRestoring == true) to prevent formatBalanceCurrencyField() from setting it (via onTextChanged),
// which can cause issues when switching locale because it parses the balance and e.g. the decimal separator may have changed.
@@ -1479,9 +1517,9 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
// This makes the DBHelper set it to the current date
// So that new and edited card are always on top when sorting by recently used
if (viewModel.getUpdateLoyaltyCard()) {
DBHelper.updateLoyaltyCard(mDatabase, viewModel.getLoyaltyCardId(), viewModel.getLoyaltyCard().store, viewModel.getLoyaltyCard().note, viewModel.getLoyaltyCard().validFrom, viewModel.getLoyaltyCard().expiry, viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType, viewModel.getLoyaltyCard().cardId, viewModel.getLoyaltyCard().barcodeId, viewModel.getLoyaltyCard().barcodeType, viewModel.getLoyaltyCard().headerColor, viewModel.getLoyaltyCard().starStatus, null, viewModel.getLoyaltyCard().archiveStatus);
DBHelper.updateLoyaltyCard(mDatabase, viewModel.getLoyaltyCardId(), viewModel.getLoyaltyCard().store, viewModel.getLoyaltyCard().note, viewModel.getLoyaltyCard().validFrom, viewModel.getLoyaltyCard().expiry, viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType, viewModel.getLoyaltyCard().cardId, viewModel.getLoyaltyCard().barcodeId, viewModel.getLoyaltyCard().barcodeType, viewModel.getLoyaltyCard().barcodeEncoding, viewModel.getLoyaltyCard().headerColor, viewModel.getLoyaltyCard().starStatus, null, viewModel.getLoyaltyCard().archiveStatus);
} else {
viewModel.setLoyaltyCardId((int) DBHelper.insertLoyaltyCard(mDatabase, viewModel.getLoyaltyCard().store, viewModel.getLoyaltyCard().note, viewModel.getLoyaltyCard().validFrom, viewModel.getLoyaltyCard().expiry, viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType, viewModel.getLoyaltyCard().cardId, viewModel.getLoyaltyCard().barcodeId, viewModel.getLoyaltyCard().barcodeType, viewModel.getLoyaltyCard().headerColor, 0, null, 0));
viewModel.setLoyaltyCardId((int) DBHelper.insertLoyaltyCard(mDatabase, viewModel.getLoyaltyCard().store, viewModel.getLoyaltyCard().note, viewModel.getLoyaltyCard().validFrom, viewModel.getLoyaltyCard().expiry, viewModel.getLoyaltyCard().balance, viewModel.getLoyaltyCard().balanceType, viewModel.getLoyaltyCard().cardId, viewModel.getLoyaltyCard().barcodeId, viewModel.getLoyaltyCard().barcodeType, viewModel.getLoyaltyCard().barcodeEncoding, viewModel.getLoyaltyCard().headerColor, 0, null, 0));
}
try {
@@ -1596,6 +1634,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
String cardIdString = viewModel.getLoyaltyCard().barcodeId != null ? viewModel.getLoyaltyCard().barcodeId : viewModel.getLoyaltyCard().cardId;
CatimaBarcode barcodeFormat = viewModel.getLoyaltyCard().barcodeType;
Charset barcodeEncoding = viewModel.getLoyaltyCard().barcodeEncoding;
if (cardIdString == null || cardIdString.isEmpty() || barcodeFormat == null) {
barcodeImageLayout.setVisibility(View.GONE);
@@ -1615,13 +1654,13 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity implements
barcodeImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Log.d(TAG, "ImageView size now known");
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, LoyaltyCardEditActivity.this, true, false);
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, barcodeEncoding, null, false, LoyaltyCardEditActivity.this, true, false);
viewModel.getTaskHandler().executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
}
});
} else {
Log.d(TAG, "ImageView size known known, creating barcode");
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, null, false, this, true, false);
BarcodeImageWriterTask barcodeWriter = new BarcodeImageWriterTask(getApplicationContext(), barcodeImage, cardIdString, barcodeFormat, barcodeEncoding, null, false, this, true, false);
viewModel.getTaskHandler().executeTask(TaskHandler.TYPE.BARCODE, barcodeWriter);
}
}

View File

@@ -39,6 +39,7 @@ import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
@@ -58,6 +59,7 @@ import com.google.zxing.BarcodeFormat;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
@@ -87,6 +89,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
String cardIdString;
String barcodeIdString;
CatimaBarcode format;
@Nullable
Charset barcodeEncoding;
Bitmap frontImageBitmap;
Bitmap backImageBitmap;
@@ -686,6 +690,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
format = loyaltyCard.barcodeType;
cardIdString = loyaltyCard.cardId;
barcodeIdString = loyaltyCard.barcodeId;
barcodeEncoding = loyaltyCard.barcodeEncoding;
binding.mainImageDescription.setText(loyaltyCard.cardId);
@@ -959,6 +964,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
barcodeRenderTarget,
barcodeIdString != null ? barcodeIdString : cardIdString,
format,
barcodeEncoding,
null,
false,
this,

View File

@@ -58,8 +58,8 @@ class MainActivity : CatimaAppCompatActivity(), CardAdapterListener {
private var selectedTab: Int = 0
private lateinit var groupsTabLayout: TabLayout
private lateinit var mUpdateLoyaltyCardListRunnable: Runnable
private lateinit var mBarcodeScannerLauncher: ActivityResultLauncher<Intent>
private lateinit var mSettingsLauncher: ActivityResultLauncher<Intent>
private lateinit var mBarcodeScannerLauncher: ActivityResultLauncher<Intent?>
private lateinit var mSettingsLauncher: ActivityResultLauncher<Intent?>
private val mCurrentActionModeCallback: ActionMode.Callback = object : ActionMode.Callback {
override fun onCreateActionMode(inputMode: ActionMode, inputMenu: Menu?): Boolean {

View File

@@ -1,17 +1,18 @@
package protect.card_locker;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class OpenWebLinkHandler {
private static final String TAG = "Catima";
public void openBrowser(Activity activity, String url) {
public void openBrowser(AppCompatActivity activity, String url) {
if (url == null) {
return;
}

View File

@@ -14,6 +14,7 @@ import org.json.JSONObject
import java.io.FileNotFoundException
import java.io.IOException
import java.math.BigDecimal
import java.nio.charset.Charset
import java.text.DateFormat
import java.text.ParseException
import java.time.ZonedDateTime
@@ -40,6 +41,7 @@ class PkpassParser(context: Context, uri: Uri?) {
private var cardId: String = context.getString(R.string.noBarcode)
private var barcodeId: String? = null
private var barcodeType: CatimaBarcode? = null
private var barcodeEncoding: Charset? = null
private var headerColor: Int? = null
private val starStatus = 0
private val lastUsed: Long = 0
@@ -134,6 +136,7 @@ class PkpassParser(context: Context, uri: Uri?) {
cardId,
barcodeId,
barcodeType,
barcodeEncoding,
headerColor,
starStatus,
lastUsed,
@@ -342,13 +345,14 @@ class PkpassParser(context: Context, uri: Uri?) {
else -> throw IllegalArgumentException("No valid barcode type")
}
// FIXME: We probably need to do something with the messageEncoding field
try {
cardId = barcodeInfo.getString("altText")
barcodeId = barcodeInfo.getString("message")
barcodeEncoding = Charset.forName(barcodeInfo.getString("messageEncoding"))
} catch (ignored: JSONException) {
cardId = barcodeInfo.getString("message")
barcodeId = null
barcodeEncoding = Charset.forName(barcodeInfo.getString("messageEncoding"))
}
// Don't set barcodeId if it's the same as cardId

View File

@@ -538,7 +538,7 @@ class ScanActivity : CatimaAppCompatActivity() {
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
permissions: Array<String?>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
@@ -548,7 +548,7 @@ class ScanActivity : CatimaAppCompatActivity() {
override fun onMockedRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
permissions: Array<String?>,
grantResults: IntArray
) {
val granted =

View File

@@ -1,97 +0,0 @@
package protect.card_locker.compose
import androidx.activity.compose.LocalActivity
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp
import protect.card_locker.OpenWebLinkHandler
import protect.card_locker.R
@Composable
fun CatimaAboutSection(
title: String,
message: String,
modifier: Modifier = Modifier,
onClickUrl: String? = null,
onClickDialogText: AnnotatedString? = null,
) {
val activity = LocalActivity.current
val openDialog = remember { mutableStateOf(false) }
Row(
modifier = modifier
.padding(horizontal = 16.dp, vertical = 8.dp)
.clickable {
if (onClickDialogText != null) {
openDialog.value = true
} else if (onClickUrl != null) {
OpenWebLinkHandler().openBrowser(activity, onClickUrl)
}
}
) {
Column(modifier = Modifier.weight(1F)) {
Text(
text = title,
style = MaterialTheme.typography.titleMedium
)
Text(text = message)
}
Text(modifier = Modifier.align(Alignment.CenterVertically),
text = ">",
style = MaterialTheme.typography.bodyMedium
)
}
if (openDialog.value && onClickDialogText != null) {
AlertDialog(
icon = {},
title = {
Text(text = title)
},
text = {
Text(
text = onClickDialogText,
modifier = Modifier.verticalScroll(rememberScrollState())
)
},
onDismissRequest = {
openDialog.value = false
},
confirmButton = {
TextButton(
onClick = {
openDialog.value = false
}
) {
Text(stringResource(R.string.ok))
}
},
dismissButton = {
if (onClickUrl != null) {
TextButton(
onClick = {
OpenWebLinkHandler().openBrowser(activity, onClickUrl)
}
) {
Text(stringResource(R.string.view_online))
}
}
}
)
}
}

View File

@@ -1,34 +0,0 @@
package protect.card_locker.compose
import androidx.activity.OnBackPressedDispatcher
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import protect.card_locker.R
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CatimaTopAppBar(title: String, onBackPressedDispatcher: OnBackPressedDispatcher?) {
TopAppBar(
modifier = Modifier.testTag("topbar_catima"),
title = { Text(text = title) },
navigationIcon = {
if (onBackPressedDispatcher != null) {
IconButton(onClick = { onBackPressedDispatcher.onBackPressed() }) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.back)
)
}
}
}
)
}

View File

@@ -1,46 +0,0 @@
package protect.card_locker.compose.theme
import android.os.Build
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import protect.card_locker.R
import protect.card_locker.preferences.Settings
@Composable
fun CatimaTheme(content: @Composable () -> Unit) {
val context = LocalContext.current
val settings = Settings(context)
val isDynamicColorSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val lightTheme = if (isDynamicColorSupported) {
dynamicLightColorScheme(context)
} else {
lightColorScheme(primary = colorResource(id = R.color.md_theme_light_primary))
}
val darkTheme = if (isDynamicColorSupported) {
dynamicDarkColorScheme(context)
} else {
darkColorScheme(primary = colorResource(id = R.color.md_theme_dark_primary))
}
val colorScheme = when (settings.theme) {
AppCompatDelegate.MODE_NIGHT_NO -> lightTheme
AppCompatDelegate.MODE_NIGHT_YES -> darkTheme
else -> if (isSystemInDarkTheme()) darkTheme else lightTheme
}
MaterialTheme(
colorScheme = colorScheme,
content = content
)
}

View File

@@ -52,6 +52,7 @@ public class CardsContentProvider extends ContentProvider {
LoyaltyCardDbIds.CARD_ID,
LoyaltyCardDbIds.BARCODE_ID,
LoyaltyCardDbIds.BARCODE_TYPE,
// FIXME: Expose BARCODE_ENCODING but without ever exposing the null value (so apps using this don't have to guess)
LoyaltyCardDbIds.STAR_STATUS,
LoyaltyCardDbIds.LAST_USED,
LoyaltyCardDbIds.ARCHIVE_STATUS,

View File

@@ -134,6 +134,7 @@ public class CatimaExporter implements Exporter {
DBHelper.LoyaltyCardDbIds.CARD_ID,
DBHelper.LoyaltyCardDbIds.BARCODE_ID,
DBHelper.LoyaltyCardDbIds.BARCODE_TYPE,
DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING,
DBHelper.LoyaltyCardDbIds.HEADER_COLOR,
DBHelper.LoyaltyCardDbIds.STAR_STATUS,
DBHelper.LoyaltyCardDbIds.LAST_USED,
@@ -154,6 +155,7 @@ public class CatimaExporter implements Exporter {
card.cardId,
card.barcodeId,
card.barcodeType != null ? card.barcodeType.name() : "",
card.barcodeEncoding != null ? card.barcodeEncoding.name() : "",
card.headerColor,
card.starStatus,
card.lastUsed,

View File

@@ -20,6 +20,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Currency;
@@ -127,10 +128,10 @@ public class CatimaImporter implements Importer {
LoyaltyCard existing = DBHelper.getLoyaltyCard(context, database, card.id);
if (existing == null) {
DBHelper.insertLoyaltyCard(database, card.id, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
card.cardId, card.barcodeId, card.barcodeType, card.barcodeEncoding, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
} else if (!isDuplicate(context, existing, card, existingImages, imageChecksums)) {
long newId = DBHelper.insertLoyaltyCard(database, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
card.cardId, card.barcodeId, card.barcodeType, card.barcodeEncoding, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
idMap.put(card.id, (int) newId);
}
}
@@ -458,6 +459,12 @@ public class CatimaImporter implements Importer {
barcodeType = CatimaBarcode.fromName(unparsedBarcodeType);
}
Charset barcodeEncoding = null;
String unparsedBarcodeEncoding = CSVHelpers.extractString(DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING, record, "");
if (!unparsedBarcodeEncoding.isEmpty()) {
barcodeEncoding = Charset.forName(unparsedBarcodeEncoding);
}
Integer headerColor = null;
try {
headerColor = CSVHelpers.extractInt(DBHelper.LoyaltyCardDbIds.HEADER_COLOR, record);
@@ -501,6 +508,7 @@ public class CatimaImporter implements Importer {
cardId,
barcodeId,
barcodeType,
barcodeEncoding,
headerColor,
starStatus,
lastUsed,

View File

@@ -160,6 +160,7 @@ public class FidmeImporter implements Importer {
cardId,
null,
barcodeType,
null,
headerColor,
starStatus,
Utils.getUnixTime(),
@@ -181,7 +182,7 @@ public class FidmeImporter implements Importer {
for (LoyaltyCard card : data.cards) {
// Do not use card.id which is set to -1
DBHelper.insertLoyaltyCard(database, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
card.cardId, card.barcodeId, card.barcodeType, card.barcodeEncoding, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
}
}
}

View File

@@ -162,6 +162,7 @@ public class VoucherVaultImporter implements Importer {
cardId,
null,
barcodeType,
null,
headerColor,
0,
Utils.getUnixTime(),
@@ -186,7 +187,7 @@ public class VoucherVaultImporter implements Importer {
for (LoyaltyCard card : data.cards) {
// Do not use card.id which is set to -1
DBHelper.insertLoyaltyCard(database, card.store, card.note, card.validFrom, card.expiry, card.balance, card.balanceType,
card.cardId, card.barcodeId, card.barcodeType, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
card.cardId, card.barcodeId, card.barcodeType, card.barcodeEncoding, card.headerColor, card.starStatus, card.lastUsed, card.archiveStatus);
}
}
}

View File

@@ -0,0 +1,421 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="protect.card_locker.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
style="?attr/toolbarStyle" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:paddingVertical="8dp"
android:clipToPadding="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/version_history"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/version_history_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/version_history"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/version_history_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/version_history_main" />
<TextView
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/arrow"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/credits"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/credits_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/credits"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/credits_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/credits_main" />
<TextView
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/arrow"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/translate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/translate_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/help_translate_this_app"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/translate_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/translate_platform"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/translate_main"/>
<TextView
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/arrow"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/license"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/license_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/license"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/license_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/app_license"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/license_main"/>
<TextView
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/arrow"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/repo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/repo_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/source_repository"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/repo_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/on_github"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/repo_main" />
<TextView
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/arrow"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/privacy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/privacy_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/privacy_policy"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/privacy_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/and_data_usage"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/privacy_main" />
<TextView
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/arrow"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/donate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/donate_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/donate"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/arrow"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/rate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/rate_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/rate_this_app"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/rate_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/on_google_play"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/rate_main" />
<TextView
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/arrow"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/report_error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp"
android:paddingHorizontal="16dp"
android:background="?android:selectableItemBackground">
<TextView
android:id="@+id/report_error_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:text="@string/report_error"
android:textSize="18sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/report_error_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/report_error_main"
app:layout_constraintStart_toStartOf="parent"
android:paddingStart="2dp"
android:paddingEnd="30dp"
android:textSize="16sp"
android:text="@string/on_github" />
<TextView
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/arrow"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -191,6 +191,32 @@
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<!-- Barcode encoding -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/inputPadding"
android:paddingTop="@dimen/inputPadding"
android:orientation="horizontal">
<!-- Barcode type -->
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/barcodeEncodingView"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:hint="@string/barcodeEncoding"
android:labelFor="@+id/barcodeEncodingField">
<AutoCompleteTextView
android:id="@+id/barcodeEncodingField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"/>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<!-- Barcode -->
<LinearLayout android:orientation="horizontal"
android:layout_marginTop="10.0dp"

View File

@@ -8,9 +8,9 @@ Oğuz Ersen
FC (Fay) Stegerman
StoyanDimitrov
大王叫我来巡山
B o d o
SlavekB
Katharine Chui
B o d o
mondstern
IllusiveMan196
Silvério Santos

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>

View File

@@ -144,6 +144,7 @@
<item>nb-rNO</item>
<item>nl</item>
<item>oc</item>
<!-- <item>peo</item> -->
<item>pl</item>
<item>pt</item>
<item>pt-rBR</item>

View File

@@ -361,5 +361,6 @@
<string name="copy_value">Copy value</string>
<string name="copied_to_clipboard">Copied to clipboard</string>
<string name="nothing_to_copy">No value found</string>
<string name="back">Back</string>
<string name="barcodeEncoding">Barcode encoding</string>
<string name="automatic">Automatic</string>
</resources>

View File

@@ -1,4 +1,5 @@
<resources>
<style name="AppTheme" parent="Theme.Material3.Light.NoActionBar">
<item name="colorPrimary">@color/md_theme_light_primary</item>
<item name="colorOnPrimary">@color/md_theme_light_onPrimary</item>

View File

@@ -0,0 +1,171 @@
package protect.card_locker
import android.content.Intent
import android.net.Uri
import android.view.View
import android.widget.TextView
import androidx.core.view.isVisible
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
import org.robolectric.shadows.ShadowActivity
import org.robolectric.shadows.ShadowLog
import java.lang.reflect.Method
@RunWith(RobolectricTestRunner::class)
class AboutActivityTest {
private lateinit var activityController: org.robolectric.android.controller.ActivityController<AboutActivity>
private lateinit var activity: AboutActivity
private lateinit var shadowActivity: ShadowActivity
@Before
fun setUp() {
ShadowLog.stream = System.out
activityController = Robolectric.buildActivity(AboutActivity::class.java)
activity = activityController.get()
shadowActivity = shadowOf(activity)
}
@Test
fun testActivityCreation() {
activityController.create().start().resume()
// Verify activity title is set correctly
assertEquals(activity.title.toString(),
activity.getString(R.string.about_title_fmt, activity.getString(R.string.app_name)))
// Check key elements are initialized
assertNotNull(activity.findViewById(R.id.toolbar))
assertNotNull(activity.findViewById(R.id.credits_sub))
assertNotNull(activity.findViewById(R.id.version_history_sub))
}
@Test
fun testDisplayOptionsBasedOnConfig() {
activityController.create().start().resume()
// Test Google Play rate button visibility based on BuildConfig
val rateButton = activity.findViewById<View>(R.id.rate)
assertEquals(BuildConfig.showRateOnGooglePlay, rateButton.isVisible)
// Test donate button visibility based on BuildConfig
val donateButton = activity.findViewById<View>(R.id.donate)
assertEquals(BuildConfig.showDonate, donateButton.isVisible)
}
@Test
fun testClickListeners() {
activityController.create().start().resume()
// Test clicking on a link that opens external browser
val repoButton = activity.findViewById<View>(R.id.repo)
repoButton.performClick()
val startedIntent = shadowActivity.nextStartedActivity
assertEquals(Intent.ACTION_VIEW, startedIntent.action)
assertEquals(Uri.parse("https://github.com/CatimaLoyalty/Android/"),
startedIntent.data)
}
@Test
fun testActivityDestruction() {
activityController.create().start().resume()
// Verify a view exists before destruction
assertNotNull(activity.findViewById(R.id.credits_sub))
activityController.pause().stop().destroy()
// Verify activity was destroyed
assertTrue(activity.isDestroyed)
}
@Test
fun testDialogContentMethods() {
activityController.create().start().resume()
// Use reflection to test private methods
try {
val showCreditsMethod: Method = AboutActivity::class.java.getDeclaredMethod("showCredits")
showCreditsMethod.isAccessible = true
showCreditsMethod.invoke(activity) // Should not throw exception
val showHistoryMethod: Method = AboutActivity::class.java.getDeclaredMethod("showHistory", View::class.java)
showHistoryMethod.isAccessible = true
showHistoryMethod.invoke(activity, activity.findViewById(R.id.version_history)) // Should not throw exception
} catch (e: Exception) {
fail("Exception when calling dialog methods: ${e.message}")
}
}
@Test
fun testExternalBrowserWithDifferentURLs() {
activityController.create().start().resume()
try {
// Get access to the private method
val openExternalBrowserMethod: Method = AboutActivity::class.java.getDeclaredMethod("openExternalBrowser", View::class.java)
openExternalBrowserMethod.isAccessible = true
// Create test URLs
val testUrls = arrayOf(
"https://hosted.weblate.org/engage/catima/",
"https://github.com/CatimaLoyalty/Android/blob/main/LICENSE",
"https://catima.app/privacy-policy/",
"https://github.com/CatimaLoyalty/Android/issues"
)
for (url in testUrls) {
// Create a View with the URL as tag
val testView = View(activity)
testView.tag = url
// Call the method directly
openExternalBrowserMethod.invoke(activity, testView)
// Verify the intent
val intent = shadowActivity.nextStartedActivity
assertNotNull("No intent launched for URL: $url", intent)
assertEquals(Intent.ACTION_VIEW, intent.action)
assertEquals(Uri.parse(url), intent.data)
}
} catch (e: Exception) {
fail("Exception during reflection: ${e.message}")
}
}
@Test
fun testButtonVisibilityBasedOnBuildConfig() {
activityController.create().start().resume()
// Get the current values from BuildConfig
val showRateOnGooglePlay = BuildConfig.showRateOnGooglePlay
val showDonate = BuildConfig.showDonate
// Test that the visibility matches the BuildConfig values
assertEquals(showRateOnGooglePlay, activity.findViewById<View>(R.id.rate).isVisible)
assertEquals(showDonate, activity.findViewById<View>(R.id.donate).isVisible)
}
@Test
fun testAboutScreenTextContent() {
activityController.create().start().resume()
// Verify that text fields contain the expected content
val creditsSub = activity.findViewById<TextView>(R.id.credits_sub)
assertNotNull(creditsSub.text)
assertFalse(creditsSub.text.toString().isEmpty())
val versionHistorySub = activity.findViewById<TextView>(R.id.version_history_sub)
assertNotNull(versionHistorySub.text)
assertFalse(versionHistorySub.text.toString().isEmpty())
}
}

View File

@@ -21,6 +21,7 @@ import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Currency;
import java.util.List;
@@ -41,7 +42,7 @@ public class DatabaseTest {
@Test
public void addRemoveOneGiftCard() {
assertEquals(0, DBHelper.getLoyaltyCardCount(mDatabase));
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), DEFAULT_HEADER_COLOR, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, DEFAULT_HEADER_COLOR, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
assertEquals(1, DBHelper.getLoyaltyCardCount(mDatabase));
@@ -57,6 +58,7 @@ public class DatabaseTest {
assertEquals("cardId", loyaltyCard.cardId);
assertEquals(null, loyaltyCard.barcodeId);
assertEquals(BarcodeFormat.UPC_A, loyaltyCard.barcodeType.format());
assertEquals(null, loyaltyCard.barcodeEncoding);
assertEquals(DEFAULT_HEADER_COLOR, loyaltyCard.headerColor);
assertEquals(0, loyaltyCard.starStatus);
assertEquals(0, loyaltyCard.archiveStatus);
@@ -69,12 +71,12 @@ public class DatabaseTest {
@Test
public void updateGiftCard() {
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), DEFAULT_HEADER_COLOR, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, DEFAULT_HEADER_COLOR, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
assertEquals(1, DBHelper.getLoyaltyCardCount(mDatabase));
result = DBHelper.updateLoyaltyCard(mDatabase, 1, "store1", "note1", null, null, new BigDecimal("10.00"), Currency.getInstance("EUR"), "cardId1", null, CatimaBarcode.fromBarcode(BarcodeFormat.AZTEC), DEFAULT_HEADER_COLOR, 0, null, 0);
result = DBHelper.updateLoyaltyCard(mDatabase, 1, "store1", "note1", null, null, new BigDecimal("10.00"), Currency.getInstance("EUR"), "cardId1", null, CatimaBarcode.fromBarcode(BarcodeFormat.AZTEC), StandardCharsets.UTF_8, DEFAULT_HEADER_COLOR, 0, null, 0);
assertTrue(result);
assertEquals(1, DBHelper.getLoyaltyCardCount(mDatabase));
@@ -89,6 +91,7 @@ public class DatabaseTest {
assertEquals("cardId1", loyaltyCard.cardId);
assertEquals(null, loyaltyCard.barcodeId);
assertEquals(BarcodeFormat.AZTEC, loyaltyCard.barcodeType.format());
assertEquals(StandardCharsets.UTF_8, loyaltyCard.barcodeEncoding);
assertEquals(DEFAULT_HEADER_COLOR, loyaltyCard.headerColor);
assertEquals(0, loyaltyCard.starStatus);
assertEquals(0, loyaltyCard.archiveStatus);
@@ -96,7 +99,7 @@ public class DatabaseTest {
@Test
public void updateGiftCardOnlyStar() {
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), DEFAULT_HEADER_COLOR, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, DEFAULT_HEADER_COLOR, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
assertEquals(1, DBHelper.getLoyaltyCardCount(mDatabase));
@@ -116,6 +119,7 @@ public class DatabaseTest {
assertEquals("cardId", loyaltyCard.cardId);
assertEquals(null, loyaltyCard.barcodeId);
assertEquals(BarcodeFormat.UPC_A, loyaltyCard.barcodeType.format());
assertEquals(null, loyaltyCard.barcodeEncoding);
assertEquals(DEFAULT_HEADER_COLOR, loyaltyCard.headerColor);
assertEquals(1, loyaltyCard.starStatus);
assertEquals(0, loyaltyCard.archiveStatus);
@@ -126,14 +130,14 @@ public class DatabaseTest {
assertEquals(0, DBHelper.getLoyaltyCardCount(mDatabase));
boolean result = DBHelper.updateLoyaltyCard(mDatabase, 1, "store1", "note1", null, null, new BigDecimal("0"), null, "cardId1",
null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), DEFAULT_HEADER_COLOR, 0, null, 0);
null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, DEFAULT_HEADER_COLOR, 0, null, 0);
assertEquals(false, result);
assertEquals(0, DBHelper.getLoyaltyCardCount(mDatabase));
}
@Test
public void emptyGiftCardValues() {
long id = DBHelper.insertLoyaltyCard(mDatabase, "", "", null, null, new BigDecimal("0"), null, "", null, null, null, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, "", "", null, null, new BigDecimal("0"), null, "", null, null, null, null, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
assertEquals(1, DBHelper.getLoyaltyCardCount(mDatabase));
@@ -149,6 +153,7 @@ public class DatabaseTest {
assertEquals("", loyaltyCard.cardId);
assertEquals(null, loyaltyCard.barcodeId);
assertEquals(null, loyaltyCard.barcodeType);
assertEquals(null, loyaltyCard.barcodeEncoding);
// headerColor is randomly generated when not given, so skip
assertEquals(0, loyaltyCard.starStatus);
assertEquals(0, loyaltyCard.archiveStatus);
@@ -162,7 +167,7 @@ public class DatabaseTest {
// that they are sorted
for (int index = CARDS_TO_ADD - 1; index >= 0; index--) {
long id = DBHelper.insertLoyaltyCard(mDatabase, "store" + index, "note" + index, null, null, new BigDecimal("0"), null, "cardId" + index,
null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), index, 0, null,0);
null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), StandardCharsets.UTF_8, index, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
}
@@ -186,6 +191,7 @@ public class DatabaseTest {
assertEquals("cardId" + index, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.CARD_ID)));
assertEquals(null, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ID)));
assertEquals(BarcodeFormat.UPC_A.toString(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)));
assertEquals(StandardCharsets.UTF_8.name(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING)));
assertEquals(index, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR)));
assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.ARCHIVE_STATUS)));
@@ -208,10 +214,10 @@ public class DatabaseTest {
for (int index = CARDS_TO_ADD - 1; index >= 0; index--) {
if (index == CARDS_TO_ADD - 1) {
id = DBHelper.insertLoyaltyCard(mDatabase, "store" + index, "note" + index, null, null, new BigDecimal("0"), null, "cardId" + index,
null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), index, 1, null,0);
null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, index, 1, null,0);
} else {
id = DBHelper.insertLoyaltyCard(mDatabase, "store" + index, "note" + index, null, null, new BigDecimal("0"), null, "cardId" + index,
null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), index, 0, null,0);
null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, index, 0, null,0);
}
boolean result = (id != -1);
assertTrue(result);
@@ -235,6 +241,7 @@ public class DatabaseTest {
assertEquals("cardId" + index, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.CARD_ID)));
assertEquals(null, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ID)));
assertEquals(BarcodeFormat.UPC_A.toString(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)));
assertEquals(null, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ENCODING)));
assertEquals(index, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR)));
assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
@@ -310,7 +317,7 @@ public class DatabaseTest {
public void updateGroup() {
// Create card
assertEquals(0, DBHelper.getLoyaltyCardCount(mDatabase));
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), DEFAULT_HEADER_COLOR, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, DEFAULT_HEADER_COLOR, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
assertEquals(1, DBHelper.getLoyaltyCardCount(mDatabase));
@@ -422,7 +429,7 @@ public class DatabaseTest {
public void cardAddAndRemoveGroups() {
// Create card
assertEquals(0, DBHelper.getLoyaltyCardCount(mDatabase));
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), DEFAULT_HEADER_COLOR, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, DEFAULT_HEADER_COLOR, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
assertEquals(1, DBHelper.getLoyaltyCardCount(mDatabase));
@@ -516,7 +523,7 @@ public class DatabaseTest {
@Test
public void updateGiftCardOnlyBalance() {
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("100"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), DEFAULT_HEADER_COLOR, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("100"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, DEFAULT_HEADER_COLOR, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
assertEquals(1, DBHelper.getLoyaltyCardCount(mDatabase));

View File

@@ -36,6 +36,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
@@ -73,7 +74,7 @@ public class ImportExportTest {
for (int index = cardsToAdd; index > 4; index--) {
String storeName = String.format("store, \"%4d", index);
String note = String.format("note, \"%4d", index);
long id = DBHelper.insertLoyaltyCard(mDatabase, storeName, note, null, null, new BigDecimal(String.valueOf(index)), null, BARCODE_DATA, null, BARCODE_TYPE, index, 1, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, storeName, note, null, null, new BigDecimal(String.valueOf(index)), null, BARCODE_DATA, null, BARCODE_TYPE, null, index, 1, null,0);
boolean result = (id != -1);
assertTrue(result);
}
@@ -81,7 +82,7 @@ public class ImportExportTest {
String storeName = String.format("store, \"%4d", index);
String note = String.format("note, \"%4d", index);
//if index is even
long id = DBHelper.insertLoyaltyCard(mDatabase, storeName, note, null, null, new BigDecimal(String.valueOf(index)), null, BARCODE_DATA, null, BARCODE_TYPE, index, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, storeName, note, null, null, new BigDecimal(String.valueOf(index)), null, BARCODE_DATA, null, BARCODE_TYPE, null, index, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
}
@@ -90,7 +91,7 @@ public class ImportExportTest {
@Test
public void addLoyaltyCardsWithExpiryNeverPastTodayFuture() {
long id = DBHelper.insertLoyaltyCard(mDatabase, "No Expiry", "", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, 0, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, "No Expiry", "", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, 0, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
@@ -104,10 +105,11 @@ public class ImportExportTest {
assertEquals(BARCODE_DATA, card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BARCODE_TYPE.format(), card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(Integer.valueOf(0), card.headerColor);
assertEquals(0, card.starStatus);
id = DBHelper.insertLoyaltyCard(mDatabase, "Past", "", null, new Date((long) 1), new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, 0, 0, null,0);
id = DBHelper.insertLoyaltyCard(mDatabase, "Past", "", null, new Date((long) 1), new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, 0, 0, null,0);
result = (id != -1);
assertTrue(result);
@@ -121,10 +123,11 @@ public class ImportExportTest {
assertEquals(BARCODE_DATA, card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BARCODE_TYPE.format(), card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(Integer.valueOf(0), card.headerColor);
assertEquals(0, card.starStatus);
id = DBHelper.insertLoyaltyCard(mDatabase, "Today", "", null, new Date(), new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, 0, 0, null,0);
id = DBHelper.insertLoyaltyCard(mDatabase, "Today", "", null, new Date(), new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, 0, 0, null,0);
result = (id != -1);
assertTrue(result);
@@ -139,12 +142,13 @@ public class ImportExportTest {
assertEquals(BARCODE_DATA, card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BARCODE_TYPE.format(), card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(Integer.valueOf(0), card.headerColor);
assertEquals(0, card.starStatus);
// This will break after 19 January 2038
// If someone is still maintaining this code base by then: I love you
id = DBHelper.insertLoyaltyCard(mDatabase, "Future", "", null, new Date(2147483648000L), new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, 0, 0, null,0);
id = DBHelper.insertLoyaltyCard(mDatabase, "Future", "", null, new Date(2147483648000L), new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, 0, 0, null,0);
result = (id != -1);
assertTrue(result);
@@ -158,6 +162,7 @@ public class ImportExportTest {
assertEquals(BARCODE_DATA, card.cardId);
assertEquals(null, card.barcodeId);
assertEquals(BARCODE_TYPE.format(), card.barcodeType.format());
assertEquals(null, card.barcodeEncoding);
assertEquals(Integer.valueOf(0), card.headerColor);
assertEquals(0, card.starStatus);
@@ -830,7 +835,7 @@ public class ImportExportTest {
HashMap<Integer, Bitmap> loyaltyCardIconImages = new HashMap<>();
// Create card 1
int loyaltyCardId = (int) DBHelper.insertLoyaltyCard(mDatabase, "Card 1", "Note 1", new Date(1601510400), new Date(1618053234), new BigDecimal("100"), Currency.getInstance("USD"), "1234", "5432", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE), 1, 0, null,0);
int loyaltyCardId = (int) DBHelper.insertLoyaltyCard(mDatabase, "Card 1", "Note 1", new Date(1601510400), new Date(1618053234), new BigDecimal("100"), Currency.getInstance("USD"), "1234", "5432", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE), StandardCharsets.UTF_8, 1, 0, null,0);
loyaltyCardHashMap.put(loyaltyCardId, DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, loyaltyCardId));
DBHelper.insertGroup(mDatabase, "One");
List<Group> groups = Arrays.asList(DBHelper.getGroup(mDatabase, "One"));
@@ -844,7 +849,7 @@ public class ImportExportTest {
loyaltyCardIconImages.put(loyaltyCardId, bitmap1);
// Create card 2
loyaltyCardId = (int) DBHelper.insertLoyaltyCard(mDatabase, "Card 2", "", null, null, new BigDecimal(0), null, "123456", null, null, 2, 1, null,0);
loyaltyCardId = (int) DBHelper.insertLoyaltyCard(mDatabase, "Card 2", "", null, null, new BigDecimal(0), null, "123456", null, null, null, 2, 1, null,0);
loyaltyCardHashMap.put(loyaltyCardId, DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, loyaltyCardId));
// Export everything
@@ -875,6 +880,7 @@ public class ImportExportTest {
assertEquals(loyaltyCard.barcodeId, dbLoyaltyCard.barcodeId);
assertEquals(loyaltyCard.starStatus, dbLoyaltyCard.starStatus);
assertEquals(loyaltyCard.barcodeType != null ? loyaltyCard.barcodeType.format() : null, dbLoyaltyCard.barcodeType != null ? dbLoyaltyCard.barcodeType.format() : null);
assertEquals(loyaltyCard.barcodeEncoding != null ? loyaltyCard.barcodeEncoding : null, dbLoyaltyCard.barcodeEncoding != null ? dbLoyaltyCard.barcodeEncoding : null);
assertEquals(loyaltyCard.balanceType, dbLoyaltyCard.balanceType);
assertEquals(loyaltyCard.headerColor, dbLoyaltyCard.headerColor);

View File

@@ -20,6 +20,7 @@ import org.robolectric.RobolectricTestRunner;
import java.io.InvalidObjectException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Currency;
import java.util.Date;
@@ -41,7 +42,7 @@ public class ImportURITest {
// Generate card
Date date = new Date();
DBHelper.insertLoyaltyCard(mDatabase, "store", "This note contains evil symbols like & and = that will break the parser if not escaped right $#!%()*+;:á", date, date, new BigDecimal("100"), null, BarcodeFormat.UPC_E.toString(), BarcodeFormat.UPC_A.toString(), CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE), Color.BLACK, 1, null,0);
DBHelper.insertLoyaltyCard(mDatabase, "store", "This note contains evil symbols like & and = that will break the parser if not escaped right $#!%()*+;:á", date, date, new BigDecimal("100"), null, BarcodeFormat.UPC_E.toString(), BarcodeFormat.UPC_A.toString(), CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE), StandardCharsets.UTF_8, Color.BLACK, 1, null,0);
// Get card
LoyaltyCard card = DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, 1);
@@ -62,6 +63,7 @@ public class ImportURITest {
assertEquals(card.cardId, parsedCard.cardId);
assertEquals(card.barcodeId, parsedCard.barcodeId);
assertEquals(card.barcodeType.format(), parsedCard.barcodeType.format());
assertEquals(card.barcodeEncoding, parsedCard.barcodeEncoding);
assertEquals(card.headerColor, parsedCard.headerColor);
// No export of starStatus for export URL foreseen therefore 0 will be imported
assertEquals(0, parsedCard.starStatus);
@@ -71,7 +73,7 @@ public class ImportURITest {
@Test
public void ensureNoCrashOnMissingHeaderFields() throws InvalidObjectException, UnsupportedEncodingException {
// Generate card
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("10.00"), Currency.getInstance("EUR"), BarcodeFormat.UPC_A.toString(), null, CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE), null, 0, null,0);
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("10.00"), Currency.getInstance("EUR"), BarcodeFormat.UPC_A.toString(), null, CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE), null, null, 0, null,0);
// Get card
LoyaltyCard card = DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, 1);
@@ -92,6 +94,7 @@ public class ImportURITest {
assertEquals(card.cardId, parsedCard.cardId);
assertEquals(card.barcodeId, parsedCard.barcodeId);
assertEquals(card.barcodeType.format(), parsedCard.barcodeType.format());
assertEquals(card.barcodeEncoding, parsedCard.barcodeEncoding);
assertNull(parsedCard.headerColor);
// No export of starStatus for export URL foreseen therefore 0 will be imported
assertEquals(0, parsedCard.starStatus);
@@ -101,7 +104,7 @@ public class ImportURITest {
@Test
public void parseWithTrailingSlash() throws InvalidObjectException, UnsupportedEncodingException {
// Generate card
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("10.00"), Currency.getInstance("EUR"), BarcodeFormat.UPC_A.toString(), null, CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE), null, 0, null,0);
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("10.00"), Currency.getInstance("EUR"), BarcodeFormat.UPC_A.toString(), null, CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE), StandardCharsets.UTF_8, null, 0, null,0);
// Get card
LoyaltyCard card = DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, 1);
@@ -123,6 +126,7 @@ public class ImportURITest {
assertEquals(card.cardId, parsedCard.cardId);
assertEquals(card.barcodeId, parsedCard.barcodeId);
assertEquals(card.barcodeType.format(), parsedCard.barcodeType.format());
assertEquals(card.barcodeEncoding, parsedCard.barcodeEncoding);
assertNull(parsedCard.headerColor);
// No export of starStatus for export URL foreseen therefore 0 will be imported
assertEquals(0, parsedCard.starStatus);

View File

@@ -96,7 +96,7 @@ public class LoyaltyCardCursorAdapterTest {
@Test
public void TestCursorAdapterEmptyNote() {
DBHelper.insertLoyaltyCard(mDatabase, "store", "", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(mDatabase, "store", "", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
LoyaltyCard card = DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, 1);
Cursor cursor = DBHelper.getLoyaltyCardCursor(mDatabase);
@@ -111,7 +111,7 @@ public class LoyaltyCardCursorAdapterTest {
@Test
public void TestCursorAdapterWithNote() {
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
LoyaltyCard card = DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, 1);
Cursor cursor = DBHelper.getLoyaltyCardCursor(mDatabase);
@@ -126,10 +126,10 @@ public class LoyaltyCardCursorAdapterTest {
@Test
public void TestCursorAdapterStarring() {
assertNotEquals(-1, DBHelper.insertLoyaltyCard(mDatabase, "storeA", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,1));
assertNotEquals(-1, DBHelper.insertLoyaltyCard(mDatabase, "storeB", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 1, null,1));
assertNotEquals(-1, DBHelper.insertLoyaltyCard(mDatabase, "storeC", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0));
assertNotEquals(-1, DBHelper.insertLoyaltyCard(mDatabase, "storeD", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 1, null,0));
assertNotEquals(-1, DBHelper.insertLoyaltyCard(mDatabase, "storeA", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,1));
assertNotEquals(-1, DBHelper.insertLoyaltyCard(mDatabase, "storeB", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 1, null,1));
assertNotEquals(-1, DBHelper.insertLoyaltyCard(mDatabase, "storeC", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0));
assertNotEquals(-1, DBHelper.insertLoyaltyCard(mDatabase, "storeD", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 1, null,0));
assertEquals(4, DBHelper.getLoyaltyCardCount(mDatabase));
@@ -177,7 +177,7 @@ public class LoyaltyCardCursorAdapterTest {
@Test
public void TestCursorAdapter0Points() {
DBHelper.insertLoyaltyCard(mDatabase, "store", "", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(mDatabase, "store", "", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
LoyaltyCard card = DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, 1);
Cursor cursor = DBHelper.getLoyaltyCardCursor(mDatabase);
@@ -192,7 +192,7 @@ public class LoyaltyCardCursorAdapterTest {
@Test
public void TestCursorAdapter0EUR() {
DBHelper.insertLoyaltyCard(mDatabase,"store", "", null, null, new BigDecimal("0"), Currency.getInstance("EUR"), "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(mDatabase,"store", "", null, null, new BigDecimal("0"), Currency.getInstance("EUR"), "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
LoyaltyCard card = DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, 1);
Cursor cursor = DBHelper.getLoyaltyCardCursor(mDatabase);
@@ -207,7 +207,7 @@ public class LoyaltyCardCursorAdapterTest {
@Test
public void TestCursorAdapter100Points() {
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("100"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("100"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
LoyaltyCard card = DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, 1);
Cursor cursor = DBHelper.getLoyaltyCardCursor(mDatabase);
@@ -222,7 +222,7 @@ public class LoyaltyCardCursorAdapterTest {
@Test
public void TestCursorAdapter10USD() {
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("10.00"), Currency.getInstance("USD"), "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(mDatabase, "store", "note", null, null, new BigDecimal("10.00"), Currency.getInstance("USD"), "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
LoyaltyCard card = DBHelper.getLoyaltyCard(activity.getApplicationContext(), mDatabase, 1);
Cursor cursor = DBHelper.getLoyaltyCardCursor(mDatabase);

View File

@@ -65,6 +65,8 @@ import org.robolectric.shadows.ShadowLog;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.ParseException;
import java.time.Instant;
@@ -133,6 +135,7 @@ public class LoyaltyCardViewActivityTest {
final String cardId,
final String barcodeId,
final String barcodeType,
final String barcodeEncoding,
boolean creatingNewCard) throws ParseException {
SQLiteDatabase database = new DBHelper(activity).getWritableDatabase();
if (creatingNewCard) {
@@ -150,6 +153,7 @@ public class LoyaltyCardViewActivityTest {
final TextView cardIdField = activity.findViewById(R.id.cardIdView);
final TextView barcodeIdField = activity.findViewById(R.id.barcodeIdField);
final TextView barcodeTypeField = activity.findViewById(R.id.barcodeTypeField);
final TextView barcodeEncodingField = activity.findViewById(R.id.barcodeEncodingField);
storeField.setText(store);
noteField.setText(note);
@@ -160,6 +164,7 @@ public class LoyaltyCardViewActivityTest {
cardIdField.setText(cardId);
barcodeIdField.setText(barcodeId);
barcodeTypeField.setText(barcodeType);
barcodeEncodingField.setText(barcodeEncoding);
assertEquals(false, activity.isFinishing());
activity.findViewById(R.id.fabSave).performClick();
@@ -207,6 +212,14 @@ public class LoyaltyCardViewActivityTest {
} else {
assertEquals(CatimaBarcode.fromName(barcodeType).format(), card.barcodeType.format());
}
// The special "Automatic" string shouldn't actually be written to the loyalty card
if (barcodeEncoding.equals(activity.getApplicationContext().getString(R.string.automatic))) {
assertEquals(null, card.barcodeEncoding);
} else {
assertEquals(Charset.forName(barcodeEncoding), card.barcodeEncoding);
}
assertNotNull(card.headerColor);
database.close();
@@ -323,6 +336,7 @@ public class LoyaltyCardViewActivityTest {
final String expiryString, final String balanceString,
final String balanceTypeString, final String cardId,
final String barcodeId, final String barcodeType,
final String barcodeEncoding,
final Bitmap frontImage, final Bitmap backImage) {
if (mode == ViewMode.VIEW_CARD) {
checkFieldProperties(activity, R.id.main_image_description, View.VISIBLE, cardId, FieldTypeView.TextView);
@@ -338,6 +352,7 @@ public class LoyaltyCardViewActivityTest {
checkFieldProperties(activity, R.id.cardIdView, View.VISIBLE, cardId, FieldTypeView.TextView);
checkFieldProperties(activity, R.id.barcodeIdField, View.VISIBLE, barcodeId, FieldTypeView.TextView);
checkFieldProperties(activity, R.id.barcodeTypeField, View.VISIBLE, barcodeType, FieldTypeView.TextView);
checkFieldProperties(activity, R.id.barcodeEncodingField, View.VISIBLE, barcodeEncoding, FieldTypeView.TextView);
//checkFieldProperties(activity, R.id.barcode, View.VISIBLE, null, FieldTypeView.ImageView);
checkFieldProperties(activity, R.id.frontImage, View.VISIBLE, frontImage, FieldTypeView.ImageView);
checkFieldProperties(activity, R.id.backImage, View.VISIBLE, backImage, FieldTypeView.ImageView);
@@ -359,7 +374,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
// Check default settings
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), context.getString(R.string.automatic), null, null);
}
@Test
@@ -379,7 +394,7 @@ public class LoyaltyCardViewActivityTest {
System.out.println();
if (!newCard) {
cardId = (int) DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
cardId = (int) DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, StandardCharsets.UTF_8, Color.BLACK, 0, null, 0);
} else {
cardId = null;
}
@@ -394,7 +409,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
// Check default settings
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, newCard ? "" : "store", newCard ? "" : "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), newCard ? "" : EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), newCard ? context.getString(R.string.noBarcode) : EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, newCard ? "" : "store", newCard ? "" : "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), newCard ? "" : EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), newCard ? context.getString(R.string.noBarcode) : EAN_BARCODE_TYPE.prettyName(), newCard ? context.getString(R.string.automatic) : StandardCharsets.UTF_8.name(), null, null);
// Change everything
final EditText storeField = activity.findViewById(R.id.storeNameEdit);
@@ -406,6 +421,7 @@ public class LoyaltyCardViewActivityTest {
final EditText cardIdField = activity.findViewById(R.id.cardIdView);
final EditText barcodeField = activity.findViewById(R.id.barcodeIdField);
final EditText barcodeTypeField = activity.findViewById(R.id.barcodeTypeField);
final EditText barcodeEncodingField = activity.findViewById(R.id.barcodeEncodingField);
final ImageView frontImageView = activity.findViewById(R.id.frontImage);
final ImageView backImageView = activity.findViewById(R.id.backImage);
@@ -426,13 +442,14 @@ public class LoyaltyCardViewActivityTest {
cardIdField.setText("12345678");
barcodeField.setText("87654321");
barcodeTypeField.setText(CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName());
barcodeEncodingField.setText(StandardCharsets.ISO_8859_1.name());
activity.setCardImage(ImageLocationType.front, frontImageView, frontBitmap, true);
activity.setCardImage(ImageLocationType.back, backImageView, backBitmap, true);
shadowOf(getMainLooper()).idle();
// Check if changed
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), frontBitmap, backBitmap);
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
// Resume
activityController.pause();
@@ -441,7 +458,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
// Check if no changes lost
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), frontBitmap, backBitmap);
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
// Rotate to landscape
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
@@ -449,7 +466,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
// Check if no changes lost
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), frontBitmap, backBitmap);
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
// Rotate to portrait
shadowOf(getMainLooper()).idle();
@@ -457,7 +474,7 @@ public class LoyaltyCardViewActivityTest {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// Check if no changes lost
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), frontBitmap, backBitmap);
checkAllFields(activity, newCard ? ViewMode.ADD_CARD : ViewMode.UPDATE_CARD, "correct store", "correct note", DateFormat.getDateInstance(DateFormat.LONG).format(validFromDate), DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate), "100.00", currency.getSymbol(), "12345678", "87654321", CatimaBarcode.fromBarcode(BarcodeFormat.QR_CODE).prettyName(), StandardCharsets.ISO_8859_1.name(), frontBitmap, backBitmap);
}
}
@@ -471,7 +488,7 @@ public class LoyaltyCardViewActivityTest {
Activity activity = (Activity) activityController.get();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), context.getString(R.string.automatic), null, null);
}
@Test
@@ -531,18 +548,18 @@ public class LoyaltyCardViewActivityTest {
Activity activity = (Activity) activityController.get();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), context.getString(R.string.automatic), null, null);
// Complete barcode capture successfully
captureBarcodeWithResult(activity, true);
activityController.resume();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
shadowOf(getMainLooper()).idle();
// Save and check the loyalty card
saveLoyaltyCardWithArguments(activity, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), new BigDecimal("0"), context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.name(), true);
saveLoyaltyCardWithArguments(activity, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), new BigDecimal("0"), context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.name(), context.getString(R.string.automatic), true);
}
@Test
@@ -555,7 +572,7 @@ public class LoyaltyCardViewActivityTest {
Activity activity = (Activity) activityController.get();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), context.getString(R.string.automatic), null, null);
// Complete barcode capture in failure
captureBarcodeWithResult(activity, false);
@@ -563,7 +580,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), context.getString(R.string.automatic), null, null);
}
@Test
@@ -576,13 +593,13 @@ public class LoyaltyCardViewActivityTest {
LoyaltyCardEditActivity activity = (LoyaltyCardEditActivity) activityController.get();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), context.getString(R.string.automatic), null, null);
// Complete barcode capture successfully
captureBarcodeWithResult(activity, true);
activityController.resume();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Cancel the loyalty card creation
assertEquals(false, activity.isFinishing());
@@ -627,17 +644,16 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
activityController.start();
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
database.close();
}
@@ -647,7 +663,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, StandardCharsets.UTF_8, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(false, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -656,7 +672,7 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.VIEW_CARD, "store", "note", null, null, "0", context.getString(R.string.points), BARCODE_DATA, null, BARCODE_TYPE.toString(), null, null);
checkAllFields(activity, ViewMode.VIEW_CARD, "store", "note", null, null, "0", context.getString(R.string.points), BARCODE_DATA, null, BARCODE_TYPE.toString(), StandardCharsets.UTF_8.name(), null, null);
database.close();
}
@@ -666,7 +682,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, StandardCharsets.UTF_8, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -675,13 +691,13 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), StandardCharsets.UTF_8.name(), null, null);
// Complete barcode capture successfully
captureBarcodeWithResult(activity, true);
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), StandardCharsets.UTF_8.name(), null, null);
database.close();
}
@@ -691,7 +707,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
LoyaltyCardEditActivity activity = (LoyaltyCardEditActivity) activityController.get();
@@ -700,13 +716,13 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Complete barcode capture successfully
captureBarcodeWithResult(activity, true);
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Cancel the loyalty card creation
assertEquals(false, activity.isFinishing());
@@ -730,7 +746,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -739,7 +755,7 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Set date to today
MaterialAutoCompleteTextView expiryField = activity.findViewById(R.id.expiryField);
@@ -753,7 +769,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), DateFormat.getDateInstance(DateFormat.LONG).format(new Date()), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), DateFormat.getDateInstance(DateFormat.LONG).format(new Date()), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
database.close();
}
@@ -763,7 +779,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, new Date(), new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, new Date(), new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -772,13 +788,13 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), DateFormat.getDateInstance(DateFormat.LONG).format(new Date()), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), DateFormat.getDateInstance(DateFormat.LONG).format(new Date()), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Set date to never
MaterialAutoCompleteTextView expiryField = activity.findViewById(R.id.expiryField);
expiryField.setText(expiryField.getAdapter().getItem(0).toString(), false);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
database.close();
}
@@ -788,7 +804,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -797,7 +813,7 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Set balance to 10 points
EditText balanceField = activity.findViewById(R.id.balanceField);
@@ -826,7 +842,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", DateFormat.getDateInstance(DateFormat.LONG).format(new Date()), DateFormat.getDateInstance(DateFormat.LONG).format(new Date()), "10.00", "", EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE.toString(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", DateFormat.getDateInstance(DateFormat.LONG).format(new Date()), DateFormat.getDateInstance(DateFormat.LONG).format(new Date()), "10.00", "", EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE.toString(), context.getString(R.string.automatic), null, null);
database.close();
}
@@ -839,7 +855,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("10.00"), Currency.getInstance("USD"), EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("10.00"), Currency.getInstance("USD"), EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -848,7 +864,7 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "10.00", "$", EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "10.00", "$", EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
shadowOf(getMainLooper()).idle();
@@ -870,7 +886,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", "", EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", "", EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
database.close();
}
@@ -880,7 +896,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -889,7 +905,7 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Change barcode ID
EditText barcodeField = activity.findViewById(R.id.barcodeIdField);
@@ -902,7 +918,7 @@ public class LoyaltyCardViewActivityTest {
AlertDialog updateBarcodeIdDialog = (AlertDialog) (ShadowDialog.getLatestDialog());
assertNull(updateBarcodeIdDialog);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
database.close();
}
@@ -912,7 +928,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -921,7 +937,7 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Change card ID
EditText cardIdField = activity.findViewById(R.id.cardIdView);
@@ -936,7 +952,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "123456", context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "123456", context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
database.close();
}
@@ -946,7 +962,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -955,7 +971,7 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Change card ID
EditText cardIdField = activity.findViewById(R.id.cardIdView);
@@ -973,7 +989,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "654321", context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "654321", context.getString(R.string.sameAsCardId), EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
database.close();
}
@@ -983,7 +999,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -992,7 +1008,7 @@ public class LoyaltyCardViewActivityTest {
activityController.visible();
activityController.resume();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), EAN_BARCODE_DATA, "123456", EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Change card ID
EditText cardIdField = activity.findViewById(R.id.cardIdView);
@@ -1010,7 +1026,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "654321", "123456", EAN_BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "654321", "123456", EAN_BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
database.close();
}
@@ -1020,7 +1036,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(false, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -1065,7 +1081,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(false, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -1086,7 +1102,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, null, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(false, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -1107,7 +1123,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, null, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -1117,7 +1133,7 @@ public class LoyaltyCardViewActivityTest {
activityController.resume();
// Save and check the loyalty card
saveLoyaltyCardWithArguments(activity, "store", "note", activity.getApplicationContext().getString(R.string.anyDate), activity.getApplicationContext().getString(R.string.never), new BigDecimal("0"), activity.getApplicationContext().getString(R.string.points), BARCODE_DATA, activity.getApplicationContext().getString(R.string.sameAsCardId), BARCODE_TYPE.name(), false);
saveLoyaltyCardWithArguments(activity, "store", "note", activity.getApplicationContext().getString(R.string.anyDate), activity.getApplicationContext().getString(R.string.never), new BigDecimal("0"), activity.getApplicationContext().getString(R.string.points), BARCODE_DATA, activity.getApplicationContext().getString(R.string.sameAsCardId), BARCODE_TYPE.name(), activity.getApplicationContext().getString(R.string.automatic), false);
database.close();
}
@@ -1127,7 +1143,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, null, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, null, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -1137,7 +1153,7 @@ public class LoyaltyCardViewActivityTest {
activityController.resume();
// Save and check the loyalty card
saveLoyaltyCardWithArguments(activity, "store", "note", activity.getApplicationContext().getString(R.string.anyDate), activity.getApplicationContext().getString(R.string.never), new BigDecimal("0"), activity.getApplicationContext().getString(R.string.points), BARCODE_DATA, activity.getApplicationContext().getString(R.string.sameAsCardId), activity.getApplicationContext().getString(R.string.noBarcode), false);
saveLoyaltyCardWithArguments(activity, "store", "note", activity.getApplicationContext().getString(R.string.anyDate), activity.getApplicationContext().getString(R.string.never), new BigDecimal("0"), activity.getApplicationContext().getString(R.string.points), BARCODE_DATA, activity.getApplicationContext().getString(R.string.sameAsCardId), activity.getApplicationContext().getString(R.string.noBarcode), activity.getApplicationContext().getString(R.string.automatic), false);
database.close();
}
@@ -1147,7 +1163,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(true, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -1157,18 +1173,18 @@ public class LoyaltyCardViewActivityTest {
activityController.resume();
// First check if the card is as expected
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), BARCODE_TYPE.prettyName(), context.getString(R.string.automatic), null, null);
// Complete empty barcode selection successfully
selectBarcodeWithResult(activity, BARCODE_DATA, null, true);
activityController.resume();
// Check if the barcode type is NO_BARCODE as expected
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), null, null);
checkAllFields(activity, ViewMode.UPDATE_CARD, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), context.getString(R.string.automatic), null, null);
assertEquals(View.GONE, activity.findViewById(R.id.barcodeLayout).getVisibility());
// Check if the special NO_BARCODE string doesn't get saved
saveLoyaltyCardWithArguments(activity, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), new BigDecimal("0"), context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), false);
saveLoyaltyCardWithArguments(activity, "store", "note", context.getString(R.string.anyDate), context.getString(R.string.never), new BigDecimal("0"), context.getString(R.string.points), BARCODE_DATA, context.getString(R.string.sameAsCardId), context.getString(R.string.noBarcode), context.getString(R.string.automatic), false);
database.close();
}
@@ -1178,7 +1194,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(false, (int) cardId);
Activity activity = (Activity) activityController.get();
@@ -1215,7 +1231,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(false, (int) cardId);
AppCompatActivity activity = (AppCompatActivity) activityController.get();
@@ -1311,7 +1327,7 @@ public class LoyaltyCardViewActivityTest {
final Context context = ApplicationProvider.getApplicationContext();
SQLiteDatabase database = TestHelpers.getEmptyDb(context).getWritableDatabase();
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, null, Color.BLACK, 0, null, 0);
long cardId = DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, BARCODE_DATA, null, null, null, Color.BLACK, 0, null, 0);
ActivityController activityController = createActivityWithLoyaltyCard(false, (int) cardId);
AppCompatActivity activity = (AppCompatActivity) activityController.get();
@@ -1350,7 +1366,7 @@ public class LoyaltyCardViewActivityTest {
public void importCard() {
Date date = new Date();
Uri importUri = Uri.parse("https://catima.app/share#store%3DExample%2BStore%26note%3D%26validfrom%3D" + date.getTime() + "%26expiry%3D" + date.getTime() + "%26balance%3D10.00%26balancetype%3DUSD%26cardid%3D123456%26barcodetype%3DAZTEC%26headercolor%3D-416706");
Uri importUri = Uri.parse("https://catima.app/share#store%3DExample%2BStore%26note%3D%26validfrom%3D" + date.getTime() + "%26expiry%3D" + date.getTime() + "%26balance%3D10.00%26balancetype%3DUSD%26cardid%3D123456%26barcodetype%3DAZTEC%26barcodeencoding%3D" + StandardCharsets.UTF_8.name() + "%26headercolor%3D-416706");
Intent intent = new Intent();
intent.setData(importUri);
@@ -1366,7 +1382,7 @@ public class LoyaltyCardViewActivityTest {
shadowOf(getMainLooper()).idle();
checkAllFields(activity, ViewMode.ADD_CARD, "Example Store", "", DateFormat.getDateInstance(DateFormat.LONG).format(date), DateFormat.getDateInstance(DateFormat.LONG).format(date), "10.00", "$", "123456", context.getString(R.string.sameAsCardId), "Aztec", null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "Example Store", "", DateFormat.getDateInstance(DateFormat.LONG).format(date), DateFormat.getDateInstance(DateFormat.LONG).format(date), "10.00", "$", "123456", context.getString(R.string.sameAsCardId), "Aztec", StandardCharsets.UTF_8.name(), null, null);
assertEquals(-416706, ((ColorDrawable) activity.findViewById(R.id.thumbnail).getBackground()).getColor());
}
@@ -1386,7 +1402,7 @@ public class LoyaltyCardViewActivityTest {
Activity activity = (Activity) activityController.get();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "Example Store", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "123456", context.getString(R.string.sameAsCardId), "Aztec", null, null);
checkAllFields(activity, ViewMode.ADD_CARD, "Example Store", "", context.getString(R.string.anyDate), context.getString(R.string.never), "0", context.getString(R.string.points), "123456", context.getString(R.string.sameAsCardId), "Aztec", context.getString(R.string.automatic), null, null);
assertEquals(-416706, ((ColorDrawable) activity.findViewById(R.id.thumbnail).getBackground()).getColor());
}
}

View File

@@ -97,7 +97,7 @@ public class MainActivityTest {
assertEquals(0, list.getAdapter().getItemCount());
SQLiteDatabase database = TestHelpers.getEmptyDb(mainActivity).getWritableDatabase();
DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "store", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
assertEquals(View.VISIBLE, helpSection.getVisibility());
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
@@ -132,10 +132,10 @@ public class MainActivityTest {
assertEquals(0, list.getAdapter().getItemCount());
SQLiteDatabase database = TestHelpers.getEmptyDb(mainActivity).getWritableDatabase();
DBHelper.insertLoyaltyCard(database, "storeB", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "storeA", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "storeD", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 1, null,0);
DBHelper.insertLoyaltyCard(database, "storeC", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 1, null,0);
DBHelper.insertLoyaltyCard(database, "storeB", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "storeA", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "storeD", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 1, null,0);
DBHelper.insertLoyaltyCard(database, "storeC", "note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 1, null,0);
assertEquals(View.VISIBLE, helpSection.getVisibility());
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
@@ -229,8 +229,8 @@ public class MainActivityTest {
TabLayout groupTabs = mainActivity.findViewById(R.id.groups);
SQLiteDatabase database = TestHelpers.getEmptyDb(mainActivity).getWritableDatabase();
DBHelper.insertLoyaltyCard(database, "The First Store", "Initial note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "The Second Store", "Secondary note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "The First Store", "Initial note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "The Second Store", "Secondary note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
DBHelper.insertGroup(database, "Group one");
List<Group> groups = new ArrayList<>();
@@ -485,8 +485,8 @@ public class MainActivityTest {
SQLiteDatabase database = TestHelpers.getEmptyDb(mainActivity).getWritableDatabase();
DBHelper.insertLoyaltyCard(database, "The First Store", "Initial note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "The Second Store", "Secondary note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "The First Store", "Initial note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
DBHelper.insertLoyaltyCard(database, "The Second Store", "Secondary note", null, null, new BigDecimal("0"), null, "cardId", null, CatimaBarcode.fromBarcode(BarcodeFormat.UPC_A), null, Color.BLACK, 0, null,0);
String finalQuery = "store";
assert mSearchView != null;

View File

@@ -55,7 +55,7 @@ public class TestHelpers {
for (int index = cardsToAdd; index > 0; index--) {
String storeName = String.format("store, \"%4d", index);
String note = String.format("note, \"%4d", index);
long id = DBHelper.insertLoyaltyCard(mDatabase, storeName, note, null, null, new BigDecimal(String.valueOf(index)), null, BARCODE_DATA, null, BARCODE_TYPE, index, 0, null,0);
long id = DBHelper.insertLoyaltyCard(mDatabase, storeName, note, null, null, new BigDecimal(String.valueOf(index)), null, BARCODE_DATA, null, BARCODE_TYPE, null, index, 0, null,0);
boolean result = (id != -1);
assertTrue(result);
}

View File

@@ -19,6 +19,8 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
@@ -94,13 +96,14 @@ public class CardsContentProviderTest {
final String cardId = "a-card-id";
final String barcodeId = "barcode-id";
final CatimaBarcode barcodeType = CatimaBarcode.fromName("QR_CODE");
final Charset barcodeEncoding = StandardCharsets.UTF_8;
final int headerColor = 0xFFFF00FF;
final int starStatus = 1;
final long lastUsed = 1687112282000L;
final int archiveStatus = 1;
long id = DBHelper.insertLoyaltyCard(
mDatabase, store, note, validFrom, expiry, balance, balanceType,
cardId, barcodeId, barcodeType, headerColor, starStatus, lastUsed,
cardId, barcodeId, barcodeType, barcodeEncoding, headerColor, starStatus, lastUsed,
archiveStatus
);
assertEquals("expect first card", 1, id);

View File

@@ -0,0 +1 @@
- Dem Hauptbildschirm eine Option zum Duplizieren hinzugefügt und die Optionen etwas verändert angeordnet

View File

@@ -1,7 +1,4 @@
[versions]
# AndroidX
compose = "2025.11.01"
# Third-party
acra = "5.13.1"
@@ -21,16 +18,6 @@ androidx-preference-preference = { group = "androidx.preference", name = "prefer
com-google-android-material-material = { group = "com.google.android.material", name = "material", version = "1.13.0" }
com-android-tools-desugar_jdk_libs = { group = "com.android.tools", name = "desugar_jdk_libs", version = "2.1.5" }
# Compose
androidx-activity-activity-compose = { group = "androidx.activity", name = "activity-compose", version = "1.10.1" }
androidx-compose-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose" }
androidx-compose-foundation-foundation = { group = "androidx.compose.foundation", name = "foundation" }
androidx-compose-material3-material3 = { group = "androidx.compose.material3", name = "material3"}
androidx-compose-material-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended", version = "1.7.8" }
androidx-compose-ui-ui-tooling-preview-android = { group = "androidx.compose.ui", name = "ui-tooling-preview-android" }
androidx-compose-ui-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
# Third-party
com-journeyapps-zxing_android_embedded = { group = "com.journeyapps", name = "zxing-android-embedded", version = "4.3.0" }
com-github-yalantis-ucrop = { group = "com.github.yalantis", name = "ucrop", version = "2.2.11" }
@@ -43,7 +30,6 @@ ch-acra-acra-dialog = { group = "ch.acra", name = "acra-dialog", version.ref = "
# Testing
androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidXTest" }
androidx-test-rules = { group = "androidx.test", name = "rules", version.ref = "androidXTest" }
androidx-test-runner = { group = "androidx.test", name = "runner", version.ref = "androidXTest" }
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version = "1.3.0" }
androidx-test-uiautomator-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version = "2.3.0" }
@@ -54,7 +40,6 @@ org-robolectric-robolectric = { group = "org.robolectric", name = "robolectric",
[plugins]
com-android-application = { id = "com.android.application", version = "8.13.2" }
org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version = "2.2.21" }
org-jetbrains-kotlin-plugin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version = "2.1.21" }
[bundles]
acra = ["ch-acra-acra-mail", "ch-acra-acra-dialog"]