Testing RX java - android

public void getTerms(boolean showDialog) {
service.getTermsFromServer().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleSubscriber<String>() {
#Override
public void onSuccess(String value) {
try {
JSONObject jsonObject = new JSONObject(value);
JSONObject data = jsonObject.getJSONObject("data");
String content = data.getString("content");
String id = data.getString("id");
if (showDialog) {
***signUpView.showDialog(content, id)***;
} else {
agreeTerms(id);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onError(Throwable error) {
Log.e(getClass().getName(), "Error : " + new Gson().toJson(error.getStackTrace()));
ErrorCheck.processError(error, gson, signUpView);
}
});
}
Please help me in testing this code. I have attached the method which i want to test. Here I want to verify that showDialog method gets called
Attaching the Unit test code also
#Test
public void testGetTermsCalled(){
String terms= "{\"data\":{\"id\":\"67f07c7a482542\",\"content\":\"<h3>Part of the test</h3>\",\"timestamp\":1484768675815,\"timestampFormatted\":\"2017-01-18T19:44:35\"},\"metadata\":null,\"version\":{\"id\":\"v1\",\"versionStatus\":\"candidate\",\"message\":null}}";
TestSubscriber<String> testSubscriber = new TestSubscriber<>();
signUpService.getTermsFromServer().just(terms).subscribe(testSubscriber);
signUpPresenter.getTerms(true);
Mockito.verify(signUpView).showDialog("<h3>Part of the test</h3>","67f07c71-1707-4b7a-a168-d7d05a482542");
}
Thanks!!!

Use RxJavaPlugins.setInitIoSchedulerHandler and RxAndroidPlugins.registerSchedulersHook to specify your own TestScheduler, then use its advanceTimeBy method to make some time pass, then verify that the expected calls happened.

Related

How to wait for the retrofit call response

I have my own rest api for application so when I create post request to api I want to wait for the response and then do something. how I can wait for the call response.
insert TicketList
public long insertApi(TicketListTable ticketListTable) throws IOException {
Call<TicketListTable> ticketListTableCall = dataService.createTicketList(ticketListTable);
ticketListTableCall.enqueue(new Callback<TicketListTable>() {
#Override
public void onResponse(Call<TicketListTable> call, Response<TicketListTable> response) {
}
#Override
public void onFailure(Call<TicketListTable> call, Throwable t) {
}
});
// want to wait for the call to complete then return the value
//ticketListTableCall.execute();
Log.d("CODE", "insertApi: "+ ticketListTableCall.isExecuted());
return repo.insert(ticketListTable);
}
this method is called when button is clicked
public void saveListToDb(String[] split, String regexData){
String newListName = listName.getText().toString();
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
TicketListTable newTicketListTable = new TicketListTable();
newTicketListTable.setTicketListName(newListName);
newTicketListTable.setTicketListCreated(sd.format(Calendar.getInstance().getTime()));
newTicketListTable.setTicketListUpdated(sd.format(Calendar.getInstance().getTime()));
long ticketTableListId = 0;
try {
ticketTableListId = ticketTableVm.insert(newTicketListTable);
} catch (IOException e) {
e.printStackTrace();
}
if(ticketTableListId<=0){
throw new ArithmeticException();
}
for (String s : split) {
String[] values = s.split(regexData);
String number = values[0].replace("\n", "").replace("\r", "");
String info = values[1];
String warningNote = values[2];
String warning = values[3];
String customer = values[4];
int useable = Integer.parseInt(values[5].replaceAll("\\s+", "").replace("\n", "").replace("\r", ""));
TicketTable ticketTable = new TicketTable(number, customer, info, warningNote, useable, ticketTableListId,warning);
ticketTableVm.insert(ticketTable);
}
}
insert Ticket api call, before calling this I want to verify that the previous call has been successfully executed
public void insert(TicketTable ticketTable) throws IOException {
Call<TicketTable> ticketCall = dataService.createTicket(ticketTable);
//Response resp = ticketCall.execute();
ticketCall.enqueue(new Callback<TicketTable>() {
#Override
public void onResponse(Call<TicketTable> call, Response<TicketTable> response) {
repo.insert(ticketTable);
}
#Override
public void onFailure(Call<TicketTable> call, Throwable t) {
}
});

How to handle errors from API in Login Activity (Template from Android Studio)

I'm implementing a simple login to an endpoints using Retrofit2. Things work fine when the user credentials are correct but break when I try to enter a non valid data.
I'm trying to handle the errors when the user is not found but I can't find a way to do that.
The error response looks like:
{
"0": [
"erreur",
"statut"
],
"erreur": "Erreur, connexion echoue.",
"statut": "KO"
}
This response has status 200 despite being an error.
The app is crashing with NPE in the LoginRepository where I'm trying to save user's data to SharedPreferences because the error result is not handled so the app threat any response as Successful.
The sample provides a Result class which doesn't seem to work for my use case because the response is always successful:
public class Result<T> {
// hide the private constructor to limit subclass types (Success, Error)
private Result() {
}
#Override
public String toString() {
if (this instanceof Result.Success) {
Result.Success success = (Result.Success) this;
return "Success[data=" + success.getData().toString() + "]";
} else if (this instanceof Result.Error) {
Result.Error error = (Result.Error) this;
return "Error[exception=" + error.getError().toString() + "]";
}
return "";
}
// Success sub-class
public final static class Success<T> extends Result {
private T data;
public Success(T data) {
this.data = data;
}
public T getData() {
return this.data;
}
}
// Error sub-class
public final static class Error extends Result {
private Exception error;
public Error(Exception error) {
this.error = error;
}
public Exception getError() {
return this.error;
}
}
}
And here is how I'm handling the login in the LoginRepository:
public Result<LoggedInUser> login(String username, String password) {
// handle login
Result<LoggedInUser> result = dataSource.login(username, password);
if (result instanceof Result.Success) {
setLoggedInUser(((Result.Success<LoggedInUser>) result).getData());
}
return result;
}
Note: I don't have access to the server. I use Gson as converter
The login activity sample I used can be found here
UPDATE:
Login successful with valid credentials:
Check this answer it will help you.
#POST("end_path")
Call<ResponseBody> LoginCall(
#Field("email") String user_id,
#Part("paassword") String language
);
Call<ResponseBody> call = Constant.service.LoginCall(
"email", "pass");
call.enqueue(new retrofit2.Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
String responseData = response.body().string();
JSONObject object = new JSONObject(responseData);
if(object.getString("statut").equalsIgnoreCase("success")){
LoggedInUser successData = new
Gson().fromJson(responseData, LoggedInUser.class);
}else{
showToast("Email password incorrect");//or show you want
this message.
}
} catch (IOException e) {
e.printStackTrace();
} catch (JsonSyntaxException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
} else {
showToast("something_went_wrong");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
}
});

IBM Watson Tone Analyzer Gives Empty Response

I am using Tone Analyzer of IBM Watson in my Android Code,but i keep getting java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
Following is my code
public class MainActivity extends AppCompatActivity {
final ToneAnalyzer toneAnalyzer =
new ToneAnalyzer("2018-01-19");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
JSONObject credentials = null; // Convert the file into a JSON object
try {
credentials = new JSONObject(IOUtils.toString(
getResources().openRawResource(R.raw.credentials), "UTF-8"
));
String username = credentials.getString("username");
String password = credentials.getString("password");
toneAnalyzer.setUsernameAndPassword(username, password);
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Button analyzeButton = (Button)findViewById(R.id.analyze_button);
analyzeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
EditText userInput = (EditText)findViewById(R.id.user_input);
final String textToAnalyze = userInput.getText().toString();
ToneOptions options = new ToneOptions.Builder()
.addTone(Tone.EMOTION)
.html(false).build();
toneAnalyzer.getTone(textToAnalyze, options).enqueue(
new ServiceCallback<ToneAnalysis>() {
#Override
public void onResponse(ToneAnalysis response) {
Log.i("Hii", "onResponse: "+response.getDocumentTone());
List<ToneScore> scores = response.getDocumentTone()
.getTones()
.get(0)
.getTones();
String detectedTones = "";
for(ToneScore score:scores) {
if(score.getScore() > 0.5f) {
detectedTones += score.getName() + " ";
}
}
final String toastMessage =
"The following emotions were detected:\n\n"
+ detectedTones.toUpperCase();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getBaseContext(),
toastMessage, Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onFailure(Exception e) {
e.printStackTrace();
}
});
}
});
}
}
Can somebody point out what am i doing wrong. I have kept my credentials.json file in raw folder.
I tried writing every emotion in my Android App but i keep getting no response. Any help would be greatly appreciated.

