What is the right way to use Espresso in android? - java

I am trying to run an Espresso test for my android app, but there is a problem that has been troubling me. In MainActivity, some views' visibility depends on data loaded from net, but in MainActivityTest, I can't manipulate the process of loading data, so I don't know the real data and which view should show and which view should not show. As a result, I don't know how to continue my test. Anyone can tell me how to handle this situation? Thanks!

Try using the MockWebServer library. It lets you mock http responses in your tests, like this:
/**
* Constructor for the test. Set up the mock web server here, so that the base
* URL for the application can be changed before the application loads
*/
public MyActivityTest() {
MockWebServer server = new MockWebServer();
try {
server.start();
} catch (IOException e) {
e.printStackTrace();
}
//Set the base URL for the application
MyApplication.sBaseUrl = server.url("/").toString();
//Create a dispatcher to handle requests to the mock web server
Dispatcher dispatcher = new Dispatcher() {
#Override
public MockResponse dispatch(RecordedRequest recordedRequest) throws InterruptedException {
try {
//When the activity requests the profile data, send it this
if(recordedRequest.getPath().startsWith("/users/self")) {
String fileName = "profile_200.json";
InputStream in = this.getClass().getClassLoader().getResourceAsStream(fileName);
String jsonString = new String(ByteStreams.toByteArray(in));
return new MockResponse().setResponseCode(200).setBody(jsonString);
}
//When the activity requests the image data, send it this
if(recordedRequest.getPath().startsWith("/users/self/media/recent")) {
String fileName = "media_collection_model_test.json";
InputStream in = this.getClass().getClassLoader().getResourceAsStream(fileName);
String jsonString = new String(ByteStreams.toByteArray(in));
return new MockResponse().setResponseCode(200).setBody(jsonString);
}
} catch (IOException e) {
e.printStackTrace();
}
return new MockResponse().setResponseCode(404);
}
};
server.setDispatcher(dispatcher);
}

Related

Download files with netty

