restforce-db 0.1.6 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -8
- data/lib/generators/templates/migration.rb.tt +2 -0
- data/lib/restforce/db/command.rb +17 -4
- data/lib/restforce/db/instances/active_record.rb +16 -0
- data/lib/restforce/db/instances/base.rb +12 -2
- data/lib/restforce/db/instances/salesforce.rb +8 -0
- data/lib/restforce/db/record_types/active_record.rb +7 -7
- data/lib/restforce/db/record_types/base.rb +17 -5
- data/lib/restforce/db/record_types/salesforce.rb +2 -1
- data/lib/restforce/db/synchronizer.rb +1 -1
- data/lib/restforce/db/tracker.rb +44 -0
- data/lib/restforce/db/version.rb +1 -1
- data/lib/restforce/db/worker.rb +47 -16
- data/lib/restforce/db.rb +3 -1
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/when_synchronization_is_stale/updates_the_database_record.yml +197 -0
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_associated_database_record/when_synchronization_is_up-to-date/does_not_update_the_database_record.yml +234 -0
- data/test/lib/restforce/db/instances/active_record_test.rb +4 -0
- data/test/lib/restforce/db/record_types/active_record_test.rb +12 -8
- data/test/lib/restforce/db/synchronizer_test.rb +45 -14
- data/test/lib/restforce/db/tracker_test.rb +50 -0
- data/test/support/active_record.rb +4 -3
- metadata +6 -3
- data/test/cassettes/Restforce_DB_Synchronizer/_run/given_a_Salesforce_record_with_an_existing_record_in_the_database/updates_the_database_record.yml +0 -158
@@ -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
|
+
- Tue, 24 Mar 2015 20:01:29 GMT
|
25
|
+
Set-Cookie:
|
26
|
+
- BrowserId=d0G0Guz1Qb2zbGglgG-bpg;Path=/;Domain=.salesforce.com;Expires=Sat,
|
27
|
+
23-May-2015 20:01:29 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":"1427227289790","token_type":"Bearer","instance_url":"https://<host>","signature":"UOEfBh3JWDC/YB0aeGuqptZD4XM3RB62QBkis2zhaZk=","access_token":"00D1a000000H3O9!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ"}'
|
41
|
+
http_version:
|
42
|
+
recorded_at: Tue, 24 Mar 2015 20:01:29 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!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ
|
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
|
+
- Tue, 24 Mar 2015 20:01:30 GMT
|
67
|
+
Set-Cookie:
|
68
|
+
- BrowserId=S3WYcky7SpSBvnqYKq6sLg;Path=/;Domain=.salesforce.com;Expires=Sat,
|
69
|
+
23-May-2015 20:01:30 GMT
|
70
|
+
Expires:
|
71
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
72
|
+
Sforce-Limit-Info:
|
73
|
+
- api-usage=143/15000
|
74
|
+
Location:
|
75
|
+
- "/services/data/v26.0/sobjects/CustomObject__c/a001a000001IyUmAAK"
|
76
|
+
Content-Type:
|
77
|
+
- application/json;charset=UTF-8
|
78
|
+
Transfer-Encoding:
|
79
|
+
- chunked
|
80
|
+
body:
|
81
|
+
encoding: ASCII-8BIT
|
82
|
+
string: '{"id":"a001a000001IyUmAAK","success":true,"errors":[]}'
|
83
|
+
http_version:
|
84
|
+
recorded_at: Tue, 24 Mar 2015 20:01:30 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%27a001a000001IyUmAAK%27
|
88
|
+
body:
|
89
|
+
encoding: US-ASCII
|
90
|
+
string: ''
|
91
|
+
headers:
|
92
|
+
User-Agent:
|
93
|
+
- Faraday v0.9.1
|
94
|
+
Authorization:
|
95
|
+
- OAuth 00D1a000000H3O9!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ
|
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
|
+
- Tue, 24 Mar 2015 20:01:31 GMT
|
107
|
+
Set-Cookie:
|
108
|
+
- BrowserId=iCZa-rO2Qze8bD7-w5DqCw;Path=/;Domain=.salesforce.com;Expires=Sat,
|
109
|
+
23-May-2015 20:01:31 GMT
|
110
|
+
Expires:
|
111
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
112
|
+
Sforce-Limit-Info:
|
113
|
+
- api-usage=144/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/a001a000001IyUmAAK"},"Id":"a001a000001IyUmAAK","SystemModstamp":"2015-03-24T20:01:30.000+0000","Name":"Custom
|
121
|
+
object","Example_Field__c":"Some sample text"}]}'
|
122
|
+
http_version:
|
123
|
+
recorded_at: Tue, 24 Mar 2015 20:01:31 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%20SystemModstamp%20%3C=%202015-03-24T20:01:31Z
|
127
|
+
body:
|
128
|
+
encoding: US-ASCII
|
129
|
+
string: ''
|
130
|
+
headers:
|
131
|
+
User-Agent:
|
132
|
+
- Faraday v0.9.1
|
133
|
+
Authorization:
|
134
|
+
- OAuth 00D1a000000H3O9!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ
|
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
|
+
- Tue, 24 Mar 2015 20:01:32 GMT
|
146
|
+
Set-Cookie:
|
147
|
+
- BrowserId=6IY41Rg2TMWpO_MnI-4K6w;Path=/;Domain=.salesforce.com;Expires=Sat,
|
148
|
+
23-May-2015 20:01:32 GMT
|
149
|
+
Expires:
|
150
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
151
|
+
Sforce-Limit-Info:
|
152
|
+
- api-usage=144/15000
|
153
|
+
Content-Type:
|
154
|
+
- application/json;charset=UTF-8
|
155
|
+
Transfer-Encoding:
|
156
|
+
- chunked
|
157
|
+
body:
|
158
|
+
encoding: ASCII-8BIT
|
159
|
+
string: '{"totalSize":3,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001IjCFAA0"},"Id":"a001a000001IjCFAA0","SystemModstamp":"2015-03-24T08:25:04.000+0000","Name":"andrew@tablexi.com","Example_Field__c":null},{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001IjP2AAK"},"Id":"a001a000001IjP2AAK","SystemModstamp":"2015-03-24T08:27:33.000+0000","Name":"somebody+new@example.com","Example_Field__c":null},{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001IyUmAAK"},"Id":"a001a000001IyUmAAK","SystemModstamp":"2015-03-24T20:01:30.000+0000","Name":"Custom
|
160
|
+
object","Example_Field__c":"Some sample text"}]}'
|
161
|
+
http_version:
|
162
|
+
recorded_at: Tue, 24 Mar 2015 20:01:32 GMT
|
163
|
+
- request:
|
164
|
+
method: delete
|
165
|
+
uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c/a001a000001IyUmAAK
|
166
|
+
body:
|
167
|
+
encoding: US-ASCII
|
168
|
+
string: ''
|
169
|
+
headers:
|
170
|
+
User-Agent:
|
171
|
+
- Faraday v0.9.1
|
172
|
+
Authorization:
|
173
|
+
- OAuth 00D1a000000H3O9!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ
|
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
|
+
- Tue, 24 Mar 2015 20:01:34 GMT
|
185
|
+
Set-Cookie:
|
186
|
+
- BrowserId=MErmNS95SD62_a5q9qw3DA;Path=/;Domain=.salesforce.com;Expires=Sat,
|
187
|
+
23-May-2015 20:01:34 GMT
|
188
|
+
Expires:
|
189
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
190
|
+
Sforce-Limit-Info:
|
191
|
+
- api-usage=143/15000
|
192
|
+
body:
|
193
|
+
encoding: UTF-8
|
194
|
+
string: ''
|
195
|
+
http_version:
|
196
|
+
recorded_at: Tue, 24 Mar 2015 20:01:34 GMT
|
197
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,234 @@
|
|
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
|
+
- Tue, 24 Mar 2015 20:01:22 GMT
|
25
|
+
Set-Cookie:
|
26
|
+
- BrowserId=66vMVxWoT9GxGXx0f_L2PA;Path=/;Domain=.salesforce.com;Expires=Sat,
|
27
|
+
23-May-2015 20:01:22 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":"1427227282626","token_type":"Bearer","instance_url":"https://<host>","signature":"nl501aqDiCh/Z5v8a3yRZ50Ft8S1uv7xIxbradmSMjY=","access_token":"00D1a000000H3O9!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ"}'
|
41
|
+
http_version:
|
42
|
+
recorded_at: Tue, 24 Mar 2015 20:01:22 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!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ
|
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
|
+
- Tue, 24 Mar 2015 20:01:23 GMT
|
67
|
+
Set-Cookie:
|
68
|
+
- BrowserId=gxq8laTeS4a7aMtwB1kg7w;Path=/;Domain=.salesforce.com;Expires=Sat,
|
69
|
+
23-May-2015 20:01:23 GMT
|
70
|
+
Expires:
|
71
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
72
|
+
Sforce-Limit-Info:
|
73
|
+
- api-usage=143/15000
|
74
|
+
Location:
|
75
|
+
- "/services/data/v26.0/sobjects/CustomObject__c/a001a000001IyUhAAK"
|
76
|
+
Content-Type:
|
77
|
+
- application/json;charset=UTF-8
|
78
|
+
Transfer-Encoding:
|
79
|
+
- chunked
|
80
|
+
body:
|
81
|
+
encoding: ASCII-8BIT
|
82
|
+
string: '{"id":"a001a000001IyUhAAK","success":true,"errors":[]}'
|
83
|
+
http_version:
|
84
|
+
recorded_at: Tue, 24 Mar 2015 20:01:23 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%20SystemModstamp%20%3C=%202015-03-24T20:01:23Z
|
88
|
+
body:
|
89
|
+
encoding: US-ASCII
|
90
|
+
string: ''
|
91
|
+
headers:
|
92
|
+
User-Agent:
|
93
|
+
- Faraday v0.9.1
|
94
|
+
Authorization:
|
95
|
+
- OAuth 00D1a000000H3O9!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ
|
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
|
+
- Tue, 24 Mar 2015 20:01:24 GMT
|
107
|
+
Set-Cookie:
|
108
|
+
- BrowserId=32lYUckHSQeMtLFmz9K8Tg;Path=/;Domain=.salesforce.com;Expires=Sat,
|
109
|
+
23-May-2015 20:01:24 GMT
|
110
|
+
Expires:
|
111
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
112
|
+
Sforce-Limit-Info:
|
113
|
+
- api-usage=143/15000
|
114
|
+
Content-Type:
|
115
|
+
- application/json;charset=UTF-8
|
116
|
+
Transfer-Encoding:
|
117
|
+
- chunked
|
118
|
+
body:
|
119
|
+
encoding: ASCII-8BIT
|
120
|
+
string: '{"totalSize":3,"done":true,"records":[{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001IjCFAA0"},"Id":"a001a000001IjCFAA0","SystemModstamp":"2015-03-24T08:25:04.000+0000","Name":"andrew@tablexi.com","Example_Field__c":null},{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001IjP2AAK"},"Id":"a001a000001IjP2AAK","SystemModstamp":"2015-03-24T08:27:33.000+0000","Name":"somebody+new@example.com","Example_Field__c":null},{"attributes":{"type":"CustomObject__c","url":"/services/data/v26.0/sobjects/CustomObject__c/a001a000001IyUhAAK"},"Id":"a001a000001IyUhAAK","SystemModstamp":"2015-03-24T20:01:23.000+0000","Name":"Custom
|
121
|
+
object","Example_Field__c":"Some sample text"}]}'
|
122
|
+
http_version:
|
123
|
+
recorded_at: Tue, 24 Mar 2015 20:01:24 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%27a001a000001IyUhAAK%27
|
127
|
+
body:
|
128
|
+
encoding: US-ASCII
|
129
|
+
string: ''
|
130
|
+
headers:
|
131
|
+
User-Agent:
|
132
|
+
- Faraday v0.9.1
|
133
|
+
Authorization:
|
134
|
+
- OAuth 00D1a000000H3O9!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ
|
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
|
+
- Tue, 24 Mar 2015 20:01:25 GMT
|
146
|
+
Set-Cookie:
|
147
|
+
- BrowserId=Vw8J1bAaRYuZY_Jnw1nTIg;Path=/;Domain=.salesforce.com;Expires=Sat,
|
148
|
+
23-May-2015 20:01:25 GMT
|
149
|
+
Expires:
|
150
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
151
|
+
Sforce-Limit-Info:
|
152
|
+
- api-usage=143/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/a001a000001IyUhAAK"},"Id":"a001a000001IyUhAAK","SystemModstamp":"2015-03-24T20:01:23.000+0000","Name":"Custom
|
160
|
+
object","Example_Field__c":"Some sample text"}]}'
|
161
|
+
http_version:
|
162
|
+
recorded_at: Tue, 24 Mar 2015 20:01:25 GMT
|
163
|
+
- request:
|
164
|
+
method: patch
|
165
|
+
uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c/a001a000001IyUhAAK
|
166
|
+
body:
|
167
|
+
encoding: UTF-8
|
168
|
+
string: '{"Name":"Some existing name","Example_Field__c":"Some existing sample
|
169
|
+
text"}'
|
170
|
+
headers:
|
171
|
+
User-Agent:
|
172
|
+
- Faraday v0.9.1
|
173
|
+
Content-Type:
|
174
|
+
- application/json
|
175
|
+
Authorization:
|
176
|
+
- OAuth 00D1a000000H3O9!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ
|
177
|
+
Accept-Encoding:
|
178
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
179
|
+
Accept:
|
180
|
+
- "*/*"
|
181
|
+
response:
|
182
|
+
status:
|
183
|
+
code: 204
|
184
|
+
message: No Content
|
185
|
+
headers:
|
186
|
+
Date:
|
187
|
+
- Tue, 24 Mar 2015 20:01:27 GMT
|
188
|
+
Set-Cookie:
|
189
|
+
- BrowserId=mrm2T-eMR3iEiP-JY4RxEg;Path=/;Domain=.salesforce.com;Expires=Sat,
|
190
|
+
23-May-2015 20:01:27 GMT
|
191
|
+
Expires:
|
192
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
193
|
+
Sforce-Limit-Info:
|
194
|
+
- api-usage=143/15000
|
195
|
+
body:
|
196
|
+
encoding: UTF-8
|
197
|
+
string: ''
|
198
|
+
http_version:
|
199
|
+
recorded_at: Tue, 24 Mar 2015 20:01:27 GMT
|
200
|
+
- request:
|
201
|
+
method: delete
|
202
|
+
uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c/a001a000001IyUhAAK
|
203
|
+
body:
|
204
|
+
encoding: US-ASCII
|
205
|
+
string: ''
|
206
|
+
headers:
|
207
|
+
User-Agent:
|
208
|
+
- Faraday v0.9.1
|
209
|
+
Authorization:
|
210
|
+
- OAuth 00D1a000000H3O9!AQ4AQLW7LvL9F5lVipVJl8BHs21lRfayiAsI3XyWdaLNmdGsBgdOTwyLzmSBrmoKxyILlRDx._h5Oz.OpUoj6pYbfHsCYjrQ
|
211
|
+
Accept-Encoding:
|
212
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
213
|
+
Accept:
|
214
|
+
- "*/*"
|
215
|
+
response:
|
216
|
+
status:
|
217
|
+
code: 204
|
218
|
+
message: No Content
|
219
|
+
headers:
|
220
|
+
Date:
|
221
|
+
- Tue, 24 Mar 2015 20:01:28 GMT
|
222
|
+
Set-Cookie:
|
223
|
+
- BrowserId=xXw1CTnhQK623u5W_v90nw;Path=/;Domain=.salesforce.com;Expires=Sat,
|
224
|
+
23-May-2015 20:01:28 GMT
|
225
|
+
Expires:
|
226
|
+
- Thu, 01 Jan 1970 00:00:00 GMT
|
227
|
+
Sforce-Limit-Info:
|
228
|
+
- api-usage=144/15000
|
229
|
+
body:
|
230
|
+
encoding: UTF-8
|
231
|
+
string: ''
|
232
|
+
http_version:
|
233
|
+
recorded_at: Tue, 24 Mar 2015 20:01:28 GMT
|
234
|
+
recorded_with: VCR 2.9.3
|
@@ -22,6 +22,10 @@ describe Restforce::DB::Instances::ActiveRecord do
|
|
22
22
|
it "updates the record in Salesforce with the passed attributes" do
|
23
23
|
expect(record.reload.example).to_equal text
|
24
24
|
end
|
25
|
+
|
26
|
+
it "bumps the record's synchronized_at timestamp" do
|
27
|
+
expect(record.reload.synchronized_at).to_not_be_nil
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
describe "#copy!" do
|
@@ -10,8 +10,9 @@ describe Restforce::DB::RecordTypes::ActiveRecord do
|
|
10
10
|
|
11
11
|
describe "#sync!" do
|
12
12
|
let(:sync_from) do
|
13
|
-
Struct.new(:id, :attributes).new(
|
13
|
+
Struct.new(:id, :last_update, :attributes).new(
|
14
14
|
salesforce_id,
|
15
|
+
Time.now,
|
15
16
|
name: "Some name",
|
16
17
|
example: "Some text",
|
17
18
|
)
|
@@ -28,32 +29,34 @@ describe Restforce::DB::RecordTypes::ActiveRecord do
|
|
28
29
|
expect(instance.salesforce_id).to_equal salesforce_id
|
29
30
|
expect(instance.name).to_equal sync_from.attributes[:name]
|
30
31
|
expect(instance.example).to_equal sync_from.attributes[:example]
|
32
|
+
expect(instance.synchronized_at).to_not_be_nil
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
36
|
describe "with an existing database record" do
|
35
|
-
let(:sync_to) do
|
37
|
+
let!(:sync_to) do
|
36
38
|
CustomObject.create!(
|
37
|
-
name:
|
38
|
-
example:
|
39
|
-
salesforce_id:
|
39
|
+
name: "Existing name",
|
40
|
+
example: "Existing sample text",
|
41
|
+
salesforce_id: salesforce_id,
|
42
|
+
synchronized_at: Time.now,
|
40
43
|
)
|
41
44
|
end
|
42
45
|
|
43
|
-
before { sync_to }
|
44
|
-
|
45
46
|
it "updates the existing database record" do
|
46
47
|
expect(instance).to_equal sync_to.reload
|
47
48
|
expect(instance.name).to_equal sync_from.attributes[:name]
|
48
49
|
expect(instance.example).to_equal sync_from.attributes[:example]
|
50
|
+
expect(instance.synchronized_at).to_not_be_nil
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
55
|
describe "#create!" do
|
54
56
|
let(:create_from) do
|
55
|
-
Struct.new(:id, :attributes).new(
|
57
|
+
Struct.new(:id, :last_update, :attributes).new(
|
56
58
|
salesforce_id,
|
59
|
+
Time.now,
|
57
60
|
name: "Some name",
|
58
61
|
example: "Some text",
|
59
62
|
)
|
@@ -68,6 +71,7 @@ describe Restforce::DB::RecordTypes::ActiveRecord do
|
|
68
71
|
expect(instance.salesforce_id).to_equal salesforce_id
|
69
72
|
expect(instance.name).to_equal create_from.attributes[:name]
|
70
73
|
expect(instance.example).to_equal create_from.attributes[:example]
|
74
|
+
expect(instance.synchronized_at).to_not_be_nil
|
71
75
|
end
|
72
76
|
end
|
73
77
|
|
@@ -9,6 +9,15 @@ describe Restforce::DB::Synchronizer do
|
|
9
9
|
let(:salesforce_type) { Restforce::DB::RecordTypes::Salesforce.new("CustomObject__c", mapping) }
|
10
10
|
let(:synchronizer) { Restforce::DB::Synchronizer.new(database_type, salesforce_type) }
|
11
11
|
|
12
|
+
describe "#initialize" do
|
13
|
+
before { Restforce::DB.last_run = Time.now }
|
14
|
+
after { Restforce::DB.last_run = nil }
|
15
|
+
|
16
|
+
it "prefills the Synchronizer's last_run timestamp with the global configuration" do
|
17
|
+
expect(synchronizer.last_run).to_equal Restforce::DB.last_run
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
12
21
|
describe "#run", vcr: { match_requests_on: [:method, VCR.request_matchers.uri_without_param(:q)] } do
|
13
22
|
let(:attributes) do
|
14
23
|
{
|
@@ -57,26 +66,48 @@ describe Restforce::DB::Synchronizer do
|
|
57
66
|
end
|
58
67
|
end
|
59
68
|
|
60
|
-
describe "given a Salesforce record with an
|
69
|
+
describe "given a Salesforce record with an associated database record" do
|
70
|
+
let!(:database_attributes) do
|
71
|
+
{
|
72
|
+
name: "Some existing name",
|
73
|
+
example: "Some existing sample text",
|
74
|
+
synchronized_at: Time.now,
|
75
|
+
}
|
76
|
+
end
|
61
77
|
let(:database_record) do
|
62
|
-
CustomObject.create!(
|
63
|
-
name: "Some existing name",
|
64
|
-
example: "Some existing sample text",
|
65
|
-
salesforce_id: salesforce_id,
|
66
|
-
)
|
78
|
+
CustomObject.create!(database_attributes.merge(salesforce_id: salesforce_id))
|
67
79
|
end
|
68
80
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
81
|
+
describe "when synchronization is stale" do
|
82
|
+
before do
|
83
|
+
# Set the synchronization timestamp to 5 seconds before the Salesforce
|
84
|
+
# modification timestamp.
|
85
|
+
updated = salesforce_type.find(salesforce_id).last_update
|
86
|
+
database_record.update!(synchronized_at: updated - 5)
|
87
|
+
|
88
|
+
synchronizer.run
|
89
|
+
end
|
90
|
+
|
91
|
+
it "updates the database record" do
|
92
|
+
record = database_record.reload
|
93
|
+
|
94
|
+
expect(record.name).to_equal attributes[:name]
|
95
|
+
expect(record.example).to_equal attributes[:example]
|
96
|
+
end
|
73
97
|
end
|
74
98
|
|
75
|
-
|
76
|
-
|
99
|
+
describe "when synchronization is up-to-date" do
|
100
|
+
before do
|
101
|
+
database_record.touch(:synchronized_at)
|
102
|
+
synchronizer.run
|
103
|
+
end
|
77
104
|
|
78
|
-
|
79
|
-
|
105
|
+
it "does not update the database record" do
|
106
|
+
record = database_record.reload
|
107
|
+
|
108
|
+
expect(record.name).to_equal database_attributes[:name]
|
109
|
+
expect(record.example).to_equal database_attributes[:example]
|
110
|
+
end
|
80
111
|
end
|
81
112
|
end
|
82
113
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative "../../../test_helper"
|
2
|
+
|
3
|
+
describe Restforce::DB::Tracker do
|
4
|
+
let(:file) { Tempfile.new(".restforce-db") }
|
5
|
+
let(:tracker) { Restforce::DB::Tracker.new(file.path) }
|
6
|
+
let(:runtime) { Time.now }
|
7
|
+
|
8
|
+
after { Restforce::DB.last_run = nil }
|
9
|
+
|
10
|
+
describe "#initialize" do
|
11
|
+
|
12
|
+
describe "when no timestamp has been recorded" do
|
13
|
+
before { tracker }
|
14
|
+
|
15
|
+
it "does not initialize Restforce::DB.last_run" do
|
16
|
+
expect(Restforce::DB.last_run).to_be_nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "when a timestamp has been recorded in the file" do
|
21
|
+
before do
|
22
|
+
file.print runtime.iso8601
|
23
|
+
file.rewind
|
24
|
+
|
25
|
+
tracker
|
26
|
+
end
|
27
|
+
|
28
|
+
it "initializes Restforce::DB.last_run to the recorded time" do
|
29
|
+
expect(Restforce::DB.last_run.to_i).to_equal runtime.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
it "initializes the tracker's last_run to the recorded time" do
|
33
|
+
expect(tracker.last_run.to_i).to_equal runtime.to_i
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#track" do
|
39
|
+
before { tracker.track runtime }
|
40
|
+
|
41
|
+
it "records the supplied timestamp in the file" do
|
42
|
+
expect(file.read).to_equal runtime.iso8601
|
43
|
+
end
|
44
|
+
|
45
|
+
it "updates the tracker's last_run to the recorded time" do
|
46
|
+
expect(tracker.last_run.to_i).to_equal runtime.to_i
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -8,9 +8,10 @@ ActiveRecord::Base.establish_connection(
|
|
8
8
|
|
9
9
|
ActiveRecord::Schema.define do
|
10
10
|
create_table :custom_objects do |table|
|
11
|
-
table.column :name,
|
12
|
-
table.column :example,
|
13
|
-
table.column :salesforce_id,
|
11
|
+
table.column :name, :string
|
12
|
+
table.column :example, :string
|
13
|
+
table.column :salesforce_id, :string
|
14
|
+
table.column :synchronized_at, :datetime
|
14
15
|
table.timestamps null: false
|
15
16
|
end
|
16
17
|
|