From 2150bc3e1373bf09e4134c3214a3158617b9a0f7 Mon Sep 17 00:00:00 2001 From: Raghu Manchiraju Date: Fri, 25 Oct 2013 01:51:44 -0700 Subject: [PATCH] Added Test classes --- src/classes/TwilioCapability.cls | 448 ++++++++++---------- src/classes/TwilioRestClient.cls | 2 + src/classes/Twilio_TestHTTPMock.cls | 182 ++++---- src/classes/Twilio_TestMessage.cls | 162 +++++++ src/classes/Twilio_TestMessage.cls-meta.xml | 5 + src/package.xml | 1 + 6 files changed, 486 insertions(+), 314 deletions(-) create mode 100644 src/classes/Twilio_TestMessage.cls create mode 100644 src/classes/Twilio_TestMessage.cls-meta.xml diff --git a/src/classes/TwilioCapability.cls b/src/classes/TwilioCapability.cls index 52fd607..8500c6e 100644 --- a/src/classes/TwilioCapability.cls +++ b/src/classes/TwilioCapability.cls @@ -29,176 +29,176 @@ OTHER DEALINGS IN THE SOFTWARE. */ global class TwilioCapability { - private class IllegalStateException extends Exception {} + private class IllegalStateException extends Exception {} - private String accountSid; - private String authToken; - private List scopes; + private String accountSid; + private String authToken; + private List scopes; - // Incoming Parameter holding until generate token time - private boolean buildIncomingScope = false; - private String incomingClientName = null; + // Incoming Parameter holding until generate token time + private boolean buildIncomingScope = false; + private String incomingClientName = null; - // Outgoing Paramater holding until generate token time - private boolean buildOutgoingScope = false; - private String appSid = null; - private Map outgoingParams = null; + // Outgoing Paramater holding until generate token time + private boolean buildOutgoingScope = false; + private String appSid = null; + private Map outgoingParams = null; - /** - * Create a new TwilioCapability with zero permissions. Next steps are to - * grant access to resources by configuring this token through the functions - * allowXXXX. - * - * @param accountSid the account sid to which this token is granted access - * @param authToken the secret key used to sign the token. Note, this auth token is not visible to the user of the token. - */ - global TwilioCapability(String accountSid, String authToken) { - this.accountSid = accountSid; - this.authToken = authToken; - this.scopes = new List(); + /** + * Create a new TwilioCapability with zero permissions. Next steps are to + * grant access to resources by configuring this token through the functions + * allowXXXX. + * + * @param accountSid the account sid to which this token is granted access + * @param authToken the secret key used to sign the token. Note, this auth token is not visible to the user of the token. + */ + global TwilioCapability(String accountSid, String authToken) { + this.accountSid = accountSid; + this.authToken = authToken; + this.scopes = new List(); - } + } - /** - * Allow the user of this token to make outgoing connections. - * - * @param applicationSid - * the application to which this token grants access - */ - global void allowClientOutgoing(String appSid) { - allowClientOutgoing(appSid, null); - } + /** + * Allow the user of this token to make outgoing connections. + * + * @param applicationSid + * the application to which this token grants access + */ + global void allowClientOutgoing(String appSid) { + allowClientOutgoing(appSid, null); + } - /** - * Allow the user of this token to make outgoing connections. - * - * @param applicationSid - * the application to which this token grants access - * @param params - * signed parameters that the user of this token cannot - * overwrite. - */ - global void allowClientOutgoing(String appSid, Map params) { - this.buildOutgoingScope = true; - this.outgoingParams = params; - this.appSid = appSid; - } - - /** - * If the user of this token should be allowed to accept incoming - * connections then configure the TwilioCapability through this method and - * specify the client name. - * - * @param clientName - */ - global void allowClientIncoming(String clientName) { - // Save the default client name - this.incomingClientName = clientName; - this.buildIncomingScope = true; - } + /** + * Allow the user of this token to make outgoing connections. + * + * @param applicationSid + * the application to which this token grants access + * @param params + * signed parameters that the user of this token cannot + * overwrite. + */ + global void allowClientOutgoing(String appSid, Map params) { + this.buildOutgoingScope = true; + this.outgoingParams = params; + this.appSid = appSid; + } + + /** + * If the user of this token should be allowed to accept incoming + * connections then configure the TwilioCapability through this method and + * specify the client name. + * + * @param clientName + */ + global void allowClientIncoming(String clientName) { + // Save the default client name + this.incomingClientName = clientName; + this.buildIncomingScope = true; + } - /** - * Allow the user of this token to access their event stream. - * - * @param filters - * key/value filters to apply to the event stream - */ - global void allowEventStream(Map filters) { - Map value = new Map(); - value.put('path', '/2010-04-01/Events'); - if (filters != null) { - value.put('params', generateParamString(filters)); - } - this.scopes.add(buildScopeString('stream', 'subscribe', value)); - } + /** + * Allow the user of this token to access their event stream. + * + * @param filters + * key/value filters to apply to the event stream + */ + global void allowEventStream(Map filters) { + Map value = new Map(); + value.put('path', '/2010-04-01/Events'); + if (filters != null) { + value.put('params', generateParamString(filters)); + } + this.scopes.add(buildScopeString('stream', 'subscribe', value)); + } - /** - * Generates a new token based on the credentials and permissions that - * previously has been granted to this token. - * - * @return the newly generated token that is valid for 3600 seconds - */ - global String generateToken() { - return generateToken(System.currentTimeMillis() + 3600); - } + /** + * Generates a new token based on the credentials and permissions that + * previously has been granted to this token. + * + * @return the newly generated token that is valid for 3600 seconds + */ + global String generateToken() { + return generateToken(System.currentTimeMillis() + 3600); + } - /** - * Generates a new token based on the credentials and permissions that - * previously has been granted to this token. - * - * @param expiresAt - * the expiration instance of the token. - * @return the newly generated token that is valid for ttl seconds - */ - global String generateToken(long ttl) { - // Build these scopes lazily when we generate tokens so we know - // if we have a default or incoming client name to use - buildIncomingScope(); - buildOutgoingScope(); - Map payload = new Map(); - payload.put('iss', this.accountSid); - payload.put('exp', String.valueOf(System.currentTimeMillis() + ttl)); - payload.put('scope', join(this.scopes, ' ')); - return jwtEncode(payload, this.authToken); - } + /** + * Generates a new token based on the credentials and permissions that + * previously has been granted to this token. + * + * @param expiresAt + * the expiration instance of the token. + * @return the newly generated token that is valid for ttl seconds + */ + global String generateToken(long ttl) { + // Build these scopes lazily when we generate tokens so we know + // if we have a default or incoming client name to use + buildIncomingScope(); + buildOutgoingScope(); + Map payload = new Map(); + payload.put('iss', this.accountSid); + payload.put('exp', String.valueOf(System.currentTimeMillis() + ttl)); + payload.put('scope', join(this.scopes, ' ')); + return jwtEncode(payload, this.authToken); + } - /* PRIVATE METHODS */ - - /** - * Construct the scope string for outgoing calls - */ - private void buildOutgoingScope() { - if (this.buildOutgoingScope) { - Map values = new Map { 'appSid' => appSid }; + /* PRIVATE METHODS */ + + /** + * Construct the scope string for outgoing calls + */ + private void buildOutgoingScope() { + if (this.buildOutgoingScope) { + Map values = new Map { 'appSid' => appSid }; - if (this.incomingClientName != null) { - values.put('clientName', this.incomingClientName); - } + if (this.incomingClientName != null) { + values.put('clientName', this.incomingClientName); + } - // Build outgoing scopes - if (this.outgoingParams != null && !this.outgoingParams.isEmpty()) { - values.put('appParams', generateParamString(this.outgoingParams)); - } - this.scopes.add(buildScopeString('client', 'outgoing', values)); - } - } - - /** - * Construct the scope string for incoming calls - */ - private void buildIncomingScope() { - if (this.buildIncomingScope) { - Map value = new Map(); + // Build outgoing scopes + if (this.outgoingParams != null && !this.outgoingParams.isEmpty()) { + values.put('appParams', generateParamString(this.outgoingParams)); + } + this.scopes.add(buildScopeString('client', 'outgoing', values)); + } + } + + /** + * Construct the scope string for incoming calls + */ + private void buildIncomingScope() { + if (this.buildIncomingScope) { + Map value = new Map(); - // Incoming name, which takes precedence over the default client name. - // However, we do NOT accept a null clientName here. - if (this.incomingClientName != null) { - value.put('clientName', this.incomingClientName); - } else { - throw new IllegalStateException('No client name set'); - } - this.scopes.add(buildScopeString('client', 'incoming', value)); - } - } - - /** - * Construct JWT scope string in the format "scope::?" - */ - private static String buildScopeString(String service, String privilege, - Map params) { - String scope = 'scope:'+service+':'+privilege; - if (params!=null && !params.isEmpty()) { - scope += '?'+generateParamString(params); - } - return scope; - } + // Incoming name, which takes precedence over the default client name. + // However, we do NOT accept a null clientName here. + if (this.incomingClientName != null) { + value.put('clientName', this.incomingClientName); + } else { + throw new IllegalStateException('No client name set'); + } + this.scopes.add(buildScopeString('client', 'incoming', value)); + } + } + + /** + * Construct JWT scope string in the format "scope::?" + */ + private static String buildScopeString(String service, String privilege, + Map params) { + String scope = 'scope:'+service+':'+privilege; + if (params!=null && !params.isEmpty()) { + scope += '?'+generateParamString(params); + } + return scope; + } - /** - * Construct URL-style query param string, e.g. key1=val1&key2=val2&...keyN=valN - */ - private static String generateParamString(Map params) { - String queryString = ''; + /** + * Construct URL-style query param string, e.g. key1=val1&key2=val2&...keyN=valN + */ + private static String generateParamString(Map params) { + String queryString = ''; Set keySet = params.keySet(); for (String key : keySet) { @@ -206,44 +206,44 @@ global class TwilioCapability { queryString += '&'; } queryString += EncodingUtil.urlEncode(key, 'UTF-8') + '=' - + EncodingUtil.urlEncode(params.get(key), 'UTF-8'); + + EncodingUtil.urlEncode(params.get(key), 'UTF-8'); } return queryString; - } + } - /** - * Construct JWT token consisting of header, payload, and signature - * - * See http://self-issued.info/docs/draft-jones-json-web-token.html - */ - private static String jwtEncode(Map payload, String key) { - Map header = new Map(); - header.put('typ', 'JWT'); - header.put('alg', 'HS256'); + /** + * Construct JWT token consisting of header, payload, and signature + * + * See http://self-issued.info/docs/draft-jones-json-web-token.html + */ + private static String jwtEncode(Map payload, String key) { + Map header = new Map(); + header.put('typ', 'JWT'); + header.put('alg', 'HS256'); - List segments = new List(); - segments.add(urlSafeEncodeBase64(JSON.serialize(header))); - segments.add(urlSafeEncodeBase64(JSON.serialize(payload))); + List segments = new List(); + segments.add(urlSafeEncodeBase64(JSON.serialize(header))); + segments.add(urlSafeEncodeBase64(JSON.serialize(payload))); - String signature = sign(join(segments, '.'), key); - segments.add(signature); + String signature = sign(join(segments, '.'), key); + segments.add(signature); - return join(segments, '.'); - } + return join(segments, '.'); + } - private static String urlSafeEncodeBase64(String data) { + private static String urlSafeEncodeBase64(String data) { return urlSafeEncodeBase64(Blob.valueOf(data)); } - private static String urlSafeEncodeBase64(Blob data) { + private static String urlSafeEncodeBase64(Blob data) { String encodedString = EncodingUtil.base64Encode(data); return encodedString.replace('+','-').replace('/','_').replace('=', ''); // make URL-safe } - - /** - * Construct a String containing the contents of 'vals' separated by 'sep' - */ - private static String join(List vals, String sep) { + + /** + * Construct a String containing the contents of 'vals' separated by 'sep' + */ + private static String join(List vals, String sep) { String sb = ''; for (Iterator it=vals.iterator(); it.hasNext(); ) { String value = it.next(); @@ -254,75 +254,75 @@ global class TwilioCapability { return sb; } - /** - * Generate a signature for the token - * - * See http://self-issued.info/docs/draft-jones-json-web-signature.html - * and http://discussion.forum.nokia.com/forum/showthread.php?130974-Help-required-How-to-generate-a-MAC-(HMAC-SHA1)-with-Java - */ - private static String sign(String data, String key) { - Blob mac = Crypto.generateMac('hmacSHA256', Blob.valueOf(data), Blob.valueOf(key)); + /** + * Generate a signature for the token + * + * See http://self-issued.info/docs/draft-jones-json-web-signature.html + * and http://discussion.forum.nokia.com/forum/showthread.php?130974-Help-required-How-to-generate-a-MAC-(HMAC-SHA1)-with-Java + */ + private static String sign(String data, String key) { + Blob mac = Crypto.generateMac('hmacSHA256', Blob.valueOf(data), Blob.valueOf(key)); String result = urlSafeEncodeBase64(mac); - return result; - } - - /* UNIT TESTS FOR PRIVATE METHODS */ - static testMethod void testGenerateParamString() { - System.assertEquals('', generateParamString(new Map())); - System.assertEquals('a=b', generateParamString(new Map {'a'=>'b'} )); - System.assertEquals('cat=dog&foo=bar', generateParamString(new Map {'foo'=>'bar', 'cat' => 'dog'} )); - System.assertEquals('e=f&c=d&a=b', generateParamString(new Map {'a'=>'b', 'c'=>'d', 'e'=>'f' } )); - System.assertEquals('split%2Bkey2=split%2Bval2&split+key1=split+val1', generateParamString(new Map {'split key1'=>'split val1', 'split+key2'=>'split+val2'} )); + return result; + } + + /* UNIT TESTS FOR PRIVATE METHODS */ + static testMethod void testGenerateParamString() { + System.assertEquals('', generateParamString(new Map())); + System.assertEquals('a=b', generateParamString(new Map {'a'=>'b'} )); + System.assertEquals('cat=dog&foo=bar', generateParamString(new Map {'foo'=>'bar', 'cat' => 'dog'} )); + System.assertEquals('e=f&c=d&a=b', generateParamString(new Map {'a'=>'b', 'c'=>'d', 'e'=>'f' } )); + System.assertEquals('split+key2=split+val2&split+key1=split+val1', generateParamString(new Map {'split key1'=>'split val1', 'split key2'=>'split val2'} )); } static testMethod void testEncodeBase64() { - System.assertEquals('',urlSafeEncodeBase64('')); - System.assertEquals('QQ',urlSafeEncodeBase64('A')); - System.assertEquals('QUI',urlSafeEncodeBase64('AB')); - System.assertEquals('QUJDRA',urlSafeEncodeBase64('ABCD')); + System.assertEquals('',urlSafeEncodeBase64('')); + System.assertEquals('QQ',urlSafeEncodeBase64('A')); + System.assertEquals('QUI',urlSafeEncodeBase64('AB')); + System.assertEquals('QUJDRA',urlSafeEncodeBase64('ABCD')); } static testMethod void testJoin() { - System.assertEquals('', join(new List(),',')); - System.assertEquals('a', join(new List{'a'},',')); - System.assertEquals('a,b,c,d,e', join(new List{'a','b','c','d','e'},',')); + System.assertEquals('', join(new List(),',')); + System.assertEquals('a', join(new List{'a'},',')); + System.assertEquals('a,b,c,d,e', join(new List{'a','b','c','d','e'},',')); } /* ACCESSOR METHODS FOR EXTERNAL TESTS */ public boolean test_buildOutgoingScope { - get { - if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); - return this.buildOutgoingScope; - } + get { + if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); + return this.buildOutgoingScope; + } } public String test_appSid { - get { - if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); - return this.appSid; - } + get { + if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); + return this.appSid; + } } public Map test_outgoingParams { - get { - if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); - return this.outgoingParams; - } + get { + if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); + return this.outgoingParams; + } } public List test_scopes { - get { - if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); - return this.scopes; - } + get { + if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); + return this.scopes; + } } public String test_incomingClientName { - get { - if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); - return this.incomingClientName; - } + get { + if (!Test.isRunningTest()) throw new TestOnlyException('Test must be running to use this method'); + return this.incomingClientName; + } } private class TestOnlyException extends Exception {} diff --git a/src/classes/TwilioRestClient.cls b/src/classes/TwilioRestClient.cls index c60b599..dc7a5c3 100644 --- a/src/classes/TwilioRestClient.cls +++ b/src/classes/TwilioRestClient.cls @@ -426,7 +426,9 @@ public class TwilioRestClient { String contentType; if (Test.isRunningTest()) { // can't execute HTTP requests during test execution + system.debug('Request :'+request); Twilio_TestHTTPMock.Response responseMock = Twilio_TestHTTPMock.getInstance().send(request); + system.debug(responseMock); responseBody = (responseMock.getBody()==null)?'':responseMock.getBody(); statusCode = responseMock.getStatusCode(); contentType = responseMock.getHeader('Content-Type'); diff --git a/src/classes/Twilio_TestHTTPMock.cls b/src/classes/Twilio_TestHTTPMock.cls index 8218713..37d441f 100644 --- a/src/classes/Twilio_TestHTTPMock.cls +++ b/src/classes/Twilio_TestHTTPMock.cls @@ -29,101 +29,103 @@ OTHER DEALINGS IN THE SOFTWARE. * * Usage: * Twilio_TestHTTPMock.getInstance().putResponse( - * 'GET', - * 'https://api.twilio.com/2010-04-01/Accounts/ACbaabc55eacf55afdae555e555c5cc55a.json', - * new Twilio_TestHTTPMock.Response( - * '{ "sid": "ACbaabc55eacf55afdae555e555c5cc55a","friendly_name": "My Test Account" }', - * 200) - * ); + * 'GET', + * 'https://api.twilio.com/2010-04-01/Accounts/ACbaabc55eacf55afdae555e555c5cc55a.json', + * new Twilio_TestHTTPMock.Response( + * '{ "sid": "ACbaabc55eacf55afdae555e555c5cc55a","friendly_name": "My Test Account" }', + * 200) + * ); */ public class Twilio_TestHTTPMock { - /** singleton */ - private final static Twilio_TestHTTPMock instance = new Twilio_TestHTTPMock(); - /** get singleton */ - public static Twilio_TestHTTPMock getInstance() { return Twilio_TestHTTPMock.instance; } + /** singleton */ + private final static Twilio_TestHTTPMock instance = new Twilio_TestHTTPMock(); + /** get singleton */ + public static Twilio_TestHTTPMock getInstance() { return Twilio_TestHTTPMock.instance; } - /** 404 NOT FOUND error */ - private static Response response404 = new Response('{"status": 404, "message": "The requested resource was not found"}', 404); + /** 404 NOT FOUND error */ + private static Response response404 = new Response('{"status": 404, "message": "The requested resource was not found"}', 404); - /** instance methods */ - private Map> methodMap = new Map>(); - - /** Mock HTTP.send(HTTPRequest) function, returns a preregistered Response or a 404 */ - public Response send(HTTPRequest req) { - System.debug('Twilio_TestHTTPMock::send() Request.Method: '+req.getMethod()); - System.debug('Twilio_TestHTTPMock::send() Request.Endpoint: '+req.getEndpoint()); + /** instance methods */ + private Map> methodMap = new Map>(); + + /** Mock HTTP.send(HTTPRequest) function, returns a preregistered Response or a 404 */ + public Response send(HTTPRequest req) { + System.debug('Twilio_TestHTTPMock::send() Request.Method: '+req.getMethod()); + System.debug('Twilio_TestHTTPMock::send() Request.Endpoint: '+req.getEndpoint()); - Response res = getResponse(req.getMethod(), req.getEndpoint()); - if (res==null) { - res = response404; - } - System.debug('Twilio_TestHTTPMock::send() Response.Body: '+res.getBody()); + Response res = getResponse(req.getMethod(), req.getEndpoint()); + if (res==null) { + res = response404; + } + System.debug('Twilio_TestHTTPMock::send() Response.Body: '+res.getBody()); - return res; - } - - /** Looks up the response for a specific HTTP method and URI. Returns null if none found. */ - public Response getResponse(String method, String uri) { - Response res = null; - Map resourceMap = this.methodMap.get(method.toUpperCase()); - if (resourceMap!=null) { - res = resourceMap.get(uri.toUpperCase()); - - if (res!=null) { - System.debug('Twilio_TestHTTPMock::getResponse() Found Resource for '+method+' '+uri+' = '+res); - } else { - System.debug('Twilio_TestHTTPMock::getResponse() Did not find Resource for '+method+' '+uri); - } - } else { - System.debug('Twilio_TestHTTPMock::getResponse() Did not find Resource Map for '+method); - } - return res; - } - - /** Registers a response to be returned for a particular HTTP method and URI */ - public void putResponse(String method, String uri, Response res) { - String methodKey = method.toUpperCase(); - String uriKey = uri.toUpperCase(); - - Map resourceMap = this.methodMap.get(methodKey); - if (resourceMap==null) { - resourceMap = new Map(); - this.methodMap.put(methodKey, resourceMap); - } - resourceMap.put(uriKey,res); - System.debug('Twilio_TestHTTPMock::putResponse() Added resource '+methodKey+' '+uriKey); - - } - - /** Response class - mock equivalent to HTTPResponse */ - public class Response { - - private String body; - private final Map headers = new Map(); - private Integer statusCode; - - public Response(String body, Integer statusCode) { - this.body = body; - this.statusCode = statusCode; - this.headers.put('Content-Type','application/json'); // default - } - - public void setHeader(String key, String value) - { - this.headers.put(key,value); - } - - public Integer getStatusCode() { - return this.statusCode; - } - - public String getBody() { - return this.body; - } - - public String getHeader(String name) { - return headers.get(name); - } - } + return res; + } + + /** Looks up the response for a specific HTTP method and URI. Returns null if none found. */ + public Response getResponse(String method, String uri) { + Response res = null; + Map resourceMap = this.methodMap.get(method.toUpperCase()); + if (resourceMap!=null) { + res = resourceMap.get(uri.toUpperCase()); + system.debug('Resource Map:'+resourceMap+' , Keys :'+resourceMap.keySet()); + if (res!=null) { + System.debug('Twilio_TestHTTPMock::getResponse() Found Resource for '+method+' '+uri+' = '+res); + } else { + System.debug('Twilio_TestHTTPMock::getResponse() Did not find Resource for '+method+' '+uri); + } + } else { + System.debug('Twilio_TestHTTPMock::getResponse() Did not find Resource Map for '+method); + } + return res; + } + + /** Registers a response to be returned for a particular HTTP method and URI */ + public void putResponse(String method, String uri, Response res) { + String methodKey = method.toUpperCase(); + String uriKey = uri.toUpperCase(); + + Map resourceMap = this.methodMap.get(methodKey); + if (resourceMap==null) { + resourceMap = new Map(); + this.methodMap.put(methodKey, resourceMap); + + } + resourceMap.put(uriKey,res); + system.debug('Put ResourceMap:'+resourceMap); + System.debug('Twilio_TestHTTPMock::putResponse() Added resource '+methodKey+' '+uriKey); + + } + + /** Response class - mock equivalent to HTTPResponse */ + public class Response { + + private String body; + private final Map headers = new Map(); + private Integer statusCode; + + public Response(String body, Integer statusCode) { + this.body = body; + this.statusCode = statusCode; + this.headers.put('Content-Type','application/json'); // default + } + + public void setHeader(String key, String value) + { + this.headers.put(key,value); + } + + public Integer getStatusCode() { + return this.statusCode; + } + + public String getBody() { + return this.body; + } + + public String getHeader(String name) { + return headers.get(name); + } + } } \ No newline at end of file diff --git a/src/classes/Twilio_TestMessage.cls b/src/classes/Twilio_TestMessage.cls new file mode 100644 index 0000000..20e1d09 --- /dev/null +++ b/src/classes/Twilio_TestMessage.cls @@ -0,0 +1,162 @@ +@isTest +private class Twilio_TestMessage +{ + + final static String authToken = '12345678901234567890123456789012'; + + static testmethod void testTwilioMessage_send() + { + string accountJsonResponseBody='{' + +'"account_sid": "AC03c2fcd60e144e7cbeee413fcbf812a3",' + +'"api_version": "2010-04-01",' + +'"body": "Test sending MMS from twilio",' + +'"num_segments": "1",' + +'"num_media": "1",' + +'"date_created": "Mon, 1 Feb 2012 10:49:17 +0000",' + +'"date_sent": "Mon, 1 Feb 2012 10:49:17 +0000",' + +'"date_updated": "Mon, 1 Feb 2012 10:49:17 +0000",' + +'"direction": "outbound-api",' + +'"from": "+14158141829",' + +'"price": "null",' + +'"price_unit":"usd",' + +'"sid": "MM90c6fc909d8504d45ecdb3a3d5b3556e",' + +'"status": "queued",' + +'"to": "+14159978453",' + +'"uri": "/2010-04-01/Accounts/AC03c2fcd60e144e7cbeee413fcbf812a3/MM90c6fc909d8504d45ecdb3a3d5b3556e.json",' + +'"subresource_uris": ' + +'{"media":"/2010-04-01/Accounts/ACadfb5891c0e4f8c6c34be620a8ec1ef3/Messages/MMbd2135c6d10f417faf1e03fac4e8397b/Media.json"}' + +'}'; + + Twilio_TestHTTPMock.getInstance().putResponse('POST', + 'https://api.twilio.com/2010-04-01/Accounts/ACadfb5891c0e4f8c6c34be620a8ec1ef3/Messages.json', + new Twilio_TestHTTPMock.Response(accountJsonResponseBody,200)); + + + // Get an API client and request the Twilio Account + TwilioRestClient client = new TwilioRestClient('ACadfb5891c0e4f8c6c34be620a8ec1ef3', authToken); + Map properties = new Map { + 'To' => '+14506007431', + 'From' => '+14509000405', + 'Body' => 'Test sending MMS from twilio' + }; + TwilioMessage sms = client.getAccount().getMessages().create(properties); + sms.getMedia(); + sms.getMedia('MM90c6fc909d8504d45ecdb3a3d5b3556e'); + sms.getResourceLocation(); + + System.assertEquals('MM90c6fc909d8504d45ecdb3a3d5b3556e', sms.getsid()); + System.assertEquals('AC03c2fcd60e144e7cbeee413fcbf812a3', sms.getaccountsid()); + System.assertEquals('+14159978453',sms.getto()); + System.assertEquals('+14158141829',sms.getfrom()); + System.assertEquals('Test sending MMS from twilio',sms.getbody()); + System.assertEquals('1',sms.getnumSegments()); + System.assertEquals('1',sms.getnumMedia()); + System.assertEquals('queued',sms.getStatus()); + System.assertEquals('null',sms.getPrice()); + System.assertEquals('usd',sms.getPriceUnit()); + System.assertEquals('outbound-api',sms.getDirection()); + System.assertEquals('2010-04-01',sms.getApiVersion()); + System.assertEquals(Datetime.newInstanceGmt(2012,2,1,10,49,17),sms.getDateCreated()); + System.assertEquals(Datetime.newInstanceGmt(2012,2,1,10,49,17),sms.getDateUpdated()); + System.assertEquals(Datetime.newInstanceGmt(2012,2,1,10,49,17),sms.getDatesent()); + } + + static testmethod void testTwilioMessageKeyPair_send() + { + string accountJsonResponseBody='{' + +'"account_sid": "AC03c2fcd60e144e7cbeee413fcbf812a3",' + +'"api_version": "2010-04-01",' + +'"body": "Test sending MMS from twilio",' + +'"num_segments": "1",' + +'"num_media": "1",' + +'"date_created": "Mon, 1 Feb 2012 10:49:17 +0000",' + +'"date_sent": "Mon, 1 Feb 2012 10:49:17 +0000",' + +'"date_updated": "Mon, 1 Feb 2012 10:49:17 +0000",' + +'"direction": "outbound-api",' + +'"from": "+14158141829",' + +'"price": "null",' + +'"sid": "MM90c6fc909d8504d45ecdb3a3d5b3556e",' + +'"status": "queued",' + +'"to": "+14159978453",' + +'"uri": "/2010-04-01/Accounts/AC03c2fcd60e144e7cbeee413fcbf812a3/MM90c6fc909d8504d45ecdb3a3d5b3556e.json"' + +'}'; + + Twilio_TestHTTPMock.getInstance().putResponse('POST', + 'https://api.twilio.com/2010-04-01/Accounts/AC03c2fcd60e144e7cbeee413fcbf812a3/Messages.json', + new Twilio_TestHTTPMock.Response(accountJsonResponseBody,200)); + + + // Get an API client and request the Twilio Account + TwilioRestClient client = new TwilioRestClient('AC03c2fcd60e144e7cbeee413fcbf812a3', authToken); + + List properties = new List(); + properties.add(new TwilioNameValuePair('To','4506007431')); + properties.add(new TwilioNameValuePair('From','4509000405')); + properties.add(new TwilioNameValuePair('MediaUrl','https://www.google.com/images/srpr/logo11w.png')); + properties.add(new TwilioNameValuePair('MediaUrl','https://www.twilio.com/packages/company/img/logos_downloadable_round.png')); + properties.add(new TwilioNameValuePair('Body','Raghu Testing Multiple MMS')); + + TwilioMessage mms = client.getAccount().getMessages().create(properties); + + + System.assertEquals('MM90c6fc909d8504d45ecdb3a3d5b3556e', mms.getsid()); + System.assertEquals('AC03c2fcd60e144e7cbeee413fcbf812a3', mms.getaccountsid()); + System.assertEquals('+14159978453',mms.getto()); + System.assertEquals('+14158141829',mms.getfrom()); + System.assertEquals('Test sending MMS from twilio',mms.getbody()); + System.assertEquals('1',mms.getnumSegments()); + System.assertEquals('1',mms.getnumMedia()); + System.assertEquals('queued',mms.getStatus()); + System.assertEquals('null',mms.getPrice()); + System.assertEquals('outbound-api',mms.getDirection()); + System.assertEquals('2010-04-01',mms.getApiVersion()); + System.assertEquals(Datetime.newInstanceGmt(2012,2,1,10,49,17),mms.getDateCreated()); + System.assertEquals(Datetime.newInstanceGmt(2012,2,1,10,49,17),mms.getDateUpdated()); + System.assertEquals(Datetime.newInstanceGmt(2012,2,1,10,49,17),mms.getDatesent()); + } + + static testmethod void testTwilioMessage_get() { + string accountJsonResponseBody='{' + +'"account_sid": "AC03c2fcd60e144e7cbeee413fcbf812a3",' + +'"api_version": "2008-08-01",' + +'"body": "Test sending mms from twilio",' + +'"date_created": "Mon, 1 Feb 2012 10:49:17 +0000",' + +'"date_sent": "Mon, 1 Feb 2012 10:49:17 +0000",' + +'"date_updated": "Mon, 1 Feb 2012 10:49:17 +0000",' + +'"direction": "outbound-api",' + +'"from": "+14158141829",' + +'"price": "-0.02000",' + +'"sid": "SM800f449d0399ed014aae2bcc0cc2f2ec",' + +'"status": "queued",' + +'"to": "+14159978453",' + +'"uri": "/2010-04-01/Accounts/AC5ef872f6da5a21de157d80997a64bd33/Messages/SM800f449d0399ed014aae2bcc0cc2f2ec.json",' + +'"subresource_uris": ' + +'{"media":"/2010-04-01/Accounts/ACadfb5891c0e4f8c6c34be620a8ec1ef3/Messages/MMbd2135c6d10f417faf1e03fac4e8397b/Media.json"}' + +'}'; + + + Twilio_TestHTTPMock.getInstance().putResponse( + 'GET', + 'https://api.twilio.com/2010-04-01/Accounts/AC03c2fcd60e144e7cbeee413fcbf812a3/Messages/SM800f449d0399ed014aae2bcc0cc2f2ec.json', + new Twilio_TestHTTPMock.Response(accountJsonResponseBody,200) + ); + + + // Get an API client and request the Twilio Account + TwilioRestClient client = new TwilioRestClient('AC03c2fcd60e144e7cbeee413fcbf812a3', authToken); + TwilioMessage sms= client.getAccount().getMessage('SM800f449d0399ed014aae2bcc0cc2f2ec'); + System.assertEquals('SM800f449d0399ed014aae2bcc0cc2f2ec', sms.getsid()); + System.assertEquals('AC03c2fcd60e144e7cbeee413fcbf812a3', sms.getaccountsid()); + System.assertEquals('+14159978453',sms.getto()); + System.assertEquals('+14158141829',sms.getfrom()); + System.assertEquals('Test sending mms from twilio',sms.getbody()); + System.assertEquals('queued',sms.getStatus()); + System.assertEquals('-0.02000',sms.getPrice()); + System.assertEquals('outbound-api',sms.getDirection()); + System.assertEquals('2008-08-01',sms.getApiVersion()); + System.assertEquals(Datetime.newInstanceGmt(2012,2,1,10,49,17),sms.getDateCreated()); + System.assertEquals(Datetime.newInstanceGmt(2012,2,1,10,49,17),sms.getDateUpdated()); + System.assertEquals(Datetime.newInstanceGmt(2012,2,1,10,49,17),sms.getDatesent()); + + } +} \ No newline at end of file diff --git a/src/classes/Twilio_TestMessage.cls-meta.xml b/src/classes/Twilio_TestMessage.cls-meta.xml new file mode 100644 index 0000000..f165265 --- /dev/null +++ b/src/classes/Twilio_TestMessage.cls-meta.xml @@ -0,0 +1,5 @@ + + + 29.0 + Active + diff --git a/src/package.xml b/src/package.xml index b0d0bec..9aeb6e2 100755 --- a/src/package.xml +++ b/src/package.xml @@ -57,6 +57,7 @@ Twilio_TestConference Twilio_TestConnectApps Twilio_TestHTTPMock + Twilio_TestMessage Twilio_TestNotification Twilio_TestPhoneNumbers Twilio_TestRecording