restforce-db 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45c8f42546b14727f6746d891ebc15e9fe5acc06
4
- data.tar.gz: 99e54fb6d7b67edf48d4b4a5ee9e0d7c205aa72b
3
+ metadata.gz: a757b3b70679ca9163fa7a856cc8e9f7228ce335
4
+ data.tar.gz: 0d6b4a908dccf33b1c15ad3c919c162a6de3411b
5
5
  SHA512:
6
- metadata.gz: b814ffac84499269d33a1e7b7a44f35607eeec4348f3217e6ed519bc6eee0e215a26377d6723287118831a8b873b8f89766599d911d479318f782092e6184a06
7
- data.tar.gz: afe966194dbc86cf758ab1c89bf708f947f604de8d436ced5deb45babd80e92e1d922d18ddb61fe33387db444e2ae3dcb77ead5e1ef827b36ac88ab60ea6c114
6
+ metadata.gz: 09a9d4fd95e92f629ac74e10efbef8e77011fb646f5548c813bf1d0375fcfcb4cb86eaca3cf3a22c94ec878f10b2f2dc2d0400e6a05600dc1a721ac2b9ad0d00
7
+ data.tar.gz: 78875a23c150314c0101a25b30cf9cd5c9bd4292853390290bbb396e587c1f4a9f7ea2cf4f0db9d8db0e4f1b6d744d5e3b4a679c1b87bcc7d807a7bb25c53b0c
@@ -79,7 +79,10 @@ module Restforce
79
79
  when :salesforce
80
80
  @fields.each_with_object({}) do |(attribute, mapping), converted|
81
81
  next unless attributes.key?(attribute)
82
- converted[mapping] = attributes[attribute]
82
+ value = attributes[attribute]
83
+ value = value.respond_to?(:iso8601) ? value.utc.iso8601 : value
84
+
85
+ converted[mapping] = value
83
86
  end
84
87
  else
85
88
  raise ArgumentError
@@ -18,6 +18,10 @@ module Restforce
18
18
  # Public: Synchronize records for the current mapping from a Hash of
19
19
  # record descriptors to attributes.
20
20
  #
21
+ # NOTE: Synchronizer assumes that the propagation step has done its job
22
+ # correctly. If we can't locate a database record for a specific Salsforce
23
+ # ID, we assume it shouldn't be synchronized.
24
+ #
21
25
  # changes - A Hash, with keys composed of a Salesforce ID and model name,
22
26
  # with Restforce::DB::Accumulator objects as values.
23
27
  #
@@ -26,8 +30,12 @@ module Restforce
26
30
  changes.each do |(id, salesforce_model), accumulator|
27
31
  next unless salesforce_model == @mapping.salesforce_model
28
32
 
29
- update(@mapping.database_record_type.find(id), accumulator)
30
- update(@mapping.salesforce_record_type.find(id), accumulator)
33
+ database_instance = @mapping.database_record_type.find(id)
34
+ salesforce_instance = @mapping.salesforce_record_type.find(id)
35
+ next unless database_instance && salesforce_instance
36
+
37
+ update(database_instance, accumulator)
38
+ update(salesforce_instance, accumulator)
31
39
  end
32
40
  end
33
41
 
@@ -3,7 +3,7 @@ module Restforce
3
3
  # :nodoc:
4
4
  module DB
5
5
 
6
- VERSION = "1.0.2"
6
+ VERSION = "1.0.3"
7
7
 
8
8
  end
9
9
 
