Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Http Test can now post files. Usage: post file <fileName> to <url>. #49

Merged
merged 6 commits into from
Apr 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.6</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/nl/hsac/fitnesse/fixture/Environment.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,17 @@ public void doHttpPost(String url, String templateName, Object model, HttpRespon
public void doHttpPost(String url, HttpResponse result, Map<String, Object> headers, String contentType) {
httpClient.post(url, result, headers, contentType);
}

/**
* Performs POST to supplied url of result's request.
* @param url url to post to.
* @param result result containing request, its response will be filled.
* @param headers headers to add.
* @param contentType contentType for request.
*/
public void doHttpFilePost(String url, HttpResponse result, Map<String, Object> headers, File file) {
httpClient.post(url, result, headers, file);
}

/**
* Performs PUT to supplied url of result of applying template with model.
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/nl/hsac/fitnesse/fixture/slim/HttpTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import freemarker.template.Template;
import nl.hsac.fitnesse.fixture.util.HttpResponse;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
Expand Down Expand Up @@ -128,6 +129,17 @@ public boolean postTo(String body, String serviceUrl) {
return postToImpl(cleanedBody, serviceUrl);
}

/**
* Sends a file by HTTP POST body to service endpoint.
* @param fileName fileName to post
* @param serviceUrl service endpoint to send body to.
* @return true if call could be made and response did not indicate error.
*/
public boolean postFileTo(String fileName, String serviceUrl) {

return postFileToImpl(fileName, serviceUrl);
}

/**
* Sends all values (url encoded) using post.
* @param serviceUrl service endpoint to send values to.
Expand All @@ -151,6 +163,31 @@ protected boolean postToImpl(String body, String serviceUrl) {
result = postProcessResponse();
return result;
}

protected boolean postFileToImpl(String fileName, String serviceUrl) {
boolean result;
resetResponse();
String url = getUrl(serviceUrl);

try {
String filePath = getFilePathFromWikiUrl(fileName);
File file = new File(filePath);
if(!isFile(file)) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should be consistent with the way paths to upload files are handled by BrowserTest:
if the file is located in the files directory its path must beging with 'files/', otherwise we expect a full path.

That means we always use this method, and not start by looking in the files section. I.e. remove the 4 lines above.

throw new Exception("File " + fileName + " not found.");
}

getEnvironment().doHttpFilePost(url, response, headerValues, file);

} catch (Throwable t) {
throw new StopTestException("Unable to get response from POST to: " + url, t);
}
result = postProcessResponse();
return result;
}

private boolean isFile(File file){
return (file.exists() && !file.isDirectory());
}

/**
* Sends HTTP PUT template with current values to service endpoint.
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/nl/hsac/fitnesse/fixture/util/HtmlCleaner.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
* Helper to remove wiki formatting from strings.
*/
public class HtmlCleaner {
private static final Pattern PATTERN = Pattern.compile("<a href=\"(.*?)\">(.*?)</a>(.*)", Pattern.CASE_INSENSITIVE);
private static final Pattern LINKPATTERN = Pattern.compile("<a href=\"(.*?)\">(.*?)</a>(.*)", Pattern.CASE_INSENSITIVE);
private static final Pattern IMAGEPATTERN = Pattern.compile("<img src=\"(.*?)\"/>", Pattern.CASE_INSENSITIVE);
private static final Pattern PRE_FORMATTED_PATTERN = Pattern.compile("<pre>\\s*(.*?)\\s*</pre>", Pattern.DOTALL);

/**
Expand All @@ -20,11 +21,15 @@ public class HtmlCleaner {
public String getUrl(String htmlLink) {
String result = htmlLink;
if (htmlLink != null) {
Matcher matcher = PATTERN.matcher(htmlLink);
if (matcher.matches()) {
String href = matcher.group(1);
Matcher linkMatcher = LINKPATTERN.matcher(htmlLink);
Matcher imgMatcher = IMAGEPATTERN.matcher(htmlLink);
if (linkMatcher.matches()) {
String href = linkMatcher.group(1);
href = StringEscapeUtils.unescapeHtml4(href);
result = href + matcher.group(3);
result = href + linkMatcher.group(3);
} else if (imgMatcher.matches()) {
String src = imgMatcher.group(1);
result = StringEscapeUtils.unescapeHtml4(src);
}
}
return result;
Expand Down Expand Up @@ -53,7 +58,7 @@ public <T> T cleanupValue(T rawValue) {
public String cleanupValue(String rawValue) {
String result = null;
if (rawValue != null) {
Matcher matcher = PATTERN.matcher(rawValue);
Matcher matcher = LINKPATTERN.matcher(rawValue);
if (matcher.matches()) {
result = matcher.group(2) + matcher.group(3);
} else {
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/nl/hsac/fitnesse/fixture/util/HttpClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;
import java.util.Map;
/**
Expand Down Expand Up @@ -49,6 +51,22 @@ public void post(String url, HttpResponse response, Map<String, Object> headers,
methodPost.setEntity(ent);
getResponse(url, response, methodPost, headers);
}

public void post(String url, HttpResponse response, Map<String, Object> headers, File file) {
HttpPost methodPost = new HttpPost(url);


MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody(file.getName(), file,
ContentType.APPLICATION_OCTET_STREAM, file.getName());
HttpEntity multipart = builder.build();

methodPost.setEntity(multipart);

getResponse(url, response, methodPost, headers);
}



/**
* @param url URL of service
Expand Down Expand Up @@ -101,6 +119,7 @@ protected void getResponse(String url, HttpResponse response, HttpRequestBase me
}
}
}

org.apache.http.HttpResponse resp;
CookieStore store = response.getCookieStore();
if (store == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
|script |file fixture |
|$createdFile=|create|upload.txt|containing|This is a file to test the file upload|

|script |mock xml server setup|
|add response|{{{<binary/>}}} |
|$url= |get mock server url |

|script |http test |
|post file|$createdFile|to|$url|

|table: Mock Server Message Report|

|script|mock xml server setup|
|stop |

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<properties>
<Edit>true</Edit>
<Files>true</Files>
<Properties>true</Properties>
<RecentChanges>true</RecentChanges>
<Refactor>true</Refactor>
<Search>true</Search>
<Test>true</Test>
<Versions>true</Versions>
<WhereUsed>true</WhereUsed>
</properties>
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,33 @@ Incomplete address: no zip code</PO:confirmation>
</detail></SOAP-ENV:Fault>
</SOAP-ENV:Body></SOAP-ENV:Envelope>}}}|with status|500|
|add response|<no xml |
|add response|{{{<binary/>}}} |
|$url= |get mock server url|

|script|xml http test |
|post |{{{<Hallo/>}}} |to |$url |
|check |xPath |count(/dag) |1 |
|reject|post |{{{<ClientFault/>}}} |to |$url |
|show |response |
|check |response status|500 |
|check |raw xPath |/env:Envelope/env:Body/env:Fault/faultstring|Message does not have necessary info |
|show |response headers |
|check |response header|Content-length |556 |
|note |next line is commented out so we won't have a real exception, uncomment to see that SOAP content is shown in exception |
|note |check |xPath |/env:Envelope/env:Body/env:Fault/faultstring|Message does not have necessary info|
|reject|post |{{{<ServerFault/>}}} |to |$url |
|show |response |
|check |response status|500 |
|check |raw xPath |/env:Envelope/env:Body/env:Fault/faultstring|Message does not have necessary info |
|note |next line is commented out so we won't have a real exception, uncomment to see that SOAP content is shown in exception |
|note |check |xPath |/env:Envelope/env:Body/env:Fault/faultstring|Message does not have necessary info|
|reject|post |{{{<NoXml/>}}} |to |$url |
|check |response status|200 |
|check |response |<no xml |
|note |next line is commented out so we won't have a real exception, uncomment to see that non-XML content is shown in exception |
|note |check |xPath |count(/*) |0 |
|script |xml http test |
|post |{{{<Hallo/>}}} |to |$url |
|check |xPath |count(/dag) |1 |
|reject |post |{{{<ClientFault/>}}} |to |$url |
|show |response |
|check |response status|500 |
|check |raw xPath |/env:Envelope/env:Body/env:Fault/faultstring|Message does not have necessary info |
|show |response headers |
|check |response header|Content-length |556 |
|note |next line is commented out so we won't have a real exception, uncomment to see that SOAP content is shown in exception |
|note |check |xPath |/env:Envelope/env:Body/env:Fault/faultstring|Message does not have necessary info|
|reject |post |{{{<ServerFault/>}}} |to |$url |
|show |response |
|check |response status|500 |
|check |raw xPath |/env:Envelope/env:Body/env:Fault/faultstring|Message does not have necessary info |
|note |next line is commented out so we won't have a real exception, uncomment to see that SOAP content is shown in exception |
|note |check |xPath |/env:Envelope/env:Body/env:Fault/faultstring|Message does not have necessary info|
|reject |post |{{{<NoXml/>}}} |to |$url |
|check |response status|200 |
|check |response |<no xml |
|note |next line is commented out so we won't have a real exception, uncomment to see that non-XML content is shown in exception |
|note |check |xPath |count(/*) |0 |

|table: Mock Server Message Report|

|script|mock xml server setup|
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a second 'stop mock server table'

|stop |
|stop |
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
!contents -R2 -g -p -f -h
!*> We start a mock server to receive the binary file and display the request later (specify one response per request)

|script |mock xml server setup |
|add response|{{{<status>OK</status>}}}|
|add response|{{{<status>OK</status>}}}|
|add response|{{{<status>OK</status>}}}|
|add response|{{{<status>OK</status>}}}|
|$mockUrl= |get mock server url |

*!
Now we post files to the service. Note the different notation options. We can:

* Use wiki-urls pointing to files in the files folder or below
* Use relative paths (non links) from files folder (include files folder)

|script |http test |
|post file|http://files/subfolder/testFile.txt|to|$mockUrl|
|post file|files/subfolder/testFile.txt |to|$mockUrl|
|post file|http://files/test.png |to|$mockUrl|
|post file|files/test.png |to|$mockUrl|

The Message report will show the received request:

|table: Mock Server Message Report|

!*> Stop the mock server

|script|mock xml server setup|
|stop |

*!
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<properties>
<Edit/>
<Files/>
<Properties/>
<RecentChanges/>
<Refactor/>
<Search/>
<Test/>
<Versions/>
<WhereUsed/>
</properties>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ The tests in this suite show example usage of this fixture:
>HttpGetTest shows how an example GET requests, specifying parameters in the query string.
>HttpPost1Test sends a POST request to a SOAP service, also adding an HTTP header.
The >HttpPost2UsingScenarioTest makes multiple SOAP calls to a service, where scenario parameters are used to change an input variable's value for each call.
>HttpPostFileTest sends a binary file.
>HttpPost3UsingFreemarkerTemplateTest shows the usage of a [[Freemarker][http://freemarker.org]] template to define the content of a SOAP request. This allows for dynamic request structure.
>JsonHttpTest shows examples with GET, POST, AND PUT, using [[!-JsonPath-!][http://goessner.net/articles/JsonPath/]] to perform checks on the response.
>HttpGetFollowRedirectTest shows checking the redirect sent by a server instead of following it.
Expand All @@ -19,6 +20,7 @@ The main commands/keywords (i.e. public methods) offered by !-nl.hsac.fitnesse.f
|get from <url> no redirect |Sends a GET to the specified url not following redirects sent by the server. |
|post <body> to <url> |Sends a POST containing the specified body to the url. |
|post template to <url> |Sends a POST to the specified url, determining the body by combining the configured template and values (see 'set value for' and 'template') |
|post file <file> to <url> |Sends a POST containing the specified file as multipart binary data to the url |
|put <body> to <url> |Sends a PUT containing the specified body to the url. |
|put template to <url> |Sends a PUT to the specified url, determining the body by combining the configured template and values (see 'set value for' and 'template') |
|template <location> |Configures the Freemarker template to use on next call using 'post template to'. |
Expand Down
1 change: 1 addition & 0 deletions wiki/FitNesseRoot/files/subfolder/testFile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file is used to test the posting of a binary data file to a webservice using HttpTest
Binary file added wiki/FitNesseRoot/files/test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.