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.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +11 -8
  3. data/lib/generators/templates/migration.rb.tt +2 -0
  4. data/lib/restforce/db/command.rb +17 -4
  5. data/lib/restforce/db/instances/active_record.rb +16 -0
  6. data/lib/restforce/db/instances/base.rb +12 -2
  7. data/lib/restforce/db/instances/salesforce.rb +8 -0
  8. data/lib/restforce/db/record_types/active_record.rb +7 -7
  9. data/lib/restforce/db/record_types/base.rb +17 -5
  10. data/lib/restforce/db/record_types/salesforce.rb +2 -1
  11. data/lib/restforce/db/synchronizer.rb +1 -1
  12. data/lib/restforce/db/tracker.rb +44 -0
  13. data/lib/restforce/db/version.rb +1 -1
  14. data/lib/restforce/db/worker.rb +47 -16
  15. data/lib/restforce/db.rb +3 -1
  16. 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
  17. 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
  18. data/test/lib/restforce/db/instances/active_record_test.rb +4 -0
  19. data/test/lib/restforce/db/record_types/active_record_test.rb +12 -8
  20. data/test/lib/restforce/db/synchronizer_test.rb +45 -14
  21. data/test/lib/restforce/db/tracker_test.rb +50 -0
  22. data/test/support/active_record.rb +4 -3
  23. metadata +6 -3
  24. 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: "Existing name",
38
- example: "Existing sample text",
39
- salesforce_id: 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 existing record in the database" do
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
- before do
70
- database_record
71
- salesforce_id
72
- synchronizer.run
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
- it "updates the database record" do
76
- record = database_record.reload
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
- expect(record.name).to_equal attributes[:name]
79
- expect(record.example).to_equal attributes[:example]
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, :string
12
- table.column :example, :string
13
- table.column :salesforce_id, :string
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