20 Commits
Author SHA1 Message Date
Pablo Fernandez d0fa8689cb Added changes to changelog and version to pom 2010-11-30 15:05:10 -03:00
roger 896e738156 Signature test fixed. New reference signature as api & token secret must be urlencoded. 2010-11-30 15:01:12 -03:00
roger cf84381127 Added URLDecoding to verifier 2010-11-30 14:49:47 -03:00
klakegg 806d548629 Parameters scope and oauth_callback are needed in the request_token step only. 2010-11-30 14:25:42 -03:00
Roger 959c093620 keyString for SecretKey must be encoded 2010-11-30 14:10:57 -03:00
Pablo Fernandez fc2c46bd3a Changed GoogleApi to use GET 2010-11-23 17:35:42 -03:00
klakegg f1ecabdb52 Token implements Serializable - nice to have when creating web service. 2010-11-23 17:29:24 -03:00
Pablo Fernandez 83f17b0652 Changed version number for release 2010-11-20 19:49:13 -03:00
Pablo Fernandez ebe0ff9eda Fixed failing tests 2010-11-20 19:46:59 -03:00
Pablo Fernandez 6e141ba6a2 Added Google Example 2010-11-20 19:42:49 -03:00
Pablo Fernandez 23af69cbf8 Minor fixes to Request javadoc 2010-11-20 19:42:12 -03:00
Pablo Fernandez c0d24b556c Refactored URLEncoing code 2010-11-20 19:27:04 -03:00
Pablo Fernandez 99a03b4679 Improved TokenExtractor error messages 2010-11-20 18:31:11 -03:00
Pablo Fernandez 9337ac01d9 Fixed EvernoteApi to use GET 2010-11-06 20:03:13 -03:00
Pablo Fernandez dee0f55b1e Updated changelog 2010-11-06 19:56:40 -03:00
Pablo Fernandez 377c3233d9 Added TimeUnit for the timeout calls 2010-11-06 19:54:47 -03:00
Pablo Fernandez 029125490d Merge https://github.com/jamietsao/scribe-java 2010-11-06 19:38:39 -03:00
Pablo Fernandez 20b200c7bc Changed Twitter OAuth endpoints to use the new api.twitter.com 2010-11-06 19:09:28 -03:00
Jamie Tsao 3e7291eaee Added methods to allow for setting the connect and read timeouts on the underlying HttpURLConnection 2010-11-04 15:23:19 -04:00
Pablo Fernandez 149756e5ed Added test for scope parameter 2010-10-27 15:35:25 -03:00
23 changed files with 229 additions and 76 deletions

No files matched your search

