22 Commits
Author SHA1 Message Date
Pablo Fernandez 72901165f8 updated readme with new pom version 2011-03-30 00:09:46 -03:00
Stuart Grimshaw 4f23cfaf20 Moved callback header above call to addOAthParams so it gets properly
signed.
2011-03-29 19:06:19 -03:00
Pablo Fernandez 5c0d150547 Added mvn-bundle script 2011-03-13 10:49:31 -03:00
Pablo Fernandez 6bdae4999e Fixed wrong method call 2011-03-13 10:44:31 -03:00
Pablo Fernandez c441b7d8a4 Merged Diego's changes for OAuth2.0 server-side flow 2011-03-13 10:40:09 -03:00
Pablo Fernandez d8ab4ba404 oauth_callback param should only be sent on the request_token request 2011-03-13 10:25:52 -03:00
Pablo Fernandez 6923d3311f Added facebook and 2.0 info on readme 2011-03-13 10:21:43 -03:00
Pablo Fernandez 0832613b60 Changed artifact version in README 2011-03-13 10:21:43 -03:00
Pablo Fernandez 73a53b363a Fixed RequestTests 2011-03-13 10:21:43 -03:00
Pablo Fernandez 16b3475926 Added uitilty method to MapUtils for appending and encoding parameters 2011-03-13 10:21:42 -03:00
Pablo Fernandez 22367de553 Changed getQuerystringParameters impl to form-urldecode the parameters 2011-03-13 10:21:42 -03:00
Pablo Fernandez 906a979e63 Removed encoding in Verifier constructor 2011-03-13 10:21:42 -03:00
Pablo Fernandez bb872e4466 Changed percentEncodings 2011-03-13 10:21:42 -03:00
Pablo Fernandez d19c5d6e35 Removed Verifier test (unused) 2011-03-13 10:21:42 -03:00
Pablo Fernandez e0e8df98d3 Added formURLEncode/Decode methods 2011-03-13 10:21:39 -03:00
diegossilveira de8f0d621d Changed the Facebook example to conform to the OAuth 2.0 server-side flow 2011-02-10 22:09:18 -02:00
diegossilveira db37744fa3 Fixed package imports 2011-02-10 21:54:46 -02:00
diegossilveira 02f3d4dac2 Changed the Facebook example to conform to the OAuth 2.0 server-side flow 2011-02-10 17:13:03 -02:00
diegossilveira 7385d3702e Added specific token extractor for OAuth 2.0 2011-02-10 17:09:11 -02:00
diegossilveira 581e2b6d84 Changed the getAccessToken() method implementation to conform to the OAuth 2.0 server-side flow 2011-02-10 17:03:28 -02:00
diegossilveira 08aebb5fb1 Added specific constants for OAuth 2.0 2011-02-10 16:56:10 -02:00
diegossilveira c7176c97e2 Added access_token related methods to OAuth 2.0 APIs 2011-02-10 16:54:28 -02:00
21 changed files with 318 additions and 92 deletions

No files matched your search