@@ -0,0 +1,197 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://<host>/services/oauth2/token
6
+ body:
7
+ encoding: US-ASCII
8
+ string: grant_type=password&client_id=<client_id>&client_secret=<client_secret>&username=<username>&password=<password><security_token>
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.9.1
12
+ Content-Type:
13
+ - application/x-www-form-urlencoded
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ Accept:
17
+ - "*/*"
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Date:
24
+ - Fri, 10 Apr 2015 18:16:05 GMT
25
+ Set-Cookie:
26
+ - BrowserId=pcw4QakVSumA7tABeMs79A;Path=/;Domain=.salesforce.com;Expires=Tue,
27
+ 09-Jun-2015 18:16:05 GMT
28
+ Expires:
29
+ - Thu, 01 Jan 1970 00:00:00 GMT
30
+ Pragma:
31
+ - no-cache
32
+ Cache-Control:
33
+ - no-cache, no-store
34
+ Content-Type:
35
+ - application/json;charset=UTF-8
36
+ Transfer-Encoding:
37
+ - chunked
38
+ body:
39
+ encoding: ASCII-8BIT
40
+ string: '{"id":"https://login.salesforce.com/id/00D1a000000H3O9EAK/0051a000000UGT8AAO","issued_at":"1428689765521","token_type":"Bearer","instance_url":"https://<host>","signature":"iVn8K79ySw/26GQM8/ZHlQ7tE1l2EUH+WGphHVWkQFg=","access_token":"00D1a000000H3O9!AQ4AQO48p7VCPJTqs85KtBx3kEBjPhP.lCvkGK3ayiFCcg2H2nbFwdKZaBetwWzVAndOSywkSvoT7_YZEmwLnhtbJ1A3E5NZ"}'
41
+ http_version:
42
+ recorded_at: Fri, 10 Apr 2015 18:16:05 GMT
43
+ - request:
44
+ method: post
45
+ uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c
46
+ body:
47
+ encoding: UTF-8
48
+ string: '{"Name":"Custom object","Example_Field__c":"Some sample text"}'
49
+ headers:
50
+ User-Agent:
51
+ - Faraday v0.9.1
52
+ Content-Type:
53
+ - application/json
54
+ Authorization:
55
+ - OAuth 00D1a000000H3O9!AQ4AQO48p7VCPJTqs85KtBx3kEBjPhP.lCvkGK3ayiFCcg2H2nbFwdKZaBetwWzVAndOSywkSvoT7_YZEmwLnhtbJ1A3E5NZ
56
+ Accept-Encoding:
57
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
58
+ Accept:
59
+ - "*/*"
60
+ response:
61
+ status:
62
+ code: 201
63
+ message: Created
64
+ headers:
65
+ Date:
66
+ - Fri, 10 Apr 2015 18:16:05 GMT
67
+ Set-Cookie:
68
+ - BrowserId=I0vlITthQ-GdMURdX_Eu4A;Path=/;Domain=.salesforce.com;Expires=Tue,
69
+ 09-Jun-2015 18:16:05 GMT
70
+ Expires:
71
+ - Thu, 01 Jan 1970 00:00:00 GMT
72
+ Sforce-Limit-Info:
73
+ - api-usage=58/15000
74
+ Location:
75
+ - "/services/data/v26.0/sobjects/CustomObject__c/a001a000001LXBfAAO"
76
+ Content-Type:
77
+ - application/json;charset=UTF-8
78
+ Transfer-Encoding:
79
+ - chunked
80
+ body:
81
+ encoding: ASCII-8BIT
82
+ string: '{"id":"a001a000001LXBfAAO","success":true,"errors":[]}'
83
+ http_version:
84
+ recorded_at: Fri, 10 Apr 2015 18:16:05 GMT
85
+ - request:
86
+ method: get
87
+ uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Name,%20Example_Field__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001LXBfAAO%27
88
+ body:
89
+ encoding: US-ASCII
90
+ string: ''
91
+ headers:
92
+ User-Agent:
93
+ - Faraday v0.9.1
94
+ Authorization:
95
+ - OAuth 00D1a000000H3O9!AQ4AQO48p7VCPJTqs85KtBx3kEBjPhP.lCvkGK3ayiFCcg2H2nbFwdKZaBetwWzVAndOSywkSvoT7_YZEmwLnhtbJ1A3E5NZ
96
+ Accept-Encoding:
97
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
98
+ Accept:
99
+ - "*/*"
100
+ response:
101
+ status:
102
+ code: 200
103
+ message: OK
104
+ headers:
105
+ Date:
106
+ - Fri, 10 Apr 2015 18:16:05 GMT
107
+ Set-Cookie:
108
+ - BrowserId=KoiOz0-gSYiQzd8NJ4uMRQ;Path=/;Domain=.salesforce.com;Expires=Tue,
109
+ 09-Jun-2015 18:16:05 GMT
110
+ Expires:
111
+ - Thu, 01 Jan 1970 00:00:00 GMT
112
+ Sforce-Limit-Info:
113
+ - api-usage=58/15000
114
+ Content-Type:
115
+ - application/json;charset=UTF-8
116
+ Transfer-Encoding:
117
+ - chunked
118
+ body:
119
+ encoding: ASCII-8BIT
120
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001LXBfAAO"},"Id":"a001a000001LXBfAAO","SystemModstamp":"2015-04-10T18:16:05.000+0000","Name":"Custom
121
+ object","Example_Field__c":"Some sample text"}]}'
122
+ http_version:
123
+ recorded_at: Fri, 10 Apr 2015 18:16:05 GMT
124
+ - request:
125
+ method: get
126
+ uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Name,%20Example_Field__c%20from%20CustomObject__c%20where%20Id%20=%20%27a001a000001LXBfAAO%27
127
+ body:
128
+ encoding: US-ASCII
129
+ string: ''
130
+ headers:
131
+ User-Agent:
132
+ - Faraday v0.9.1
133
+ Authorization:
134
+ - OAuth 00D1a000000H3O9!AQ4AQO48p7VCPJTqs85KtBx3kEBjPhP.lCvkGK3ayiFCcg2H2nbFwdKZaBetwWzVAndOSywkSvoT7_YZEmwLnhtbJ1A3E5NZ
135
+ Accept-Encoding:
136
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
137
+ Accept:
138
+ - "*/*"
139
+ response:
140
+ status:
141
+ code: 200
142
+ message: OK
143
+ headers:
144
+ Date:
145
+ - Fri, 10 Apr 2015 18:16:06 GMT
146
+ Set-Cookie:
147
+ - BrowserId=GS8k_s93SVmx-JpXvfVjPQ;Path=/;Domain=.salesforce.com;Expires=Tue,
148
+ 09-Jun-2015 18:16:06 GMT
149
+ Expires:
150
+ - Thu, 01 Jan 1970 00:00:00 GMT
151
+ Sforce-Limit-Info:
152
+ - api-usage=58/15000
153
+ Content-Type:
154
+ - application/json;charset=UTF-8
155
+ Transfer-Encoding:
156
+ - chunked
157
+ body:
158
+ encoding: ASCII-8BIT
159
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001LXBfAAO"},"Id":"a001a000001LXBfAAO","SystemModstamp":"2015-04-10T18:16:05.000+0000","Name":"Custom
160
+ object","Example_Field__c":"Some sample text"}]}'
161
+ http_version:
162
+ recorded_at: Fri, 10 Apr 2015 18:16:06 GMT
163
+ - request:
164
+ method: delete
165
+ uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c/a001a000001LXBfAAO
166
+ body:
167
+ encoding: US-ASCII
168
+ string: ''
169
+ headers:
170
+ User-Agent:
171
+ - Faraday v0.9.1
172
+ Authorization:
173
+ - OAuth 00D1a000000H3O9!AQ4AQO48p7VCPJTqs85KtBx3kEBjPhP.lCvkGK3ayiFCcg2H2nbFwdKZaBetwWzVAndOSywkSvoT7_YZEmwLnhtbJ1A3E5NZ
174
+ Accept-Encoding:
175
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
176
+ Accept:
177
+ - "*/*"
178
+ response:
179
+ status:
180
+ code: 204
181
+ message: No Content
182
+ headers:
183
+ Date:
184
+ - Fri, 10 Apr 2015 18:16:09 GMT
185
+ Set-Cookie:
186
+ - BrowserId=KJPi4MJTQ0mr8dA2ahBjEw;Path=/;Domain=.salesforce.com;Expires=Tue,
187
+ 09-Jun-2015 18:16:09 GMT
188
+ Expires:
189
+ - Thu, 01 Jan 1970 00:00:00 GMT
190
+ Sforce-Limit-Info:
191
+ - api-usage=58/15000
192
+ body:
193
+ encoding: UTF-8
194
+ string: ''
195
+ http_version:
196
+ recorded_at: Fri, 10 Apr 2015 18:16:09 GMT
197
+ recorded_with: VCR 2.9.3
@@ -55,6 +55,17 @@ describe Restforce::DB::AttributeMap do
55
55
  it "performs no special conversion for database columns" do