I am creating a very basic webserver using netty and java. I will have basic functionality. It's main responsibilities would be to serve responses for API calls done from a client (e.g a browser, or a console app I am building) in JSON form or send a zip file. For that reason I have created the HttpServerHanddler class which is responsible for getting the request, parsing it to find the command and call the appropriate api call.It extends SimpleChannelInboundHandler
and overrides the following functions;
#Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
LOG.debug("channelActive");
}
#Override
public void channelReadComplete(ChannelHandlerContext ctx) {
LOG.debug("In channelComplete()");
ctx.flush();
}
#Override
public void channelRead0(ChannelHandlerContext ctx, Object msg)
throws IOException {
ctx = processMessage(ctx, msg);
if (!HttpHeaders.isKeepAlive(request)) {
// If keep-alive is off, close the connection once the content is
// fully written.
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(
ChannelFutureListener.CLOSE);
}
}
private ChannelHandlerContext processMessage(ChannelHandlerContext ctx, Object msg){
if (msg instanceof HttpRequest) {
HttpRequest request = this.request = (HttpRequest) msg;
if (HttpHeaders.is100ContinueExpected(request)) {
send100Continue(ctx);
}
//parse message to find command, parameters and cookies
ctx = executeCommand(command, parameters, cookies)
}
if (msg instanceof LastHttpContent) {
LOG.debug("msg is of LastHttpContent");
if (!HttpHeaders.isKeepAlive(request)) {
// If keep-alive is off, close the connection once the content is
// fully written.
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(
ChannelFutureListener.CLOSE);
}
}
return ctx;
}
private ChanndelHandlerContext executeCommand(String command, HashMap<String, List<String>>> parameters, Set<Cookie> cookies>){
//switch case to see which command has to be invoked
switch(command){
//many cases
case "/report":
ctx = myApi.getReport(parameters, cookies); //This is a member var of ServerHandler
break;
//many more cases
}
return ctx;
}
In my Api class that has the getReport function.
getReport
public ChannelHandlerContext getReportFile(Map<String, List<String>> parameters,
Set<Cookie> cookies) {
//some initiliazations. Actual file handing happens bellow
File file = new File(fixedReportPath);
RandomAccessFile raf = null;
long fileLength = 0L;
try {
raf = new RandomAccessFile(file, "r");
fileLength = raf.length();
LOG.debug("creating response for file");
this.response = Response.createFileResponse(fileLength);
this.ctx.write(response);
this.ctx.write(new HttpChunkedInput(new ChunkedFile(raf, 0,
fileLength,
8192)),
this.ctx.newProgressivePromise());
} catch (FileNotFoundException fnfe) {
LOG.debug("File was not found", fnfe);
this.response = Response.createStringResponse("failure");
this.ctx.write(response);
} catch (IOException ioe) {
LOG.debug("Error getting file size", ioe);
this.response = Response.createStringResponse("failure");
this.ctx.write(response);
} finally {
try {
raf.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return this.ctx;
}
Response class is responsible for handling various types of response creations (JsonString JsonArray JsonInteger File, etc)
public static FullHttpResponse createFileResponse(long fileLength) {
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
HttpHeaders.setContentLength(response, fileLength);
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/octet-stream");
return response;
}
My Api works great for my Json responses(easier to achieve) but It won't work well with my json responses, but not with my file response. When making a request from e.g chrome it only hangs and does not download the file. Should I do something else when downloading a file using netty? I know its not the best wittern code, I still think I have some bits and pieces missing from totally understanding the code, but I would like your advice on how to handle download on my code. For my code I took under consideration this and this
First, some remarks on your code...
Instead of returning ctx, I would prefer to return the last Future for the last command, such that your last event (no keep alive on) could use it directly.
public void channelRead0(ChannelHandlerContext ctx, Object msg)
throws IOException {
ChannelFuture future = processMessage(ctx, msg);
if (future != null && !HttpHeaders.isKeepAlive(request)) {
// If keep-alive is off, close the connection once the content is
// fully written.
future.addListener(ChannelFutureListener.CLOSE);
}
}
Doing this way will allow to directly close without having any "pseudo" send, even empty.
Important: Note that in Http, the response is managed such that there are chunk send for all data after the first HttpResponse item, until the last one which is empty (LastHttpContent). Sending another empty one (Empty chunk but not LastHttpContent) could break the internal logic.
Moreover, you're doing the work twice (once in read0, once in processMessage), which could lead to some issues perhaps.
Also, since you check for KeepAlive, you should ensure to set it back in the response:
if (HttpHeaders.isKeepAlive(request)) {
response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
}
On your send, you have 2 choices (depending on the usage of SSL or not): you've selected only the second one, which is more general, so of course valid in all cases but less efficient.
// Write the content.
ChannelFuture sendFileFuture;
ChannelFuture lastContentFuture;
if (ctx.pipeline().get(SslHandler.class) == null) {
sendFileFuture =
ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
// Write the end marker.
lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT); // <= last writeAndFlush
} else {
sendFileFuture =
ctx.writeAndFlush(new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)),
ctx.newProgressivePromise()); // <= last writeAndFlush
// HttpChunkedInput will write the end marker (LastHttpContent) for us.
lastContentFuture = sendFileFuture;
}
This is this lastContentFuture that you can get back to the caller to check the KeepAlive.
Note however that you didn't include a single flush there (except with your EMPTY_BUFFER but which can be the main reason of your issue there!), contrary to the example (from which I copied the source).
Note that both use a writeAndFlush for the last call (or the unique one).

How to add a graphical image signature using CoSign Signature Soap API