AsyncHttpResponseHandler issue: get value before completion of AsyncTask

I have a String variable in main class private String gameEnabled = "0"; , how can I update the variable immediately inside my AsyncHttpResponseHandler to avoid getting value before completion of AsyncTask?
My AsyncHttpResponseHandler:
try {
APICaller.App_Game_Enabled(getApplicationContext(), new AsyncHttpResponseHandler() {
#Override
public void onFailure(Throwable arg0, String error) {
}
#Override
public void onSuccess(String response) {
try {
JSONArray json_Response = APICaller.XMLtoJsonArray(response);
if (json_Response.length() > 0) {
JSONObject dataNode = json_Response.getJSONObject(0);
gameEnabled = dataNode.getString("result");
} else {
//showAlert(getResources().getString(R.string.ShowAlert_Alert), getResources().getString(R.string.ShowAlert_CreatorAccess));
}
// Progress_Hide();
} catch (Exception ex) {
ex.printStackTrace();
//finish();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
Expected to update gameEnabled to "1" after this code but I always get the default "0". How can I deal with this if I need to follow below conditions? Thanks in advanced.
Use AsyncHttpResponseHandler
Update gameEnabled inside the AsyncHttpResponseHandler class and use it outside the class

Android: how return a value from JsonObjectRequest?

Let's say I have this Dashboard.java:
public class DashboardActivity extends ActionBarActivity {
private TextView login_response;
private static String TAG = DashboardActivity.class.getSimpleName();
final static String API_URL_ACCOUNT = "http://www.example.com/apiv2/account";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
login_response = (TextView) findViewById(R.id.login_response);
Intent intent = getIntent();
if(intent.hasExtra("TOKEN"))
{
String token = intent.getStringExtra("TOKEN");
getShopName(token);
}
else
{
}
And this is the getShopName method:
private void getShopName(String token) {
JsonObjectRequest req = new JsonObjectRequest(API_URL_ACCOUNT + "?token=" + token, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
JSONArray account = response.getJSONArray("account");
//Log.d(TAG, "Account: "+account.toString());
JSONObject shop = account.getJSONObject(0);
String name_shop = shop.getString("name_shop");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// add the request object to the queue to be executed
VolleyController.getInstance().addToRequestQueue(req);
}
My goal is to have
if(intent.hasExtra("TOKEN"))
{
String token = intent.getStringExtra("TOKEN");
String shop_name = getShopName(token);
}
The "shop_name" in variable, to reuse in other part.
So, I know that void doesn't return nothing, but, I tried to edit like this answer, without success:
How can I return value from function onResponse of Volley?
Thank you
The issue is not returning a value from a JsonObjectRequest, but rather that you're trying to do an asynchronous operation in a synchronous way.
Here is a great explanation: Asynchronous vs synchronous execution, what does it really mean?
And to your specific question: I advise using an AsyncTask for your network operation.

Categories

Resources