Add Voucher Vault import to UI

This commit is contained in:
Sylvia van Os
2021-03-04 23:35:44 +01:00
parent 40de4a8dc4
commit ffa39000f7
8 changed files with 198 additions and 169 deletions

View File

@@ -1,5 +1,11 @@
# Changelog
## Unreleased
Changes:
- Support importing [Voucher Vault](https://github.com/tim-smart/vouchervault/) exports
## v1.9.2 (2021-02-24)
Changes:

View File

@@ -2,7 +2,7 @@ package protect.card_locker;
public enum DataFormat
{
CSV,
Catima,
VoucherVault
;
}

View File

@@ -35,10 +35,12 @@ public class ImportExportActivity extends AppCompatActivity
private static final int PERMISSIONS_EXTERNAL_STORAGE = 1;
private static final int CHOOSE_EXPORT_LOCATION = 2;
private static final int CHOOSE_EXPORTED_FILE = 3;
private static final int IMPORT = 3;
private ImportExportTask importExporter;
private DataFormat importDataFormat;
@Override
protected void onCreate(Bundle savedInstanceState)
{
@@ -93,7 +95,7 @@ public class ImportExportActivity extends AppCompatActivity
@Override
public void onClick(View v)
{
chooseFileWithIntent(intentGetContentAction, CHOOSE_EXPORTED_FILE);
chooseImportType(intentGetContentAction);
}
});
@@ -106,12 +108,35 @@ public class ImportExportActivity extends AppCompatActivity
@Override
public void onClick(View v)
{
chooseFileWithIntent(intentPickAction, CHOOSE_EXPORTED_FILE);
chooseImportType(intentPickAction);
}
});
}
private void startImport(final InputStream target, final Uri targetUri)
private void chooseImportType(Intent baseIntent) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.chooseImportType)
.setItems(R.array.import_types_array, (dialog, which) -> {
switch (which) {
// Catima
case 0:
// Loyalty Card Keychain
case 1:
importDataFormat = DataFormat.Catima;
break;
// Voucher Vault
case 2:
importDataFormat = DataFormat.VoucherVault;
break;
default:
throw new IllegalArgumentException("Unknown DataFormat");
}
chooseFileWithIntent(baseIntent, IMPORT);
});
builder.show();
}
private void startImport(final InputStream target, final Uri targetUri, final DataFormat dataFormat)
{
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener()
{
@@ -123,7 +148,7 @@ public class ImportExportActivity extends AppCompatActivity
};
importExporter = new ImportExportTask(ImportExportActivity.this,
DataFormat.CSV, target, listener);
dataFormat, target, listener);
importExporter.execute();
}
@@ -139,7 +164,7 @@ public class ImportExportActivity extends AppCompatActivity
};
importExporter = new ImportExportTask(ImportExportActivity.this,
DataFormat.CSV, target, listener);
DataFormat.Catima, target, listener);
importExporter.execute();
}
@@ -294,7 +319,7 @@ public class ImportExportActivity extends AppCompatActivity
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_OK || (requestCode != CHOOSE_EXPORT_LOCATION && requestCode != CHOOSE_EXPORTED_FILE))
if (resultCode != RESULT_OK)
{
Log.w(TAG, "Failed onActivityResult(), result=" + resultCode);
return;
@@ -336,8 +361,9 @@ public class ImportExportActivity extends AppCompatActivity
reader = new FileInputStream(new File(uri.toString()));
}
Log.e(TAG, "Starting file export with: " + uri.toString());
startImport(reader, uri);
Log.e(TAG, "Starting file import with: " + uri.toString());
startImport(reader, uri, importDataFormat);
}
}
catch(FileNotFoundException e)

View File

@@ -30,7 +30,7 @@ public class MultiFormatExporter
switch(format)
{
case CSV:
case Catima:
exporter = new CsvDatabaseExporter();
break;
}

View File

