From 1fd725aab14d3abb1581c536bbf3cbb9a44f0591 Mon Sep 17 00:00:00 2001 From: permission-error Date: Mon, 12 Feb 2024 18:01:46 +0300 Subject: [PATCH 1/2] Create tests for PropertiesFileUtils --- .../builder/PropertiesFileUtilsTest.java | 214 ++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 androidlibrary_lib/src/androidTest/java/org/opendatakit/builder/PropertiesFileUtilsTest.java diff --git a/androidlibrary_lib/src/androidTest/java/org/opendatakit/builder/PropertiesFileUtilsTest.java b/androidlibrary_lib/src/androidTest/java/org/opendatakit/builder/PropertiesFileUtilsTest.java new file mode 100644 index 00000000..d648080e --- /dev/null +++ b/androidlibrary_lib/src/androidTest/java/org/opendatakit/builder/PropertiesFileUtilsTest.java @@ -0,0 +1,214 @@ +package org.opendatakit.builder; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.opendatakit.provider.KeyValueStoreColumns.TABLE_ID; + +import org.junit.Before; +import org.junit.Test; +import org.opendatakit.database.data.KeyValueStoreEntry; +import org.opendatakit.database.data.OrderedColumns; +import org.opendatakit.exception.ServicesAvailabilityException; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class PropertiesFileUtilsTest { + + private String appName; + private String tableId; + private OrderedColumns orderedDefns; + private List kvsEntries; + private File definitionCsv; + private File propertiesCsv; + + @Before + public void setUp() { + appName = "TestApp"; + tableId = "TestTable"; + kvsEntries = new ArrayList<>(); + definitionCsv = new File("definition.csv"); + propertiesCsv = new File("properties.csv"); + } + + @Test + public void testWritePropertiesIntoCsv_NullAppName() throws ServicesAvailabilityException { + // Test writing properties into CSV with null appName + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(null, tableId, orderedDefns, kvsEntries, definitionCsv, propertiesCsv); + assertFalse(success); + } + + @Test + public void testWritePropertiesIntoCsv_NullTableId() throws ServicesAvailabilityException { + // Test writing properties into CSV with null tableId + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, null, orderedDefns, kvsEntries, definitionCsv, propertiesCsv); + assertFalse(success); + } + + @Test + public void testWritePropertiesIntoCsv_NullOrderedDefns() throws ServicesAvailabilityException { + // Test writing properties into CSV with null orderedDefns + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, null, kvsEntries, definitionCsv, propertiesCsv); + assertFalse(success); + } + + @Test + public void testWritePropertiesIntoCsv_NullKvsEntries() throws ServicesAvailabilityException { + // Test writing properties into CSV with null kvsEntries + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, null, definitionCsv, propertiesCsv); + assertFalse(success); + } + + @Test(expected = IllegalArgumentException.class) + public void testReadPropertiesFromCsv_NullTableId() throws IOException { + // Test reading properties from CSV with null tableId + PropertiesFileUtils.readPropertiesFromCsv(appName, null); + } + + @Test(expected = IOException.class) + public void testReadPropertiesFromCsv_NonExistentFile() throws IOException { + // Test reading properties from non-existent CSV file + PropertiesFileUtils.readPropertiesFromCsv(appName, "NonExistentTable"); + } + + @Test + public void testReadPropertiesFromCsv_NullAppName() { + // Test reading properties from CSV with null appName + try { + PropertiesFileUtils.readPropertiesFromCsv(null, tableId); + fail("Expected IllegalArgumentException was not thrown"); + } catch (IllegalArgumentException e) { + assertTrue(true); + } catch (IOException e) { + fail("Unexpected IOException occurred"); + } + } + + @Test + public void testReadPropertiesFromCsv_EmptyTableId() { + // Test reading properties from CSV with empty tableId + try { + PropertiesFileUtils.readPropertiesFromCsv(appName, ""); + fail("Expected IllegalArgumentException was not thrown"); + } catch (IllegalArgumentException e) { + assertTrue(true); + } catch (IOException e) { + fail("Unexpected IOException occurred"); + } + } + + @Test + public void testWritePropertiesIntoCsv_IOException() throws ServicesAvailabilityException { + // Test writing properties into CSV with IOException + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, new File("definition.csv"), new File("properties.csv")); + assertFalse(success); + } + + @Test + public void testReadPropertiesFromCsv_IOException() { + // Test reading properties from CSV with IOException + try { + PropertiesFileUtils.readPropertiesFromCsv(appName, "IOExceptionTable"); + fail("Expected IOException was not thrown"); + } catch (IOException e) { + assertTrue(true); + } + } + + @Test + public void testWritePropertiesIntoCsv_PermissionDenied() throws IOException, ServicesAvailabilityException { + // Create a read-only CSV file + propertiesCsv.setReadOnly(); + + // Attempt to write properties into read-only CSV + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, definitionCsv, propertiesCsv); + assertFalse(success); + } + + @Test + public void testWritePropertiesIntoCsv_NullPropertiesCsv() throws ServicesAvailabilityException { + // Test writing properties into CSV with null propertiesCsv + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, definitionCsv, null); + assertFalse(success); + } + + @Test + public void testWritePropertiesIntoCsv_NullAppNameAndTableId() throws ServicesAvailabilityException { + // Test writing properties into CSV with null appName and tableId + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(null, null, orderedDefns, kvsEntries, definitionCsv, propertiesCsv); + assertFalse(success); + } + + @Test + public void testReadPropertiesFromCsv_NullAppNameAndTableId() { + // Test reading properties from CSV with null appName and tableId + try { + PropertiesFileUtils.readPropertiesFromCsv(null, null); + fail("Expected IllegalArgumentException was not thrown"); + } catch (IllegalArgumentException e) { + assertTrue(true); + } catch (IOException e) { + fail("Unexpected IOException occurred"); + } + } + + @Test + public void testWritePropertiesIntoCsv_DifferentDefinitionAndPropertiesCsv() throws ServicesAvailabilityException { + // Test writing properties into CSV with different definitionCsv and propertiesCsv files + File differentDefinitionCsv = new File("different_definition.csv"); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, differentDefinitionCsv, propertiesCsv); + assertFalse(success); + } + + @Test + public void testCreateKeyValueStoreEntries() { + List entries = createKeyValueStoreEntries(); + assertNotNull("KeyValueStoreEntries should not be null", entries); + assertEquals("Number of entries should match", 2, entries.size()); + } + + @Test + public void testCreateKeyValueStoreEntry() { + KeyValueStoreEntry entry = createKeyValueStoreEntry("partition1", "aspect1", "key1", "INTEGER", "123"); + assertNotNull("KeyValueStoreEntry should not be null", entry); + assertEquals("Partition should match", "partition1", entry.partition); + assertEquals("Aspect should match", "aspect1", entry.aspect); + assertEquals("Key should match", "key1", entry.key); + assertEquals("Type should match", "INTEGER", entry.type); + assertEquals("Value should match", "123", entry.value); + } + + @Test + public void testWritePropertiesFailure() throws ServicesAvailabilityException { + PropertiesFileUtils.writePropertiesIntoCsv(null, null, null, + null, null, null); + assertFalse("Writing properties should fail", fileExists("definition.csv") && fileExists("properties.csv")); + } + + private List createKeyValueStoreEntries() { + List kvsEntries = new ArrayList<>(); + kvsEntries.add(createKeyValueStoreEntry("partition1", "aspect1", "key1", "INTEGER", "123")); + kvsEntries.add(createKeyValueStoreEntry("partition2", "aspect2", "key2", "STRING", "value2")); + return kvsEntries; + } + + private KeyValueStoreEntry createKeyValueStoreEntry(String partition, String aspect, String key, String type, String value) { + KeyValueStoreEntry entry = new KeyValueStoreEntry(); + entry.tableId = TABLE_ID; + entry.partition = partition; + entry.aspect = aspect; + entry.key = key; + entry.type = type; + entry.value = value; + return entry; + } + + private boolean fileExists(String fileName) { + return new File(fileName).exists(); + } +} From fbfbcb89723d855aac488809660b052eb2faa0f1 Mon Sep 17 00:00:00 2001 From: permission-error Date: Thu, 15 Feb 2024 00:36:35 +0300 Subject: [PATCH 2/2] Refactor the code to use DocumentFile for file operations --- .../builder/PropertiesFileUtilsTest.java | 106 ++++++++---------- .../java/org/opendatakit/builder/CsvUtil.java | 7 +- .../builder/PropertiesFileUtils.java | 10 +- 3 files changed, 60 insertions(+), 63 deletions(-) diff --git a/androidlibrary_lib/src/androidTest/java/org/opendatakit/builder/PropertiesFileUtilsTest.java b/androidlibrary_lib/src/androidTest/java/org/opendatakit/builder/PropertiesFileUtilsTest.java index d648080e..0ef3feb0 100644 --- a/androidlibrary_lib/src/androidTest/java/org/opendatakit/builder/PropertiesFileUtilsTest.java +++ b/androidlibrary_lib/src/androidTest/java/org/opendatakit/builder/PropertiesFileUtilsTest.java @@ -7,6 +7,8 @@ import static org.junit.Assert.fail; import static org.opendatakit.provider.KeyValueStoreColumns.TABLE_ID; +import androidx.documentfile.provider.DocumentFile; + import org.junit.Before; import org.junit.Test; import org.opendatakit.database.data.KeyValueStoreEntry; @@ -39,28 +41,28 @@ public void setUp() { @Test public void testWritePropertiesIntoCsv_NullAppName() throws ServicesAvailabilityException { // Test writing properties into CSV with null appName - boolean success = PropertiesFileUtils.writePropertiesIntoCsv(null, tableId, orderedDefns, kvsEntries, definitionCsv, propertiesCsv); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(null, tableId, orderedDefns, kvsEntries, DocumentFile.fromFile(definitionCsv), DocumentFile.fromFile(propertiesCsv)); assertFalse(success); } @Test public void testWritePropertiesIntoCsv_NullTableId() throws ServicesAvailabilityException { // Test writing properties into CSV with null tableId - boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, null, orderedDefns, kvsEntries, definitionCsv, propertiesCsv); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, null, orderedDefns, kvsEntries, DocumentFile.fromFile(definitionCsv), DocumentFile.fromFile(propertiesCsv)); assertFalse(success); } @Test public void testWritePropertiesIntoCsv_NullOrderedDefns() throws ServicesAvailabilityException { // Test writing properties into CSV with null orderedDefns - boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, null, kvsEntries, definitionCsv, propertiesCsv); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, null, kvsEntries, DocumentFile.fromFile(definitionCsv), DocumentFile.fromFile(propertiesCsv)); assertFalse(success); } @Test public void testWritePropertiesIntoCsv_NullKvsEntries() throws ServicesAvailabilityException { // Test writing properties into CSV with null kvsEntries - boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, null, definitionCsv, propertiesCsv); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, null, DocumentFile.fromFile(definitionCsv), DocumentFile.fromFile(propertiesCsv)); assertFalse(success); } @@ -76,19 +78,6 @@ public void testReadPropertiesFromCsv_NonExistentFile() throws IOException { PropertiesFileUtils.readPropertiesFromCsv(appName, "NonExistentTable"); } - @Test - public void testReadPropertiesFromCsv_NullAppName() { - // Test reading properties from CSV with null appName - try { - PropertiesFileUtils.readPropertiesFromCsv(null, tableId); - fail("Expected IllegalArgumentException was not thrown"); - } catch (IllegalArgumentException e) { - assertTrue(true); - } catch (IOException e) { - fail("Unexpected IOException occurred"); - } - } - @Test public void testReadPropertiesFromCsv_EmptyTableId() { // Test reading properties from CSV with empty tableId @@ -105,7 +94,7 @@ public void testReadPropertiesFromCsv_EmptyTableId() { @Test public void testWritePropertiesIntoCsv_IOException() throws ServicesAvailabilityException { // Test writing properties into CSV with IOException - boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, new File("definition.csv"), new File("properties.csv")); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, DocumentFile.fromFile(new File("definition.csv")), DocumentFile.fromFile(new File("properties.csv"))); assertFalse(success); } @@ -126,21 +115,21 @@ public void testWritePropertiesIntoCsv_PermissionDenied() throws IOException, Se propertiesCsv.setReadOnly(); // Attempt to write properties into read-only CSV - boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, definitionCsv, propertiesCsv); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, DocumentFile.fromFile(definitionCsv), DocumentFile.fromFile(propertiesCsv)); assertFalse(success); } @Test public void testWritePropertiesIntoCsv_NullPropertiesCsv() throws ServicesAvailabilityException { // Test writing properties into CSV with null propertiesCsv - boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, definitionCsv, null); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, DocumentFile.fromFile(definitionCsv), null); assertFalse(success); } @Test public void testWritePropertiesIntoCsv_NullAppNameAndTableId() throws ServicesAvailabilityException { // Test writing properties into CSV with null appName and tableId - boolean success = PropertiesFileUtils.writePropertiesIntoCsv(null, null, orderedDefns, kvsEntries, definitionCsv, propertiesCsv); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(null, null, orderedDefns, kvsEntries, DocumentFile.fromFile(definitionCsv), DocumentFile.fromFile(propertiesCsv)); assertFalse(success); } @@ -161,54 +150,57 @@ public void testReadPropertiesFromCsv_NullAppNameAndTableId() { public void testWritePropertiesIntoCsv_DifferentDefinitionAndPropertiesCsv() throws ServicesAvailabilityException { // Test writing properties into CSV with different definitionCsv and propertiesCsv files File differentDefinitionCsv = new File("different_definition.csv"); - boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, differentDefinitionCsv, propertiesCsv); + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, DocumentFile.fromFile(differentDefinitionCsv), DocumentFile.fromFile(propertiesCsv)); assertFalse(success); } @Test - public void testCreateKeyValueStoreEntries() { - List entries = createKeyValueStoreEntries(); - assertNotNull("KeyValueStoreEntries should not be null", entries); - assertEquals("Number of entries should match", 2, entries.size()); - } + public void testCreateKeyValueStoreEntries() { + List entries = createKeyValueStoreEntries(); + assertNotNull("KeyValueStoreEntries should not be null", entries); + assertEquals("Number of entries should match", 2, entries.size()); + } @Test - public void testCreateKeyValueStoreEntry() { - KeyValueStoreEntry entry = createKeyValueStoreEntry("partition1", "aspect1", "key1", "INTEGER", "123"); - assertNotNull("KeyValueStoreEntry should not be null", entry); - assertEquals("Partition should match", "partition1", entry.partition); - assertEquals("Aspect should match", "aspect1", entry.aspect); - assertEquals("Key should match", "key1", entry.key); - assertEquals("Type should match", "INTEGER", entry.type); - assertEquals("Value should match", "123", entry.value); - } + public void testCreateKeyValueStoreEntry() { + KeyValueStoreEntry entry = createKeyValueStoreEntry("partition1", "aspect1", "key1", "INTEGER", "123"); + assertNotNull("KeyValueStoreEntry should not be null", entry); + assertEquals("Partition should match", "partition1", entry.partition); + assertEquals("Aspect should match", "aspect1", entry.aspect); + assertEquals("Key should match", "key1", entry.key); + assertEquals("Type should match", "INTEGER", entry.type); + assertEquals("Value should match", "123", entry.value); + } @Test - public void testWritePropertiesFailure() throws ServicesAvailabilityException { - PropertiesFileUtils.writePropertiesIntoCsv(null, null, null, - null, null, null); - assertFalse("Writing properties should fail", fileExists("definition.csv") && fileExists("properties.csv")); - } + public void testWritePropertiesFailure() throws ServicesAvailabilityException { + // Convert file paths to DocumentFile and check existence + boolean success = PropertiesFileUtils.writePropertiesIntoCsv(null, null, null, + null, null, null); + assertFalse("Writing properties should fail", success && fileExists("definition.csv") && fileExists("properties.csv")); + } private List createKeyValueStoreEntries() { - List kvsEntries = new ArrayList<>(); - kvsEntries.add(createKeyValueStoreEntry("partition1", "aspect1", "key1", "INTEGER", "123")); - kvsEntries.add(createKeyValueStoreEntry("partition2", "aspect2", "key2", "STRING", "value2")); - return kvsEntries; - } + List kvsEntries = new ArrayList<>(); + kvsEntries.add(createKeyValueStoreEntry("partition1", "aspect1", "key1", "INTEGER", "123")); + kvsEntries.add(createKeyValueStoreEntry("partition2", "aspect2", "key2", "STRING", "value2")); + return kvsEntries; + } private KeyValueStoreEntry createKeyValueStoreEntry(String partition, String aspect, String key, String type, String value) { - KeyValueStoreEntry entry = new KeyValueStoreEntry(); - entry.tableId = TABLE_ID; - entry.partition = partition; - entry.aspect = aspect; - entry.key = key; - entry.type = type; - entry.value = value; - return entry; - } + KeyValueStoreEntry entry = new KeyValueStoreEntry(); + entry.tableId = TABLE_ID; + entry.partition = partition; + entry.aspect = aspect; + entry.key = key; + entry.type = type; + entry.value = value; + return entry; + } private boolean fileExists(String fileName) { - return new File(fileName).exists(); - } + // Convert fileName to DocumentFile and check existence + DocumentFile file = DocumentFile.fromFile(new File(fileName)); + return file.exists(); + } } diff --git a/androidlibrary_lib/src/main/java/org/opendatakit/builder/CsvUtil.java b/androidlibrary_lib/src/main/java/org/opendatakit/builder/CsvUtil.java index d0bbdcf7..455d1eb1 100644 --- a/androidlibrary_lib/src/main/java/org/opendatakit/builder/CsvUtil.java +++ b/androidlibrary_lib/src/main/java/org/opendatakit/builder/CsvUtil.java @@ -16,6 +16,9 @@ package org.opendatakit.builder; import android.content.ContentValues; + +import androidx.documentfile.provider.DocumentFile; + import org.opendatakit.aggregate.odktables.rest.ConflictType; import org.opendatakit.aggregate.odktables.rest.ElementDataType; import org.opendatakit.aggregate.odktables.rest.KeyValueStoreConstants; @@ -302,8 +305,8 @@ private boolean writePropertiesCsv(DbHandle db, String tableId, OrderedColumns o } return PropertiesFileUtils - .writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, definitionCsv, - propertiesCsv); + .writePropertiesIntoCsv(appName, tableId, orderedDefns, kvsEntries, DocumentFile.fromFile(definitionCsv), + DocumentFile.fromFile(propertiesCsv)); } /** diff --git a/androidlibrary_lib/src/main/java/org/opendatakit/builder/PropertiesFileUtils.java b/androidlibrary_lib/src/main/java/org/opendatakit/builder/PropertiesFileUtils.java index a77f3e88..cbe4dd4a 100644 --- a/androidlibrary_lib/src/main/java/org/opendatakit/builder/PropertiesFileUtils.java +++ b/androidlibrary_lib/src/main/java/org/opendatakit/builder/PropertiesFileUtils.java @@ -15,6 +15,8 @@ */ package org.opendatakit.builder; +import androidx.documentfile.provider.DocumentFile; + import org.opendatakit.aggregate.odktables.rest.ElementDataType; import org.opendatakit.aggregate.odktables.rest.RFC4180CsvReader; import org.opendatakit.aggregate.odktables.rest.RFC4180CsvWriter; @@ -79,8 +81,8 @@ public static class DataTableDefinition { * @throws ServicesAvailabilityException if the database is down */ public static synchronized boolean writePropertiesIntoCsv(String appName, String tableId, - OrderedColumns orderedDefns, List kvsEntries, File definitionCsv, - File propertiesCsv) throws ServicesAvailabilityException { + OrderedColumns orderedDefns, List kvsEntries, DocumentFile definitionCsv, + DocumentFile propertiesCsv) throws ServicesAvailabilityException { WebLogger.getLogger(appName).i(TAG, "writePropertiesIntoCsv: tableId: " + tableId); // writing metadata @@ -89,7 +91,7 @@ public static synchronized boolean writePropertiesIntoCsv(String appName, String OutputStreamWriter output = null; try { // emit definition.csv table... - out = new FileOutputStream(definitionCsv); + out = new FileOutputStream(String.valueOf(definitionCsv)); output = new OutputStreamWriter(out, StandardCharsets.UTF_8); cw = new RFC4180CsvWriter(output); @@ -119,7 +121,7 @@ public static synchronized boolean writePropertiesIntoCsv(String appName, String cw.close(); // emit properties.csv... - out = new FileOutputStream(propertiesCsv); + out = new FileOutputStream(String.valueOf(propertiesCsv)); output = new OutputStreamWriter(out, StandardCharsets.UTF_8); cw = new RFC4180CsvWriter(output);