sfdc 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +96 -0
  3. data/Gemfile +11 -0
  4. data/Guardfile +11 -0
  5. data/LICENSE +22 -0
  6. data/README.md +88 -98
  7. data/Rakefile +10 -0
  8. data/lib/sfdc.rb +1 -0
  9. data/lib/sfdc/abstract_client.rb +1 -1
  10. data/lib/sfdc/attachment.rb +0 -2
  11. data/lib/sfdc/concerns/api.rb +1 -2
  12. data/lib/sfdc/concerns/authentication.rb +1 -2
  13. data/lib/sfdc/concerns/base.rb +5 -7
  14. data/lib/sfdc/concerns/caching.rb +1 -3
  15. data/lib/sfdc/concerns/canvas.rb +0 -2
  16. data/lib/sfdc/concerns/connection.rb +2 -3
  17. data/lib/sfdc/concerns/picklists.rb +1 -4
  18. data/lib/sfdc/concerns/streaming.rb +2 -2
  19. data/lib/sfdc/concerns/verbs.rb +0 -2
  20. data/lib/sfdc/config.rb +1 -0
  21. data/lib/sfdc/middleware/authentication.rb +4 -2
  22. data/lib/sfdc/middleware/authentication/password.rb +2 -5
  23. data/lib/sfdc/middleware/authorization.rb +1 -5
  24. data/lib/sfdc/middleware/caching.rb +0 -2
  25. data/lib/sfdc/middleware/instance_url.rb +0 -4
  26. data/lib/sfdc/middleware/mashify.rb +1 -3
  27. data/lib/sfdc/middleware/multipart.rb +6 -4
  28. data/lib/sfdc/signed_request.rb +1 -1
  29. data/lib/sfdc/tooling/client.rb +4 -6
  30. data/lib/sfdc/version.rb +2 -2
  31. data/sfdc.gemspec +27 -0
  32. data/spec/fixtures/auth_error_response.json +4 -0
  33. data/spec/fixtures/auth_success_response.json +7 -0
  34. data/spec/fixtures/blob.jpg +0 -0
  35. data/spec/fixtures/expired_session_response.json +6 -0
  36. data/spec/fixtures/reauth_success_response.json +7 -0
  37. data/spec/fixtures/refresh_error_response.json +4 -0
  38. data/spec/fixtures/refresh_success_response.json +7 -0
  39. data/spec/fixtures/services_data_success_response.json +12 -0
  40. data/spec/fixtures/sobject/create_success_response.json +5 -0
  41. data/spec/fixtures/sobject/delete_error_response.json +1 -0
  42. data/spec/fixtures/sobject/describe_sobjects_success_response.json +31 -0
  43. data/spec/fixtures/sobject/list_sobjects_success_response.json +31 -0
  44. data/spec/fixtures/sobject/org_query_response.json +11 -0
  45. data/spec/fixtures/sobject/query_aggregate_success_response.json +23 -0
  46. data/spec/fixtures/sobject/query_empty_response.json +5 -0
  47. data/spec/fixtures/sobject/query_error_response.json +6 -0
  48. data/spec/fixtures/sobject/query_paginated_first_page_response.json +14 -0
  49. data/spec/fixtures/sobject/query_paginated_last_page_response.json +13 -0
  50. data/spec/fixtures/sobject/query_success_response.json +38 -0
  51. data/spec/fixtures/sobject/recent_success_response.json +18 -0
  52. data/spec/fixtures/sobject/search_error_response.json +6 -0
  53. data/spec/fixtures/sobject/search_success_response.json +16 -0
  54. data/spec/fixtures/sobject/sobject_describe_error_response.json +6 -0
  55. data/spec/fixtures/sobject/sobject_describe_success_response.json +1429 -0
  56. data/spec/fixtures/sobject/sobject_find_error_response.json +6 -0
  57. data/spec/fixtures/sobject/sobject_find_success_response.json +29 -0
  58. data/spec/fixtures/sobject/upsert_created_success_response.json +5 -0
  59. data/spec/fixtures/sobject/upsert_error_response.json +6 -0
  60. data/spec/fixtures/sobject/upsert_multiple_error_response.json +4 -0
  61. data/spec/fixtures/sobject/upsert_updated_success_response.json +0 -0
  62. data/spec/fixtures/sobject/write_error_response.json +6 -0
  63. data/spec/integration/abstract_client_spec.rb +306 -0
  64. data/spec/integration/data/client_spec.rb +90 -0
  65. data/spec/spec_helper.rb +20 -0
  66. data/spec/support/client_integration.rb +45 -0
  67. data/spec/support/concerns.rb +18 -0
  68. data/spec/support/event_machine.rb +14 -0
  69. data/spec/support/fixture_helpers.rb +45 -0
  70. data/spec/support/matchers.rb +11 -0
  71. data/spec/support/middleware.rb +76 -0
  72. data/spec/support/mock_cache.rb +13 -0
  73. data/spec/unit/abstract_client_spec.rb +11 -0
  74. data/spec/unit/attachment_spec.rb +15 -0
  75. data/spec/unit/collection_spec.rb +52 -0
  76. data/spec/unit/concerns/api_spec.rb +244 -0
  77. data/spec/unit/concerns/authentication_spec.rb +98 -0
  78. data/spec/unit/concerns/base_spec.rb +42 -0
  79. data/spec/unit/concerns/caching_spec.rb +29 -0
  80. data/spec/unit/concerns/canvas_spec.rb +30 -0
  81. data/spec/unit/concerns/connection_spec.rb +22 -0
  82. data/spec/unit/config_spec.rb +99 -0
  83. data/spec/unit/data/client_spec.rb +10 -0
  84. data/spec/unit/mash_spec.rb +36 -0
  85. data/spec/unit/middleware/authentication/password_spec.rb +31 -0
  86. data/spec/unit/middleware/authentication/token_spec.rb +24 -0
  87. data/spec/unit/middleware/authentication_spec.rb +67 -0
  88. data/spec/unit/middleware/authorization_spec.rb +11 -0
  89. data/spec/unit/middleware/gzip_spec.rb +66 -0
  90. data/spec/unit/middleware/instance_url_spec.rb +24 -0
  91. data/spec/unit/middleware/logger_spec.rb +19 -0
  92. data/spec/unit/middleware/mashify_spec.rb +11 -0
  93. data/spec/unit/middleware/raise_error_spec.rb +32 -0
  94. data/spec/unit/signed_request_spec.rb +24 -0
  95. data/spec/unit/sobject_spec.rb +86 -0
  96. data/spec/unit/tooling/client_spec.rb +7 -0
  97. metadata +225 -65
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4a336e27a5dc02b776c7d3898a80ff1d51c0020
4
- data.tar.gz: d7c5c2eb05b464a0da43d7d92cd014831446c5b2
3
+ metadata.gz: c0777cd578c83c00d2e82e11381cf201beaa77fc
4
+ data.tar.gz: 53c8f26b935d9417311c2407a7e7e65f3a7d0531
5
5
  SHA512:
6
- metadata.gz: 3081785e27bc7dbd8d55dd481c179d35bee99f420912fc05178a8ee8e08183d0aebb47ab44507504b0710ebdb0d9b3113c21c8fdc073f3802718b4500ce75567
7
- data.tar.gz: 27e4897d37ab690d6faa5c82dd1a5c05f83fe1c196de559203f3a1a27ab65d89a734c17aafbad0021d490759b1a80d94bbd133df3afad4f538ddbd9fd5f99d4a
6
+ metadata.gz: 73424a61e0a4dc7cb3782757e2c016a1d487a52d53c3b4c0817089b30b68f8db3cb02304275bbdd131a54ca2b2fa1d15c54efd3e70d6580f8b0aff6c2e792e11
7
+ data.tar.gz: 8f010622a2019db48a46fcd766c2046aa059846885cb6eab6db34b340380f90fa2393c3bdfe58e53c1d62bffc1bf70f3429d1fcf8da1e81f598343564f91ac7c
@@ -0,0 +1,96 @@
1
+ ## 1.4.1 (Jun 18, 2013)
2
+
3
+ * Fixed a bug with HTTP 413 responses #75 @patronmanager
4
+
5
+ ## 1.4.0 (Jun 9, 2013)
6
+
7
+ * Added support for the tooling API.
8
+ * Fixed a bug with EMSynchrony adapter.
9
+ * Added proxy support.
10
+
11
+ ## 1.3.0 (Apr 6, 2013)
12
+
13
+ * Added support for lazily traversing paginated collections #61 by @nahiluhmot.
14
+
15
+ ## 1.2.0 (Mar 30, 2013)
16
+
17
+ * Added support for proxies #60 by @wazoo.
18
+
19
+ ## 1.1.0 (Mar 3, 2013)
20
+
21
+ * Added ability to download attachments easily.
22
+
23
+ Example
24
+
25
+ attachment = client.query('select Id, Name, Body from Attachment').first
26
+ File.open(attachment.Name, 'wb') { |f| f.write(attachment.Body) }
27
+
28
+ ## 1.0.6 (Feb 16, 2013)
29
+
30
+ * Added `url` method.
31
+
32
+ Example
33
+
34
+ # Url to a record id
35
+ client.url('0013000000rRz')
36
+ # => https://na1.salesforce.com/0013000000rRz
37
+
38
+ # Url to an object that responds to `to_sparam`
39
+ record = Struct.new(:to_sparam).new('0013000000rRz')
40
+ client.url('0013000000rRz')
41
+ # => https://na1.salesforce.com/0013000000rRz
42
+
43
+
44
+ ## 1.0.5 (Jan 11, 2013)
45
+
46
+ * Added `picklist_values` method.
47
+
48
+ Example
49
+
50
+ client.picklist_values('Account', 'Type')
51
+
52
+ client.picklist_values('Automobile__c', 'Model__c', :valid_for => 'Honda')
53
+
54
+ * Added CHANGELOG.md
55
+
56
+ ## 1.0.4 (Jan 8, 2013)
57
+
58
+ * `Sfdc::Client#inspect` now only prints out the options and not the
59
+ Faraday connection.
60
+
61
+ * The Faraday adapter is now configurabled:
62
+
63
+ Example:
64
+
65
+ Sfdc.configure do |config|
66
+ config.adapter = :excon
67
+ end
68
+
69
+ * The http connection read/open timeout is now configurabled.
70
+
71
+ Example:
72
+
73
+ Sfdc.configure do |config|
74
+ config.timeout = 300
75
+ end
76
+
77
+ ## 1.0.3 (Jan 7, 2013)
78
+
79
+ * Fixed typo in method call.
80
+
81
+ ## 1.0.2 (Jan 7, 2013)
82
+
83
+ * Minor cleanup.
84
+ * Moved decoding of signed requests into it's own class.
85
+
86
+ ## 1.0.1 (Dec 31, 2012)
87
+
88
+ * `username`, `password`, `security_token`, `client_id` and `client_secret`
89
+ options now obtain defaults from environment variables.
90
+ * Add `head` verb.
91
+
92
+ ## 1.0.0 (Dec 23, 2012)
93
+
94
+ * Default api version changed from 24.0 to 26.0.
95
+ * Fixed tests for streaming api to work with latest versions of faye.
96
+ * Added .find method to obtain all fields from an sobject.
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sfdc.gemspec
4
+ gemspec
5
+
6
+ gem 'rake'
7
+ gem 'jruby-openssl', :platforms => :jruby
8
+
9
+ group :development do
10
+ gem 'guard-rspec'
11
+ end
@@ -0,0 +1,11 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', all_on_start: false, all_after_pass: false do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch('spec/spec_helper.rb') { "spec" }
7
+
8
+ watch(%r{^lib/sfdc/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
9
+ watch(%r{^lib/sfdc/(.+)\.rb$}) { |m| "spec/integration/#{m[1]}_spec.rb" }
10
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
11
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Eric J. Holmes
2
+
3
+ With portions Copyright (c) 2013 Heroku (http://heroku.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,9 +1,19 @@
1
1
  # Sfdc
2
2
 
3
- Sfdc is a ruby gem for the [Salesforce REST api](http://www.salesforce.com/us/developer/docs/api_rest/index.htm).
3
+ _A ruby gem for the [Salesforce REST api](http://www.salesforce.com/us/developer/docs/api_rest/index.htm)._
4
4
 
5
- Features include:
5
+ ## Features
6
6
 
7
+ - A clean and modular architecture using [Faraday middleware](https://github.com/technoweenie/faraday) and [Hashie::Mash](https://github.com/intridea/hashie/tree/v1.2.0)'d responses.
8
+ - Support for interacting with multiple users from different orgs.
9
+ - Support for parent-to-child relationships.
10
+ - Support for aggregate queries.
11
+ - Support for the [Streaming API](#streaming)
12
+ - Support for blob data types.
13
+ - Support for GZIP compression.
14
+ - Support for [custom Apex REST endpoints](#custom-apex-rest-endpoints).
15
+ - Support for dependent picklists.
16
+ - Support for decoding [force.com Canvas](http://www.salesforce.com/us/developer/docs/platform_connectpre/canvas_framework.pdf) signed requests. (NEW!)
7
17
 
8
18
  ## Installation
9
19
 
@@ -22,7 +32,7 @@ Or install it yourself as:
22
32
  ## Usage
23
33
 
24
34
  Sfdc is designed with flexibility and ease of use in mind. By default, all api calls will
25
- return [Hashie::Mash](https://github.com/intridea/hashie/) objects,
35
+ return [Hashie::Mash](https://github.com/intridea/hashie/tree/v1.2.0) objects,
26
36
  so you can do things like `client.query('select Id, (select Name from Children__r) from Account').Children__r.first.Name`.
27
37
 
28
38
  ### Initialization
@@ -36,22 +46,22 @@ If you're using the gem to interact with a single org (maybe you're building som
36
46
  salesforce integration internally?) then you should use the username/password
37
47
  authentication method.
38
48
 
39
- #### OAuth token authentication
49
+ #### OAuth Token Authentication
40
50
 
41
51
  ```ruby
42
- client = Sfdc.new :oauth_token => 'oauth token',
43
- :instance_url => 'instance url'
52
+ client = Sfdc.new :instance_url => 'xx.salesforce.com',
53
+ :oauth_token => '...'
44
54
  ```
45
55
 
46
56
  Although the above will work, you'll probably want to take advantage of the
47
57
  (re)authentication middleware by specifying a refresh token, client id and client secret:
48
58
 
49
59
  ```ruby
50
- client = Sfdc.new :oauth_token => 'oauth token',
51
- :refresh_token => 'refresh token',
52
- :instance_url => 'instance url',
53
- :client_id => 'client_id',
54
- :client_secret => 'client_secret'
60
+ client = Sfdc.new :instance_url => 'xx.salesforce.com',
61
+ :oauth_token => '...',
62
+ :refresh_token => '...',
63
+ :client_id => '...',
64
+ :client_secret => '...'
55
65
  ```
56
66
 
57
67
  #### Username/Password authentication
@@ -59,11 +69,11 @@ client = Sfdc.new :oauth_token => 'oauth token',
59
69
  If you prefer to use a username and password to authenticate:
60
70
 
61
71
  ```ruby
62
- client = Sfdc.new :username => 'foo',
63
- :password => 'bar',
64
- :security_token => 'security token'
65
- :client_id => 'client_id',
66
- :client_secret => 'client_secret'
72
+ client = Sfdc.new :username => 'user@example.com',
73
+ :password => '...',
74
+ :security_token => '...',
75
+ :client_id => '...',
76
+ :client_secret => '...'
67
77
  ```
68
78
 
69
79
  You can also set the username, password, security token, client id and client
@@ -80,49 +90,39 @@ export SALESFORCE_CLIENT_SECRET="client secret"
80
90
  ```ruby
81
91
  client = Sfdc.new
82
92
  ```
93
+
83
94
  ### Proxy Support
84
95
 
85
96
  You can specify a http proxy using the :proxy_uri option, as follows:
86
97
 
87
98
  ```ruby
88
- client = Sfdc.new :username => 'foo',
89
- :password => 'bar',
90
- :security_token => 'security token'
91
- :client_id => 'client_id',
92
- :client_secret => 'client_secret',
93
- :proxy_uri => 'http://proxy.example.com:123'
99
+ client = Sfdc.new :proxy_uri => 'http://proxy.example.com:123'
94
100
  ```
95
- This paramter also will accept 'http://user@password:proxy.example.com:123' or using the environemnt variable PROXY_URI.
101
+
102
+ This paramter also will accept `http://user@password:proxy.example.com:123` or using the environemnt variable `PROXY_URI`.
96
103
 
97
104
  #### Sandbox Orgs
98
105
 
99
106
  You can connect to sandbox orgs by specifying a host. The default host is
100
- 'login.salesforce.com':
107
+ `login.salesforce.com`:
101
108
 
102
109
  ```ruby
103
110
  client = Sfdc.new :host => 'test.salesforce.com'
104
111
  ```
112
+ The host can also be set with the environment variable `SALESFORCE_HOST`.
105
113
 
106
- #### Global configuration
114
+ #### Global Configuration
107
115
 
108
116
  You can set any of the options passed into Sfdc.new globally:
109
117
 
110
118
  ```ruby
111
119
  Sfdc.configure do |config|
112
- config.client_id = 'foo'
120
+ config.client_id = 'foo'
113
121
  config.client_secret = 'bar'
114
122
  end
115
123
  ```
116
124
 
117
- ### Bang! methods
118
-
119
- All the CRUD methods (create, update, upsert, destroy) have equivalent methods with
120
- a ! at the end (create!, update!, upsert!, destroy!), which can be used if you need
121
- to do some custom error handling. The bang methods will raise exceptions, while the
122
- non-bang methods will return false in the event that an exception is raised. This
123
- works similarly to ActiveRecord.
124
-
125
- * * *
125
+ ---
126
126
 
127
127
  ### query
128
128
 
@@ -130,7 +130,7 @@ works similarly to ActiveRecord.
130
130
  accounts = client.query("select Id, Something__c from Account where Id = 'someid'")
131
131
  # => #<Sfdc::Collection >
132
132
 
133
- account = records.first
133
+ account = accounts.first
134
134
  # => #<Sfdc::SObject >
135
135
 
136
136
  account.sobject_type
@@ -172,67 +172,63 @@ client.search('FIND {genepoint} RETURNING Account (Name)').map(&:Name)
172
172
  ### create
173
173
 
174
174
  ```ruby
175
- # Add a new account
176
- client.create('Account', Name: 'Foobar Inc.')
177
- # => '0016000000MRatd'
175
+ client.create('Account', Name: 'Foobar Inc.') # => '0016000000MRatd'
178
176
  ```
179
177
 
180
178
  ### update
181
179
 
182
180
  ```ruby
183
- # Update the Account with Id '0016000000MRatd'
184
- client.update('Account', Id: '0016000000MRatd', Name: 'Whizbang Corp')
185
- # => true
181
+ client.update('Account', Id: '0016000000MRatd', Name: 'Whizbang Corp') # => true
186
182
  ```
187
183
 
188
184
  ### upsert
189
185
 
190
186
  ```ruby
191
- # Update the record with external ID of 12
192
- client.upsert('Account', 'External__c', External__c: 12, Name: 'Foobar')
187
+ client.upsert('Account', 'External__c', External__c: 12, Name: 'Foobar') # => true
193
188
  ```
194
189
 
195
190
  ### destroy
196
191
 
197
192
  ```ruby
198
- # Delete the Account with Id '0016000000MRatd'
199
- client.destroy('Account', '0016000000MRatd')
200
- # => true
193
+ client.destroy('Account', '0016000000MRatd') # => true
201
194
  ```
202
195
 
196
+ > All the CRUD methods (`create`, `update`, `upsert`, `destroy`) have equivalent methods with a ! at the end (`create!`, `update!`, `upsert!`, `destroy!`), which can be used if you need to do some custom error handling. The bang methods will raise exceptions, while the
197
+ non-bang methods will return false in the event that an exception is raised.
198
+
203
199
  ### describe
204
200
 
205
201
  ```ruby
206
- # get the global describe for all sobjects
207
- client.describe
208
- # => { ... }
209
-
210
- # get the describe for the Account object
211
- client.describe('Account')
212
- # => { ... }
202
+ client.describe # => { ... }
203
+ client.describe('Account') # => { ... }
213
204
  ```
214
205
 
215
- ### picklist\_values
206
+ ### describe_layouts
216
207
 
208
+ ```ruby
209
+ client.describe_layout('Account') # => { ... }
210
+ client.describe_layouts('Account', '012E0000000RHEp') # => { ... }
211
+ ```
212
+
213
+ ### picklist_values
217
214
 
218
215
  ```ruby
219
- client.picklist_values('Account', 'Type')
220
- # => [#<Sfdc::Mash label="Prospect" value="Prospect">]
216
+ client.picklist_values('Account', 'Type') # => [#<Sfdc::Mash label="Prospect" value="Prospect">]
221
217
 
222
- # Given a custom object named Automobile__c with picklist fields
223
- # Model__c and Make__c, where Model__c depends on the value of
224
- # Make__c.
218
+ # Given a custom object named Automobile__c
219
+ # with picklist fields Model__c and Make__c,
220
+ # where Model__c depends on the value of Make__c.
225
221
  client.picklist_values('Automobile__c', 'Model__c', :valid_for => 'Honda')
226
222
  # => [#<Sfdc::Mash label="Civic" value="Civic">, ... ]
227
223
  ```
228
224
 
229
- * * *
225
+ ---
230
226
 
231
227
  ### authenticate!
232
228
 
233
229
  Performs an authentication and returns the response. In general, calling this
234
230
  directly shouldn't be required, since the client will handle authentication for
235
- you automatically. This should only be used if you want to force
231
+ you automatically. This should only be used if you want to sfdc
236
232
  an authentication before using the streaming api, or you want to get some
237
233
  information about the user.
238
234
 
@@ -246,31 +242,29 @@ info.user_id
246
242
  # => '005E0000001eM4LIAU'
247
243
  ```
248
244
 
249
- * * *
250
-
251
245
  ### File Uploads
252
246
 
253
247
  Using the new [Blob Data](http://www.salesforce.com/us/developer/docs/api_rest/Content/dome_sobject_insert_update_blob.htm) api feature (500mb limit):
254
248
 
255
249
  ```ruby
250
+ image = Sfdc::UploadIO.new(File.expand_path('image.jpg', __FILE__), 'image/jpeg')
256
251
  client.create 'Document', FolderId: '00lE0000000FJ6H',
257
- Description: 'Document test',
258
- Name: 'My image',
259
- Body: Sfdc::UploadIO.new(File.expand_path('image.jpg', __FILE__), 'image/jpeg'))
252
+ Description: 'Document test',
253
+ Name: 'My image',
254
+ Body: image)
260
255
  ```
261
256
 
262
- Using base64 encoded data (37.5mb limit):
257
+ Using base64-encoded data _(37.5mb limit)_:
263
258
 
264
259
  ```ruby
260
+ data = Base64::encode64(File.read('image.jpg')
265
261
  client.create 'Document', FolderId: '00lE0000000FJ6H',
266
- Description: 'Document test',
267
- Name: 'My image',
268
- Body: Base64::encode64(File.read('image.jpg'))
262
+ Description: 'Document test',
263
+ Name: 'My image',
264
+ Body: data)
269
265
  ```
270
266
 
271
- _See also: http://www.salesforce.com/us/developer/docs/api_rest/Content/dome_sobject_insert_update_blob.htm_
272
-
273
- * * *
267
+ > See also: http://www.salesforce.com/us/developer/docs/api_rest/Content/dome_sobject_insert_update_blob.htm
274
268
 
275
269
  ### Downloading Attachments
276
270
 
@@ -281,8 +275,6 @@ attachment = client.query('select Id, Name, Body from Attachment').first
281
275
  File.open(attachment.Name, 'wb') { |f| f.write(attachment.Body) }
282
276
  ```
283
277
 
284
- * * *
285
-
286
278
  ### Custom Apex REST endpoints
287
279
 
288
280
  You can use Sfdc to interact with your custom REST endpoints, by using
@@ -304,7 +296,7 @@ global class RESTCaseController {
304
296
  }
305
297
  ```
306
298
 
307
- Then you could query the cases using Sfdc:
299
+ ...then you could query the cases using Sfdc:
308
300
 
309
301
  ```ruby
310
302
  client.get '/services/apexrest/FieldCase', :company => 'GenePoint'
@@ -315,7 +307,7 @@ client.get '/services/apexrest/FieldCase', :company => 'GenePoint'
315
307
 
316
308
  ### Streaming
317
309
 
318
- Sfdc supports the [Streaming API](http://wiki.developerforce.com/page/Getting_Started_with_the_Force.com_Streaming_API), and makes implementing
310
+ Sfdc supports the [Streaming API](http://wiki.developerforce.com/page/Getting_Started_with_the_Sfdc.com_Streaming_API), and makes implementing
319
311
  pub/sub with Salesforce a trivial task:
320
312
 
321
313
  ```ruby
@@ -347,9 +339,6 @@ EM.run {
347
339
  }
348
340
  ```
349
341
 
350
- Boom, you're now receiving push notifications when Accounts are
351
- created/updated.
352
-
353
342
  _See also: http://www.salesforce.com/us/developer/docs/api_streaming/index.htm_
354
343
 
355
344
  * * *
@@ -377,11 +366,9 @@ client.without_caching do
377
366
  end
378
367
  ```
379
368
 
380
- * * *
381
-
382
- ### Logging/Debugging/Instrumenting
369
+ ### Logging / Debugging / Instrumenting
383
370
 
384
- You can easily inspect what Sfdc is sending/receiving by setting
371
+ You can inspect what Sfdc is sending/receiving by setting
385
372
  `Sfdc.log = true`.
386
373
 
387
374
  ```ruby
@@ -389,18 +376,20 @@ Sfdc.log = true
389
376
  client = Sfdc.new.query('select Id, Name from Account')
390
377
  ```
391
378
 
392
- Another awesome feature about Sfdc is that, because it is based on
393
- Faraday, you can insert your own middleware. For example, if you were using
394
- Sfdc in a rails app, you can setup custom reporting to
395
- [Librato](https://github.com/librato/librato-rails) using ActiveSupport::Notifications:
379
+ Another awesome feature about sfdc is that, because it is based on Faraday, you can insert your own middleware.
380
+
381
+ For example, if you were using Sfdc in a Rails app, you can setup custom reporting to [Librato](https://github.com/librato/librato-rails) using ActiveSupport::Notifications:
396
382
 
397
383
  ```ruby
398
384
  client = Sfdc.new do |builder|
399
385
  builder.insert_after Sfdc::Middleware::InstanceURL,
400
- FaradayMiddleware::Instrumentation, name: 'request.salesforce'
386
+ FaradayMiddleware::Instrumentation, name: 'request.salesforce'
401
387
  end
388
+ ```
402
389
 
403
- # config/initializers/notifications.rb
390
+ #### config/initializers/notifications.rb
391
+
392
+ ```ruby
404
393
  ActiveSupport::Notifications.subscribe('request.salesforce') do |*args|
405
394
  event = ActiveSupport::Notifications::Event.new(*args)
406
395
  Librato.increment 'api.salesforce.request.total'
@@ -408,7 +397,7 @@ ActiveSupport::Notifications.subscribe('request.salesforce') do |*args|
408
397
  end
409
398
  ```
410
399
 
411
- ## Force.com Canvas
400
+ ## Sfdc.com Canvas
412
401
 
413
402
  You can use Sfdc to decode signed requests from Salesforce. See [the example app](https://gist.github.com/4052312).
414
403
 
@@ -421,11 +410,12 @@ call `Sfdc.tooling` instead of `Sfdc.new`:
421
410
  client = Sfdc.tooling(...)
422
411
  ```
423
412
 
413
+ ---
414
+
415
+ ## Contact
416
+
417
+ - Mattt Thompson <mattt@heroku.com>
424
418
 
425
- ## Contributing
419
+ ## License
426
420
 
427
- 1. Fork it
428
- 2. Create your feature branch (`git checkout -b my-new-feature`)
429
- 3. Commit your changes (`git commit -am 'Added some feature'`)
430
- 4. Push to the branch (`git push origin my-new-feature`)
431
- 5. Create new Pull Request
421
+ Sfdc is available under the MIT license. See the LICENSE file for more info.