@@ -35,9 +35,12 @@ public class MultiFormatImporter
switch(format)
{
case CSV:
case Catima:
importer = new CsvDatabaseImporter();
break;
case VoucherVault:
importer = new VoucherVaultImporter();
break;
}
if (importer != null)

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="import_types_array">
<item>Catima</item>
<item>Loyalty Card Keychain</item>
<item>Voucher Vault</item>
</string-array>
</resources>

View File

@@ -151,4 +151,5 @@
<string name="points">Points</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> does not seem to be a valid balance.</string>
<string name="chooseImportType">Import data from which app?</string>
</resources>

View File

@@ -37,7 +37,6 @@ import java.util.List;
import protect.card_locker.importexport.MultiFormatExporter;
import protect.card_locker.importexport.MultiFormatImporter;
import protect.card_locker.importexport.VoucherVaultImporter;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -322,34 +321,31 @@ public class ImportExportTest
{
final int NUM_CARDS = 10;
for(DataFormat format : DataFormat.values())
{
addLoyaltyCards(NUM_CARDS);
addLoyaltyCards(NUM_CARDS);
ByteArrayOutputStream outData = new ByteArrayOutputStream();
OutputStreamWriter outStream = new OutputStreamWriter(outData);
ByteArrayOutputStream outData = new ByteArrayOutputStream();
OutputStreamWriter outStream = new OutputStreamWriter(outData);
// Export data to CSV format
boolean result = MultiFormatExporter.exportData(db, outStream, format);
assertTrue(result);
outStream.close();
// Export data to CSV format
boolean result = MultiFormatExporter.exportData(db, outStream, DataFormat.Catima);
assertTrue(result);
outStream.close();
clearDatabase();
clearDatabase();
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
InputStreamReader inStream = new InputStreamReader(inData);
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
InputStreamReader inStream = new InputStreamReader(inData);
// Import the CSV data
result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
assertTrue(result);
// Import the CSV data
result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertTrue(result);
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
checkLoyaltyCards();
checkLoyaltyCards();
// Clear the database for the next format under test
clearDatabase();
}
// Clear the database for the next format under test
clearDatabase();
}
@Test
@@ -357,34 +353,31 @@ public class ImportExportTest
{
final int NUM_CARDS = 9;
for(DataFormat format : DataFormat.values())
{
addLoyaltyCardsFiveStarred();
addLoyaltyCardsFiveStarred();
ByteArrayOutputStream outData = new ByteArrayOutputStream();
OutputStreamWriter outStream = new OutputStreamWriter(outData);
ByteArrayOutputStream outData = new ByteArrayOutputStream();
OutputStreamWriter outStream = new OutputStreamWriter(outData);
// Export data to CSV format
boolean result = MultiFormatExporter.exportData(db, outStream, format);
assertTrue(result);
outStream.close();
// Export data to CSV format
boolean result = MultiFormatExporter.exportData(db, outStream, DataFormat.Catima);
assertTrue(result);
outStream.close();
clearDatabase();
clearDatabase();
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
InputStreamReader inStream = new InputStreamReader(inData);
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
InputStreamReader inStream = new InputStreamReader(inData);
// Import the CSV data
result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
assertTrue(result);
// Import the CSV data
result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertTrue(result);
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
checkLoyaltyCardsFiveStarred();
checkLoyaltyCardsFiveStarred();
// Clear the database for the next format under test
clearDatabase();
}
// Clear the database for the next format under test
clearDatabase();
}
private List<String> groupsToGroupNames(List<Group> groups)
@@ -404,77 +397,74 @@ public class ImportExportTest
final int NUM_CARDS = 10;
final int NUM_GROUPS = 3;
for(DataFormat format : DataFormat.values())
{
addLoyaltyCards(NUM_CARDS);
addGroups(NUM_GROUPS);
addLoyaltyCards(NUM_CARDS);
addGroups(NUM_GROUPS);
List<Group> emptyGroup = new ArrayList<>();
List<Group> emptyGroup = new ArrayList<>();
List<Group> groupsForOne = new ArrayList<>();
groupsForOne.add(db.getGroup("group, \" 1"));
List<Group> groupsForOne = new ArrayList<>();
groupsForOne.add(db.getGroup("group, \" 1"));
List<Group> groupsForTwo = new ArrayList<>();
groupsForTwo.add(db.getGroup("group, \" 1"));
groupsForTwo.add(db.getGroup("group, \" 2"));
List<Group> groupsForTwo = new ArrayList<>();
groupsForTwo.add(db.getGroup("group, \" 1"));
groupsForTwo.add(db.getGroup("group, \" 2"));
List<Group> groupsForThree = new ArrayList<>();
groupsForThree.add(db.getGroup("group, \" 1"));
groupsForThree.add(db.getGroup("group, \" 2"));
groupsForThree.add(db.getGroup("group, \" 3"));
List<Group> groupsForThree = new ArrayList<>();
groupsForThree.add(db.getGroup("group, \" 1"));
groupsForThree.add(db.getGroup("group, \" 2"));
groupsForThree.add(db.getGroup("group, \" 3"));
List<Group> groupsForFour = new ArrayList<>();
groupsForFour.add(db.getGroup("group, \" 1"));
groupsForFour.add(db.getGroup("group, \" 2"));
groupsForFour.add(db.getGroup("group, \" 3"));
List<Group> groupsForFour = new ArrayList<>();
groupsForFour.add(db.getGroup("group, \" 1"));
groupsForFour.add(db.getGroup("group, \" 2"));
groupsForFour.add(db.getGroup("group, \" 3"));
List<Group> groupsForFive = new ArrayList<>();
groupsForFive.add(db.getGroup("group, \" 1"));
groupsForFive.add(db.getGroup("group, \" 3"));
List<Group> groupsForFive = new ArrayList<>();
groupsForFive.add(db.getGroup("group, \" 1"));
groupsForFive.add(db.getGroup("group, \" 3"));
db.setLoyaltyCardGroups(1, groupsForOne);
db.setLoyaltyCardGroups(2, groupsForTwo);
db.setLoyaltyCardGroups(3, groupsForThree);
db.setLoyaltyCardGroups(4, groupsForFour);
db.setLoyaltyCardGroups(5, groupsForFive);
db.setLoyaltyCardGroups(1, groupsForOne);
db.setLoyaltyCardGroups(2, groupsForTwo);
db.setLoyaltyCardGroups(3, groupsForThree);
db.setLoyaltyCardGroups(4, groupsForFour);
db.setLoyaltyCardGroups(5, groupsForFive);
ByteArrayOutputStream outData = new ByteArrayOutputStream();
OutputStreamWriter outStream = new OutputStreamWriter(outData);
ByteArrayOutputStream outData = new ByteArrayOutputStream();
OutputStreamWriter outStream = new OutputStreamWriter(outData);
// Export data to CSV format
boolean result = MultiFormatExporter.exportData(db, outStream, format);
assertTrue(result);
outStream.close();
// Export data to CSV format
boolean result = MultiFormatExporter.exportData(db, outStream, DataFormat.Catima);
assertTrue(result);
outStream.close();
clearDatabase();
clearDatabase();
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
InputStreamReader inStream = new InputStreamReader(inData);
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
InputStreamReader inStream = new InputStreamReader(inData);
// Import the CSV data
result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
assertTrue(result);
// Import the CSV data
result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertTrue(result);
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
assertEquals(NUM_GROUPS, db.getGroupCount());
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
assertEquals(NUM_GROUPS, db.getGroupCount());
checkLoyaltyCards();
checkGroups();
checkLoyaltyCards();
checkGroups();
assertEquals(groupsToGroupNames(groupsForOne), groupsToGroupNames(db.getLoyaltyCardGroups(1)));
assertEquals(groupsToGroupNames(groupsForTwo), groupsToGroupNames(db.getLoyaltyCardGroups(2)));
assertEquals(groupsToGroupNames(groupsForThree), groupsToGroupNames(db.getLoyaltyCardGroups(3)));
assertEquals(groupsToGroupNames(groupsForFour), groupsToGroupNames(db.getLoyaltyCardGroups(4)));
assertEquals(groupsToGroupNames(groupsForFive), groupsToGroupNames(db.getLoyaltyCardGroups(5)));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(6));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(7));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(8));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(9));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(10));
assertEquals(groupsToGroupNames(groupsForOne), groupsToGroupNames(db.getLoyaltyCardGroups(1)));
assertEquals(groupsToGroupNames(groupsForTwo), groupsToGroupNames(db.getLoyaltyCardGroups(2)));
assertEquals(groupsToGroupNames(groupsForThree), groupsToGroupNames(db.getLoyaltyCardGroups(3)));
assertEquals(groupsToGroupNames(groupsForFour), groupsToGroupNames(db.getLoyaltyCardGroups(4)));
assertEquals(groupsToGroupNames(groupsForFive), groupsToGroupNames(db.getLoyaltyCardGroups(5)));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(6));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(7));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(8));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(9));
assertEquals(emptyGroup, db.getLoyaltyCardGroups(10));
// Clear the database for the next format under test
clearDatabase();
}
// Clear the database for the next format under test
clearDatabase();
}
@Test
@@ -482,32 +472,29 @@ public class ImportExportTest
{
final int NUM_CARDS = 10;
for(DataFormat format : DataFormat.values())
{
addLoyaltyCards(NUM_CARDS);
addLoyaltyCards(NUM_CARDS);
ByteArrayOutputStream outData = new ByteArrayOutputStream();
OutputStreamWriter outStream = new OutputStreamWriter(outData);
ByteArrayOutputStream outData = new ByteArrayOutputStream();
OutputStreamWriter outStream = new OutputStreamWriter(outData);
// Export into CSV data
boolean result = MultiFormatExporter.exportData(db, outStream, format);
assertTrue(result);
outStream.close();
// Export into CSV data
boolean result = MultiFormatExporter.exportData(db, outStream, DataFormat.Catima);
assertTrue(result);
outStream.close();
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
InputStreamReader inStream = new InputStreamReader(inData);
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
InputStreamReader inStream = new InputStreamReader(inData);
// Import the CSV data on top of the existing database
result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
assertTrue(result);
// Import the CSV data on top of the existing database
result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertTrue(result);
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
checkLoyaltyCards();
checkLoyaltyCards();
// Clear the database for the next format under test
clearDatabase();
}
// Clear the database for the next format under test
clearDatabase();
}
@Test
@@ -523,7 +510,7 @@ public class ImportExportTest
OutputStreamWriter outStream = new OutputStreamWriter(outData);
// Export data to CSV format
boolean result = MultiFormatExporter.exportData(db, outStream, format);
boolean result = MultiFormatExporter.exportData(db, outStream, DataFormat.Catima);
assertTrue(result);
clearDatabase();
@@ -537,8 +524,8 @@ public class ImportExportTest
ByteArrayInputStream inData = new ByteArrayInputStream((outData.toString() + corruptEntry).getBytes());
InputStreamReader inStream = new InputStreamReader(inData);
// Attempt to import the CSV data
result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
// Attempt to import the data
result = MultiFormatImporter.importData(db, inStream, format);
assertEquals(false, result);
assertEquals(0, db.getLoyaltyCardCount());
@@ -566,49 +553,46 @@ public class ImportExportTest
final File sdcardDir = Environment.getExternalStorageDirectory();
final File exportFile = new File(sdcardDir, "Catima.csv");
for(DataFormat format : DataFormat.values())
{
addLoyaltyCards(NUM_CARDS);
addLoyaltyCards(NUM_CARDS);
TestTaskCompleteListener listener = new TestTaskCompleteListener();
TestTaskCompleteListener listener = new TestTaskCompleteListener();
// Export to the file
FileOutputStream fileOutputStream = new FileOutputStream(exportFile);
ImportExportTask task = new ImportExportTask(activity, format, fileOutputStream, listener);
task.execute();
// Export to the file
FileOutputStream fileOutputStream = new FileOutputStream(exportFile);
ImportExportTask task = new ImportExportTask(activity, DataFormat.Catima, fileOutputStream, listener);
task.execute();
// Actually run the task to completion
Robolectric.flushBackgroundThreadScheduler();
// Actually run the task to completion
Robolectric.flushBackgroundThreadScheduler();
// Check that the listener was executed
assertNotNull(listener.success);
assertEquals(true, listener.success);
// Check that the listener was executed
assertNotNull(listener.success);
assertEquals(true, listener.success);
clearDatabase();
clearDatabase();
// Import everything back from the default location
// Import everything back from the default location
listener = new TestTaskCompleteListener();
listener = new TestTaskCompleteListener();
FileInputStream fileStream = new FileInputStream(exportFile);
FileInputStream fileStream = new FileInputStream(exportFile);
task = new ImportExportTask(activity, format, fileStream, listener);
task.execute();
task = new ImportExportTask(activity, DataFormat.Catima, fileStream, listener);
task.execute();
// Actually run the task to completion
Robolectric.flushBackgroundThreadScheduler();
// Actually run the task to completion
Robolectric.flushBackgroundThreadScheduler();
// Check that the listener was executed
assertNotNull(listener.success);
assertEquals(true, listener.success);
// Check that the listener was executed
assertNotNull(listener.success);
assertEquals(true, listener.success);
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
checkLoyaltyCards();
checkLoyaltyCards();
// Clear the database for the next format under test
clearDatabase();
}
// Clear the database for the next format under test
clearDatabase();
}
@Test
@@ -628,7 +612,7 @@ public class ImportExportTest
InputStreamReader inStream = new InputStreamReader(inputStream);
// Import the CSV data
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertTrue(result);
assertEquals(1, db.getLoyaltyCardCount());
@@ -666,7 +650,7 @@ public class ImportExportTest
InputStreamReader inStream = new InputStreamReader(inputStream);
// Import the CSV data
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertTrue(result);
assertEquals(1, db.getLoyaltyCardCount());
@@ -704,7 +688,7 @@ public class ImportExportTest
InputStreamReader inStream = new InputStreamReader(inputStream);
// Import the CSV data
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertEquals(false, result);
assertEquals(0, db.getLoyaltyCardCount());
@@ -730,7 +714,7 @@ public class ImportExportTest
InputStreamReader inStream = new InputStreamReader(inputStream);
// Import the CSV data
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertEquals(true, result);
assertEquals(1, db.getLoyaltyCardCount());
@@ -768,7 +752,7 @@ public class ImportExportTest
InputStreamReader inStream = new InputStreamReader(inputStream);
// Import the CSV data
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertEquals(true, result);
assertEquals(1, db.getLoyaltyCardCount());
@@ -806,7 +790,7 @@ public class ImportExportTest
InputStreamReader inStream = new InputStreamReader(inputStream);
// Import the CSV data
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertEquals(true, result);
assertEquals(1, db.getLoyaltyCardCount());
@@ -844,7 +828,7 @@ public class ImportExportTest
InputStreamReader inStream = new InputStreamReader(inputStream);
// Import the CSV data
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertTrue(result);
assertEquals(1, db.getLoyaltyCardCount());
@@ -864,7 +848,7 @@ public class ImportExportTest
inStream = new InputStreamReader(inputStream);
// Import the CSV data
result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
result = MultiFormatImporter.importData(db, inStream, DataFormat.Catima);
assertTrue(result);
assertEquals(1, db.getLoyaltyCardCount());
@@ -912,7 +896,8 @@ public class ImportExportTest
InputStreamReader inStream = new InputStreamReader(inputStream);
// Import the Voucher Vault data
new VoucherVaultImporter().importData(db, inStream);
boolean result = MultiFormatImporter.importData(db, inStream, DataFormat.VoucherVault);
assertTrue(result);
assertEquals(2, db.getLoyaltyCardCount());
LoyaltyCard card = db.getLoyaltyCard(1);