Skip to content

Commit

Permalink
Add Goals API.
Browse files Browse the repository at this point in the history
  • Loading branch information
patloew committed Oct 25, 2016
1 parent aee206e commit 5655a78
Show file tree
Hide file tree
Showing 11 changed files with 316 additions and 21 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Version 1.5.0

* Updated Play Services (9.8.0) and RxJava (1.2.1).
* Added support for Goals API.

## Version 1.4.0

* Updated Play Services (9.6.1) and RxJava (1.2.0).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ A basic sample app is available in the `sample` project. You need to create an O
The lib is available on jCenter. Add the following to your `build.gradle`:

dependencies {
compile 'com.patloew.rxfit:rxfit:1.4.0'
compile 'com.patloew.rxfit:rxfit:1.5.0'
}

# Testing
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.1'
classpath 'com.android.tools.build:gradle:2.2.2'

classpath 'me.tatarka:gradle-retrolambda:3.3.0'
classpath 'me.tatarka:gradle-retrolambda:3.3.1'

classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.1'
classpath "com.github.dcendents:android-maven-gradle-plugin:1.5"
Expand Down
16 changes: 8 additions & 8 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ apply plugin: 'com.jfrog.bintray'
apply plugin: 'com.github.dcendents.android-maven'

group = 'com.patloew.rxfit'
version = '1.4.0'
version = '1.5.0'
project.archivesBaseName = 'rxfit'

android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
compileSdkVersion 25
buildToolsVersion "25.0.0"