56
56
  expect(attribute_map.convert(database_model, attributes)).to_equal(attributes)
57
57
  end
58
+
59
+ describe "when one of the attributes is a Date or Time" do
60
+ let(:timestamp) { Time.now }
61
+ let(:attributes) { { column_one: timestamp } }
62
+
63
+ it "converts the attribute to an ISO-8601 string for Salesforce" do
64
+ expect(attribute_map.convert(salesforce_model, attributes)).to_equal(
65
+ fields[attributes.keys.first] => timestamp.iso8601,
66
+ )
67
+ end
68
+ end
58
69
  end
59
70
 
60
71
  describe "#convert_from_salesforce" do
@@ -20,6 +20,30 @@ describe Restforce::DB::Synchronizer do
20
20
  mapping.convert(salesforce_model, attributes),
21
21
  )
22
22
  end
23
+ let(:changes) { { [salesforce_id, salesforce_model] => accumulator } }
24
+ let(:new_attributes) do
25
+ {
26
+ "Name" => "Some new name",
27
+ "Example_Field__c" => "New sample text",
28
+ }
29
+ end
30
+ let(:accumulator) do
31
+ Restforce::DB::Accumulator.new.tap do |accumulator|
32
+ accumulator.store(Time.now, new_attributes)
33
+ end
34
+ end
35
+
36
+ describe "given a Salesforce record with no associated database record" do
37
+ before do
38
+ salesforce_id
39
+ synchronizer.run(changes)
40
+ end
41
+
42
+ it "does nothing for this specific mapping" do
43
+ record = mapping.salesforce_record_type.find(salesforce_id)
44
+ expect(record.attributes).to_equal attributes
45
+ end
46
+ end
23
47
 