If possible add some code snippet. I have used Java for coding.
DSS: I would like to add multiple graphical image signature using CoSign Signature Soap API, how can I achieve it? If possible add some code snippet.
Here is a code sample in Java that demonstrates how to add a graphical signature using CoSign Signature SOAP API:
public static void AddGraphicalImage(String username, String domain, String password, byte[] imageBuffer, String imageName) throws Exception {
try {
SignRequest request = new SignRequest();
RequestBaseType.OptionalInputs optInputs = new RequestBaseType.OptionalInputs();
// Set signature type
optInputs.setSignatureType("http://arx.com/SAPIWS/DSS/1.0/set-graphic-image");
// Set user credentials
ClaimedIdentity claimedIdentity = new ClaimedIdentity();
NameIdentifierType nameIdentifier = new NameIdentifierType();
nameIdentifier.setValue(username);
nameIdentifier.setNameQualifier(domain);
CoSignAuthDataType coSignAuthData = new CoSignAuthDataType();
coSignAuthData.setLogonPassword(password);
claimedIdentity.setName(nameIdentifier);
claimedIdentity.setSupportingInfo(coSignAuthData);
optInputs.setClaimedIdentity(claimedIdentity);
// Set graphical image data
GraphicImageType graphicImage = new GraphicImageType();
graphicImage.setGraphicImage(imageBuffer);
graphicImage.setDataFormat(Long.valueOf(6)); //JPG
graphicImage.setGraphicImageName(imageName);
optInputs.setGraphicImageToSet(graphicImage);
request.setOptionalInputs(optInputs);
// Initiate service client
DSS client = new DSS(new URL("https://prime.cosigntrial.com:8080/sapiws/dss.asmx"));
// Send the request
DssSignResult response = client.getDSSSoap().dssSign(request);
// Check result
String errmsg = "" + response.getResult().getResultMajor();
if (errmsg.compareTo("urn:oasis:names:tc:dss:1.0:resultmajor:Success") == 0) {
System.out.println("Graphical image was added successfully!");
return;
}
else {
throw new Exception(response.getResult().getResultMessage().toString());
}
}
catch (Exception e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
}
}

Android Restlet framework - Get list of the Files and download file

