Commit 0ed4f95e authored by Shaun Burch's avatar Shaun Burch 💻

#11 Add Unit Tests, refactor API package

parent 03b070f1
Pipeline #22230179 passed with stages
in 7 minutes and 40 seconds
......@@ -8,9 +8,8 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import com.example.exchangerates.api.fixer.io.FixerResponse;
import com.example.exchangerates.api.fixer.io.Rate;
import com.example.exchangerates.api.fixer.FixerResponse;
import com.example.exchangerates.api.fixer.Rate;
/**
* An activity representing a single Rate detail screen. This
......
......@@ -9,17 +9,15 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.exchangerates.api.fixer.io.FixerResponse;
import com.example.exchangerates.api.fixer.io.Rate;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.example.exchangerates.api.fixer.FixerResponse;
import com.example.exchangerates.api.fixer.Rate;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* A fragment representing a single Rate detail screen.
* This fragment is either contained in a {@link RateListActivity}
......@@ -57,6 +55,7 @@ public class RateDetailFragment extends Fragment {
App.getComponent(mContext).inject(this);
Bundle arguments = getArguments();
// TODO: 5/17/18 null check Args
if (arguments.containsKey(ARG_RATE_ID) && arguments.containsKey(ARG_RATE_CONTEXT)) {
mRate = (Rate) arguments.getSerializable(ARG_RATE_ID);
mRateContext = (FixerResponse) arguments.getSerializable(ARG_RATE_CONTEXT);
......
......@@ -15,18 +15,16 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.example.exchangerates.api.fixer.io.FixerApi;
import com.example.exchangerates.api.fixer.io.FixerResponse;
import com.example.exchangerates.api.fixer.io.Rate;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.example.exchangerates.api.fixer.FixerApi;
import com.example.exchangerates.api.fixer.FixerResponse;
import com.example.exchangerates.api.fixer.Rate;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import javax.inject.Inject;
/**
* An activity representing a list of Rates. This activity
* has different presentations for handset and tablet-size devices. On
......
package com.example.exchangerates.api.fixer;
import io.reactivex.Single;
import retrofit2.http.GET;
/**
* Retrofit Interface for the Fixer.io exchange rates API.
* <p>
* Doc: https://fixer.io/documentation
*/
public interface FixerApi {
String VERSION = "/latest";
/**
* Get a list of exchange rates
*
* @return Call with list of exchange rates
*/
@GET("/api" + VERSION)
Single<FixerResponse> listRates();
}
package com.example.exchangerates.api.fixer;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* Created by shaunburch on 3/19/18.
*/
public class FixerResponse implements Serializable {
private boolean success;
private long timestamp;
private String base;
private Date date;
private Map<String, Double> rates;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Map<String, Double> getRates() {
return rates;
}
public void setRates(Map<String, Double> rates) {
this.rates = rates;
}
public List<Rate> getRateList() {
ArrayList<Rate> rateList = new ArrayList<>();
for (Map.Entry<String, Double> entry : rates.entrySet()) {
rateList.add(new Rate(entry.getKey(), entry.getValue()));
}
return rateList;
}
@Override
public String toString() {
return "FixerResponse{" +
"success=" + success +
", timestamp=" + timestamp +
", base='" + base + '\'' +
", date=" + date +
", rates=" + rates +
'}';
}
}
package com.example.exchangerates.api.fixer;
import java.io.Serializable;
/**
* Created by shaunburch on 3/19/18.
*/
public class Rate implements Serializable {
private String symbol;
private double rate;
public Rate(String symbol, double rate) {
this.symbol = symbol;
this.rate = rate;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
}
......@@ -3,22 +3,16 @@ package com.example.exchangerates.di;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.example.exchangerates.api.fixer.io.FixerApi;
import javax.inject.Singleton;
import com.example.exchangerates.api.fixer.FixerApi;
import dagger.Module;
import dagger.Provides;
import okhttp3.Cache;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.*;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import javax.inject.Singleton;
@Module
public class ApiModule {
......
package com.example.exchangerates;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
package com.example.exchangerates;
import com.example.exchangerates.api.fixer.FixerResponse;
import com.example.exchangerates.api.fixer.Rate;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertThat;
public class FixerResponseTest {
private FixerResponse fixerResponseObj = new FixerResponse();
@Before
public void setUp() {
Map<String, Double> rateMap = new HashMap<>();
rateMap.put("AUD", 1.566015);
rateMap.put("CAD", 1.560132);
rateMap.put("CHF", 1.154727);
rateMap.put("CNY", 7.827874);
rateMap.put("GBP", 0.882047);
rateMap.put("JPY", 132.360679);
rateMap.put("USD", 1.23396);
fixerResponseObj.setRates(rateMap);
}
@Test
public void getRateList() {
List<Rate> rateList = fixerResponseObj.getRateList();
// Is a list
assertThat(rateList, instanceOf(List.class));
// of Rates
assertThat(rateList.get(0), instanceOf(Rate.class));
}
}
\ No newline at end of file
package com.example.exchangerates;
import com.example.exchangerates.api.fixer.Rate;
import org.junit.Test;
import static org.junit.Assert.*;
public class RateTest {
// TODO: 5/17/18 These might actually be better in instrumented test to monitor for API changes
private Rate rateObj = new Rate("USD", 0.806942);
private String ratePattern = "^([0-9]*)[.]?([0-9]{0,6})$";
@Test
public void getSymbol() {
// No mutation
assertSame("USD", rateObj.getSymbol());
// Only three capital letters
assertTrue(rateObj.getSymbol().matches("^[A-Z]{3}$"));
}
@Test
public void setSymbol() {
// No mutation
rateObj.setSymbol("EUR");
assertSame("EUR", rateObj.getSymbol());
}
@Test
public void getRate() {
double rate = this.rateObj.getRate();
// No mutation
assertEquals(0.806942, rate, 0.0);
// Double amount pattern
assertTrue(String.valueOf(rate).matches(ratePattern));
}
@Test
public void setRate() {
rateObj.setRate(1);
// No mutation
assertEquals(1.0, rateObj.getRate(), 0.0);
// Whole # is ok
assertTrue(String.valueOf(rateObj.getRate()).matches(ratePattern));
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment