restforce-db 1.0.4 → 1.1.0

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +38 -22
  3. data/lib/restforce/db/associations/base.rb +152 -0
  4. data/lib/restforce/db/associations/belongs_to.rb +70 -0
  5. data/lib/restforce/db/associations/foreign_key.rb +80 -0
  6. data/lib/restforce/db/associations/has_many.rb +37 -0
  7. data/lib/restforce/db/associations/has_one.rb +33 -0
  8. data/lib/restforce/db/dsl.rb +25 -13
  9. data/lib/restforce/db/mapping.rb +2 -3
  10. data/lib/restforce/db/record_types/active_record.rb +3 -8
  11. data/lib/restforce/db/record_types/salesforce.rb +23 -8
  12. data/lib/restforce/db/strategies/associated.rb +58 -0
  13. data/lib/restforce/db/version.rb +1 -1
  14. data/lib/restforce/db.rb +6 -1
  15. data/restforce-db.gemspec +0 -1
  16. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_build/returns_an_associated_record_populated_with_the_Salesforce_attributes.yml +271 -0
  17. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_synced_for_/when_a_matching_associated_record_has_been_synchronized/returns_true.yml +271 -0
  18. data/test/cassettes/Restforce_DB_Associations_BelongsTo/with_an_inverse_mapping/_synced_for_/when_no_matching_associated_record_has_been_synchronized/returns_false.yml +271 -0
  19. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_build/builds_a_number_of_associated_records_from_the_data_in_Salesforce.yml +439 -0
  20. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_synced_for_/when_a_matching_associated_record_has_been_synchronized/returns_true.yml +439 -0
  21. data/test/cassettes/Restforce_DB_Associations_HasMany/with_an_inverse_mapping/_synced_for_/when_no_matching_associated_record_has_been_synchronized/returns_false.yml +196 -0
  22. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_build/returns_an_associated_record_populated_with_the_Salesforce_attributes.yml +271 -0
  23. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_synced_for_/when_a_matching_associated_record_has_been_synchronized/returns_true.yml +271 -0
  24. data/test/cassettes/Restforce_DB_Associations_HasOne/with_an_inverse_mapping/_synced_for_/when_no_matching_associated_record_has_been_synchronized/returns_false.yml +271 -0
  25. data/test/cassettes/Restforce_DB_Strategies_Associated/_build_/given_an_inverse_mapping/with_a_synchronized_association_record/wants_to_build_a_new_record.yml +275 -0
  26. data/test/cassettes/Restforce_DB_Strategies_Associated/_build_/given_an_inverse_mapping/with_an_existing_database_record/does_not_want_to_build_a_new_record.yml +237 -0
  27. data/test/cassettes/Restforce_DB_Strategies_Associated/_build_/given_an_inverse_mapping/with_no_synchronized_association_record/does_not_want_to_build_a_new_record.yml +275 -0
  28. data/test/lib/restforce/db/associations/belongs_to_test.rb +82 -0
  29. data/test/lib/restforce/db/associations/has_many_test.rb +96 -0
  30. data/test/lib/restforce/db/associations/has_one_test.rb +80 -0
  31. data/test/lib/restforce/db/dsl_test.rb +22 -3
  32. data/test/lib/restforce/db/mapping_test.rb +10 -8
  33. data/test/lib/restforce/db/record_types/active_record_test.rb +12 -5
  34. data/test/lib/restforce/db/runner_test.rb +2 -3
  35. data/test/lib/restforce/db/strategies/always_test.rb +2 -2
  36. data/test/lib/restforce/db/strategies/associated_test.rb +78 -0
  37. data/test/lib/restforce/db/strategies/passive_test.rb +1 -1
  38. data/test/lib/restforce/db/tracker_test.rb +0 -2
  39. data/test/support/active_record.rb +25 -2
  40. data/test/support/salesforce.rb +1 -1
  41. data/test/support/utilities.rb +5 -7
  42. data/test/test_helper.rb +0 -1
  43. metadata +24 -18
  44. data/lib/restforce/db/associations/active_record.rb +0 -68
  45. data/test/lib/restforce/db/associations/active_record_test.rb +0 -43
@@ -0,0 +1,237 @@
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
+ - Sat, 11 Apr 2015 06:43:08 GMT
25
+ Set-Cookie:
26
+ - BrowserId=kncqiWysTfyQJadJaRa7UA;Path=/;Domain=.salesforce.com;Expires=Wed,
27
+ 10-Jun-2015 06:43:08 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":"1428734589061","token_type":"Bearer","instance_url":"https://<host>","signature":"m7X5wKIMbwHnUlVdcdtxbIwCECW4Yq8Q91BjPfqF68g=","access_token":"00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx"}'
41
+ http_version:
42
+ recorded_at: Sat, 11 Apr 2015 06:43:09 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":"Sample object"}'
49
+ headers:
50
+ User-Agent:
51
+ - Faraday v0.9.1
52
+ Content-Type:
53
+ - application/json
54
+ Authorization:
55
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
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
+ - Sat, 11 Apr 2015 06:43:10 GMT
67
+ Set-Cookie:
68
+ - BrowserId=bTsYI43_Tv-pk6GLS7lg2g;Path=/;Domain=.salesforce.com;Expires=Wed,
69
+ 10-Jun-2015 06:43:10 GMT
70
+ Expires:
71
+ - Thu, 01 Jan 1970 00:00:00 GMT
72
+ Sforce-Limit-Info:
73
+ - api-usage=154/15000
74
+ Location:
75
+ - "/services/data/v26.0/sobjects/CustomObject__c/a001a000001LXq7AAG"
76
+ Content-Type:
77
+ - application/json;charset=UTF-8
78
+ Transfer-Encoding:
79
+ - chunked
80
+ body:
81
+ encoding: ASCII-8BIT
82
+ string: '{"id":"a001a000001LXq7AAG","success":true,"errors":[]}'
83
+ http_version:
84
+ recorded_at: Sat, 11 Apr 2015 06:43:10 GMT
85
+ - request:
86
+ method: post
87
+ uri: https://<host>/services/data/v26.0/sobjects/CustomObjectDetail__c
88
+ body:
89
+ encoding: UTF-8
90
+ string: '{"CustomObject__c":"a001a000001LXq7AAG"}'
91
+ headers:
92
+ User-Agent:
93
+ - Faraday v0.9.1
94
+ Content-Type:
95
+ - application/json
96
+ Authorization:
97
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
98
+ Accept-Encoding:
99
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
100
+ Accept:
101
+ - "*/*"
102
+ response:
103
+ status:
104
+ code: 201
105
+ message: Created
106
+ headers:
107
+ Date:
108
+ - Sat, 11 Apr 2015 06:43:11 GMT
109
+ Set-Cookie:
110
+ - BrowserId=Lhfp2cMxRoSCH0nS76hilw;Path=/;Domain=.salesforce.com;Expires=Wed,
111
+ 10-Jun-2015 06:43:11 GMT
112
+ Expires:
113
+ - Thu, 01 Jan 1970 00:00:00 GMT
114
+ Sforce-Limit-Info:
115
+ - api-usage=154/15000
116
+ Location:
117
+ - "/services/data/v26.0/sobjects/CustomObjectDetail__c/a011a000000gyxRAAQ"
118
+ Content-Type:
119
+ - application/json;charset=UTF-8
120
+ Transfer-Encoding:
121
+ - chunked
122
+ body:
123
+ encoding: ASCII-8BIT
124
+ string: '{"id":"a011a000000gyxRAAQ","success":true,"errors":[]}'
125
+ http_version:
126
+ recorded_at: Sat, 11 Apr 2015 06:43:11 GMT
127
+ - request:
128
+ method: get
129
+ uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Name,%20CustomObject__c%20from%20CustomObjectDetail__c%20where%20Id%20=%20%27a011a000000gyxRAAQ%27
130
+ body:
131
+ encoding: US-ASCII
132
+ string: ''
133
+ headers:
134
+ User-Agent:
135
+ - Faraday v0.9.1
136
+ Authorization:
137
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
138
+ Accept-Encoding:
139
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
140
+ Accept:
141
+ - "*/*"
142
+ response:
143
+ status:
144
+ code: 200
145
+ message: OK
146
+ headers:
147
+ Date:
148
+ - Sat, 11 Apr 2015 06:43:12 GMT
149
+ Set-Cookie:
150
+ - BrowserId=YS6CyteqTZKGh7PRTbMr0Q;Path=/;Domain=.salesforce.com;Expires=Wed,
151
+ 10-Jun-2015 06:43:12 GMT
152
+ Expires:
153
+ - Thu, 01 Jan 1970 00:00:00 GMT
154
+ Sforce-Limit-Info:
155
+ - api-usage=154/15000
156
+ Content-Type:
157
+ - application/json;charset=UTF-8
158
+ Transfer-Encoding:
159
+ - chunked
160
+ body:
161
+ encoding: ASCII-8BIT
162
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObjectDetail__c","url":"/services/data/v26.0/sobjects/CustomObjectDetail__c/a011a000000gyxRAAQ"},"Id":"a011a000000gyxRAAQ","SystemModstamp":"2015-04-11T06:43:11.000+0000","Name":"a011a000000gyxR","CustomObject__c":"a001a000001LXq7AAG"}]}'
163
+ http_version:
164
+ recorded_at: Sat, 11 Apr 2015 06:43:12 GMT
165
+ - request:
166
+ method: delete
167
+ uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c/a001a000001LXq7AAG
168
+ body:
169
+ encoding: US-ASCII
170
+ string: ''
171
+ headers:
172
+ User-Agent:
173
+ - Faraday v0.9.1
174
+ Authorization:
175
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
176
+ Accept-Encoding:
177
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
178
+ Accept:
179
+ - "*/*"
180
+ response:
181
+ status:
182
+ code: 204
183
+ message: No Content
184
+ headers:
185
+ Date:
186
+ - Sat, 11 Apr 2015 06:43:13 GMT
187
+ Set-Cookie:
188
+ - BrowserId=Awcxw7G1SXiCTkdZWqE9OA;Path=/;Domain=.salesforce.com;Expires=Wed,
189
+ 10-Jun-2015 06:43:13 GMT
190
+ Expires:
191
+ - Thu, 01 Jan 1970 00:00:00 GMT
192
+ Sforce-Limit-Info:
193
+ - api-usage=155/15000
194
+ body:
195
+ encoding: UTF-8
196
+ string: ''
197
+ http_version:
198
+ recorded_at: Sat, 11 Apr 2015 06:43:13 GMT
199
+ - request:
200
+ method: delete
201
+ uri: https://<host>/services/data/v26.0/sobjects/CustomObjectDetail__c/a011a000000gyxRAAQ
202
+ body:
203
+ encoding: US-ASCII
204
+ string: ''
205
+ headers:
206
+ User-Agent:
207
+ - Faraday v0.9.1
208
+ Authorization:
209
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
210
+ Accept-Encoding:
211
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
212
+ Accept:
213
+ - "*/*"
214
+ response:
215
+ status:
216
+ code: 404
217
+ message: Not Found
218
+ headers:
219
+ Date:
220
+ - Sat, 11 Apr 2015 06:43:14 GMT
221
+ Set-Cookie:
222
+ - BrowserId=SRD1PfCKT0G8l0jXm4cOVQ;Path=/;Domain=.salesforce.com;Expires=Wed,
223
+ 10-Jun-2015 06:43:14 GMT
224
+ Expires:
225
+ - Thu, 01 Jan 1970 00:00:00 GMT
226
+ Sforce-Limit-Info:
227
+ - api-usage=155/15000
228
+ Content-Type:
229
+ - application/json;charset=UTF-8
230
+ Transfer-Encoding:
231
+ - chunked
232
+ body:
233
+ encoding: UTF-8
234
+ string: '[{"message":"entity is deleted","errorCode":"ENTITY_IS_DELETED","fields":[]}]'
235
+ http_version:
236
+ recorded_at: Sat, 11 Apr 2015 06:43:15 GMT
237
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,275 @@
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
+ - Sat, 11 Apr 2015 06:42:59 GMT
25
+ Set-Cookie:
26
+ - BrowserId=u-7EnRPMQEOh3y4FZAIEHg;Path=/;Domain=.salesforce.com;Expires=Wed,
27
+ 10-Jun-2015 06:42:59 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":"1428734579132","token_type":"Bearer","instance_url":"https://<host>","signature":"22v+bPU50gx+t0KAwCUnZYB07Lyh/CzrwLhWUeAOwQs=","access_token":"00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx"}'
41
+ http_version:
42
+ recorded_at: Sat, 11 Apr 2015 06:42:59 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":"Sample object"}'
49
+ headers:
50
+ User-Agent:
51
+ - Faraday v0.9.1
52
+ Content-Type:
53
+ - application/json
54
+ Authorization:
55
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
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
+ - Sat, 11 Apr 2015 06:43:00 GMT
67
+ Set-Cookie:
68
+ - BrowserId=iL1n2l9wSwa25t41vHCoEg;Path=/;Domain=.salesforce.com;Expires=Wed,
69
+ 10-Jun-2015 06:43:00 GMT
70
+ Expires:
71
+ - Thu, 01 Jan 1970 00:00:00 GMT
72
+ Sforce-Limit-Info:
73
+ - api-usage=153/15000
74
+ Location:
75
+ - "/services/data/v26.0/sobjects/CustomObject__c/a001a000001LXq2AAG"
76
+ Content-Type:
77
+ - application/json;charset=UTF-8
78
+ Transfer-Encoding:
79
+ - chunked
80
+ body:
81
+ encoding: ASCII-8BIT
82
+ string: '{"id":"a001a000001LXq2AAG","success":true,"errors":[]}'
83
+ http_version:
84
+ recorded_at: Sat, 11 Apr 2015 06:43:00 GMT
85
+ - request:
86
+ method: post
87
+ uri: https://<host>/services/data/v26.0/sobjects/CustomObjectDetail__c
88
+ body:
89
+ encoding: UTF-8
90
+ string: '{"CustomObject__c":"a001a000001LXq2AAG"}'
91
+ headers:
92
+ User-Agent:
93
+ - Faraday v0.9.1
94
+ Content-Type:
95
+ - application/json
96
+ Authorization:
97
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
98
+ Accept-Encoding:
99
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
100
+ Accept:
101
+ - "*/*"
102
+ response:
103
+ status:
104
+ code: 201
105
+ message: Created
106
+ headers:
107
+ Date:
108
+ - Sat, 11 Apr 2015 06:43:01 GMT
109
+ Set-Cookie:
110
+ - BrowserId=2y5mWp0eR0ighxHLFk0XPg;Path=/;Domain=.salesforce.com;Expires=Wed,
111
+ 10-Jun-2015 06:43:01 GMT
112
+ Expires:
113
+ - Thu, 01 Jan 1970 00:00:00 GMT
114
+ Sforce-Limit-Info:
115
+ - api-usage=153/15000
116
+ Location:
117
+ - "/services/data/v26.0/sobjects/CustomObjectDetail__c/a011a000000gyxMAAQ"
118
+ Content-Type:
119
+ - application/json;charset=UTF-8
120
+ Transfer-Encoding:
121
+ - chunked
122
+ body:
123
+ encoding: ASCII-8BIT
124
+ string: '{"id":"a011a000000gyxMAAQ","success":true,"errors":[]}'
125
+ http_version:
126
+ recorded_at: Sat, 11 Apr 2015 06:43:01 GMT
127
+ - request:
128
+ method: get
129
+ uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Name,%20CustomObject__c%20from%20CustomObjectDetail__c%20where%20Id%20=%20%27a011a000000gyxMAAQ%27
130
+ body:
131
+ encoding: US-ASCII
132
+ string: ''
133
+ headers:
134
+ User-Agent:
135
+ - Faraday v0.9.1
136
+ Authorization:
137
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
138
+ Accept-Encoding:
139
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
140
+ Accept:
141
+ - "*/*"
142
+ response:
143
+ status:
144
+ code: 200
145
+ message: OK
146
+ headers:
147
+ Date:
148
+ - Sat, 11 Apr 2015 06:43:02 GMT
149
+ Set-Cookie:
150
+ - BrowserId=sRFL1Q8DQm-fm1RgKmjBIw;Path=/;Domain=.salesforce.com;Expires=Wed,
151
+ 10-Jun-2015 06:43:02 GMT
152
+ Expires:
153
+ - Thu, 01 Jan 1970 00:00:00 GMT
154
+ Sforce-Limit-Info:
155
+ - api-usage=153/15000
156
+ Content-Type:
157
+ - application/json;charset=UTF-8
158
+ Transfer-Encoding:
159
+ - chunked
160
+ body:
161
+ encoding: ASCII-8BIT
162
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObjectDetail__c","url":"/services/data/v26.0/sobjects/CustomObjectDetail__c/a011a000000gyxMAAQ"},"Id":"a011a000000gyxMAAQ","SystemModstamp":"2015-04-11T06:43:01.000+0000","Name":"a011a000000gyxM","CustomObject__c":"a001a000001LXq2AAG"}]}'
163
+ http_version:
164
+ recorded_at: Sat, 11 Apr 2015 06:43:02 GMT
165
+ - request:
166
+ method: get
167
+ uri: https://<host>/services/data/v26.0/query?q=select%20Id,%20SystemModstamp,%20Name,%20CustomObject__c%20from%20CustomObjectDetail__c%20where%20Id%20=%20%27a011a000000gyxMAAQ%27
168
+ body:
169
+ encoding: US-ASCII
170
+ string: ''
171
+ headers:
172
+ User-Agent:
173
+ - Faraday v0.9.1
174
+ Authorization:
175
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
176
+ Accept-Encoding:
177
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
178
+ Accept:
179
+ - "*/*"
180
+ response:
181
+ status:
182
+ code: 200
183
+ message: OK
184
+ headers:
185
+ Date:
186
+ - Sat, 11 Apr 2015 06:43:03 GMT
187
+ Set-Cookie:
188
+ - BrowserId=BKTUJbnMQMyam6jgObGEQA;Path=/;Domain=.salesforce.com;Expires=Wed,
189
+ 10-Jun-2015 06:43:03 GMT
190
+ Expires:
191
+ - Thu, 01 Jan 1970 00:00:00 GMT
192
+ Sforce-Limit-Info:
193
+ - api-usage=153/15000
194
+ Content-Type:
195
+ - application/json;charset=UTF-8
196
+ Transfer-Encoding:
197
+ - chunked
198
+ body:
199
+ encoding: ASCII-8BIT
200
+ string: '{"totalSize":1,"done":true,"records":[{"attributes":{"type":"CustomObjectDetail__c","url":"/services/data/v26.0/sobjects/CustomObjectDetail__c/a011a000000gyxMAAQ"},"Id":"a011a000000gyxMAAQ","SystemModstamp":"2015-04-11T06:43:01.000+0000","Name":"a011a000000gyxM","CustomObject__c":"a001a000001LXq2AAG"}]}'
201
+ http_version:
202
+ recorded_at: Sat, 11 Apr 2015 06:43:04 GMT
203
+ - request:
204
+ method: delete
205
+ uri: https://<host>/services/data/v26.0/sobjects/CustomObject__c/a001a000001LXq2AAG
206
+ body:
207
+ encoding: US-ASCII
208
+ string: ''
209
+ headers:
210
+ User-Agent:
211
+ - Faraday v0.9.1
212
+ Authorization:
213
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
214
+ Accept-Encoding:
215
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
216
+ Accept:
217
+ - "*/*"
218
+ response:
219
+ status:
220
+ code: 204
221
+ message: No Content
222
+ headers:
223
+ Date:
224
+ - Sat, 11 Apr 2015 06:43:04 GMT
225
+ Set-Cookie:
226
+ - BrowserId=ADr5HBxESOiPA9wrwXFnmw;Path=/;Domain=.salesforce.com;Expires=Wed,
227
+ 10-Jun-2015 06:43:04 GMT
228
+ Expires:
229
+ - Thu, 01 Jan 1970 00:00:00 GMT
230
+ Sforce-Limit-Info:
231
+ - api-usage=154/15000
232
+ body:
233
+ encoding: UTF-8
234
+ string: ''
235
+ http_version:
236
+ recorded_at: Sat, 11 Apr 2015 06:43:05 GMT
237
+ - request:
238
+ method: delete
239
+ uri: https://<host>/services/data/v26.0/sobjects/CustomObjectDetail__c/a011a000000gyxMAAQ
240
+ body:
241
+ encoding: US-ASCII
242
+ string: ''
243
+ headers:
244
+ User-Agent:
245
+ - Faraday v0.9.1
246
+ Authorization:
247
+ - OAuth 00D1a000000H3O9!AQ4AQIyTuSKn1TCR6oX6k4qCgK2hb4xjUYNDY3Jrprus.eG.vfY9WTiqMBJovOXyNilB_lzfaHH0cbBzfmw1gYcg7_8PyEzx
248
+ Accept-Encoding:
249
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
250
+ Accept:
251
+ - "*/*"
252
+ response:
253
+ status:
254
+ code: 404
255
+ message: Not Found
256
+ headers:
257
+ Date:
258
+ - Sat, 11 Apr 2015 06:43:05 GMT
259
+ Set-Cookie:
260
+ - BrowserId=Ch5ajP1eRXSAfvcy_VMG0g;Path=/;Domain=.salesforce.com;Expires=Wed,
261
+ 10-Jun-2015 06:43:05 GMT
262
+ Expires:
263
+ - Thu, 01 Jan 1970 00:00:00 GMT
264
+ Sforce-Limit-Info:
265
+ - api-usage=154/15000
266
+ Content-Type:
267
+ - application/json;charset=UTF-8
268
+ Transfer-Encoding:
269
+ - chunked
270
+ body:
271
+ encoding: UTF-8
272
+ string: '[{"message":"entity is deleted","errorCode":"ENTITY_IS_DELETED","fields":[]}]'
273
+ http_version:
274
+ recorded_at: Sat, 11 Apr 2015 06:43:06 GMT
275
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,82 @@
1
+ require_relative "../../../../test_helper"
2
+
3
+ describe Restforce::DB::Associations::BelongsTo do
4
+
5
+ configure!
6
+ mappings!
7
+
8
+ let(:association) { Restforce::DB::Associations::BelongsTo.new(:user, through: "Friend__c") }
9
+
10
+ it "sets the lookup field" do
11
+ expect(association.lookup).to_equal "Friend__c"
12
+ end
13
+
14
+ describe "#fields" do
15
+
16
+ it "returns the configured lookups for the association" do
17
+ expect(association.fields).to_equal [association.lookup]
18
+ end
19
+ end
20
+
21
+ describe "with an inverse mapping", :vcr do
22
+ let(:inverse_mapping) do
23
+ Restforce::DB::Mapping.new(User, "Contact").tap do |m|
24
+ m.fields = { email: "Email" }
25
+ m.associations << Restforce::DB::Associations::HasOne.new(
26
+ :custom_object,
27
+ through: "Friend__c",
28
+ )
29
+ end
30
+ end
31
+ let(:user_salesforce_id) do
32
+ Salesforce.create!(
33
+ inverse_mapping.salesforce_model,
34
+ "Email" => "somebody@example.com",
35
+ "LastName" => "Somebody",
36
+ )
37
+ end
38
+ let(:object_salesforce_id) do
39
+ Salesforce.create!(mapping.salesforce_model, "Friend__c" => user_salesforce_id)
40
+ end
41
+
42
+ before do
43
+ Restforce::DB::Registry << mapping
44
+ Restforce::DB::Registry << inverse_mapping
45
+ mapping.associations << association
46
+ end
47
+
48
+ describe "#synced_for?" do
49
+ let(:salesforce_instance) { mapping.salesforce_record_type.find(object_salesforce_id) }
50
+
51
+ describe "when no matching associated record has been synchronized" do
52
+
53
+ it "returns false" do
54
+ expect(association).to_not_be :synced_for?, salesforce_instance
55
+ end
56
+ end
57
+
58
+ describe "when a matching associated record has been synchronized" do
59
+ before do
60
+ inverse_mapping.database_model.create!(salesforce_id: user_salesforce_id)
61
+ end
62
+
63
+ it "returns true" do
64
+ expect(association).to_be :synced_for?, salesforce_instance
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#build" do
70
+ let(:database_record) { CustomObject.new }
71
+ let(:salesforce_record) { mapping.salesforce_record_type.find(object_salesforce_id).record }
72
+ let(:associated) { association.build(database_record, salesforce_record) }
73
+
74
+ it "returns an associated record, populated with the Salesforce attributes" do
75
+ expect(associated.custom_object).to_equal database_record
76
+ expect(associated.email).to_equal "somebody@example.com"
77
+ expect(associated.salesforce_id).to_equal user_salesforce_id
78
+ end
79
+ end
80
+ end
81
+
82
+ end
@@ -0,0 +1,96 @@
1
+ require_relative "../../../../test_helper"
2
+
3
+ describe Restforce::DB::Associations::HasMany do
4
+
5
+ configure!
6
+ mappings!
7
+
8
+ let(:association) { Restforce::DB::Associations::HasMany.new(:details, through: "CustomObject__c") }
9
+
10
+ it "sets the lookup field" do
11
+ expect(association.lookup).to_equal "CustomObject__c"
12
+ end
13
+
14
+ describe "#fields" do
15
+
16
+ it "returns nothing (since the lookup field is external)" do
17
+ expect(association.fields).to_equal []
18
+ end
19
+ end
20
+
21
+ describe "with an inverse mapping", :vcr do
22
+ let(:inverse_mapping) do
23
+ Restforce::DB::Mapping.new(Detail, "CustomObjectDetail__c").tap do |m|
24
+ m.fields = { name: "Name" }
25
+ m.associations << Restforce::DB::Associations::BelongsTo.new(
26
+ :custom_object,
27
+ through: "CustomObject__c",
28
+ )
29
+ end
30
+ end
31
+ let(:object_salesforce_id) { Salesforce.create!(mapping.salesforce_model) }
32
+ let(:detail_salesforce_ids) do
33
+ [
34
+ Salesforce.create!(
35
+ inverse_mapping.salesforce_model,
36
+ "Name" => "First Detail",
37
+ "CustomObject__c" => object_salesforce_id,
38
+ ),
39
+ Salesforce.create!(
40
+ inverse_mapping.salesforce_model,
41
+ "Name" => "Second Detail",
42
+ "CustomObject__c" => object_salesforce_id,
43
+ ),
44
+ Salesforce.create!(
45
+ inverse_mapping.salesforce_model,
46
+ "Name" => "Third Detail",
47
+ "CustomObject__c" => object_salesforce_id,
48
+ ),
49
+ ]
50
+ end
51
+
52
+ before do
53
+ Restforce::DB::Registry << mapping
54
+ Restforce::DB::Registry << inverse_mapping
55
+ mapping.associations << association
56
+ end
57
+
58
+ describe "#synced_for?" do
59
+ let(:salesforce_instance) { mapping.salesforce_record_type.find(object_salesforce_id) }
60
+
61
+ describe "when no matching associated record has been synchronized" do
62
+
63
+ it "returns false" do
64
+ expect(association).to_not_be :synced_for?, salesforce_instance
65
+ end
66
+ end
67
+
68
+ describe "when a matching associated record has been synchronized" do
69
+ before do
70
+ detail_salesforce_ids.each do |id|
71
+ inverse_mapping.database_model.create!(salesforce_id: id)
72
+ end
73
+ end
74
+
75
+ it "returns true" do
76
+ expect(association).to_be :synced_for?, salesforce_instance
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "#build" do
82
+ let(:database_record) { CustomObject.new }
83
+ let(:salesforce_record) { mapping.salesforce_record_type.find(object_salesforce_id).record }
84
+ let(:associated) { association.build(database_record, salesforce_record) }
85
+
86
+ it "builds a number of associated records from the data in Salesforce" do
87
+ detail_salesforce_ids.each do |id|
88
+ record = associated.detect { |a| a.salesforce_id == id }
89
+
90
+ expect(record).to_not_be_nil
91
+ expect(record.custom_object).to_equal database_record
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end