restforce-db 0.1.6 → 0.2.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 +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
|
|