CatimaLoyalty/Android

Loyalty card shortcut not updating with latest card information

PaulFarid opened this issue · 2 comments

When attempting to update the shortcut associated with a loyalty card with the latest card information, the updateShortcuts method does not correctly update the shortcut with the newest card details. Instead, the shortcut retains the previous loyalty card information even after attempting to update it with the latest data.

Steps to Reproduce:

1-Launch the App
2-Navigate to Import Functionality
3-Select Import Source
4-Import Cards/Codes
5-Add Shortcut
6-Update Loyalty Card Information
7-Update Shortcut

The following Test will expose the bug

package protect.card_locker;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.Bitmap;

import androidx.core.content.pm.ShortcutInfoCompat;
import androidx.core.content.pm.ShortcutManagerCompat;
import androidx.core.graphics.drawable.IconCompat;
import androidx.test.core.app.ApplicationProvider;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowShortcutManager;

import java.math.BigDecimal;
import java.util.Currency;
import java.util.Date;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

@RunWith(RobolectricTestRunner.class)
@Config(sdk = 28)
public class ShortcutHelperTest {

    private Context context;
    private ShortcutManager shortcutManager;
    private ShadowShortcutManager shadowShortcutManager;
    private DBHelper dbHelper;

    @Before
    public void setup() {
        context = ApplicationProvider.getApplicationContext();
        shortcutManager = (ShortcutManager) context.getSystemService(Context.SHORTCUT_SERVICE);
        shadowShortcutManager = Shadow.extract(shortcutManager);
        dbHelper = new DBHelper(context);
        dbHelper.getWritableDatabase(); // Create the database
    }

    @Test
    public void testUpdateShortcutReflectsUpdatedCardInfo() {
        Date validFrom = new Date();
        Date expiry = new Date(validFrom.getTime() + 86400000); // plus one day
        BigDecimal balance = new BigDecimal("20.00");
        Currency currency = Currency.getInstance("USD");
        int headerColor = 0xFF0000FF; // Blue color
        CatimaBarcode barcodeType = CatimaBarcode.fromName("QR_CODE");

        // Create a placeholder icon (can be replaced with any drawable resource or bitmap)
        Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
        IconCompat icon = IconCompat.createWithBitmap(bitmap);
        LoyaltyCard originalCard = new LoyaltyCard(1, "Old Store", "Initial note",
                validFrom, expiry, balance, currency, "card123", "barcode123",
                barcodeType, headerColor, 0, System.currentTimeMillis(), 100,
                0);

        // Insert the loyalty card into the database
        DBHelper.insertLoyaltyCard(dbHelper.getWritableDatabase(), originalCard.store,
                originalCard.note, originalCard.validFrom, originalCard.expiry,
                originalCard.balance, originalCard.balanceType, originalCard.cardId,
                originalCard.barcodeId, originalCard.barcodeType, headerColor, 0,
                System.currentTimeMillis(), 0);

        ShortcutInfoCompat originalShortcut = new ShortcutInfoCompat.Builder(context, "1")
                .setShortLabel(originalCard.store)
                .setIcon(icon)  // Setting icon here
                .setIntent(new Intent(Intent.ACTION_VIEW)) // Placeholder intent
                .build();

        ShortcutManagerCompat.addDynamicShortcuts(context, List.of(originalShortcut));

        // Verify shortcuts are added
        List<ShortcutInfo> shortcuts = shortcutManager.getDynamicShortcuts();
        assertNotNull(shortcuts);
        assertEquals(1, shortcuts.size());
        assertEquals("Old Store", shortcuts.get(0).getShortLabel());

        // Update the card and shortcut
        LoyaltyCard updatedCard = new LoyaltyCard(
                1, "New Store", "Updated note", validFrom, expiry, balance, currency,
                "card123", "barcode123", barcodeType, headerColor, 0,
                System.currentTimeMillis(), 100, 0
        );

        ShortcutHelper.updateShortcuts(context, updatedCard);

        // Verify the update
        shortcuts = shortcutManager.getDynamicShortcuts();
        assertEquals("New Store", shortcuts.get(0).getShortLabel());
    }
}

Actual Behavior:
The updateShortcuts method retrieves the loyalty card information from the database instead of using the updated card provided in the parameter. As a result, the shortcut retains the previous card details even after attempting to update it with the latest information.

Proposed Solution:
Modify the updateShortcuts method implementation to use the loyalty card provided as a parameter for updating shortcuts instead of fetching the card from the database. By directly using the updated card information, the shortcuts will accurately reflect the latest card details.

I'm having trouble reproducing this on my device. Are you running Android 5 by any chance? I'm thinking this issue might be a duplicate of #687.

See also the video in #687 (comment), despite all the time that has passed since it still works the exact same for me right now.

No new info for almost 3 months, closing. Feel free to ask for a re-open if you can supply more info