Skip to content

Commit 4e8be2e

Browse files
authored
Add UploadRequest.startNow() api to support immediate upload requests
1 parent 7ce4456 commit 4e8be2e

15 files changed

+486
-129
lines changed

lib/src/androidTest/java/com/cloudinary/android/AbstractTest.java

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22

33
import android.content.Context;
44
import android.content.res.AssetFileDescriptor;
5+
import android.os.Bundle;
6+
import android.support.annotation.NonNull;
57
import android.support.test.InstrumentationRegistry;
68

9+
import com.cloudinary.android.payload.FilePayload;
10+
import com.cloudinary.android.policy.TimeWindow;
11+
import com.cloudinary.android.policy.UploadPolicy;
712
import com.cloudinary.android.signed.Signature;
813
import com.cloudinary.android.signed.SignatureProvider;
914

@@ -14,6 +19,7 @@
1419
import java.io.IOException;
1520
import java.io.InputStream;
1621
import java.util.Map;
22+
import java.util.UUID;
1723

1824
public class AbstractTest {
1925
public static final String TEST_IMAGE = "images/old_logo.png";
@@ -79,4 +85,92 @@ protected static File assetToFile(String testImage) throws IOException {
7985

8086
return file;
8187
}
88+
89+
/**
90+
* Centralize processor creation in case we want to test different implementations in the future.
91+
*/
92+
protected RequestProcessor provideRequestProcessor(DefaultCallbackDispatcher callbackDispatcher) {
93+
return new DefaultRequestProcessor(callbackDispatcher);
94+
}
95+
96+
/**
97+
* Centralize params creation in case we want to test different implementations in the future.
98+
*/
99+
protected RequestParams provideRequestParams() {
100+
TestParams testParams = new TestParams();
101+
testParams.putString("requestId", UUID.randomUUID().toString());
102+
return testParams;
103+
}
104+
105+
/**
106+
* Centralize callback dispatcher creation in case we want to test different implementations in the future.
107+
*/
108+
protected DefaultCallbackDispatcher provideCallbackDispatcher() {
109+
return new DefaultCallbackDispatcher(InstrumentationRegistry.getTargetContext());
110+
}
111+
112+
@NonNull
113+
protected FilePayload buildPayload() throws IOException {
114+
return new FilePayload(assetToFile(TEST_IMAGE).getAbsolutePath());
115+
}
116+
117+
protected UploadRequest<FilePayload> buildUploadRequest(FilePayload payload, int maxExecutionDisplay) {
118+
return MediaManager.get().upload(payload)
119+
.unsigned(TEST_PRESET)
120+
.constrain(new TimeWindow.Builder().minLatencyMillis(20).maxExecutionDelayMillis(maxExecutionDisplay).build())
121+
.policy(new UploadPolicy.Builder()
122+
.networkPolicy(UploadPolicy.NetworkType.UNMETERED)
123+
.requiresCharging(true)
124+
.requiresIdle(false)
125+
.backoffCriteria(100, UploadPolicy.BackoffPolicy.LINEAR)
126+
.maxRetries(9)
127+
.build());
128+
}
129+
130+
/**
131+
* Bundle based implementation for RequestParams, for testing purposes.
132+
*/
133+
protected static final class TestParams implements RequestParams {
134+
private final Bundle values = new Bundle();
135+
136+
@Override
137+
public void putString(String key, String value) {
138+
values.putString(key, value);
139+
}
140+
141+
@Override
142+
public void putInt(String key, int value) {
143+
values.putInt(key, value);
144+
}
145+
146+
@Override
147+
public void putLong(String key, long value) {
148+
values.putLong(key, value);
149+
}
150+
151+
@Override
152+
public void putBoolean(String key, boolean value) {
153+
values.putBoolean(key, value);
154+
}
155+
156+
@Override
157+
public String getString(String key, String defaultValue) {
158+
return values.getString(key, defaultValue);
159+
}
160+
161+
@Override
162+
public int getInt(String key, int defaultValue) {
163+
return values.getInt(key, defaultValue);
164+
}
165+
166+
@Override
167+
public long getLong(String key, long defaultValue) {
168+
return values.getLong(key, defaultValue);
169+
}
170+
171+
@Override
172+
public boolean getBoolean(String key, boolean defaultValue) {
173+
return values.getBoolean(key, defaultValue);
174+
}
175+
}
82176
}