I have in my app Restlet server and If I open the server address in the browser then the server should return list of files in some folder and If the user click on the file then it should download the file.
I looked at this tutorial. Part 6 Serving static file. It´s this code:
public static final String ROOT_URI = "file:///c:/restlet/docs/api/";
[...]
// Create a component
Component component = new Component();
component.getServers().add(Protocol.HTTP, 8182);
component.getClients().add(Protocol.FILE);
// Create an application
Application application = new Application() {
#Override
public Restlet createInboundRoot() {
return new Directory(getContext(), ROOT_URI);
}
};
// Attach the application to the component and start it
component.getDefaultHost().attach(application);
component.start();
but if I use for example file:///sdcard/ in URI, then if I open the address in the browser I get
Not Found
The server has not found anything matching the request URI
You can get technical details here.
Please continue your visit at our home page.
What´s wrong? How can I return list of the files with Restlet?
My solution:
mWebServerComponent = new Component();
mWebServerComponent.getClients().add(Protocol.FILE);
mWebServerComponent.getServers().add(Protocol.HTTP, 8182);
mWebServerComponent.getDefaultHost().attach(new FileApplication());
try {
mWebServerComponent.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
And the FileApplication class:
public class FileApplication extends Application {
// for example: public static final String ROOT_URI =
// "file:///C:/restlet-jee-2.0.6/docs/api/";
#Override
public synchronized Restlet createInboundRoot() {
String ROOT_URI = "file:///"
+ Environment.getExternalStorageDirectory() + "/";
Directory directory = new Directory(getContext(),
LocalReference.localizePath(ROOT_URI));
directory.setListingAllowed(true);
Router router = new Router(getContext());
router.attach("/files", directory);
return router;
}
}

nearest equivalent of a webpage reload in java

I am taking some data from a database via a servlet and a db handler java class and hosting it at a url. Since the database is changing I'm taking care only to host the changes rather than the entire db data.
I'm getting the required functionality by a browser i.e after every (manual) reload, I'm getting the data as required by me,
1. at the first page load, entire data gets displayed.
2. at subsequent reloads, I get either null data if there is no change in the database, or the appended rows if the database extends. (the database can only extend).
But then in a java program, I'm not getting the same functionality. The java program using HttpUrlConnection.
This is the code for the java client for servlet...
public class HTTPClient implements Runnable {
private CallbackInterface callbackinterface;
private URL url;
private HttpURLConnection http;
private InputStream response;
private String previousMessage = "";
public HTTPClient() {
try {
url = new URL("http://localhost:8080/RESTful-Server/index.jsp");
http = (HttpURLConnection) url.openConnection();
http.connect();
} catch (IOException e) {
}
}
#Override
public void run() {
while (true) {
try {
String currentmessage = "";
response = http.getInputStream();
if (http.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader buffread = new BufferedReader(new InputStreamReader(response));
String line;
for (; (line = buffread.readLine()) != null;) {
currentmessage += line;
}
if ((!currentmessage.equals(previousMessage)
|| !previousMessage.equals(""))
&& !currentmessage.equals("")) {
//this.callbackinterface.event(currentmessage);\
System.out.println(currentmessage + "\t" + previousMessage);
}
previousMessage = currentmessage;
Thread.sleep(2500);
} else {
throw new IOException();
}
} catch (IOException | InterruptedException e) {
System.err.println("Exception" + e);
}
}
}
The shown class is a thread which read the connections every 2.5 s. If it gets something significant in the getline(), it will issue a callback to a worker method, which takes care of remaining things.
I am thinking the issues is because of the class variable conn, and that reload as in the browser is not getting replicated..
Any idea how to do this?
You're basically connecting (requesting) only once and trying to read the response multiple times, while it can be read only once. You basically need to create a new connection (request) everytime. You need to move the creation of the connection by url.openConnection() to inside the loop. The line http.connect() is by the way superfluous. You can safely omit it. The http.getInputStream() will already implicitly do it.
See also:
Using java.net.URLConnection to fire and handle HTTP requests

Uploading file as stream in play framework 2.0

I'm writing a play 2.0 java application that allows users to upload files. Those files are stored on a third-party service I access using a Java library, the method I use in this API has the following signature:
void store(InputStream stream, String path, String contentType)
I've managed to make uploads working using the following simple controller:
public static Result uploadFile(String path) {
MultipartFormData body = request().body().asMultipartFormData();
FilePart filePart = body.getFile("files[]");
InputStream is = new FileInputStream(filePart.getFile())
myApi.store(is,path,filePart.getContentType());
return ok();
}
My concern is that this solution is not efficient because by default the play framework stores all the data uploaded by the client in a temporary file on the server then calls my uploadFile() method in the controller.
In a traditional servlet application I would have written a servlet behaving this way:
myApi.store(request.getInputStream(), ...)
I have been searching everywhere and didn't find any solution. The closest example I found is Why makes calling error or done in a BodyParser's Iteratee the request hang in Play Framework 2.0? but I didn't found how to modify it to fit my needs.
Is there a way in play2 to achieve this behavior, i.e. having the data uploaded by the client to go "through" the web-application directly to another system ?
Thanks.
I've been able to stream data to my third-party API using the following Scala controller code:
def uploadFile() =
Action( parse.multipartFormData(myPartHandler) )
{
request => Ok("Done")
}
def myPartHandler: BodyParsers.parse.Multipart.PartHandler[MultipartFormData.FilePart[Result]] = {
parse.Multipart.handleFilePart {
case parse.Multipart.FileInfo(partName, filename, contentType) =>
//Still dirty: the path of the file is in the partName...
String path = partName;
//Set up the PipedOutputStream here, give the input stream to a worker thread
val pos:PipedOutputStream = new PipedOutputStream();
val pis:PipedInputStream = new PipedInputStream(pos);
val worker:UploadFileWorker = new UploadFileWorker(path,pis);
worker.contentType = contentType.get;
worker.start();
//Read content to the POS
Iteratee.fold[Array[Byte], PipedOutputStream](pos) { (os, data) =>
os.write(data)
os
}.mapDone { os =>
os.close()
Ok("upload done")
}
}
}
The UploadFileWorker is a really simple Java class that contains the call to the thrid-party API.
public class UploadFileWorker extends Thread {
String path;
PipedInputStream pis;
public String contentType = "";
public UploadFileWorker(String path, PipedInputStream pis) {
super();
this.path = path;
this.pis = pis;
}
public void run() {
try {
myApi.store(pis, path, contentType);
pis.close();
} catch (Exception ex) {
ex.printStackTrace();
try {pis.close();} catch (Exception ex2) {}
}
}
}
It's not completely perfect because I would have preferred to recover the path as a parameter to the Action but I haven't been able to do so. I thus have added a piece of javascript that updates the name of the input field (and thus the partName) and it does the trick.

Categories

Resources