Permalink
Browse files

* Add collection membership removal, closes #82

 * Move test project into main project
  • Loading branch information...
1 parent 832bfc3 commit a24f09a5703e0fe654fbf4c8e9021d5c7df6629f @avram committed Jan 28, 2012
View
@@ -3,3 +3,12 @@ bin/*
gen/*
.classpath
project.properties
+test/assets/*
+test/bin/*
+test/gen/*
+app/assets/*
+app/bin/*
+app/gen/*
+app/.classpath
+app/project.properties
+test/project.properties
@@ -188,7 +188,7 @@ public void onClick(DialogInterface dialog, int whichButton) {
public void onClick(DialogInterface dialog, int whichButton) {
Item item = Item.load(itemKey, db);
ItemCollection coll = ItemCollection.load(collectionKey, db);
- coll.remove(item, db);
+ coll.remove(item, false, db);
ArrayAdapter<ItemCollection> la = (ArrayAdapter<ItemCollection>) getListAdapter();
la.clear();
for (ItemCollection b : ItemCollection.getCollections(item,db)) {
@@ -43,6 +43,7 @@
*/
public class RequestActivity extends ListActivity {
+ @SuppressWarnings("unused")
private static final String TAG = "com.gimranov.zandy.app.RequestActivity";
private Database db;
@@ -96,13 +96,23 @@ public ItemCollection() {
/**
* We call void remove(Item) to allow for queueing
* the action for application on the server, via the API.
+ *
+ * When fromAPI is not true, queues a collection membership
+ * request for the server as well.
+ *
+ * @param item
+ * @param fromAPI False for collection memberships we receive from the server
+ * @param db
*/
- public boolean remove(Item item, Database db) {
+ public boolean remove(Item item, boolean fromAPI, Database db) {
String[] args = {dbId, item.dbId};
db.rawQuery("delete from itemtocollections where collection_id=? and item_id=?", args);
- APIRequest req = APIRequest.remove(item, this);
- req.status = APIRequest.REQ_NEW;
- req.save(db);
+
+ if (!fromAPI) {
+ APIRequest req = APIRequest.remove(item, this);
+ req.status = APIRequest.REQ_NEW;
+ req.save(db);
+ }
super.remove(item);
return true;
}
@@ -226,6 +236,21 @@ public boolean add(Item item, boolean fromAPI, Database db) {
}
/**
+ * Returns ArrayList of Item objects not in the specified ArrayList of item keys. Used for determining
+ * when items have been deleted from a collection.
+ */
+ public ArrayList<Item> notInKeys(ArrayList<String> keys) {
+ ArrayList<Item> notThere = new ArrayList<Item>();
+
+ for (Item i : this) {
+ if (!keys.contains(i.getKey()))
+ notThere.add(i);
+ }
+
+ return notThere;
+ }
+
+ /**
* Saves the collection metadata to the database.
*
* Does nothing with the collection children.
@@ -23,6 +23,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
@@ -775,6 +776,15 @@ public void issue(Database db, ServerCredentials cred) throws APIException {
if (coll != null) {
coll.loadChildren(db);
+
+ // If this is a collection's key listing, we first look
+ // for any synced keys we have that aren't in the list
+ ArrayList<String> keyAL = new ArrayList<String>(Arrays.asList(keys));
+ ArrayList<Item> notThere = coll.notInKeys(keyAL);
+ // We should then remove those memberships
+ for (Item i : notThere) {
+ coll.remove(i, true, db);
+ }
}
ArrayList<Item> recd = new ArrayList<Item>();
@@ -828,7 +838,7 @@ public void issue(Database db, ServerCredentials cred) throws APIException {
}
}
} else if (type == ITEMS_CHILDREN) {
- // Try to get a parent collection
+ // Try to get a parent item
// Our query looks like this:
// /users/5770/items/2AJUSIU9/children
int itemloc = query.indexOf("/items/");
View
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>zandy_test</name>
+ <comment></comment>
+ <projects>
+ <project>zandy</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.gimranov.zandy.app.test"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk android:minSdkVersion="8" />
+
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.gimranov.zandy.app" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name" >
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+</manifest>
View
@@ -0,0 +1,3 @@
+Tests for the main Zandy code.
+
+This is part of the Zandy project; see https://github.com/ajlyon/zandy for more.
View
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+</lint>
View
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/hello" />
+
+</LinearLayout>
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="hello">Hello World!</string>
+ <string name="app_name">ZandyTestTest</string>
+
+</resources>
@@ -0,0 +1,80 @@
+package com.gimranov.zandy.app.test;
+
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.test.AndroidTestCase;
+import android.test.IsolatedContext;
+
+import com.gimranov.zandy.app.ServerCredentials;
+import com.gimranov.zandy.app.data.Database;
+import com.gimranov.zandy.app.task.APIException;
+import com.gimranov.zandy.app.task.APIRequest;
+
+
+public class ApiTest extends AndroidTestCase {
+
+ private IsolatedContext mContext;
+ private Database mDb;
+ private ServerCredentials mCred;
+
+ /**
+ * Access information for the Zandy test user on Zotero.org
+ */
+ private static final String TEST_UID = "743083";
+ private static final String TEST_KEY = "JFRP2k4qvhRUm62kuDHXUUX3";
+ private static final String TEST_COLLECTION = "U8GNSSF3";
+
+ // unlikely to exist
+ private static final String TEST_MISSING_ITEM = "ZZZZZZZZ";
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContext = new IsolatedContext(null, getContext());
+ mDb = new Database(mContext);
+
+ SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mContext);
+ SharedPreferences.Editor editor = settings.edit();
+ // For Zotero, the key and secret are identical, it seems
+ editor.putString("user_key", TEST_KEY);
+ editor.putString("user_secret", TEST_KEY);
+ editor.putString("user_id", TEST_UID);
+ editor.commit();
+
+ mCred = new ServerCredentials(mContext);
+ }
+
+ public void testPreConditions() {
+ // Make sure we do indeed have the key set up
+ assertTrue(ServerCredentials.check(mContext));
+ }
+
+ public void testItemsRequest() throws APIException {
+ APIRequest items = APIRequest.fetchItems(false, mCred);
+ items.issue(mDb, mCred);
+ }
+
+ public void testCollectionsRequest() throws APIException {
+ APIRequest collections = APIRequest.fetchCollections(mCred);
+ collections.issue(mDb, mCred);
+ }
+
+ public void testItemsForCollection() throws APIException {
+ APIRequest collection = APIRequest.fetchItems(TEST_COLLECTION, false, mCred);
+ collection.issue(mDb, mCred);
+ }
+
+ public void testMissingItem() throws APIException {
+ APIRequest missingItem = APIRequest.fetchItem(TEST_MISSING_ITEM, mCred);
+ try {
+ missingItem.issue(mDb, mCred);
+ // We shouldn't get here
+ assertTrue(false);
+ } catch (APIException e) {
+ // We expect only one specific exception message
+ if (!"Item does not exist".equals(e.getMessage()))
+ throw e;
+ }
+ }
+}
@@ -0,0 +1,27 @@
+package com.gimranov.zandy.app.test;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.widget.Button;
+
+import com.gimranov.zandy.app.MainActivity;
+
+public class MainTest extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mActivity;
+ private Button loginButton;
+
+ public MainTest() {
+ super("com.gimranov.zandy.app", MainActivity.class);
+ }
+
+ public void testPreconditions() {
+ assertNotNull(loginButton);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = this.getActivity();
+ loginButton = (Button) mActivity.findViewById(com.gimranov.zandy.app.R.id.loginButton);
+ }
+}

0 comments on commit a24f09a

Please sign in to comment.