lib/src/androidTest/java/com/cloudinary/android/AndroidJobStrategyTest.java

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import android.support.test.runner.AndroidJUnit4;
44

55
import com.cloudinary.android.payload.FilePayload;
6-
import com.cloudinary.android.policy.TimeWindow;
7-
import com.cloudinary.android.policy.UploadPolicy;
86
import com.evernote.android.job.JobRequest;
97

108
import org.junit.Test;
@@ -13,26 +11,16 @@
1311
import java.io.IOException;
1412

1513
import static junit.framework.Assert.assertEquals;
16-
import static junit.framework.Assert.assertTrue;
1714

1815
@RunWith(AndroidJUnit4.class)
1916
public class AndroidJobStrategyTest extends AbstractTest {
2017

2118
@Test
2219
public void testAdapter() throws InterruptedException, IOException {
23-
FilePayload payload = new FilePayload(assetToFile(TEST_IMAGE).getAbsolutePath());
20+
FilePayload payload = buildPayload();
2421

2522
int tenMinutes = 10 * 60 * 1000;
26-
UploadRequest<FilePayload> request =
27-
new UploadRequest<>(new UploadContext<>(payload, null), null)
28-
.constrain(new TimeWindow.Builder().minLatencyMillis(20).maxExecutionDelayMillis(tenMinutes).build())
29-
.policy(new UploadPolicy.Builder()
30-
.networkPolicy(UploadPolicy.NetworkType.UNMETERED)
31-
.requiresCharging(true)
32-
.requiresIdle(false)
33-
.backoffCriteria(100, UploadPolicy.BackoffPolicy.LINEAR)
34-
.maxRetries(9)
35-
.build());
23+
UploadRequest<FilePayload> request = buildUploadRequest(payload, tenMinutes);
3624

3725
JobRequest adapted = AndroidJobStrategy.adapt(request);
3826

@@ -43,14 +31,5 @@ public void testAdapter() throws InterruptedException, IOException {
4331
assertEquals(100, adapted.getBackoffMs());
4432
assertEquals(JobRequest.BackoffPolicy.LINEAR, adapted.getBackoffPolicy());
4533
assertEquals(9, adapted.getExtras().get("maxErrorRetries"));
46-
47-
UploadRequest<FilePayload> exactRequest =
48-
new UploadRequest<>(new UploadContext<>(payload, null), null)
49-
.constrain(TimeWindow.immediate());
50-
51-
JobRequest adaptedExact = AndroidJobStrategy.adapt(exactRequest);
52-
assertTrue(adaptedExact.isExact());
53-
assertEquals(adaptedExact.getStartMs(), 1);
54-
assertEquals(adaptedExact.getEndMs(), 1);
5534
}
5635
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package com.cloudinary.android;
2+
3+
import android.content.Context;
4+
import android.support.test.InstrumentationRegistry;
5+
import android.support.test.runner.AndroidJUnit4;
6+
7+
import com.cloudinary.android.payload.FilePayload;
8+
import com.cloudinary.android.preprocess.ImagePreprocessChain;
9+
10+
import org.awaitility.Awaitility;
11+
import org.awaitility.Duration;
12+
import org.junit.Test;
13+
import org.junit.runner.RunWith;
14+
15+
import java.io.IOException;
16+
import java.util.concurrent.Callable;
17+
18+
import static org.junit.Assert.assertEquals;
19+
import static org.junit.Assert.assertNotNull;
20+
21+
@RunWith(AndroidJUnit4.class)
22+
public class ImmediateRequestHandlerTest extends AbstractTest {
23+
24+
@Test
25+
public void testImmediateRequest() throws IOException {
26+
final StatefulCallback statefulCallback = new StatefulCallback();
27+
28+
Context appContext = InstrumentationRegistry.getTargetContext();
29+
DefaultCallbackDispatcher callbackDispatcher = new DefaultCallbackDispatcher(appContext);
30+
callbackDispatcher.registerCallback(statefulCallback);
31+
32+
RequestProcessor processor = provideRequestProcessor(callbackDispatcher);
33+
ImmediateRunnerForTests requestsRunner = new ImmediateRunnerForTests(processor);
34+
RequestDispatcher dispatcher = new DefaultRequestDispatcher(new NOPStrategy(), requestsRunner);
35+
UploadRequest<FilePayload> uploadRequest = buildUploadRequest(buildPayload(), 1000);
36+
uploadRequest.serializeOptions();
37+
38+
assertEquals(0, requestsRunner.taskRan);
39+
dispatcher.startNow(appContext, uploadRequest);
40+
41+
// wait for result
42+
Awaitility.await().atMost(Duration.TEN_SECONDS).until(new Callable<Boolean>() {
43+
@Override
44+
public Boolean call() {
45+
return statefulCallback.hasResponse();
46+
}
47+
});
48+
49+
// verify the upload succeeded, and actually went through the immediate channels.
50+
assertNotNull(statefulCallback.lastSuccess);
51+
assertEquals(1, requestsRunner.taskRan);
52+
}
53+
54+
@Test
55+
public void testImmediateWithPreprocess() throws IOException {
56+
final StatefulCallback statefulCallback = new StatefulCallback();
57+
58+
UploadRequest<FilePayload> request = buildUploadRequest(buildPayload(), 1000).preprocess(ImagePreprocessChain.limitDimensionsChain(16, 16));
59+
MediaManager.get().registerCallback(statefulCallback);
60+
request.startNow(InstrumentationRegistry.getTargetContext());
61+
62+
// wait for result
63+
Awaitility.await().atMost(Duration.TEN_SECONDS).until(new Callable<Boolean>() {
64+
@Override
65+
public Boolean call() {
66+
return statefulCallback.hasResponse();
67+
}
68+
});
69+
70+
// verify the upload succeeded, and actually went through the immediate channels.
71+
assertNotNull(statefulCallback.lastSuccess);
72+
assertEquals(16, statefulCallback.lastSuccess.get("width"));
73+
MediaManager.get().unregisterCallback(statefulCallback);
74+
}
75+
76+
@Test(expected = IllegalArgumentException.class)
77+
public void testNullContext() {
78+
MediaManager.get().upload("path").startNow(null);
79+
}
80+
81+
private class ImmediateRunnerForTests extends DefaultImmediateRequestsRunner {
82+
int taskRan = 0;
83+
84+
ImmediateRunnerForTests(RequestProcessor requestProcessor) {
85+
super(requestProcessor);
86+
}
87+
88+
@Override
89+
public synchronized void runRequest(Context context, UploadRequest uploadRequest) {
90+
super.runRequest(context, uploadRequest);
91+
taskRan++;
92+
}
93+
}
94+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.cloudinary.android;
2+
3+
import android.content.Context;
4+
5+
class NOPStrategy implements BackgroundRequestStrategy {
6+
@Override
7+
public void init(Context context) {
8+
9+
}
10+
11+
@Override
12+
public void doDispatch(UploadRequest request) {
13+
14+
}
15+
16+
@Override
17+
public void executeRequestsNow(int howMany) {
18+
19+
}
20+
21+
@Override
22+
public boolean cancelRequest(String requestId) {
23+
return false;
24+
}
25+
26+
@Override
27+
public int cancelAllRequests() {
28+
return 0;
29+
}
30+
31+
@Override
32+
public int getPendingImmediateJobsCount() {
33+
return 0;
34+
}
35+
36+
@Override
37+
public int getRunningJobsCount() {
38+
return 0;
39+
}
40+
}

lib/src/androidTest/java/com/cloudinary/android/PreprocessTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import android.content.Context;
44
import android.graphics.Bitmap;
55
import android.graphics.BitmapFactory;
6+
import android.support.annotation.NonNull;
67
import android.support.test.InstrumentationRegistry;
78

89
import com.cloudinary.android.payload.FilePayload;
@@ -49,6 +50,11 @@ public String dispatch(UploadRequest request) {
4950
return null;
5051
}
5152

53+
@Override
54+
public String startNow(@NonNull Context context, UploadRequest request) {
55+
return null;
56+
}
57+
5258
@Override
5359
public boolean cancelRequest(String requestId) {
5460
return false;

0 commit comments

Comments
 (0)