+12
View File
@@ -6,3 +6,15 @@
* FEATURE: Added support for Yammer and Evernote ( thanks oparrsih ) * FEATURE: Added support for Yammer and Evernote ( thanks oparrsih )
* FIX: Fixed bug that preventing setting the scope param on Google Api * FIX: Fixed bug that preventing setting the scope param on Google Api
[1.0.8]
* FEATURE: Added setConnectTimeout and setReadTimeout for the Request Object
* FIX: Fixed Evernote Api (uses GET for request and access tokens)
* REFACTOR: URLEncoding stuff. LinkedIn specific decoder is no longer needed
* FEATURE: Added Google example
[1.0.9]
* FEATURE: Token made Serializable
* FIX: Google Api encoding issues (thanks @roger and @klakegg)
+1 -1
View File
@@ -4,7 +4,7 @@
<groupId>org.scribe</groupId> <groupId>org.scribe</groupId>
<artifactId>scribe</artifactId> <artifactId>scribe</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.0.7</version> <version>1.0.9</version>
<name>Scribe OAuth Library</name> <name>Scribe OAuth Library</name>
<description>The best OAuth library out there</description> <description>The best OAuth library out there</description>
<url>http://github.com/fernandezpablo85/scribe-java</url> <url>http://github.com/fernandezpablo85/scribe-java</url>
@@ -1,7 +1,14 @@
package org.scribe.builder.api; package org.scribe.builder.api;
import org.scribe.model.Verb;
public class EvernoteApi extends DefaultApi10a public class EvernoteApi extends DefaultApi10a
{ {
@Override
protected Verb getRequestTokenVerb()
{
return Verb.GET;
}
@Override @Override
public String getRequestTokenEndpoint() public String getRequestTokenEndpoint()
@@ -10,9 +17,14 @@ public class EvernoteApi extends DefaultApi10a
} }
@Override @Override
public String getAccessTokenEndpoint() protected Verb getAccessTokenVerb()
{ {
return "https://www.evernote.com/oauth"; return Verb.GET;
} }
@Override
public String getAccessTokenEndpoint()
{
return "https://www.evernote.com/oauth";
}
} }
@@ -1,5 +1,7 @@
package org.scribe.builder.api; package org.scribe.builder.api;
import org.scribe.model.*;
public class GoogleApi extends DefaultApi10a public class GoogleApi extends DefaultApi10a
{ {
@Override @Override
@@ -13,4 +15,16 @@ public class GoogleApi extends DefaultApi10a
{ {
return "https://www.google.com/accounts/OAuthGetRequestToken"; return "https://www.google.com/accounts/OAuthGetRequestToken";
} }
@Override
protected Verb getAccessTokenVerb()
{
return Verb.GET;
}
@Override
protected Verb getRequestTokenVerb()
{
return Verb.GET;
}
} }
@@ -1,11 +1,7 @@
package org.scribe.builder.api; package org.scribe.builder.api;
import org.scribe.extensions.linkedin.*;
import org.scribe.extractors.*;
public class LinkedInApi extends DefaultApi10a public class LinkedInApi extends DefaultApi10a
{ {
@Override @Override
protected String getAccessTokenEndpoint() protected String getAccessTokenEndpoint()
{ {
@@ -17,11 +13,4 @@ public class LinkedInApi extends DefaultApi10a
{ {
return "https://api.linkedin.com/uas/oauth/requestToken"; return "https://api.linkedin.com/uas/oauth/requestToken";
} }
@Override
protected BaseStringExtractor getBaseStringExtractor()
{
return new LinkedInBaseStringExtractorImpl();
}
} }
@@ -5,12 +5,12 @@ public class TwitterApi extends DefaultApi10a
@Override @Override
protected String getAccessTokenEndpoint() protected String getAccessTokenEndpoint()
{ {
return "http://twitter.com/oauth/access_token"; return "http://api.twitter.com/oauth/access_token";
} }
@Override @Override
protected String getRequestTokenEndpoint() protected String getRequestTokenEndpoint()
{ {
return "http://twitter.com/oauth/request_token"; return "http://api.twitter.com/oauth/request_token";
} }
} }
@@ -1,23 +0,0 @@
package org.scribe.extensions.linkedin;
import org.scribe.extractors.*;
import org.scribe.model.*;
/**
* LinkedIn's specific extractor that does not encode the tilde character.
*
* @author Pablo Fernandez
*/
public class LinkedInBaseStringExtractorImpl extends BaseStringExtractorImpl
{
/**
* {@inheritDoc}
*/
@Override
public String extract(OAuthRequest request)
{
String baseString = super.extract(request);
return baseString.replace("%7E", "~");
}
}
@@ -22,7 +22,7 @@ public class TokenExtractorImpl implements RequestTokenExtractor, AccessTokenExt
*/ */
public Token extract(String response) public Token extract(String response)
{ {
Preconditions.checkEmptyString(response, "Cant extract a token from null object or an empty string."); Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response); Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response);
if (matcher.matches()) if (matcher.matches())
@@ -32,7 +32,7 @@ public class TokenExtractorImpl implements RequestTokenExtractor, AccessTokenExt
return new Token(token, secret); return new Token(token, secret);
} else } else
{ {
throw new OAuthException("Could not find request token or secret in response: " + response, null); throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null);
} }
} }
} }
+24 -11
View File
@@ -3,6 +3,7 @@ package org.scribe.model;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import org.scribe.exceptions.*; import org.scribe.exceptions.*;
import org.scribe.utils.*; import org.scribe.utils.*;
@@ -21,7 +22,6 @@ class Request
private Map<String, String> bodyParams; private Map<String, String> bodyParams;
private Map<String, String> headers; private Map<String, String> headers;
private String payload = null; private String payload = null;
private Integer timeout = null;
private HttpURLConnection connection; private HttpURLConnection connection;
/** /**
@@ -39,7 +39,6 @@ class Request
try try
{ {
connection = (HttpURLConnection) new URL(url).openConnection(); connection = (HttpURLConnection) new URL(url).openConnection();
if(timeout != null) connection.setConnectTimeout(timeout);
} catch (IOException ioe) } catch (IOException ioe)
{ {
throw new OAuthException("Could not open connection to: " + url, ioe); throw new OAuthException("Could not open connection to: " + url, ioe);
@@ -91,8 +90,8 @@ class Request
/** /**
* Add an HTTP Header to the Request * Add an HTTP Header to the Request
* *
* @param name * @param key the header name
* @param value * @param value the header value
*/ */
public void addHeader(String key, String value) public void addHeader(String key, String value)
{ {
@@ -102,8 +101,8 @@ class Request
/** /**
* Add a body Parameter (for POST/ PUT Requests) * Add a body Parameter (for POST/ PUT Requests)
* *
* @param name * @param key the parameter name
* @param value * @param value the parameter value
*/ */
public void addBodyParameter(String key, String value) public void addBodyParameter(String key, String value)
{ {
@@ -118,7 +117,7 @@ class Request
* *
* Note: The contents are not part of the OAuth signature * Note: The contents are not part of the OAuth signature
* *
* @param payload * @param payload the body of the request
*/ */
public void addPayload(String payload) public void addPayload(String payload)
{ {
@@ -212,13 +211,27 @@ class Request
} }
/** /**
* Sets the connection timeout in milliseconds for the underlying {@link HttpURLConnection} * Sets the connect timeout for the underlying {@link HttpURLConnection}
* *
* @param timeout in milliseconds * @param duration duration of the timeout
*
* @param unit unit of time (milliseconds, seconds, etc)
*/ */
public void setTimeout(int timeout) public void setConnectTimeout(int duration, TimeUnit unit)
{ {
this.timeout = timeout; this.connection.setConnectTimeout((int) unit.toMillis(duration));
}
/**
* Sets the read timeout for the underlying {@link HttpURLConnection}
*
* @param duration duration of the timeout
*
* @param unit unit of time (milliseconds, seconds, etc)
*/
public void setReadTimeout(int duration, TimeUnit unit)
{
this.connection.setReadTimeout((int) unit.toMillis(duration));
} }
/* /*
+5 -1
View File
@@ -1,12 +1,16 @@
package org.scribe.model; package org.scribe.model;
import java.io.Serializable;
/** /**
* Represents an OAuth token (either request or access token) and its secret * Represents an OAuth token (either request or access token) and its secret
* *
* @author Pablo Fernandez * @author Pablo Fernandez
*/ */
public class Token public class Token implements Serializable
{ {
private static final long serialVersionUID = 715000866082812683L;
private final String token; private final String token;
private final String secret; private final String secret;
+4 -1
View File
@@ -1,5 +1,7 @@
package org.scribe.model; package org.scribe.model;
import org.scribe.utils.*;
/** /**
* Represents an OAuth verifier code. * Represents an OAuth verifier code.
* *
@@ -7,6 +9,7 @@ package org.scribe.model;
*/ */
public class Verifier public class Verifier
{ {
private final String value; private final String value;
/** /**
@@ -16,7 +19,7 @@ public class Verifier
*/ */
public Verifier(String value) public Verifier(String value)
{ {
this.value = value; this.value = URLUtils.percentDecode(value);
} }
public String getValue() public String getValue()
@@ -53,6 +53,8 @@ public class OAuth10aServiceImpl implements OAuthService
public Token getRequestToken() public Token getRequestToken()
{ {
OAuthRequest request = new OAuthRequest(config.getRequestTokenVerb(), config.getRequestTokenEndpoint()); OAuthRequest request = new OAuthRequest(config.getRequestTokenVerb(), config.getRequestTokenEndpoint());
request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback());
if(scope != NO_SCOPE) request.addOAuthParameter(OAuthConstants.SCOPE, scope);
addOAuthParams(request, OAuthConstants.EMPTY_TOKEN); addOAuthParams(request, OAuthConstants.EMPTY_TOKEN);
addOAuthHeader(request); addOAuthHeader(request);
Response response = request.send(); Response response = request.send();
@@ -66,8 +68,6 @@ public class OAuth10aServiceImpl implements OAuthService
request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey()); request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey());
request.addOAuthParameter(OAuthConstants.SIGN_METHOD, signatureService.getSignatureMethod()); request.addOAuthParameter(OAuthConstants.SIGN_METHOD, signatureService.getSignatureMethod());
request.addOAuthParameter(OAuthConstants.VERSION, getVersion()); request.addOAuthParameter(OAuthConstants.VERSION, getVersion());
request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback());
if(scope != NO_SCOPE) request.addOAuthParameter(OAuthConstants.SCOPE, scope);
request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, token)); request.addOAuthParameter(OAuthConstants.SIGNATURE, getSignature(request, token));
} }
@@ -30,7 +30,7 @@ public class HMACSha1SignatureService implements SignatureService
{ {
Preconditions.checkEmptyString(baseString, "Base string cant be null or empty string"); Preconditions.checkEmptyString(baseString, "Base string cant be null or empty string");
Preconditions.checkEmptyString(apiSecret, "Api secret cant be null or empty string"); Preconditions.checkEmptyString(apiSecret, "Api secret cant be null or empty string");
return doSign(baseString, apiSecret + '&' + tokenSecret); return doSign(baseString, URLUtils.percentEncode(apiSecret) + '&' + URLUtils.percentEncode(tokenSecret));
} }
catch (Exception e) catch (Exception e)
{ {
+35 -2
View File
@@ -20,6 +20,17 @@ public class URLUtils
private static final String ERROR_MSG = String.format("Cannot find specified encoding: %s", UTF_8); private static final String ERROR_MSG = String.format("Cannot find specified encoding: %s", UTF_8);
private static final Set<EncodingRule> ENCODING_RULES;
static
{
Set<EncodingRule> rules = new HashSet<EncodingRule>();
rules.add(new EncodingRule("*","%2A"));
rules.add(new EncodingRule("+","%20"));
rules.add(new EncodingRule("%7E", "~"));
ENCODING_RULES = Collections.unmodifiableSet(rules);
}
/** /**
* Turns a map into a form-url-encoded string (key=value&key2=value2) * Turns a map into a form-url-encoded string (key=value&key2=value2)
* *
@@ -57,7 +68,12 @@ public class URLUtils
Preconditions.checkNotNull(string, "Cannot encode null string"); Preconditions.checkNotNull(string, "Cannot encode null string");
try try
{ {
return URLEncoder.encode(string, UTF_8).replaceAll("\\+", "%20"); String encoded = URLEncoder.encode(string, UTF_8);
for(EncodingRule rule : ENCODING_RULES)
{
encoded = rule.apply(encoded);
}
return encoded;
} }
catch (UnsupportedEncodingException uee) catch (UnsupportedEncodingException uee)
{ {
@@ -77,9 +93,26 @@ public class URLUtils
try try
{ {
return URLDecoder.decode(string, UTF_8); return URLDecoder.decode(string, UTF_8);
} catch (UnsupportedEncodingException uee) }
catch (UnsupportedEncodingException uee)
{ {
throw new OAuthException(ERROR_MSG, uee); throw new OAuthException(ERROR_MSG, uee);
} }
} }
private static final class EncodingRule
{
private final String ch;
private final String toCh;
EncodingRule(String ch, String toCh)
{
this.ch = ch;
this.toCh = toCh;
}
String apply(String string) {
return string.replace(ch, toCh);
}
}
} }
@@ -0,0 +1,66 @@
package org.scribe.examples;
import java.util.*;
import org.scribe.builder.*;
import org.scribe.builder.api.*;
import org.scribe.model.*;
import org.scribe.oauth.*;
public class GoogleExample
{
private static final String NETWORK_NAME = "Google";
private static final String AUTHORIZE_URL = "https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=";
private static final String PROTECTED_RESOURCE_URL = "https://docs.google.com/feeds/default/private/full/";
private static final String SCOPE = "https://docs.google.com/feeds/";
public static void main(String[] args)
{
OAuthService service = new ServiceBuilder()
.provider(GoogleApi.class)
.apiKey("anonymous")
.apiSecret("anonymous")
.scope(SCOPE)
.build();
Scanner in = new Scanner(System.in);
System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
System.out.println();
// Obtain the Request Token
System.out.println("Fetching the Request Token...");
Token requestToken = service.getRequestToken();
System.out.println("Got the Request Token!");
System.out.println("(if your curious it looks like this: " + requestToken + " )");
System.out.println();
System.out.println("Now go and authorize Scribe here:");
System.out.println(AUTHORIZE_URL + requestToken.getToken());
System.out.println("And paste the verifier here");
System.out.print(">>");
Verifier verifier = new Verifier(in.nextLine());
System.out.println();
// Trade the Request Token and Verfier for the Access Token
System.out.println("Trading the Request Token for an Access Token...");
Token accessToken = service.getAccessToken(requestToken, verifier);
System.out.println("Got the Access Token!");
System.out.println("(if your curious it looks like this: " + accessToken + " )");
System.out.println();
// Now let's go and ask for a protected resource!
System.out.println("Now we're going to access a protected resource...");
OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL);
service.signRequest(accessToken, request);
request.addHeader("GData-Version", "3.0");
Response response = request.send();
System.out.println("Got it! Lets see what we found...");
System.out.println();
System.out.println(response.getCode());
System.out.println(response.getBody());
System.out.println();
System.out.println("Thats it man! Go and build something awesome with Scribe! :)");
}
}
@@ -55,8 +55,6 @@ public class LinkedInExample
System.out.println(); System.out.println();
System.out.println("Thats it man! Go and build something awesome with Scribe! :)"); System.out.println("Thats it man! Go and build something awesome with Scribe! :)");
System.out.println(service.getRequestToken());
} }
} }
@@ -9,7 +9,7 @@ import org.scribe.oauth.*;
public class TwitterExample public class TwitterExample
{ {
private static final String AUTHORIZE_URL = "https://twitter.com/oauth/authorize?oauth_token="; private static final String AUTHORIZE_URL = "https://api.twitter.com/oauth/authorize?oauth_token=";
private static final String PROTECTED_RESOURCE_URL = "http://api.twitter.com/1/account/verify_credentials.xml"; private static final String PROTECTED_RESOURCE_URL = "http://api.twitter.com/1/account/verify_credentials.xml";
public static void main(String[] args) public static void main(String[] args)
@@ -23,7 +23,7 @@ public class BaseStringExtractorTest
@Test @Test
public void shouldExtractBaseStringFromOAuthRequest() public void shouldExtractBaseStringFromOAuthRequest()
{ {
String expected = "GET&http%3A%2F%2Fexample.com&oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E*%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456"; String expected = "GET&http%3A%2F%2Fexample.com&oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456";
String baseString = extractor.extract(request); String baseString = extractor.extract(request);
assertEquals(expected, baseString); assertEquals(expected, baseString);
} }
@@ -45,7 +45,7 @@ public class BaseStringExtractorTest
@Test @Test
public void shouldProperlyEncodeSpaces() public void shouldProperlyEncodeSpaces()
{ {
String expected = "GET&http%3A%2F%2Fexample.com&body%3Dthis%2520param%2520has%2520whitespace%26oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E*%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456"; String expected = "GET&http%3A%2F%2Fexample.com&body%3Dthis%2520param%2520has%2520whitespace%26oauth_callback%3Dhttp%253A%252F%252Fexample%252Fcallback%26oauth_consumer_key%3DAS%2523%2524%255E%252A%2540%2526%26oauth_signature%3DOAuth-Signature%26oauth_timestamp%3D123456";
request.addBodyParameter("body", "this param has whitespace"); request.addBodyParameter("body", "this param has whitespace");
assertEquals(expected, extractor.extract(request)); assertEquals(expected, extractor.extract(request));
} }
@@ -24,7 +24,7 @@ public class HeaderExtractorTest
public void shouldExtractStandardHeader() public void shouldExtractStandardHeader()
{ {
String expected = "OAuth oauth_callback=\"http%3A%2F%2Fexample%2Fcallback\", " + "oauth_signature=\"OAuth-Signature\", " String expected = "OAuth oauth_callback=\"http%3A%2F%2Fexample%2Fcallback\", " + "oauth_signature=\"OAuth-Signature\", "
+ "oauth_consumer_key=\"AS%23%24%5E*%40%26\", " + "oauth_timestamp=\"123456\""; + "oauth_consumer_key=\"AS%23%24%5E%2A%40%26\", " + "oauth_timestamp=\"123456\"";
String header = extractor.extract(request); String header = extractor.extract(request);
assertEquals(expected, header); assertEquals(expected, header);
} }
@@ -21,8 +21,9 @@ public class OAuthRequestTest
request.addOAuthParameter(OAuthConstants.TOKEN, "token"); request.addOAuthParameter(OAuthConstants.TOKEN, "token");
request.addOAuthParameter(OAuthConstants.NONCE, "nonce"); request.addOAuthParameter(OAuthConstants.NONCE, "nonce");
request.addOAuthParameter(OAuthConstants.TIMESTAMP, "ts"); request.addOAuthParameter(OAuthConstants.TIMESTAMP, "ts");
request.addOAuthParameter(OAuthConstants.SCOPE, "feeds");
assertEquals(3, request.getOauthParameters().size()); assertEquals(4, request.getOauthParameters().size());
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@@ -0,0 +1,21 @@
package org.scribe.model;
import static org.junit.Assert.*;
import org.junit.*;
public class VerifierTest
{
@Test
public void shouldParse()
{
Verifier verifier = new Verifier("p8k%2BGIjIL9PblXq%2BpH6LmT9l");
assertEquals(verifier.getValue(), "p8k+GIjIL9PblXq+pH6LmT9l");
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowErrorForNullString()
{
new Verifier(null);
}
}
@@ -3,7 +3,7 @@ package org.scribe.services;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.*; import org.junit.*;
import org.scribe.exceptions.OAuthException; import org.scribe.exceptions.*;
public class HMACSha1SignatureServiceTest public class HMACSha1SignatureServiceTest
{ {
@@ -29,7 +29,7 @@ public class HMACSha1SignatureServiceTest
String apiSecret = "api secret"; String apiSecret = "api secret";
String tokenSecret = "token secret"; String tokenSecret = "token secret";
String baseString = "base string"; String baseString = "base string";
String signature = "cyxvUDZY/5cQBcBiKulaNgnhN/w="; String signature = "uGymw2KHOTWI699YEaoi5xyLT50=";
assertEquals(signature, service.getSignature(baseString, apiSecret, tokenSecret)); assertEquals(signature, service.getSignature(baseString, apiSecret, tokenSecret));
} }
@@ -8,13 +8,6 @@ import org.junit.*;
public class URLUtilsTest public class URLUtilsTest
{ {
@Before
public void setup()
{
}
@Test @Test
public void shouldPercentEncodeMap() public void shouldPercentEncodeMap()
{ {
@@ -51,6 +44,23 @@ public class URLUtilsTest
assertEquals(expected, URLUtils.percentDecode(toDecode)); assertEquals(expected, URLUtils.percentDecode(toDecode));
} }
@Test
public void shouldEncodeAllSpecialCharacters()
{
String plain = "!*'();:@&=+$,/?#[]";
String encoded = "%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D";
assertEquals(encoded, URLUtils.percentEncode(plain));
assertEquals(plain, URLUtils.percentDecode(encoded));
}
@Test
public void shouldNotEncodeReservedCharacters()
{
String plain = "abcde123456-._~";
String encoded = plain;
assertEquals(encoded, URLUtils.percentEncode(plain));
}
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfMapIsNull() public void shouldThrowExceptionIfMapIsNull()
{ {