defaultConfig {
minSdkVersion 9
targetSdkVersion 24
versionCode 7
versionName "1.4.0"
targetSdkVersion 25
versionCode 8
versionName "1.5.0"
}
buildTypes {
release {
Expand All @@ -33,8 +33,8 @@ android {

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'io.reactivex:rxjava:1.2.0'
compile 'com.google.android.gms:play-services-fitness:9.6.1'
compile 'io.reactivex:rxjava:1.2.1'
compile 'com.google.android.gms:play-services-fitness:9.8.0'

testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
Expand Down
57 changes: 57 additions & 0 deletions library/src/main/java/com/patloew/rxfit/Goals.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.patloew.rxfit;

import android.support.annotation.NonNull;

import com.google.android.gms.fitness.data.Goal;
import com.google.android.gms.fitness.request.GoalsReadRequest;

import java.util.List;
import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Single;
import rx.functions.Func1;

/* Copyright 2016 Patrick Löwenstein
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. */
public class Goals {

private final RxFit rxFit;

Goals(RxFit rxFit) {
this.rxFit = rxFit;
}


// read current

public Observable<Goal> readCurrent(@NonNull GoalsReadRequest goalsReadRequest) {
return readCurrentInternal(goalsReadRequest, null, null);
}

public Observable<Goal> readCurrent(@NonNull GoalsReadRequest goalsReadRequest, long timeout, @NonNull TimeUnit timeUnit) {
return readCurrentInternal(goalsReadRequest, timeout, timeUnit);
}

private Observable<Goal> readCurrentInternal(GoalsReadRequest goalsReadRequest, Long timeout, TimeUnit timeUnit) {
return Single.create(new GoalsReadCurrentSingle(rxFit, goalsReadRequest, timeout, timeUnit))
.flatMapObservable(new Func1<List<Goal>, Observable<? extends Goal>>() {
@Override
public Observable<? extends Goal> call(List<Goal> goals) {
return Observable.from(goals);
}
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.patloew.rxfit;

import android.support.annotation.NonNull;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.Goal;
import com.google.android.gms.fitness.request.GoalsReadRequest;
import com.google.android.gms.fitness.result.GoalsResult;

import java.util.List;
import java.util.concurrent.TimeUnit;

import rx.SingleSubscriber;

/* Copyright 2016 Patrick Löwenstein
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. */
class GoalsReadCurrentSingle extends BaseSingle<List<Goal>> {

final GoalsReadRequest goalsReadRequest;

GoalsReadCurrentSingle(RxFit rxFit, GoalsReadRequest goalsReadRequest, Long timeout, TimeUnit timeUnit) {
super(rxFit, timeout, timeUnit);
this.goalsReadRequest = goalsReadRequest;
}

@Override
protected void onGoogleApiClientReady(GoogleApiClient apiClient, final SingleSubscriber<? super List<Goal>> subscriber) {
setupFitnessPendingResult(Fitness.GoalsApi.readCurrentGoals(apiClient, goalsReadRequest), new ResultCallback<GoalsResult>() {
@Override
public void onResult(@NonNull GoalsResult goalsResult) {
if (!goalsResult.getStatus().isSuccess()) {
subscriber.onError(new StatusException(goalsResult.getStatus()));
} else {
subscriber.onSuccess(goalsResult.getGoals());
}
}
});
}
}
5 changes: 5 additions & 0 deletions library/src/main/java/com/patloew/rxfit/RxFit.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class RxFit {

private final Ble ble = new Ble(this);
private final Config config = new Config(this);
private final Goals goals = new Goals(this);
private final History history = new History(this);
private final Recording recording = new Recording(this);
private final Sensors sensors = new Sensors(this);
Expand Down Expand Up @@ -99,6 +100,10 @@ public Config config() {
return config;
}

public Goals goals() {
return goals;
}

public History history() {
return history;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.google.android.gms.fitness.BleApi;
import com.google.android.gms.fitness.ConfigApi;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.GoalsApi;
import com.google.android.gms.fitness.HistoryApi;
import com.google.android.gms.fitness.RecordingApi;
import com.google.android.gms.fitness.SensorsApi;
Expand Down Expand Up @@ -44,6 +45,7 @@ public abstract class BaseOnSubscribeTest extends BaseTest {

@Mock BleApi bleApi;
@Mock ConfigApi configApi;
@Mock GoalsApi goalsApi;
@Mock HistoryApi historyApi;
@Mock RecordingApi recordingApi;
@Mock SensorsApi sensorsApi;
Expand All @@ -54,6 +56,7 @@ public void setup() throws Exception {
PowerMockito.mockStatic(Fitness.class);
Whitebox.setInternalState(Fitness.class, bleApi);
Whitebox.setInternalState(Fitness.class, configApi);
Whitebox.setInternalState(Fitness.class, goalsApi);
Whitebox.setInternalState(Fitness.class, historyApi);
Whitebox.setInternalState(Fitness.class, recordingApi);
Whitebox.setInternalState(Fitness.class, sensorsApi);
Expand Down
104 changes: 104 additions & 0 deletions library/src/test/java/com/patloew/rxfit/GoalsOnSubscribeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package com.patloew.rxfit;

import android.app.PendingIntent;
import android.support.v4.content.ContextCompat;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataPoint;
import com.google.android.gms.fitness.data.DataSource;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Goal;
import com.google.android.gms.fitness.request.DataSourcesRequest;
import com.google.android.gms.fitness.request.GoalsReadRequest;
import com.google.android.gms.fitness.request.OnDataPointListener;
import com.google.android.gms.fitness.request.SensorRequest;
import com.google.android.gms.fitness.result.DataSourcesResult;
import com.google.android.gms.fitness.result.GoalsResult;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;

import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.Single;
import rx.observers.TestSubscriber;

import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("com.google.android.gms.fitness.Fitness")
@PrepareOnlyThisForTest({ ContextCompat.class, Fitness.class, Status.class, ConnectionResult.class, BaseRx.class })
public class GoalsOnSubscribeTest extends BaseOnSubscribeTest {

@Mock GoalsReadRequest goalsReadRequest;
@Mock Goal goal;

@Override
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
super.setup();
}

// GoalsReadCurrentSingle

@Test
public void GoalsReadCurrentSingle_Success() {
TestSubscriber<List<Goal>> sub = new TestSubscriber<>();
GoalsResult goalsResult = Mockito.mock(GoalsResult.class);

GoalsReadCurrentSingle single = PowerMockito.spy(new GoalsReadCurrentSingle(rxFit, goalsReadRequest, null, null));

List<Goal> goalList = new ArrayList<>();
goalList.add(goal);
when(goalsResult.getGoals()).thenReturn(goalList);

setPendingResultValue(goalsResult);
when(goalsResult.getStatus()).thenReturn(status);
when(status.isSuccess()).thenReturn(true);
when(goalsApi.readCurrentGoals(apiClient, goalsReadRequest)).thenReturn(pendingResult);

setupBaseSingleSuccess(single);
Single.create(single).subscribe(sub);

assertSingleValue(sub, goalList);
}

@Test
public void GoalsReadCurrentSingle_StatusException() {
TestSubscriber<List<Goal>> sub = new TestSubscriber<>();
GoalsResult goalsResult = Mockito.mock(GoalsResult.class);

GoalsReadCurrentSingle single = PowerMockito.spy(new GoalsReadCurrentSingle(rxFit, goalsReadRequest, null, null));

List<Goal> goalList = new ArrayList<>();
goalList.add(goal);
when(goalsResult.getGoals()).thenReturn(goalList);

setPendingResultValue(goalsResult);
when(goalsResult.getStatus()).thenReturn(status);
when(status.isSuccess()).thenReturn(false);
when(goalsApi.readCurrentGoals(apiClient, goalsReadRequest)).thenReturn(pendingResult);

setupBaseSingleSuccess(single);
Single.create(single).subscribe(sub);

assertError(sub, StatusException.class);
}
}
69 changes: 69 additions & 0 deletions library/src/test/java/com/patloew/rxfit/GoalsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.patloew.rxfit;

import android.app.PendingIntent;
import android.support.v4.content.ContextCompat;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.request.DataSourcesRequest;
import com.google.android.gms.fitness.request.GoalsReadRequest;
import com.google.android.gms.fitness.request.SensorRequest;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;

import rx.Observable;
import rx.Single;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.times;

@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor("com.google.android.gms.fitness.Fitness")
@PrepareOnlyThisForTest({ Observable.class, Single.class, ContextCompat.class, Fitness.class, Status.class, ConnectionResult.class })
public class GoalsTest extends BaseTest {

@Override
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
PowerMockito.spy(Single.class);
PowerMockito.mockStatic(Observable.class);
super.setup();
}

// Read Current

@Test
public void Goals_ReadCurrent() throws Exception {
ArgumentCaptor<GoalsReadCurrentSingle> captor = ArgumentCaptor.forClass(GoalsReadCurrentSingle.class);

final GoalsReadRequest request = Mockito.mock(GoalsReadRequest.class);
rxFit.goals().readCurrent(request);
rxFit.goals().readCurrent(request, TIMEOUT_TIME, TIMEOUT_TIMEUNIT);

PowerMockito.verifyStatic(atLeast(2));
Single.create(captor.capture());

GoalsReadCurrentSingle single = captor.getAllValues().get(0);
assertEquals(request, single.goalsReadRequest);
assertNoTimeoutSet(single);

single = captor.getAllValues().get(2);
assertEquals(request, single.goalsReadRequest);
assertTimeoutSet(single);
}

}
Loading

0 comments on commit 5655a78

Please sign in to comment.