package org.ohmage.activity.async;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.ohmage.OhmageApi;
import org.ohmage.OhmageApi.CampaignReadResponse;
import org.ohmage.OhmageApi.Result;
import org.ohmage.async.CampaignReadTask;
import org.ohmage.db.DbContract;
import org.ohmage.db.DbContract.Campaigns;
import org.ohmage.db.Models.Campaign;
import org.ohmage.db.test.CampaignCursor;
import org.ohmage.db.test.EmptyMockCursor;
import org.ohmage.db.test.OhmageUriMatcher;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import java.util.ArrayList;
import junit.framework.TestCase;
/**
* Tests the {@link CampaignReadTask}
*
* @author cketcham
*
*/
public class CampaignReadTaskTest extends TestCase {
private CampaignReadTask mReadTask;
@Override
protected void tearDown() throws Exception{
mReadTask = null;
super.tearDown();
}
private CampaignReadResponse generateCampaignJSON(Campaign... campaigns) {
CampaignReadResponse response = new CampaignReadResponse();
response.setResult(Result.SUCCESS);
generateCampaignJSON(response, campaigns);
return response;
}
private void generateCampaignJSON(CampaignReadResponse response, Campaign... campaigns) {
try {
JSONArray items = new JSONArray();
JSONObject data = new JSONObject();
for(Campaign c : campaigns) {
items.put(c.mUrn);
JSONObject campaign = new JSONObject();
campaign.put("name", c.mName);
campaign.put("creation_timestamp", c.mCreationTimestamp);
campaign.put("description", "");
if(c.mStatus == Campaign.STATUS_READY || c.mStatus == Campaign.STATUS_REMOTE)
campaign.put("running_state","running");
else
campaign.put("running_state","not running");
data.put(c.mUrn, campaign);
}
JSONObject metadata = new JSONObject();
metadata.put("items", items);
response.setMetadata(metadata);
response.setData(data);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public abstract static class CampaignReadTaskContext extends MockContext {
private MockContentResolver mResolver;
private final Campaign[] mCampaigns;
public CampaignReadTaskContext(Campaign... campaigns) {
mCampaigns = campaigns;
}
public CampaignReadTaskContext(int status) {
this(status, "0");
}
public CampaignReadTaskContext(int status, String creationTimestamp) {
mCampaigns = new Campaign[1];
mCampaigns[0] = new Campaign();
mCampaigns[0].mUrn = CampaignCursor.DEFAULT_CAMPAIGN_URN;
mCampaigns[0].mName = CampaignCursor.DEFAULT_CAMPAIGN_NAME;
mCampaigns[0].mStatus = status;
mCampaigns[0].mCreationTimestamp = creationTimestamp;
}
@Override
public Context getApplicationContext() {
return this;
}
@Override
public ContentResolver getContentResolver() {
if(mResolver == null) {
mResolver = new MockContentResolver() {
@Override
public ContentProviderResult[] applyBatch(String authority,
ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException {
CampaignReadTaskContext.this.applyBatch(operations);
return null;
}
};
mResolver.addProvider(DbContract.CONTENT_AUTHORITY, new MockContentProvider(this) {
@Override
public int update(Uri uri, ContentValues values, String where, String[] selectionArgs) {
return 0;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
switch(OhmageUriMatcher.getMatcher().match(uri)) {
case OhmageUriMatcher.CAMPAIGNS:
return new CampaignCursor(projection, mCampaigns);
}
return new EmptyMockCursor();
}
});
}
return mResolver;
}
public abstract void applyBatch(ArrayList<ContentProviderOperation> operations);
public Campaign[] getCampaigns() {
return mCampaigns;
}
}
public interface TestOperations {
public void test(ArrayList<ContentProviderOperation> operations);
}
private void helperTestStateChange(int localState, final int remoteState, final TestOperations tests) {
final CampaignReadTaskContext context = new CampaignReadTaskContext(localState) {
@Override
public void applyBatch(ArrayList<ContentProviderOperation> operations) {
tests.test(operations);
}
};
mReadTask = new CampaignReadTask(context);
mReadTask.setOhmageApi(new OhmageApi() {
@Override
public CampaignReadResponse campaignRead(String serverUrl, String username, String hashedPassword, String client, String outputFormat, String campaignUrnList) {
Campaign c = CampaignCursor.cloneCampaign(context.getCampaigns()[0]);
if(remoteState == Campaign.STATUS_NO_EXIST)
return generateCampaignJSON();
else if(remoteState == Campaign.STATUS_OUT_OF_DATE)
c.mCreationTimestamp = String.valueOf(Long.valueOf(c.mCreationTimestamp) + 1);
else
c.mStatus = remoteState;
return generateCampaignJSON(c);
}
});
mReadTask.loadInBackground();
}
public void testRunningCampaignOutOfDate() {
helperTestStateChange(Campaign.STATUS_READY, Campaign.STATUS_OUT_OF_DATE, new TestOperations() {
@Override
public void test(ArrayList<ContentProviderOperation> operations) {
// Check that we are doing an update to set the campaign to deleted
assertEquals(1, operations.size());
assertTrue(operations.get(0).toString().startsWith("mType: 2"));
assertTrue(operations.get(0).toString().matches(".*mValues: .*campaign_status=" + Campaign.STATUS_OUT_OF_DATE + ".*" ));
}
});
}
public void testRunningCampaignDeleted() {
helperTestStateChange(Campaign.STATUS_READY, Campaign.STATUS_NO_EXIST, new TestOperations() {
@Override
public void test(ArrayList<ContentProviderOperation> operations) {
// Check that we are doing an update to set the campaign to deleted
assertEquals(1, operations.size());
assertTrue(operations.get(0).toString().startsWith("mType: 2"));
assertTrue(operations.get(0).toString().matches(".*mValues: .*campaign_status=" + Campaign.STATUS_NO_EXIST + ".*" ));
}
});
}
public void testRemoteCampaignDeleted() {
helperTestStateChange(Campaign.STATUS_REMOTE, Campaign.STATUS_NO_EXIST, new TestOperations() {
@Override
public void test(ArrayList<ContentProviderOperation> operations) {
// Check that we are doing an update to set the campaign to deleted
assertEquals(1, operations.size());
assertTrue(operations.get(0).toString().startsWith("mType: 3"));
assertTrue(operations.get(0).getUri().compareTo(Campaigns.buildCampaignUri(CampaignCursor.DEFAULT_CAMPAIGN_URN)) == 0);
}
});
}
public void testRunningCampaignRunning() {
helperTestStateChange(Campaign.STATUS_READY, Campaign.STATUS_READY, new TestOperations() {
@Override
public void test(ArrayList<ContentProviderOperation> operations) {
// Check that we are doing an update to set the campaign to deleted
assertEquals(1, operations.size());
assertTrue(operations.get(0).toString().startsWith("mType: 2"));
assertTrue(operations.get(0).toString().matches(".*mValues: .*campaign_status=" + Campaign.STATUS_READY + ".*" ));
}
});
}
public void testRemoteCampaignRunning() {
helperTestStateChange(Campaign.STATUS_REMOTE, Campaign.STATUS_READY, new TestOperations() {
@Override
public void test(ArrayList<ContentProviderOperation> operations) {
// Check that we are doing an update to set the campaign to deleted
assertEquals(1, operations.size());
assertTrue(operations.get(0).toString().startsWith("mType: 1"));
assertTrue(operations.get(0).toString().matches(".*mValues: .*campaign_status=" + Campaign.STATUS_REMOTE + ".*" ));
}
});
}
public void testRunningCampaignStopped() {
helperTestStateChange(Campaign.STATUS_READY, Campaign.STATUS_STOPPED, new TestOperations() {
@Override
public void test(ArrayList<ContentProviderOperation> operations) {
// Check that we are doing an update to set the campaign to deleted
assertEquals(1, operations.size());
assertTrue(operations.get(0).toString().startsWith("mType: 2"));
assertTrue(operations.get(0).toString().matches(".*mValues: .*campaign_status=" + Campaign.STATUS_STOPPED + ".*" ));
}
});
}
public void testRemoteCampaignStopped() {
helperTestStateChange(Campaign.STATUS_REMOTE, Campaign.STATUS_STOPPED, new TestOperations() {
@Override
public void test(ArrayList<ContentProviderOperation> operations) {
assertEquals(1, operations.size());
assertTrue(operations.get(0).toString().startsWith("mType: 3"));
assertTrue(operations.get(0).getUri().compareTo(Campaigns.buildCampaignUri(CampaignCursor.DEFAULT_CAMPAIGN_URN)) == 0);
}
});
}
}