Skip to content

Commit

Permalink
Add update with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tspoke committed Sep 13, 2017
1 parent 04c3384 commit 18aadd2
Show file tree
Hide file tree
Showing 4 changed files with 284 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.playmoweb.store2store.mock;

import android.util.Log;

import com.playmoweb.store2store.store.Optional;
import com.playmoweb.store2store.store.StoreDao;
import com.playmoweb.store2store.utils.Filter;
Expand Down Expand Up @@ -77,9 +75,7 @@ public Flowable<Optional<TestModel>> insertOrUpdate(TestModel object) {

@Override
public Flowable<Optional<List<TestModel>>> insertOrUpdate(final List<TestModel> items) {
Log.e("INSERT", "SIZE = "+items.size());
for(int i = 0; i < items.size(); i++) {
Log.e("INSERT", ""+items.get(i).getId());
insertObjectOrUpdate(items.get(i));
}
return Flowable.just(Optional.wrap(items));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,22 @@ public Flowable<Optional<TestModel>> insert(TestModel item) {
return Flowable.just(Optional.wrap(item)).delay(1, TimeUnit.SECONDS);
}

@Override
public Flowable<Optional<TestModel>> update(TestModel item) {
if(shouldThrowError){
return Flowable.error(new Exception("updateSingle.error"));
}
return Flowable.just(Optional.wrap(item)).delay(1, TimeUnit.SECONDS);
}

@Override
public Flowable<Optional<List<TestModel>>> update(List<TestModel> items) {
if(shouldThrowError){
return Flowable.error(new Exception("update.error"));
}
return Flowable.just(Optional.wrap(items)).delay(1, TimeUnit.SECONDS);
}

@Override
public Flowable<Integer> delete(TestModel item) {
if(shouldThrowError){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,157 @@ public void testInsertOrUpdateManyWithError(){
Assert.assertEquals(3, MemoryDao.models.size());
}

@Test
public void testUpdateList(){
models.clear();
List<TestModel> list = new ArrayList<>();
list.add(new TestModel(1));
list.add(new TestModel(2));
list.add(new TestModel(3));
memoryStore.insertOrUpdate(list);

List<TestModel> updateList = new ArrayList<>();
TestModel testModel = new TestModel(1);
testModel.setAvailable(true);
updateList.add(testModel);
testModel = new TestModel(3);
testModel.setAvailable(true);
updateList.add(testModel);

TestSubscriber<Optional<List<TestModel>>> observer = new TestSubscriber<>();
disposables.add(testStore.update(updateList)
.subscribeOn(Schedulers.io())
.subscribeWith(observer));

observer.awaitTerminalEvent(4, SECONDS);
observer.assertComplete();
observer.assertNoErrors();

Optional<List<TestModel>> results = observer.values().get(0);
Optional<List<TestModel>> resultsAfter = observer.values().get(1);
Assert.assertNotNull(results.get());
Assert.assertNotNull(resultsAfter.get());
Assert.assertEquals(2, results.get().size());
Assert.assertEquals(2, resultsAfter.get().size());

for(TestModel tm : results.get()){
Assert.assertTrue(tm.isAvailable());
}
for(TestModel tm : resultsAfter.get()){
Assert.assertTrue(tm.isAvailable());
}

Assert.assertEquals(3, models.size());
for(TestModel tm : models){
if(tm.getId() != 2){
Assert.assertTrue(tm.isAvailable());
}
}
}

@Test
public void testUpdateListWithError(){
models.clear();
testStore.shouldThrowError(true); // enable error

List<TestModel> list = new ArrayList<>();
list.add(new TestModel(1));
list.add(new TestModel(2));
list.add(new TestModel(3));
memoryStore.insertOrUpdate(list);

List<TestModel> updateList = new ArrayList<>();
TestModel testModel = new TestModel(1);
testModel.setAvailable(true);
updateList.add(testModel);
testModel = new TestModel(3);
testModel.setAvailable(true);
updateList.add(testModel);

TestSubscriber<Optional<List<TestModel>>> observer = new TestSubscriber<>();
disposables.add(testStore.update(updateList)
.subscribeOn(Schedulers.io())
.subscribeWith(observer));

observer.awaitTerminalEvent(4, SECONDS);
observer.assertError(Throwable.class);
observer.assertErrorMessage("update.error");

testStore.shouldThrowError(false); // disable error

Assert.assertEquals(3, models.size()); // should have been cleared
for(TestModel tm : models){
Assert.assertFalse(tm.isAvailable());
}
}

@Test
public void testUpdate(){
models.clear();
List<TestModel> list = new ArrayList<>();
list.add(new TestModel(1));
list.add(new TestModel(2));
list.add(new TestModel(3));
memoryStore.insertOrUpdate(list);

TestModel testModel = new TestModel(1);
testModel.setAvailable(true);

TestSubscriber<Optional<TestModel>> observer = new TestSubscriber<>();
disposables.add(testStore.update(testModel)
.subscribeOn(Schedulers.io())
.subscribeWith(observer));

observer.awaitTerminalEvent(4, SECONDS);
observer.assertComplete();
observer.assertNoErrors();

Optional<TestModel> results = observer.values().get(0);
Optional<TestModel> resultsAfter = observer.values().get(1);
Assert.assertNotNull(results.get());
Assert.assertNotNull(resultsAfter.get());
Assert.assertTrue(results.get().isAvailable());
Assert.assertTrue(resultsAfter.get().isAvailable());

Assert.assertEquals(3, models.size());
for(TestModel tm : models){
if(tm.getId() == 1){
Assert.assertTrue(tm.isAvailable());
}
}
}

@Test
public void testUpdateWithError(){
models.clear();
testStore.shouldThrowError(true); // enable error

List<TestModel> list = new ArrayList<>();
list.add(new TestModel(1));
list.add(new TestModel(2));
list.add(new TestModel(3));
memoryStore.insertOrUpdate(list);

TestModel testModel = new TestModel(1);
testModel.setAvailable(true);

TestSubscriber<Optional<TestModel>> observer = new TestSubscriber<>();
disposables.add(testStore.update(testModel)
.subscribeOn(Schedulers.io())
.subscribeWith(observer));

observer.awaitTerminalEvent(4, SECONDS);
observer.assertError(Throwable.class);
observer.assertErrorMessage("updateSingle.error");

testStore.shouldThrowError(false); // disable error

Assert.assertEquals(3, models.size()); // should have been cleared
for(TestModel tm : models){
Assert.assertFalse(tm.isAvailable());
}
}

@After
public void after() {
disposables.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,19 @@ public Flowable<Optional<T>> apply(Integer notUsed) throws Exception {
}
});
} else { // it did exists, re-apply previous version
return syncedStore.insertOrUpdate(originalItem.get()).flatMap(new Function<Optional<T>, Flowable<Optional<T>>>() {
@Override
public Flowable<Optional<T>> apply(Optional<T> notUsed) throws Exception {
return Flowable.error(throwable);
}
});
return syncedStore.delete(item)
.flatMap(new Function<Integer, Flowable<Optional<T>>>() {
@Override
public Flowable<Optional<T>> apply(Integer integer) throws Exception {
return syncedStore.insertOrUpdate(originalItem.get());
}
})
.flatMap(new Function<Optional<T>, Flowable<Optional<T>>>() {
@Override
public Flowable<Optional<T>> apply(Optional<T> notUsed) throws Exception {
return Flowable.error(throwable);
}
});
}
}
})
Expand All @@ -386,6 +393,110 @@ public Flowable<Optional<T>> apply(Optional<T> itemInsertedOrUpdated) throws Exc
return flowStorage;
}