+4 -2
View File
@@ -20,10 +20,12 @@ h3. Threadsafe
Hit Scribe as hard and with many threads as you like.
h3. Supports all major OAuth APIs out-of-the-box
h3. Supports all major 1.0a and 2.0 OAuth APIs out-of-the-box
* Google
* Facebook
* Yahoo
* LinkedIn
@@ -61,7 +63,7 @@ You can pull scribe from a maven repository, just add this to your __pom.xml__ f
@<dependency>@
@<groupId>org.scribe</groupId>@
@<artifactId>scribe</artifactId>@
@<version>1.0.6</version>@
@<version>1.1.2</version>@
@</dependency>@
h1. Getting started in less than 2 minutes
Executable
+2
View File
@@ -0,0 +1,2 @@
#!/bin/sh
mvn source:jar javadoc:jar package gpg:sign repository:bundle-create -Dgpg.passphrase=$1
+7 -1
View File
@@ -28,4 +28,10 @@
[1.1.1]
* FIX: Removed isEmpty() from OAuth2.0 code in order to support older JVMs
* FEATURE: Overloaded provider() method to support instances as well as classes (thanks dustismo)
* FEATURE: Overloaded provider() method to support instances as well as classes (thanks dustismo)
* FIX: White-space parameter bug (thanks Krogoth)
* FEATURE: OAuth 2.0 now implements server-flow (thanks Diego Silveira)
[1.1.2]
* FIX: Fixed ugly bug that made 1.1.1 practically unusable (thanks Stubbs)
+1 -1
View File
@@ -4,7 +4,7 @@
<groupId>org.scribe</groupId>
<artifactId>scribe</artifactId>
<packaging>jar</packaging>
<version>1.1.0</version>
<version>1.1.2</version>
<name>Scribe OAuth Library</name>
<description>The best OAuth library out there</description>
<url>http://github.com/fernandezpablo85/scribe-java</url>
@@ -1,5 +1,6 @@
package org.scribe.builder.api;
import org.scribe.extractors.*;
import org.scribe.model.*;
import org.scribe.oauth.*;
@@ -22,6 +23,33 @@ import org.scribe.oauth.*;
public abstract class DefaultApi20 implements Api
{
/**
* Returns the access token extractor.
*
* @return access token extractor
*/
public AccessTokenExtractor getAccessTokenExtractor()
{
return new TokenExtractor20Impl();
}
/**
* Returns the verb for the access token endpoint (defaults to GET)
*
* @return access token endpoint verb
*/
public Verb getAccessTokenVerb()
{
return Verb.GET;
}
/**
* Returns the URL that receives the access token requests.
*
* @return access token URL
*/
public abstract String getAccessTokenEndpoint();
/**
* Returns the URL where you should redirect your users to authenticate
* your application.
@@ -5,12 +5,18 @@ import org.scribe.utils.*;
public class FacebookApi extends DefaultApi20
{
private static final String AUTHORIZE_URL = "https://graph.facebook.com/oauth/authorize?response_type=token&client_id=%s&redirect_uri=%s";
private static final String AUTHORIZE_URL = "https://www.facebook.com/dialog/oauth?client_id=%s&redirect_uri=%s";
@Override
public String getAccessTokenEndpoint()
{
return "https://graph.facebook.com/oauth/access_token";
}
@Override
public String getAuthorizationUrl(OAuthConfig config)
{
Preconditions.checkValidUrl(config.getCallback(), "Must provide a valid url as callback. Facebook does not support OOB");
return String.format(AUTHORIZE_URL, config.getApiKey(), URLUtils.percentEncode(config.getCallback()));
return String.format(AUTHORIZE_URL, config.getApiKey(), URLUtils.formURLEncode(config.getCallback()));
}
}
@@ -32,11 +32,11 @@ public class BaseStringExtractorImpl implements BaseStringExtractor
private String getSortedAndEncodedParams(OAuthRequest request)
{
Map<String, String> params = new HashMap<String, String>();
params.putAll(request.getQueryStringParams());
params.putAll(request.getBodyParams());
params.putAll(request.getOauthParameters());
MapUtils.decodeAndAppendEntries(request.getQueryStringParams(), params);
MapUtils.decodeAndAppendEntries(request.getBodyParams(), params);
MapUtils.decodeAndAppendEntries(request.getOauthParameters(), params);
params = MapUtils.sort(params);
return URLUtils.percentEncode(URLUtils.formURLEncodeMap(params));
return URLUtils.percentEncode(URLUtils.concatSortedPercentEncodedParams(params));
}
private void checkPreconditions(OAuthRequest request)
@@ -0,0 +1,36 @@
package org.scribe.extractors;
import java.util.regex.*;
import org.scribe.exceptions.*;
import org.scribe.model.*;
import org.scribe.utils.*;
/**
* Default implementation of {@AccessTokenExtractor}. Conforms to OAuth 2.0
*
*/
public class TokenExtractor20Impl implements AccessTokenExtractor
{
private static final String TOKEN_REGEX = "access_token=(\\S*?)(&(\\S*))?";
private static final String EMPTY_SECRET = "";
/**
* {@inheritDoc}
*/
public Token extract(String response)
{
Preconditions.checkEmptyString(response, "Response body is incorrect. Can't extract a token from an empty string");
Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response);
if (matcher.matches())
{
String token = URLUtils.formURLDecode(matcher.group(1));
return new Token(token, EMPTY_SECRET);
}
else
{
throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null);
}
}
}
@@ -27,10 +27,11 @@ public class TokenExtractorImpl implements RequestTokenExtractor, AccessTokenExt
Matcher matcher = Pattern.compile(TOKEN_REGEX).matcher(response);
if (matcher.matches())
{
String token = URLUtils.percentDecode(matcher.group(1));
String secret = URLUtils.percentDecode(matcher.group(2));
String token = URLUtils.formURLDecode(matcher.group(1));
String secret = URLUtils.formURLDecode(matcher.group(2));
return new Token(token, secret);
} else
}
else
{
throw new OAuthException("Response body is incorrect. Can't extract a token from this: '" + response + "'", null);
}
@@ -41,4 +41,9 @@ public class OAuthConstants
//OAuth 2.0
public static final String ACCESS_TOKEN = "access_token";
public static final String CLIENT_ID = "client_id";
public static final String CLIENT_SECRET = "client_secret";
public static final String REDIRECT_URI = "redirect_uri";
public static final String CODE = "code";
}
+4 -10
View File
@@ -144,22 +144,16 @@ class Request
* Get a {@link Map} of the query string parameters.
*
* @return a map containing the query string parameters
* @throws OAuthException if the URL is not valid
*/
public Map<String, String> getQueryStringParams()
{
try
{
Map<String, String> params = new HashMap<String, String>();
String query = new URL(url).getQuery();
if (query != null)
{
for (String param : query.split("&"))
{
String pair[] = param.split("=");
params.put(pair[0], pair[1]);
}
}
params.putAll(querystringParams);
String queryString = new URL(url).getQuery();
params.putAll(URLUtils.queryStringToMap(queryString));
params.putAll(this.querystringParams);
return params;
}
catch (MalformedURLException mue)
+2 -1
View File
@@ -19,7 +19,8 @@ public class Verifier
*/
public Verifier(String value)
{
this.value = URLUtils.percentDecode(value);
Preconditions.checkNotNull(value, "Must provide a valid string as verifier");
this.value = value;
}
public String getValue()
@@ -36,6 +36,7 @@ public class OAuth10aServiceImpl implements OAuthService
public Token getRequestToken()
{
OAuthRequest request = new OAuthRequest(api.getRequestTokenVerb(), api.getRequestTokenEndpoint());
request.addOAuthParameter(OAuthConstants.CALLBACK, config.getCallback());
addOAuthParams(request, OAuthConstants.EMPTY_TOKEN);
addOAuthHeader(request);
Response response = request.send();
@@ -49,7 +50,6 @@ public class OAuth10aServiceImpl implements OAuthService
request.addOAuthParameter(OAuthConstants.CONSUMER_KEY, config.getApiKey());
request.addOAuthParameter(OAuthConstants.SIGN_METHOD, api.getSignatureService().getSignatureMethod());
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));
}
@@ -35,7 +35,13 @@ public class OAuth20ServiceImpl implements OAuthService
*/
public Token getAccessToken(Token requestToken, Verifier verifier)
{
throw new UnsupportedOperationException("Unsupported operation, please use 'getAuthorizationUrl' and redirect your users there");
OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue());
request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
Response response = request.send();
return api.getAccessTokenExtractor().extract(response.getBody());
}
/**
@@ -33,4 +33,19 @@ public class MapUtils
Collections.sort(keys);
return keys;
}
/**
* Form-urlDecodes and appends all keys from the source {@link Map} to the
* target {@link Map}
*
* @param source Map from where the keys get copied and decoded
* @param target Map where the decoded keys are copied to
*/
public static void decodeAndAppendEntries(Map<String, String> source, Map<String, String> target)
{
for (String key: source.keySet())
{
target.put(URLUtils.percentEncode(key), URLUtils.percentEncode(source.get(key)));
}
}
}
+78 -22
View File
@@ -13,8 +13,8 @@ public class URLUtils
{
private static final String EMPTY_STRING = "";
private static final String UTF_8 = "UTF-8";
private static final char PAIR_SEPARATOR = '=';
private static final char PARAM_SEPARATOR = '&';
private static final String PAIR_SEPARATOR = "=";
private static final String PARAM_SEPARATOR = "&";
private static final char QUERY_STRING_SEPARATOR = '?';
private static final String ERROR_MSG = String.format("Cannot find specified encoding: %s", UTF_8);
@@ -31,7 +31,7 @@ public class URLUtils
}
/**
* Turns a map into a form-url-encoded string (key=value&key2=value2)
* Turns a map into a form-urlencoded string
*
* @param map any map
* @return form-url-encoded string
@@ -47,32 +47,43 @@ public class URLUtils
StringBuffer encodedString = new StringBuffer(map.size() * 20);
for (String key : map.keySet())
{
if(encodedString.length() > 0)
encodedString.append(PARAM_SEPARATOR).append(formURLEncode(key));
if(map.get(key) != null)
{
encodedString.append(PARAM_SEPARATOR);
encodedString.append(PAIR_SEPARATOR).append(formURLEncode(map.get(key)));
}
encodedString.append(percentEncode(key)).append(PAIR_SEPARATOR).append(percentEncode(map.get(key)));
}
return encodedString.toString();
return encodedString.toString().substring(1);
}
/**
* Percent encodes a string
*
* @param plain
* @param string plain string
* @return percent encoded string
*/
public static String percentEncode(String string)
{
String encoded = formURLEncode(string);
for (EncodingRule rule : ENCODING_RULES)
{
encoded = rule.apply(encoded);
}
return encoded;
}
/**
* Translates a string into application/x-www-form-urlencoded format
*
* @param plain
* @return form-urlencoded string
*/
public static String formURLEncode(String string)
{
Preconditions.checkNotNull(string, "Cannot encode null string");
try
{
String encoded = URLEncoder.encode(string, UTF_8);
for(EncodingRule rule : ENCODING_RULES)
{
encoded = rule.apply(encoded);
}
return encoded;
return URLEncoder.encode(string, UTF_8);
}
catch (UnsupportedEncodingException uee)
{
@@ -81,12 +92,12 @@ public class URLUtils
}
/**
* Percent decodes a string
* Decodes a application/x-www-form-urlencoded string
*
* @param string percent encoded string
* @param string form-urlencoded string
* @return plain string
*/
public static String percentDecode(String string)
public static String formURLDecode(String string)
{
Preconditions.checkNotNull(string, "Cannot decode null string");
try
@@ -110,12 +121,57 @@ public class URLUtils
{
Preconditions.checkNotNull(url, "Cannot append to null URL");
String queryString = URLUtils.formURLEncodeMap(params);
if (queryString.length() == 0) return url;
if (queryString.equals(EMPTY_STRING))
{
return url;
}
else
{
url += url.indexOf(QUERY_STRING_SEPARATOR) != -1 ? PARAM_SEPARATOR : QUERY_STRING_SEPARATOR;
url += queryString;
return url;
}
}
// Check if there are parameters in the url already and use '&' instead of '?'
url += url.indexOf(QUERY_STRING_SEPARATOR) != -1 ? PARAM_SEPARATOR : QUERY_STRING_SEPARATOR;
url += queryString;
return url;
/**
* Concats a key-value map into a querystring-like String
*
* @param params key-value map
* @return querystring-like String
*/
// TODO Move to MapUtils
public static String concatSortedPercentEncodedParams(Map<String, String> params)
{
StringBuilder result = new StringBuilder();
for (String key : params.keySet())
{
result.append(key).append(PAIR_SEPARATOR);
result.append(params.get(key)).append(PARAM_SEPARATOR);
}
return result.toString().substring(0, result.length() - 1);
}
/**
* Parses and form-urldecodes a querystring-like string into a map
*
* @param queryString querystring-like String
* @return a map with the form-urldecoded parameters
*/
// TODO Move to MapUtils
public static Map<String, String> queryStringToMap(String queryString)
{
Map<String, String> result = new HashMap<String, String>();
if (queryString != null && queryString.length() > 0)
{
for (String param : queryString.split(PARAM_SEPARATOR))
{
String pair[] = param.split(PAIR_SEPARATOR);
String key = formURLDecode(pair[0]);
String value = pair.length > 1 ? formURLDecode(pair[1]) : EMPTY_STRING;
result.put(key, value);
}
}
return result;
}
private static final class EncodingRule
@@ -11,13 +11,12 @@ public class FacebookExample
{
private static final String NETWORK_NAME = "Facebook";
private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/me";
private static final String NO_SECRET_NEEDED = "";
private static final Token EMPTY_TOKEN = null;
public static void main(String[] args)
{
// Replace these with your own api key and secret
String apiKey = "your_api_key";
String apiKey = "your_app_id";
String apiSecret = "your_api_secret";
OAuthService service = new ServiceBuilder()
.provider(FacebookApi.class)
@@ -36,9 +35,16 @@ public class FacebookExample
System.out.println("Got the Authorization URL!");
System.out.println("Now go and authorize Scribe here:");
System.out.println(authorizationUrl);
System.out.println("And paste the access token here");
System.out.println("And paste the authorization code here");
System.out.print(">>");
Token accessToken = new Token(in.nextLine(), NO_SECRET_NEEDED);
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(EMPTY_TOKEN, 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!
@@ -0,0 +1,58 @@
package org.scribe.extractors;
import static org.junit.Assert.*;
import org.junit.*;
import org.scribe.exceptions.*;
import org.scribe.model.*;
public class TokenExtractor20Test
{
private TokenExtractor20Impl extractor;
@Before
public void setup()
{
extractor = new TokenExtractor20Impl();
}
@Test
public void shouldExtractTokenFromOAuthStandardResponse()
{
String response = "access_token=166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE";
Token extracted = extractor.extract(response);
assertEquals("166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE", extracted.getToken());
assertEquals("", extracted.getSecret());
}
@Test
public void shouldExtractTokenFromResponseWithExpiresParam()
{
String response = "access_token=166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE&expires=5108";
Token extracted = extractor.extract(response);
assertEquals("166942940015970|2.2ltzWXYNDjCtg5ZDVVJJeg__.3600.1295816400-548517159|RsXNdKrpxg8L6QNLWcs2TVTmcaE", extracted.getToken());
assertEquals("", extracted.getSecret());
}
@Test(expected = OAuthException.class)
public void shouldThrowExceptionIfTokenIsAbsent()
{
String response = "&expires=5108";
extractor.extract(response);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfResponseIsNull()
{
String response = null;
extractor.extract(response);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionIfResponseIsEmptyString()
{
String response = "";
extractor.extract(response);
}
}
@@ -16,8 +16,10 @@ public class RequestTest
{
connection = new ConnectionStub();
postRequest = new Request(Verb.POST, "http://example.com");
postRequest.addBodyParameter("param", "value");
postRequest.addBodyParameter("param with spaces", "value with spaces");
postRequest.setConnection(connection);
getRequest = new Request(Verb.GET, "http://example.com?qsparam=value&other=value+with+spaces");
getRequest = new Request(Verb.GET, "http://example.com?qsparam=value&other+param=value+with+spaces");
getRequest.setConnection(connection);
}
@@ -34,6 +36,7 @@ public class RequestTest
assertEquals(2, getRequest.getQueryStringParams().size());
assertEquals(0, postRequest.getQueryStringParams().size());
assertTrue(getRequest.getQueryStringParams().containsKey("qsparam"));
assertTrue(getRequest.getQueryStringParams().get("qsparam").equals("value"));
}
@Test
@@ -47,12 +50,10 @@ public class RequestTest
}
@Test
public void shouldSetBodyParamsAndHeaders()
public void shouldSetBodyParamsAndAddContentLength()
{
postRequest.addBodyParameter("param", "value");
postRequest.addBodyParameter("param two", "value with spaces");
assertEquals("param=value&param+with+spaces=value+with+spaces", postRequest.getBodyContents());
postRequest.send();
assertEquals("param%20two=value%20with%20spaces&param=value", postRequest.getBodyContents());
assertTrue(connection.getHeaders().containsKey("Content-Length"));
}
@@ -74,4 +75,9 @@ public class RequestTest
assertEquals(3, request.getQueryStringParams().size());
}
@Test
public void shouldHandleQueryStringSpaceEncodingProperly()
{
assertTrue(getRequest.getQueryStringParams().get("other param").equals("value with spaces"));
}
}
@@ -1,21 +0,0 @@
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);
}
}
@@ -16,7 +16,7 @@ public class URLUtilsTest
params.put("key with spaces", "value with spaces");
params.put("&symbols!", "#!");
String expected = "key=value&key%20with%20spaces=value%20with%20spaces&%26symbols%21=%23%21";
String expected = "key=value&key+with+spaces=value+with+spaces&%26symbols%21=%23%21";
assertEquals(expected, URLUtils.formURLEncodeMap(params));
}
@@ -28,6 +28,17 @@ public class URLUtilsTest
assertEquals(expected, URLUtils.formURLEncodeMap(params));
}
@Test
public void shouldFormURLEncodeMapWithMissingValues()
{
Map<String, String> params = new LinkedHashMap<String, String>();
params.put("key", "value");
params.put("key with spaces", null);
String expected = "key=value&key+with+spaces";
assertEquals(expected, URLUtils.formURLEncodeMap(params));
}
@Test
public void shouldPercentEncodeString()
{
@@ -37,24 +48,32 @@ public class URLUtilsTest
}
@Test
public void shouldPercentDecodeString()
public void shouldFormURLEncodeString()
{
String toDecode = "this+is+a+test+%26%5E";
String expected = "this is a test &^";
assertEquals(expected, URLUtils.percentDecode(toDecode));
String toEncode = "this is a test &^";
String expected = "this+is+a+test+%26%5E";
assertEquals(expected, URLUtils.formURLEncode(toEncode));
}
@Test
public void shouldEncodeAllSpecialCharacters()
public void shouldFormURLDecodeString()
{
String toDecode = "this+is+a+test+%26%5E";
String expected = "this is a test &^";
assertEquals(expected, URLUtils.formURLDecode(toDecode));
}
@Test
public void shouldPercentEncodeAllSpecialCharacters()
{
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));
assertEquals(plain, URLUtils.formURLDecode(encoded));
}
@Test
public void shouldNotEncodeReservedCharacters()
public void shouldNotPercentEncodeReservedCharacters()
{
String plain = "abcde123456-._~";
String encoded = plain;
@@ -79,7 +98,7 @@ public class URLUtilsTest
public void shouldThrowExceptionIfStringToDecodeIsNull()
{
String toDecode = null;
URLUtils.percentDecode(toDecode);
URLUtils.formURLDecode(toDecode);
}
@Test(expected = IllegalArgumentException.class)
@@ -103,7 +122,7 @@ public class URLUtilsTest
public void shouldAppendParametersToSimpleUrl()
{
String url = "http://www.example.com";
String expectedUrl = "http://www.example.com?param1=value1&param2=value%20with%20spaces";
String expectedUrl = "http://www.example.com?param1=value1&param2=value+with+spaces";
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "value1");
@@ -117,7 +136,7 @@ public class URLUtilsTest
public void shouldAppendParametersToUrlWithQuerystring()
{
String url = "http://www.example.com?already=present";
String expectedUrl = "http://www.example.com?already=present&param1=value1&param2=value%20with%20spaces";
String expectedUrl = "http://www.example.com?already=present&param1=value1&param2=value+with+spaces";
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "value1");
@@ -128,7 +147,7 @@ public class URLUtilsTest
}
@Test
public void shouldEncodePlusSymbol()
public void shouldPercentEncodePlusSymbol()
{
String plain = "7aEP+jNAwvjc0mjhqg0nuXPf";
String encoded = "7aEP%2BjNAwvjc0mjhqg0nuXPf";
@@ -137,11 +156,11 @@ public class URLUtilsTest
}
@Test
public void shouldDecodePlusSymbol()
public void shouldURLDecodePlusSymbol()
{
String encoded = "oauth_verifier=7aEP%2BjNAwvjc0mjhqg0nuXPf";
String expected = "oauth_verifier=7aEP+jNAwvjc0mjhqg0nuXPf";
Assert.assertEquals(expected, URLUtils.percentDecode(encoded));
Assert.assertEquals(expected, URLUtils.formURLDecode(encoded));
}
}