From ce272fe7f13c998001f30227f6e04c4bba8ad63e Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Thu, 12 May 2016 22:53:52 -0400 Subject: [PATCH] Add ability to import/export cards to/from CSV --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 3 +- .../card_locker/CsvDatabaseExporter.java | 50 +++++ .../card_locker/CsvDatabaseImporter.java | 135 ++++++++++++ .../java/protect/card_locker/DataFormat.java | 8 + .../protect/card_locker/DatabaseExporter.java | 17 ++ .../protect/card_locker/DatabaseImporter.java | 19 ++ .../protect/card_locker/FormatException.java | 19 ++ .../card_locker/MultiFormatExporter.java | 57 +++++ .../card_locker/MultiFormatImporter.java | 62 ++++++ .../protect/card_locker/ImportExportTest.java | 207 ++++++++++++++++++ 11 files changed, 577 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/protect/card_locker/CsvDatabaseExporter.java create mode 100644 app/src/main/java/protect/card_locker/CsvDatabaseImporter.java create mode 100644 app/src/main/java/protect/card_locker/DataFormat.java create mode 100644 app/src/main/java/protect/card_locker/DatabaseExporter.java create mode 100644 app/src/main/java/protect/card_locker/DatabaseImporter.java create mode 100644 app/src/main/java/protect/card_locker/FormatException.java create mode 100644 app/src/main/java/protect/card_locker/MultiFormatExporter.java create mode 100644 app/src/main/java/protect/card_locker/MultiFormatImporter.java create mode 100644 app/src/test/java/protect/card_locker/ImportExportTest.java diff --git a/app/build.gradle b/app/build.gradle index a05fd310d..53b8b1014 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,6 +39,7 @@ dependencies { compile 'com.android.support:design:23.1.1' compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar' compile 'com.google.zxing:core:3.2.1' + compile 'org.apache.commons:commons-csv:1.2' testCompile 'junit:junit:4.12' testCompile "org.robolectric:robolectric:3.0" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fdc322e6b..611e5bc82 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,7 +5,8 @@ + 0; index--) + { + String storeName = String.format("store, \"%4d", index); + String note = String.format("note, \"%4d", index); + boolean result = db.insertLoyaltyCard(storeName, note, BARCODE_DATA, BARCODE_TYPE); + assertTrue(result); + } + + assertEquals(cardsToAdd, db.getLoyaltyCardCount()); + } + + /** + * Check that all of the cards follow the pattern + * specified in addLoyaltyCards(), and are in sequential order + * where the smallest card's index is 1 + */ + private void checkLoyaltyCards() + { + Cursor cursor = db.getLoyaltyCardCursor(); + int index = 1; + + while(cursor.moveToNext()) + { + LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cursor); + + String expectedStore = String.format("store, \"%4d", index); + String expectedNote = String.format("note, \"%4d", index); + + assertEquals(expectedStore, card.store); + assertEquals(expectedNote, card.note); + assertEquals(BARCODE_DATA, card.cardId); + assertEquals(BARCODE_TYPE, card.barcodeType); + + index++; + } + cursor.close(); + } + + /** + * Delete the contents of the database + */ + private void clearDatabase() + { + SQLiteDatabase database = db.getWritableDatabase(); + database.execSQL("delete from " + DBHelper.LoyaltyCardDbIds.TABLE); + database.close(); + + assertEquals(0, db.getLoyaltyCardCount()); + } + + @Test + public void multipleCardsExportImport() throws IOException + { + final int NUM_CARDS = 1000; + + for(DataFormat format : DataFormat.values()) + { + addLoyaltyCards(NUM_CARDS); + + 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(); + + clearDatabase(); + + ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray()); + InputStreamReader inStream = new InputStreamReader(inData); + + // Import the CSV data + result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV); + assertTrue(result); + + assertEquals(NUM_CARDS, db.getLoyaltyCardCount()); + + checkLoyaltyCards(); + + // Clear the database for the next format under test + clearDatabase(); + } + } + + @Test + public void importExistingCardsNotReplace() throws IOException + { + final int NUM_CARDS = 1000; + + for(DataFormat format : DataFormat.values()) + { + addLoyaltyCards(NUM_CARDS); + + ByteArrayOutputStream outData = new ByteArrayOutputStream(); + OutputStreamWriter outStream = new OutputStreamWriter(outData); + + // Export into CSV data + boolean result = MultiFormatExporter.exportData(db, outStream, format); + assertTrue(result); + outStream.close(); + + 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); + + assertEquals(NUM_CARDS, db.getLoyaltyCardCount()); + + checkLoyaltyCards(); + + // Clear the database for the next format under test + clearDatabase(); + } + } + + @Test + public void corruptedImportNothingSaved() throws IOException + { + final int NUM_CARDS = 1000; + + for(DataFormat format : DataFormat.values()) + { + addLoyaltyCards(NUM_CARDS); + + ByteArrayOutputStream outData = new ByteArrayOutputStream(); + OutputStreamWriter outStream = new OutputStreamWriter(outData); + + // Export data to CSV format + boolean result = MultiFormatExporter.exportData(db, outStream, format); + assertTrue(result); + + clearDatabase(); + + String corruptEntry = "ThisStringIsLikelyNotPartOfAnyFormat"; + + 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); + assertEquals(false, result); + + assertEquals(0, db.getLoyaltyCardCount()); + } + } +}