@Override
public Flowable<Optional<List<T>>> update(final List<T> items) {
Flowable<Optional<List<T>>> flowStorage;

if(hasSyncedStore()) {
flowStorage = syncedStore.getAll(items) // try to get a copy before trying to update/insert
.flatMap(new Function<Optional<List<T>>, Flowable<Optional<List<T>>>>() {
@Override
public Flowable<Optional<List<T>>> apply(final Optional<List<T>> originalItems) {
if(originalItems.isNull() || originalItems.get().size() < items.size()){
return Flowable.error(new IllegalArgumentException(
"One or many items do not exist and can't be updated. Please use insertOrUpdate if this behaviour is not expected !"
));
}

return Flowable.concat(
syncedStore.update(items),
dao.update(items)
.onErrorResumeNext(new Function<Throwable, Flowable<Optional<List<T>>>>() {
@Override
public Flowable<Optional<List<T>>> apply(final Throwable throwable) {
return syncedStore.delete(items)
.flatMap(new Function<Integer, Flowable<Optional<List<T>>>>() {
@Override
public Flowable<Optional<List<T>>> apply(Integer deleteCount) throws Exception {
return syncedStore.insert(originalItems.get());
}
})
.flatMap(new Function<Optional<List<T>>, Flowable<Optional<List<T>>>>() {
@Override
public Flowable<Optional<List<T>>> apply(Optional<List<T>> notUsed) {
return Flowable.error(throwable);
}
});
}
})
.flatMap(new Function<Optional<List<T>>, Flowable<Optional<List<T>>>>() {
@Override
public Flowable<Optional<List<T>>> apply(Optional<List<T>> itemsUpdated) {
return syncedStore.update(itemsUpdated.get());
}
})
);
}
});
} else {
flowStorage = dao.insertOrUpdate(items);
}

return flowStorage;
}

@Override
public Flowable<Optional<T>> update(final T item) {
Flowable<Optional<T>> flowStorage;

if(hasSyncedStore()) {
flowStorage = syncedStore.getOne(item) // get a copy before trying to update/insert
.flatMap(new Function<Optional<T>, Flowable<Optional<T>>>() {
@Override
public Flowable<Optional<T>> apply(final Optional<T> originalItem) throws Exception {
if(originalItem.isNull()){
return Flowable.error(new IllegalArgumentException(
"This item does not exists and can't be updated. Please use insertOrUpdate if this behaviour is not expected !"
));
}

return Flowable.concat(
syncedStore.update(item),
dao.update(item)
.onErrorResumeNext(new Function<Throwable, Flowable<Optional<T>>>() {
@Override
public Flowable<Optional<T>> apply(final Throwable throwable) throws Exception {
return syncedStore.delete(item)
.flatMap(new Function<Integer, Flowable<Optional<T>>>() {
@Override
public Flowable<Optional<T>> apply(Integer integer) throws Exception {
return syncedStore.insert(originalItem.get());
}
})
.flatMap(new Function<Optional<T>, Flowable<Optional<T>>>() {
@Override
public Flowable<Optional<T>> apply(Optional<T> notUsed) throws Exception {
return Flowable.error(throwable);
}
});
}
})
.flatMap(new Function<Optional<T>, Flowable<Optional<T>>>() {
@Override
public Flowable<Optional<T>> apply(Optional<T> itemUpdated) throws Exception {
return syncedStore.update(itemUpdated.get());
}
})
);
}
});
} else {
flowStorage = dao.update(item);
}

return flowStorage;
}

@Override
public Flowable<Integer> deleteAll() {
List<Flowable<Integer>> flowables = new ArrayList<>();
Expand Down

0 comments on commit 18aadd2

Please sign in to comment.