24
48
  describe "given a Salesforce record with an associated database record" do
25
49
  let(:database_attributes) do
@@ -33,19 +57,6 @@ describe Restforce::DB::Synchronizer do
33
57
  database_model.create!(database_attributes.merge(salesforce_id: salesforce_id))
34
58
  end
35
59
 
36
- let(:changes) { { [salesforce_id, salesforce_model] => accumulator } }
37
- let(:new_attributes) do
38
- {
39
- "Name" => "Some new name",
40
- "Example_Field__c" => "New sample text",
41
- }
42
- end
43
- let(:accumulator) do
44
- Restforce::DB::Accumulator.new.tap do |accumulator|
45
- accumulator.store(Time.now, new_attributes)
46
- end
47
- end
48
-
49
60
  before do
50
61
  database_record
51
62
  synchronizer.run(changes)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restforce-db
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Horner
@@ -271,6 +271,7 @@ files:
271
271
  - test/cassettes/Restforce_DB_Strategies_Always/_build_/given_a_Salesforce_record/with_a_corresponding_database_record/does_not_want_to_build_a_new_record.yml
272
272
  - test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/updates_the_database_record.yml
273
273
  - test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/updates_the_salesforce_record.yml
274
+ - test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_no_associated_database_record/does_nothing_for_this_specific_mapping.yml
274
275
  - test/lib/restforce/db/accumulator_test.rb
275
276
  - test/lib/restforce/db/associations/active_record_test.rb
276
277
  - test/lib/restforce/db/attribute_map_test.rb