зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1363924 p1 - Add flowID to Client commands. r=Grisha
MozReview-Commit-ID: 58rumpyfQy6 --HG-- extra : rebase_source : 96d975e42096c13725faf7e9e66af240eb095a95
This commit is contained in:
Родитель
4d5651404b
Коммит
4665edb220
|
@ -1,200 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
package org.mozilla.gecko.background.db;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.repositories.NullCursorException;
|
||||
import org.mozilla.gecko.sync.repositories.android.ClientsDatabase;
|
||||
import org.mozilla.gecko.sync.repositories.android.RepoUtils;
|
||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||
import org.mozilla.gecko.sync.setup.Constants;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
public class TestClientsDatabase extends AndroidTestCase {
|
||||
|
||||
protected ClientsDatabase db;
|
||||
|
||||
public void setUp() {
|
||||
db = new ClientsDatabase(mContext);
|
||||
db.wipeDB();
|
||||
}
|
||||
|
||||
public void testStoreAndFetch() {
|
||||
ClientRecord record = new ClientRecord();
|
||||
String profileConst = Constants.DEFAULT_PROFILE;
|
||||
db.store(profileConst, record);
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
// Test stored item gets fetched correctly.
|
||||
cur = db.fetchClientsCursor(record.guid, profileConst);
|
||||
assertTrue(cur.moveToFirst());
|
||||
assertEquals(1, cur.getCount());
|
||||
|
||||
String guid = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_ACCOUNT_GUID);
|
||||
String profileId = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_PROFILE);
|
||||
String clientName = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_NAME);
|
||||
String clientType = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_TYPE);
|
||||
|
||||
assertEquals(record.guid, guid);
|
||||
assertEquals(profileConst, profileId);
|
||||
assertEquals(record.name, clientName);
|
||||
assertEquals(record.type, clientType);
|
||||
} catch (NullCursorException e) {
|
||||
fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testStoreAndFetchSpecificCommands() {
|
||||
String accountGUID = Utils.generateGuid();
|
||||
ArrayList<String> args = new ArrayList<String>();
|
||||
args.add("URI of Page");
|
||||
args.add("Sender GUID");
|
||||
args.add("Title of Page");
|
||||
String jsonArgs = JSONArray.toJSONString(args);
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
db.store(accountGUID, "displayURI", jsonArgs);
|
||||
|
||||
// This row should not show up in the fetch.
|
||||
args.add("Another arg.");
|
||||
db.store(accountGUID, "displayURI", JSONArray.toJSONString(args));
|
||||
|
||||
// Test stored item gets fetched correctly.
|
||||
cur = db.fetchSpecificCommand(accountGUID, "displayURI", jsonArgs);
|
||||
assertTrue(cur.moveToFirst());
|
||||
assertEquals(1, cur.getCount());
|
||||
|
||||
String guid = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_ACCOUNT_GUID);
|
||||
String commandType = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_COMMAND);
|
||||
String fetchedArgs = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_ARGS);
|
||||
|
||||
assertEquals(accountGUID, guid);
|
||||
assertEquals("displayURI", commandType);
|
||||
assertEquals(jsonArgs, fetchedArgs);
|
||||
} catch (NullCursorException e) {
|
||||
fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testFetchCommandsForClient() {
|
||||
String accountGUID = Utils.generateGuid();
|
||||
ArrayList<String> args = new ArrayList<String>();
|
||||
args.add("URI of Page");
|
||||
args.add("Sender GUID");
|
||||
args.add("Title of Page");
|
||||
String jsonArgs = JSONArray.toJSONString(args);
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
db.store(accountGUID, "displayURI", jsonArgs);
|
||||
|
||||
// This row should ALSO show up in the fetch.
|
||||
args.add("Another arg.");
|
||||
db.store(accountGUID, "displayURI", JSONArray.toJSONString(args));
|
||||
|
||||
// Test both stored items with the same GUID but different command are fetched.
|
||||
cur = db.fetchCommandsForClient(accountGUID);
|
||||
assertTrue(cur.moveToFirst());
|
||||
assertEquals(2, cur.getCount());
|
||||
} catch (NullCursorException e) {
|
||||
fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public void testDelete() {
|
||||
ClientRecord record1 = new ClientRecord();
|
||||
ClientRecord record2 = new ClientRecord();
|
||||
String profileConst = Constants.DEFAULT_PROFILE;
|
||||
|
||||
db.store(profileConst, record1);
|
||||
db.store(profileConst, record2);
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
// Test record doesn't exist after delete.
|
||||
db.deleteClient(record1.guid, profileConst);
|
||||
cur = db.fetchClientsCursor(record1.guid, profileConst);
|
||||
assertFalse(cur.moveToFirst());
|
||||
assertEquals(0, cur.getCount());
|
||||
|
||||
// Test record2 still there after deleting record1.
|
||||
cur = db.fetchClientsCursor(record2.guid, profileConst);
|
||||
assertTrue(cur.moveToFirst());
|
||||
assertEquals(1, cur.getCount());
|
||||
|
||||
String guid = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_ACCOUNT_GUID);
|
||||
String profileId = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_PROFILE);
|
||||
String clientName = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_NAME);
|
||||
String clientType = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_TYPE);
|
||||
|
||||
assertEquals(record2.guid, guid);
|
||||
assertEquals(profileConst, profileId);
|
||||
assertEquals(record2.name, clientName);
|
||||
assertEquals(record2.type, clientType);
|
||||
} catch (NullCursorException e) {
|
||||
fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
public void testWipe() {
|
||||
ClientRecord record1 = new ClientRecord();
|
||||
ClientRecord record2 = new ClientRecord();
|
||||
String profileConst = Constants.DEFAULT_PROFILE;
|
||||
|
||||
db.store(profileConst, record1);
|
||||
db.store(profileConst, record2);
|
||||
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
// Test before wipe the records are there.
|
||||
cur = db.fetchClientsCursor(record2.guid, profileConst);
|
||||
assertTrue(cur.moveToFirst());
|
||||
assertEquals(1, cur.getCount());
|
||||
cur = db.fetchClientsCursor(record2.guid, profileConst);
|
||||
assertTrue(cur.moveToFirst());
|
||||
assertEquals(1, cur.getCount());
|
||||
|
||||
// Test after wipe neither record exists.
|
||||
db.wipeClientsTable();
|
||||
cur = db.fetchClientsCursor(record2.guid, profileConst);
|
||||
assertFalse(cur.moveToFirst());
|
||||
assertEquals(0, cur.getCount());
|
||||
cur = db.fetchClientsCursor(record1.guid, profileConst);
|
||||
assertFalse(cur.moveToFirst());
|
||||
assertEquals(0, cur.getCount());
|
||||
} catch (NullCursorException e) {
|
||||
fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
package org.mozilla.gecko.background.db;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mozilla.gecko.background.testhelpers.CommandHelpers;
|
||||
import org.mozilla.gecko.sync.CommandProcessor.Command;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.repositories.NullCursorException;
|
||||
import org.mozilla.gecko.sync.repositories.android.ClientsDatabaseAccessor;
|
||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
public class TestClientsDatabaseAccessor extends AndroidTestCase {
|
||||
|
||||
public class StubbedClientsDatabaseAccessor extends ClientsDatabaseAccessor {
|
||||
public StubbedClientsDatabaseAccessor(Context mContext) {
|
||||
super(mContext);
|
||||
}
|
||||
}
|
||||
|
||||
StubbedClientsDatabaseAccessor db;
|
||||
|
||||
public void setUp() {
|
||||
db = new StubbedClientsDatabaseAccessor(mContext);
|
||||
db.wipeDB();
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
db.close();
|
||||
}
|
||||
|
||||
public void testStoreArrayListAndFetch() throws NullCursorException {
|
||||
ArrayList<ClientRecord> list = new ArrayList<ClientRecord>();
|
||||
ClientRecord record1 = new ClientRecord(Utils.generateGuid());
|
||||
ClientRecord record2 = new ClientRecord(Utils.generateGuid());
|
||||
ClientRecord record3 = new ClientRecord(Utils.generateGuid());
|
||||
|
||||
list.add(record1);
|
||||
list.add(record2);
|
||||
db.store(list);
|
||||
|
||||
ClientRecord r1 = db.fetchClient(record1.guid);
|
||||
ClientRecord r2 = db.fetchClient(record2.guid);
|
||||
ClientRecord r3 = db.fetchClient(record3.guid);
|
||||
|
||||
assertNotNull(r1);
|
||||
assertNotNull(r2);
|
||||
assertNull(r3);
|
||||
assertTrue(record1.equals(r1));
|
||||
assertTrue(record2.equals(r2));
|
||||
assertFalse(record3.equals(r3));
|
||||
}
|
||||
|
||||
public void testStoreAndFetchCommandsForClient() {
|
||||
String accountGUID1 = Utils.generateGuid();
|
||||
String accountGUID2 = Utils.generateGuid();
|
||||
|
||||
Command command1 = CommandHelpers.getCommand1();
|
||||
Command command2 = CommandHelpers.getCommand2();
|
||||
Command command3 = CommandHelpers.getCommand3();
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
db.store(accountGUID1, command1);
|
||||
db.store(accountGUID1, command2);
|
||||
db.store(accountGUID2, command3);
|
||||
|
||||
List<Command> commands = db.fetchCommandsForClient(accountGUID1);
|
||||
assertEquals(2, commands.size());
|
||||
assertEquals(1, commands.get(0).args.size());
|
||||
assertEquals(1, commands.get(1).args.size());
|
||||
} catch (NullCursorException e) {
|
||||
fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testNumClients() {
|
||||
final int COUNT = 5;
|
||||
ArrayList<ClientRecord> list = new ArrayList<ClientRecord>();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
list.add(new ClientRecord());
|
||||
}
|
||||
db.store(list);
|
||||
assertEquals(COUNT, db.clientsCount());
|
||||
}
|
||||
|
||||
public void testFetchAll() throws NullCursorException {
|
||||
ArrayList<ClientRecord> list = new ArrayList<ClientRecord>();
|
||||
ClientRecord record1 = new ClientRecord(Utils.generateGuid());
|
||||
ClientRecord record2 = new ClientRecord(Utils.generateGuid());
|
||||
|
||||
list.add(record1);
|
||||
list.add(record2);
|
||||
|
||||
boolean thrown = false;
|
||||
try {
|
||||
Map<String, ClientRecord> records = db.fetchAllClients();
|
||||
|
||||
assertNotNull(records);
|
||||
assertEquals(0, records.size());
|
||||
|
||||
db.store(list);
|
||||
records = db.fetchAllClients();
|
||||
assertNotNull(records);
|
||||
assertEquals(2, records.size());
|
||||
assertTrue(record1.equals(records.get(record1.guid)));
|
||||
assertTrue(record2.equals(records.get(record2.guid)));
|
||||
|
||||
// put() should throw an exception since records is immutable.
|
||||
records.put(null, null);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue(thrown);
|
||||
}
|
||||
|
||||
public void testFetchNonStaleClients() throws NullCursorException {
|
||||
String goodRecord1 = Utils.generateGuid();
|
||||
ClientRecord record1 = new ClientRecord(goodRecord1);
|
||||
record1.fxaDeviceId = "fxa1";
|
||||
ClientRecord record2 = new ClientRecord(Utils.generateGuid());
|
||||
record2.fxaDeviceId = "fxa2";
|
||||
String goodRecord2 = Utils.generateGuid();
|
||||
ClientRecord record3 = new ClientRecord(goodRecord2);
|
||||
record3.fxaDeviceId = "fxa4";
|
||||
|
||||
ArrayList<ClientRecord> list = new ArrayList<>();
|
||||
list.add(record1);
|
||||
list.add(record2);
|
||||
list.add(record3);
|
||||
db.store(list);
|
||||
|
||||
assertTrue(db.hasNonStaleClients(new String[]{"fxa1", "fxa-unknown"}));
|
||||
assertFalse(db.hasNonStaleClients(new String[]{}));
|
||||
|
||||
String noFxADeviceId = Utils.generateGuid();
|
||||
ClientRecord record4 = new ClientRecord(noFxADeviceId);
|
||||
record4.fxaDeviceId = null;
|
||||
list.clear();
|
||||
list.add(record4);
|
||||
db.store(list);
|
||||
|
||||
assertTrue(db.hasNonStaleClients(new String[]{}));
|
||||
|
||||
Collection<ClientRecord> filtered = db.fetchNonStaleClients(new String[]{"fxa1", "fxa4", "fxa-unknown"});
|
||||
ClientRecord[] filteredArr = filtered.toArray(new ClientRecord[0]);
|
||||
assertEquals(3, filteredArr.length);
|
||||
assertEquals(filteredArr[0].guid, goodRecord1);
|
||||
assertEquals(filteredArr[1].guid, goodRecord2);
|
||||
assertEquals(filteredArr[2].guid, noFxADeviceId);
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
package org.mozilla.gecko.background.testhelpers;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.mozilla.gecko.sync.CommandProcessor.Command;
|
||||
|
||||
public class CommandHelpers {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Command getCommand1() {
|
||||
JSONArray args = new JSONArray();
|
||||
args.add("argsA");
|
||||
return new Command("displayURI", args);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Command getCommand2() {
|
||||
JSONArray args = new JSONArray();
|
||||
args.add("argsB");
|
||||
return new Command("displayURI", args);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Command getCommand3() {
|
||||
JSONArray args = new JSONArray();
|
||||
args.add("argsC");
|
||||
return new Command("displayURI", args);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Command getCommand4() {
|
||||
JSONArray args = new JSONArray();
|
||||
args.add("URI of Page");
|
||||
args.add("Sender ID");
|
||||
args.add("Title of Page");
|
||||
return new Command("displayURI", args);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import android.content.ComponentName;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.mozilla.gecko.background.common.log.Logger;
|
||||
|
@ -55,10 +56,12 @@ public class CommandProcessor {
|
|||
public final String commandType;
|
||||
public final JSONArray args;
|
||||
private List<String> argsList;
|
||||
@Nullable public String flowID;
|
||||
|
||||
public Command(String commandType, JSONArray args) {
|
||||
public Command(String commandType, JSONArray args, @Nullable String flowID) {
|
||||
this.commandType = commandType;
|
||||
this.args = args;
|
||||
this.flowID = flowID;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,6 +91,9 @@ public class CommandProcessor {
|
|||
JSONObject out = new JSONObject();
|
||||
out.put("command", this.commandType);
|
||||
out.put("args", this.args);
|
||||
if (this.flowID != null) {
|
||||
out.put("flowID", this.flowID);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
@ -149,8 +155,9 @@ public class CommandProcessor {
|
|||
if (unparsedArgs == null) {
|
||||
return null;
|
||||
}
|
||||
final String flowID = unparsedCommand.getString("flowID");
|
||||
|
||||
return new Command(type, unparsedArgs);
|
||||
return new Command(type, unparsedArgs, flowID);
|
||||
} catch (NonArrayJSONException e) {
|
||||
Logger.debug(LOG_TAG, "Unable to parse args array. Invalid command");
|
||||
return null;
|
||||
|
@ -169,7 +176,8 @@ public class CommandProcessor {
|
|||
args.add(sender);
|
||||
args.add(title);
|
||||
|
||||
final Command displayURICommand = new Command("displayURI", args);
|
||||
final String flowID = Utils.generateGuid();
|
||||
final Command displayURICommand = new Command("displayURI", args, flowID);
|
||||
this.sendCommand(clientID, displayURICommand, context);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ public class ClientsDatabase extends CachedSQLiteOpenHelper {
|
|||
|
||||
// Database Specifications.
|
||||
protected static final String DB_NAME = "clients_database";
|
||||
protected static final int SCHEMA_VERSION = 4;
|
||||
protected static final int SCHEMA_VERSION = 5;
|
||||
|
||||
// Clients Table.
|
||||
public static final String TBL_CLIENTS = "clients";
|
||||
|
@ -46,8 +46,9 @@ public class ClientsDatabase extends CachedSQLiteOpenHelper {
|
|||
public static final String TBL_COMMANDS = "commands";
|
||||
public static final String COL_COMMAND = "command";
|
||||
public static final String COL_ARGS = "args";
|
||||
public static final String COL_FLOW_ID = "flow_id";
|
||||
|
||||
public static final String[] TBL_COMMANDS_COLUMNS = new String[] { COL_ACCOUNT_GUID, COL_COMMAND, COL_ARGS };
|
||||
public static final String[] TBL_COMMANDS_COLUMNS = new String[] { COL_ACCOUNT_GUID, COL_COMMAND, COL_ARGS, COL_FLOW_ID };
|
||||
public static final String TBL_COMMANDS_KEY = COL_ACCOUNT_GUID + " = ? AND " +
|
||||
COL_COMMAND + " = ? AND " +
|
||||
COL_ARGS + " = ?";
|
||||
|
@ -91,6 +92,7 @@ public class ClientsDatabase extends CachedSQLiteOpenHelper {
|
|||
+ COL_ACCOUNT_GUID + " TEXT, "
|
||||
+ COL_COMMAND + " TEXT, "
|
||||
+ COL_ARGS + " TEXT, "
|
||||
+ COL_FLOW_ID + " TEXT, "
|
||||
+ "PRIMARY KEY (" + COL_ACCOUNT_GUID + ", " + COL_COMMAND + ", " + COL_ARGS + "), "
|
||||
+ "FOREIGN KEY (" + COL_ACCOUNT_GUID + ") REFERENCES " + TBL_CLIENTS + " (" + COL_ACCOUNT_GUID + "))";
|
||||
db.execSQL(createCommandsTableSql);
|
||||
|
@ -120,6 +122,10 @@ public class ClientsDatabase extends CachedSQLiteOpenHelper {
|
|||
db.execSQL("ALTER TABLE " + TBL_CLIENTS + " ADD COLUMN " + COL_FXA_DEVICE_ID + " TEXT");
|
||||
db.execSQL("CREATE INDEX idx_fxa_device_id ON " + TBL_CLIENTS + "(" + COL_FXA_DEVICE_ID + ")");
|
||||
}
|
||||
|
||||
if (oldVersion < 5 && newVersion >= 5) {
|
||||
db.execSQL("ALTER TABLE " + TBL_COMMANDS + " ADD COLUMN " + COL_FLOW_ID + " TEXT");
|
||||
}
|
||||
}
|
||||
|
||||
public void wipeDB() {
|
||||
|
@ -189,9 +195,10 @@ public class ClientsDatabase extends CachedSQLiteOpenHelper {
|
|||
* @param accountGUID
|
||||
* @param command - The command type
|
||||
* @param args - A JSON string of args
|
||||
* @param flowID - Optional - The flowID
|
||||
* @throws NullCursorException
|
||||
*/
|
||||
public void store(String accountGUID, String command, String args) throws NullCursorException {
|
||||
public void store(String accountGUID, String command, String args, String flowID) throws NullCursorException {
|
||||
if (Logger.LOG_PERSONAL_INFORMATION) {
|
||||
Logger.pii(LOG_TAG, "Storing command " + command + " with args " + args);
|
||||
} else {
|
||||
|
@ -207,6 +214,9 @@ public class ClientsDatabase extends CachedSQLiteOpenHelper {
|
|||
} else {
|
||||
cv.put(COL_ARGS, args);
|
||||
}
|
||||
if (flowID != null) {
|
||||
cv.put(COL_FLOW_ID, flowID);
|
||||
}
|
||||
|
||||
Cursor cur = this.fetchSpecificCommand(accountGUID, command, args);
|
||||
try {
|
||||
|
@ -229,6 +239,8 @@ public class ClientsDatabase extends CachedSQLiteOpenHelper {
|
|||
return queryHelper.safeQuery(db, ".fetchClientsCursor", TBL_CLIENTS, TBL_CLIENTS_COLUMNS, TBL_CLIENTS_KEY, args);
|
||||
}
|
||||
|
||||
// This method does not check flowID on purpose because we do not want to take it into account
|
||||
// when de-duping commands.
|
||||
public Cursor fetchSpecificCommand(String accountGUID, String command, String commandArgs) throws NullCursorException {
|
||||
String[] args = new String[] { accountGUID, command, commandArgs };
|
||||
SQLiteDatabase db = this.getCachedReadableDatabase();
|
||||
|
|
|
@ -50,7 +50,7 @@ public class ClientsDatabaseAccessor {
|
|||
}
|
||||
|
||||
public void store(String accountGUID, Command command) throws NullCursorException {
|
||||
db.store(accountGUID, command.commandType, command.args.toJSONString());
|
||||
db.store(accountGUID, command.commandType, command.args.toJSONString(), command.flowID);
|
||||
}
|
||||
|
||||
public ClientRecord fetchClient(String accountGUID) throws NullCursorException {
|
||||
|
@ -195,9 +195,10 @@ public class ClientsDatabaseAccessor {
|
|||
}
|
||||
|
||||
protected static Command commandFromCursor(Cursor cur) {
|
||||
String commandType = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_COMMAND);
|
||||
JSONArray commandArgs = RepoUtils.getJSONArrayFromCursor(cur, ClientsDatabase.COL_ARGS);
|
||||
return new Command(commandType, commandArgs);
|
||||
final String commandType = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_COMMAND);
|
||||
final JSONArray commandArgs = RepoUtils.getJSONArrayFromCursor(cur, ClientsDatabase.COL_ARGS);
|
||||
final String flowID = RepoUtils.optStringFromCursor(cur, ClientsDatabase.COL_FLOW_ID);
|
||||
return new Command(commandType, commandArgs, flowID);
|
||||
}
|
||||
|
||||
public int clientsCount() {
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
package org.mozilla.gecko.background.db;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.repositories.NullCursorException;
|
||||
import org.mozilla.gecko.sync.repositories.android.ClientsDatabase;
|
||||
import org.mozilla.gecko.sync.repositories.android.RepoUtils;
|
||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||
import org.mozilla.gecko.sync.setup.Constants;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@RunWith(TestRunner.class)
|
||||
public class TestClientsDatabase {
|
||||
|
||||
protected ClientsDatabase db;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
db = new ClientsDatabase(context);
|
||||
db.wipeDB();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreAndFetch() {
|
||||
ClientRecord record = new ClientRecord();
|
||||
String profileConst = Constants.DEFAULT_PROFILE;
|
||||
db.store(profileConst, record);
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
// Test stored item gets fetched correctly.
|
||||
cur = db.fetchClientsCursor(record.guid, profileConst);
|
||||
Assert.assertTrue(cur.moveToFirst());
|
||||
Assert.assertEquals(1, cur.getCount());
|
||||
|
||||
String guid = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_ACCOUNT_GUID);
|
||||
String profileId = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_PROFILE);
|
||||
String clientName = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_NAME);
|
||||
String clientType = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_TYPE);
|
||||
|
||||
Assert.assertEquals(record.guid, guid);
|
||||
Assert.assertEquals(profileConst, profileId);
|
||||
Assert.assertEquals(record.name, clientName);
|
||||
Assert.assertEquals(record.type, clientType);
|
||||
} catch (NullCursorException e) {
|
||||
Assert.fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreAndFetchSpecificCommands() {
|
||||
String accountGUID = Utils.generateGuid();
|
||||
ArrayList<String> args = new ArrayList<>();
|
||||
args.add("URI of Page");
|
||||
args.add("Sender GUID");
|
||||
args.add("Title of Page");
|
||||
String jsonArgs = JSONArray.toJSONString(args);
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
db.store(accountGUID, "displayURI", jsonArgs, "flowID");
|
||||
|
||||
// This row should not show up in the fetch.
|
||||
args.add("Another arg.");
|
||||
db.store(accountGUID, "displayURI", JSONArray.toJSONString(args), "flowID");
|
||||
|
||||
// Test stored item gets fetched correctly.
|
||||
cur = db.fetchSpecificCommand(accountGUID, "displayURI", jsonArgs);
|
||||
Assert.assertTrue(cur.moveToFirst());
|
||||
Assert.assertEquals(1, cur.getCount());
|
||||
|
||||
String guid = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_ACCOUNT_GUID);
|
||||
String commandType = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_COMMAND);
|
||||
String fetchedArgs = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_ARGS);
|
||||
|
||||
Assert.assertEquals(accountGUID, guid);
|
||||
Assert.assertEquals("displayURI", commandType);
|
||||
Assert.assertEquals(jsonArgs, fetchedArgs);
|
||||
} catch (NullCursorException e) {
|
||||
Assert.fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchCommandsForClient() {
|
||||
String accountGUID = Utils.generateGuid();
|
||||
ArrayList<String> args = new ArrayList<>();
|
||||
args.add("URI of Page");
|
||||
args.add("Sender GUID");
|
||||
args.add("Title of Page");
|
||||
String jsonArgs = JSONArray.toJSONString(args);
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
db.store(accountGUID, "displayURI", jsonArgs, "flowID");
|
||||
|
||||
// This row should ALSO show up in the fetch.
|
||||
args.add("Another arg.");
|
||||
db.store(accountGUID, "displayURI", JSONArray.toJSONString(args), "flowID");
|
||||
|
||||
// Test both stored items with the same GUID but different command are fetched.
|
||||
cur = db.fetchCommandsForClient(accountGUID);
|
||||
Assert.assertTrue(cur.moveToFirst());
|
||||
Assert.assertEquals(2, cur.getCount());
|
||||
} catch (NullCursorException e) {
|
||||
Assert.fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void testDelete() {
|
||||
ClientRecord record1 = new ClientRecord();
|
||||
ClientRecord record2 = new ClientRecord();
|
||||
String profileConst = Constants.DEFAULT_PROFILE;
|
||||
|
||||
db.store(profileConst, record1);
|
||||
db.store(profileConst, record2);
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
// Test record doesn't exist after delete.
|
||||
db.deleteClient(record1.guid, profileConst);
|
||||
cur = db.fetchClientsCursor(record1.guid, profileConst);
|
||||
Assert.assertFalse(cur.moveToFirst());
|
||||
Assert.assertEquals(0, cur.getCount());
|
||||
|
||||
// Test record2 still there after deleting record1.
|
||||
cur = db.fetchClientsCursor(record2.guid, profileConst);
|
||||
Assert.assertTrue(cur.moveToFirst());
|
||||
Assert.assertEquals(1, cur.getCount());
|
||||
|
||||
String guid = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_ACCOUNT_GUID);
|
||||
String profileId = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_PROFILE);
|
||||
String clientName = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_NAME);
|
||||
String clientType = RepoUtils.getStringFromCursor(cur, ClientsDatabase.COL_TYPE);
|
||||
|
||||
Assert.assertEquals(record2.guid, guid);
|
||||
Assert.assertEquals(profileConst, profileId);
|
||||
Assert.assertEquals(record2.name, clientName);
|
||||
Assert.assertEquals(record2.type, clientType);
|
||||
} catch (NullCursorException e) {
|
||||
Assert.fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("resource")
|
||||
public void testWipe() {
|
||||
ClientRecord record1 = new ClientRecord();
|
||||
ClientRecord record2 = new ClientRecord();
|
||||
String profileConst = Constants.DEFAULT_PROFILE;
|
||||
|
||||
db.store(profileConst, record1);
|
||||
db.store(profileConst, record2);
|
||||
|
||||
|
||||
Cursor cur = null;
|
||||
try {
|
||||
// Test before wipe the records are there.
|
||||
cur = db.fetchClientsCursor(record2.guid, profileConst);
|
||||
Assert.assertTrue(cur.moveToFirst());
|
||||
Assert.assertEquals(1, cur.getCount());
|
||||
cur = db.fetchClientsCursor(record2.guid, profileConst);
|
||||
Assert.assertTrue(cur.moveToFirst());
|
||||
Assert.assertEquals(1, cur.getCount());
|
||||
|
||||
// Test after wipe neither record exists.
|
||||
db.wipeClientsTable();
|
||||
cur = db.fetchClientsCursor(record2.guid, profileConst);
|
||||
Assert.assertFalse(cur.moveToFirst());
|
||||
Assert.assertEquals(0, cur.getCount());
|
||||
cur = db.fetchClientsCursor(record1.guid, profileConst);
|
||||
Assert.assertFalse(cur.moveToFirst());
|
||||
Assert.assertEquals(0, cur.getCount());
|
||||
} catch (NullCursorException e) {
|
||||
Assert.fail("Should not have NullCursorException");
|
||||
} finally {
|
||||
if (cur != null) {
|
||||
cur.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
package org.mozilla.gecko.background.db;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mozilla.gecko.background.testhelpers.CommandHelpers;
|
||||
import org.mozilla.gecko.background.testhelpers.TestRunner;
|
||||
import org.mozilla.gecko.sync.CommandProcessor.Command;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.repositories.NullCursorException;
|
||||
import org.mozilla.gecko.sync.repositories.android.ClientsDatabaseAccessor;
|
||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@RunWith(TestRunner.class)
|
||||
public class TestClientsDatabaseAccessor {
|
||||
|
||||
ClientsDatabaseAccessor db;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
db = new ClientsDatabaseAccessor(context);
|
||||
db.wipeDB();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
db.close();
|
||||
}
|
||||
|
||||
public void testStoreArrayListAndFetch() throws NullCursorException {
|
||||
ArrayList<ClientRecord> list = new ArrayList<>();
|
||||
ClientRecord record1 = new ClientRecord(Utils.generateGuid());
|
||||
ClientRecord record2 = new ClientRecord(Utils.generateGuid());
|
||||
ClientRecord record3 = new ClientRecord(Utils.generateGuid());
|
||||
|
||||
list.add(record1);
|
||||
list.add(record2);
|
||||
db.store(list);
|
||||
|
||||
ClientRecord r1 = db.fetchClient(record1.guid);
|
||||
ClientRecord r2 = db.fetchClient(record2.guid);
|
||||
ClientRecord r3 = db.fetchClient(record3.guid);
|
||||
|
||||
Assert.assertNotNull(r1);
|
||||
Assert.assertNotNull(r2);
|
||||
Assert.assertNull(r3);
|
||||
Assert.assertTrue(record1.equals(r1));
|
||||
Assert.assertTrue(record2.equals(r2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreAndFetchCommandsForClient() {
|
||||
String accountGUID1 = Utils.generateGuid();
|
||||
String accountGUID2 = Utils.generateGuid();
|
||||
|
||||
Command command1 = CommandHelpers.getCommand1();
|
||||
Command command2 = CommandHelpers.getCommand2();
|
||||
Command command3 = CommandHelpers.getCommand3();
|
||||
|
||||
try {
|
||||
db.store(accountGUID1, command1);
|
||||
db.store(accountGUID1, command2);
|
||||
db.store(accountGUID2, command3);
|
||||
|
||||
List<Command> commands = db.fetchCommandsForClient(accountGUID1);
|
||||
Assert.assertEquals(2, commands.size());
|
||||
Assert.assertEquals(1, commands.get(0).args.size());
|
||||
Assert.assertEquals(1, commands.get(1).args.size());
|
||||
} catch (NullCursorException e) {
|
||||
Assert.fail("Should not have NullCursorException");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumClients() {
|
||||
final int COUNT = 5;
|
||||
ArrayList<ClientRecord> list = new ArrayList<>();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
list.add(new ClientRecord());
|
||||
}
|
||||
db.store(list);
|
||||
Assert.assertEquals(COUNT, db.clientsCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchAll() throws NullCursorException {
|
||||
ArrayList<ClientRecord> list = new ArrayList<>();
|
||||
ClientRecord record1 = new ClientRecord(Utils.generateGuid());
|
||||
ClientRecord record2 = new ClientRecord(Utils.generateGuid());
|
||||
|
||||
list.add(record1);
|
||||
list.add(record2);
|
||||
|
||||
boolean thrown = false;
|
||||
try {
|
||||
Map<String, ClientRecord> records = db.fetchAllClients();
|
||||
|
||||
Assert.assertNotNull(records);
|
||||
Assert.assertEquals(0, records.size());
|
||||
|
||||
db.store(list);
|
||||
records = db.fetchAllClients();
|
||||
Assert.assertNotNull(records);
|
||||
Assert.assertEquals(2, records.size());
|
||||
Assert.assertTrue(record1.equals(records.get(record1.guid)));
|
||||
Assert.assertTrue(record2.equals(records.get(record2.guid)));
|
||||
|
||||
// put() should throw an exception since records is immutable.
|
||||
records.put(null, null);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
thrown = true;
|
||||
}
|
||||
Assert.assertTrue(thrown);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchNonStaleClients() throws NullCursorException {
|
||||
String goodRecord1 = Utils.generateGuid();
|
||||
ClientRecord record1 = new ClientRecord(goodRecord1);
|
||||
record1.fxaDeviceId = "fxa1";
|
||||
ClientRecord record2 = new ClientRecord(Utils.generateGuid());
|
||||
record2.fxaDeviceId = "fxa2";
|
||||
String goodRecord2 = Utils.generateGuid();
|
||||
ClientRecord record3 = new ClientRecord(goodRecord2);
|
||||
record3.fxaDeviceId = "fxa4";
|
||||
|
||||
ArrayList<ClientRecord> list = new ArrayList<>();
|
||||
list.add(record1);
|
||||
list.add(record2);
|
||||
list.add(record3);
|
||||
db.store(list);
|
||||
|
||||
Assert.assertTrue(db.hasNonStaleClients(new String[]{"fxa1", "fxa-unknown"}));
|
||||
Assert.assertFalse(db.hasNonStaleClients(new String[]{}));
|
||||
|
||||
String noFxADeviceId = Utils.generateGuid();
|
||||
ClientRecord record4 = new ClientRecord(noFxADeviceId);
|
||||
record4.fxaDeviceId = null;
|
||||
list.clear();
|
||||
list.add(record4);
|
||||
db.store(list);
|
||||
|
||||
Assert.assertTrue(db.hasNonStaleClients(new String[]{}));
|
||||
|
||||
Collection<ClientRecord> filtered = db.fetchNonStaleClients(new String[]{"fxa1", "fxa4", "fxa-unknown"});
|
||||
ClientRecord[] filteredArr = filtered.toArray(new ClientRecord[0]);
|
||||
Assert.assertEquals(3, filteredArr.length);
|
||||
Assert.assertEquals(filteredArr[0].guid, goodRecord1);
|
||||
Assert.assertEquals(filteredArr[1].guid, goodRecord2);
|
||||
Assert.assertEquals(filteredArr[2].guid, noFxADeviceId);
|
||||
}
|
||||
}
|
|
@ -12,21 +12,21 @@ public class CommandHelpers {
|
|||
public static Command getCommand1() {
|
||||
JSONArray args = new JSONArray();
|
||||
args.add("argsA");
|
||||
return new Command("displayURI", args);
|
||||
return new Command("displayURI", args, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Command getCommand2() {
|
||||
JSONArray args = new JSONArray();
|
||||
args.add("argsB");
|
||||
return new Command("displayURI", args);
|
||||
return new Command("displayURI", args, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Command getCommand3() {
|
||||
JSONArray args = new JSONArray();
|
||||
args.add("argsC");
|
||||
return new Command("displayURI", args);
|
||||
return new Command("displayURI", args, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -35,6 +35,6 @@ public class CommandHelpers {
|
|||
args.add("URI of Page");
|
||||
args.add("Sender ID");
|
||||
args.add("Title of Page");
|
||||
return new Command("displayURI", args);
|
||||
return new Command("displayURI", args, null);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче