activeforce 1.8.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA512:
3
- data.tar.gz: 3677373f8d2f88bfbc535ff345e25a2682af1f2e4d8e237f2efebd2e9f5a06317b1159a5238563b41b59df1dd35cad781b7579e76ea323665bff3f8e16861ab5
4
- metadata.gz: b8fe6ebdc9af91c5a981923ef600ab8c85473a50008d12895b47131f2ccfd1e2a6197a03c084e9cb112f9853dcccf5d14aa0856ed77a1b273ac2fcd5bc404be0
5
- SHA1:
6
- data.tar.gz: 758e87d2f47d73b4e802ce38d7a46f80b65ef4be
7
- metadata.gz: 0b7190d439284ef237ed95ff98f76a2e011e6a4f
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ee133e1f38fd2878fae6ad22990f625a434b2fdc
4
+ data.tar.gz: ec6a6096cbe30589dec37bd467b362a01012ccd1
5
+ SHA512:
6
+ metadata.gz: b39056785f47e3dc32959d1fe8b989cfd26480c86ba3ebad486e65cf358c2c233abfbb9a08b5a2e055b8bed54cdacfece9fd6d21bf86677adad9897bf0f1901e
7
+ data.tar.gz: 3ed81dc8bc50798555fa1e43123e888f68617755bb86c42332b62be1fa72a3bd56d4fa036909d73369ce3e8c887aabe6fb3d26917858089c785e91c7a0d27588
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- activeforce (1.8.0)
4
+ activeforce (1.9.0)
5
5
  blockenspiel
6
6
  fastercsv
7
7
  rails (>= 3.0)
@@ -53,16 +53,18 @@ GEM
53
53
  rack
54
54
  i18n (0.6.5)
55
55
  journey (1.0.4)
56
- json (1.8.0)
56
+ json (1.8.1)
57
57
  mail (2.5.4)
58
58
  mime-types (~> 1.16)
59
59
  treetop (~> 1.4.8)
60
60
  metaclass (0.0.1)
61
- mime-types (1.24)
61
+ mime-types (1.25)
62
+ mini_portile (0.5.1)
62
63
  mocha (0.14.0)
63
64
  metaclass (~> 0.0.1)
64
- multi_json (1.7.9)
65
- nokogiri (1.5.10)
65
+ multi_json (1.8.2)
66
+ nokogiri (1.6.0)
67
+ mini_portile (~> 0.5.0)
66
68
  nori (1.1.3)
67
69
  polyglot (0.3.3)
68
70
  rack (1.4.5)
@@ -110,7 +112,7 @@ GEM
110
112
  treetop (1.4.15)
111
113
  polyglot
112
114
  polyglot (>= 0.3.1)
113
- tzinfo (0.3.37)
115
+ tzinfo (0.3.38)
114
116
  wasabi (2.5.0)
115
117
  httpi (~> 1.0)
116
118
  nokogiri (>= 1.4.0)
@@ -17,6 +17,7 @@ require 'salesforce/bulk/operations'
17
17
  require 'salesforce/base'
18
18
  require 'salesforce/bulk/job'
19
19
  require 'salesforce/bulk/update_job'
20
+ require 'salesforce/bulk/upsert_job'
20
21
  require 'salesforce/bulk/batch'
21
22
 
22
23
  module Salesforce
@@ -1,3 +1,3 @@
1
1
  module Activeforce
2
- VERSION = '1.8.0'.freeze
3
- end
2
+ VERSION = '1.9.0'.freeze
3
+ end
@@ -19,6 +19,14 @@ module Salesforce
19
19
  job.process!
20
20
  end
21
21
  end
22
+
23
+ def bulk_upsert(external_id, columns = [], &block)
24
+ UpsertJob.new(self, external_id, columns).tap do |job|
25
+ Blockenspiel.invoke(block, job)
26
+ job.process!
27
+ end
28
+ end
29
+
22
30
  end
23
31
  end
24
32
  end
@@ -0,0 +1,38 @@
1
+ module Salesforce
2
+ module Bulk
3
+ class UpsertJob < Job
4
+
5
+ attr_accessor :external_id_col
6
+
7
+ def initialize(object_type, external_id_col, columns = :all)
8
+ super(object_type, 'upsert', columns)
9
+ self.external_id_col = object_type.columns.find { |scol| scol.name == external_id_col.to_s }
10
+ raise UnrecognizedColumn.new("#{external_id_col} is not a valid column.") unless self.external_id_col
11
+ end
12
+
13
+ def csv_columns
14
+ if columns.blank? || columns == :all
15
+ ([self.external_id_col] + object_type.columns.editable).uniq
16
+ else
17
+ cols = columns.map do |col|
18
+ sf_col = object_type.columns.find { |scol| scol.name == col.to_s }
19
+ raise UnrecognizedColumn.new("#{col} is not a valid column.") unless sf_col
20
+ sf_col
21
+ end
22
+ ([self.external_id_col] + cols).uniq
23
+ end
24
+ end
25
+
26
+ def create_job_xml
27
+ job_xml do |job_info|
28
+ job_info.operation self.operation
29
+ job_info.object self.object
30
+ job_info.externalIdFieldName self.external_id_col.original_name
31
+ job_info.contentType "CSV"
32
+ end
33
+ end
34
+
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,134 @@
1
+ require 'test_helper'
2
+
3
+ class Salesforce::Bulk::UpsertJobTest < ActiveSupport::TestCase
4
+
5
+ setup :setup_columns_for_bulk_table
6
+ setup :setup_columns_for_account
7
+
8
+
9
+ def test_initialize
10
+ job = Salesforce::Bulk::UpsertJob.new(Salesforce::Account, "id")
11
+ assert_equal Salesforce::Account, job.object_type
12
+ assert_equal 'upsert', job.operation
13
+ assert_equal 'Parallel', job.concurrency_mode
14
+ assert_equal 'Account', job.object
15
+ assert_equal 'id', job.external_id_col.name
16
+ assert_equal ["Id","City","Address","Name", "Number", "Type","State"].sort, job.send(:csv_header).sort
17
+ end
18
+
19
+ def test_initialize__with_columns
20
+ job = Salesforce::Bulk::UpsertJob.new(Salesforce::Account, "id", [:name, :state])
21
+ assert_equal Salesforce::Account, job.object_type
22
+ assert_equal 'upsert', job.operation
23
+ assert_equal 'Parallel', job.concurrency_mode
24
+ assert_equal 'Account', job.object
25
+ assert_equal 'id', job.external_id_col.name
26
+ assert_equal 'Id,Name,State', job.send(:csv_header).join(',')
27
+ end
28
+
29
+ def test_initialize__with_all
30
+ job = Salesforce::Bulk::UpsertJob.new(Salesforce::Account, "id", :all)
31
+ assert_equal Salesforce::Account, job.object_type
32
+ assert_equal 'upsert', job.operation
33
+ assert_equal 'Parallel', job.concurrency_mode
34
+ assert_equal 'Account', job.object
35
+ assert_equal 'id', job.external_id_col.name
36
+ assert_equal ["Id","City","Address","Name", "Number", "Type","State"].sort, job.send(:csv_header).sort
37
+ end
38
+
39
+ def test_csv_columns__unrecognized_column
40
+ assert_raises Salesforce::UnrecognizedColumn do
41
+ Salesforce::Bulk::UpsertJob.new(Salesforce::Account, "id", [:ssn]).csv_columns
42
+ end
43
+ end
44
+
45
+ def test_csv_columns__unrecognized_column_external_id
46
+ assert_raises Salesforce::UnrecognizedColumn do
47
+ Salesforce::Bulk::UpsertJob.new(Salesforce::Account, "ssn").csv_columns
48
+ end
49
+ end
50
+
51
+ def test_bulk_update
52
+ Salesforce::Bulk::UpsertJob.any_instance.expects(:process!)
53
+
54
+ job = Salesforce::BulkTable.bulk_upsert("id") do
55
+ serial!
56
+ batch do
57
+ record({})
58
+ record({})
59
+ end
60
+ end
61
+
62
+ assert_equal Salesforce::BulkTable, job.object_type
63
+ assert_equal 'upsert', job.operation
64
+ assert_equal 'Serial', job.concurrency_mode
65
+ assert_equal 'BulkTable__c', job.object
66
+ assert_equal 1, job.batches.size
67
+ end
68
+
69
+ def test_process
70
+ job = Salesforce::Bulk::UpsertJob.new(Salesforce::Account, "id")
71
+ job.expects(:create_job!)
72
+ job.expects(:create_batches!)
73
+ job.expects(:close_job!)
74
+ job.process!
75
+ end
76
+
77
+ def test_create_job
78
+ job = Salesforce::Bulk::UpsertJob.new(Salesforce::Account, "id")
79
+ xml = anything
80
+ Salesforce.connection.expects(:async_post).with("job", xml, :format => :xml).returns({ "id" => 3})
81
+ job.send :create_job!
82
+ assert_equal 3, job.id
83
+ end
84
+
85
+ def test_completed
86
+ job_with_batches
87
+ @batch_1.stubs(:update_status)
88
+ @batch_2.stubs(:update_status)
89
+ @batch_1.expects(:completed?).returns(false)
90
+ @batch_1.expects(:failed?).returns(false)
91
+ assert_equal false, @job.completed?
92
+
93
+ @batch_1.expects(:completed?).returns(true)
94
+ @batch_2.expects(:completed?).returns(false)
95
+ @batch_2.expects(:failed?).returns(false)
96
+ assert_equal false, @job.completed?
97
+
98
+ @batch_1.expects(:completed?).returns(true)
99
+ @batch_2.expects(:completed?).returns(false)
100
+ @batch_2.expects(:failed?).returns(true)
101
+ assert @job.completed?
102
+ end
103
+
104
+ def test_results
105
+ job_with_batches
106
+ @batch_1.expects(:results).returns([ :result_1, :result_2])
107
+ @batch_2.expects(:results).returns([ :result_3, :result_4])
108
+ assert_equal [ :result_1, :result_2, :result_3, :result_4 ], @job.results
109
+ end
110
+
111
+ def test_close_job
112
+ Salesforce::Authentication.stubs(:session_id).returns('session_id')
113
+ job_with_batches
114
+ Salesforce.connection.expects(:async_post).with("job/jobId", includes("<state>Closed</state>"), :format => :xml).returns("state" => "Closed", "number_batches_total" => 2)
115
+ @job.send(:close_job!)
116
+ assert_equal 2, @job.number_batches_total
117
+ assert @job.closed?
118
+ end
119
+
120
+ private
121
+
122
+ def job_with_batches
123
+ Salesforce::Authentication.stubs(:session_id).returns('session_id')
124
+
125
+ @job = Salesforce::Bulk::UpsertJob.new(Salesforce::Account, "id")
126
+ @job.id = "jobId"
127
+ @batch_1 = Salesforce::Bulk::Batch.new(@job)
128
+ @batch_2 = Salesforce::Bulk::Batch.new(@job)
129
+ @job.batches << @batch_1
130
+ @job.batches << @batch_2
131
+ end
132
+
133
+
134
+ end
metadata CHANGED
@@ -1,76 +1,97 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: activeforce
3
- version: !ruby/object:Gem::Version
4
- version: 1.8.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.9.0
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - Tushar Ranka
8
8
  - Andrew Mutz
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2013-08-27 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- type: :runtime
12
+ date: 2013-08-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: rails
18
- version_requirements: &id001 !ruby/object:Gem::Requirement
19
- requirements:
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: "3.0"
23
- requirement: *id001
24
- prerelease: false
25
- - !ruby/object:Gem::Dependency
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '3.0'
26
21
  type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '3.0'
28
+ - !ruby/object:Gem::Dependency
27
29
  name: savon
28
- version_requirements: &id002 !ruby/object:Gem::Requirement
29
- requirements:
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
30
32
  - - ~>
31
- - !ruby/object:Gem::Version
32
- version: "1.0"
33
- requirement: *id002
34
- prerelease: false
35
- - !ruby/object:Gem::Dependency
33
+ - !ruby/object:Gem::Version
34
+ version: '1.0'
36
35
  type: :runtime
37
- name: blockenspiel
38
- version_requirements: &id003 !ruby/object:Gem::Requirement
39
- requirements:
40
- - &id004
41
- - ">="
42
- - !ruby/object:Gem::Version
43
- version: "0"
44
- requirement: *id003
45
36
  prerelease: false
46
- - !ruby/object:Gem::Dependency
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '1.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: blockenspiel
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
47
49
  type: :runtime
48
- name: rest-client
49
- version_requirements: &id005 !ruby/object:Gem::Requirement
50
- requirements:
51
- - *id004
52
- requirement: *id005
53
50
  prerelease: false
54
- - !ruby/object:Gem::Dependency
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rest-client
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
55
63
  type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
56
71
  name: fastercsv
57
- version_requirements: &id006 !ruby/object:Gem::Requirement
58
- requirements:
59
- - *id004
60
- requirement: *id006
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
61
78
  prerelease: false
62
- description: " Activeforce provides a simple to use and extend interface to Salesforce using the REST API"
63
- email:
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description: ' Activeforce provides a simple to use and extend interface to Salesforce
85
+ using the REST API'
86
+ email:
64
87
  - tusharranka@gmail.com
65
88
  - andrew.mutz@appfolio.com
66
89
  executables: []
67
-
68
90
  extensions: []
69
-
70
- extra_rdoc_files:
91
+ extra_rdoc_files:
71
92
  - LICENSE.txt
72
93
  - README.md
73
- files:
94
+ files:
74
95
  - .gitignore
75
96
  - Gemfile
76
97
  - Gemfile.lock
@@ -135,6 +156,7 @@ files:
135
156
  - lib/salesforce/bulk/job.rb
136
157
  - lib/salesforce/bulk/operations.rb
137
158
  - lib/salesforce/bulk/update_job.rb
159
+ - lib/salesforce/bulk/upsert_job.rb
138
160
  - lib/salesforce/column.rb
139
161
  - lib/salesforce/columns.rb
140
162
  - lib/salesforce/config.rb
@@ -150,6 +172,7 @@ files:
150
172
  - test/salesforce/base_test.rb
151
173
  - test/salesforce/bulk/batch_test.rb
152
174
  - test/salesforce/bulk/update_job_test.rb
175
+ - test/salesforce/bulk/upsert_job_test.rb
153
176
  - test/salesforce/column_test.rb
154
177
  - test/salesforce/config_test.rb
155
178
  - test/salesforce/connection/async_test.rb
@@ -159,27 +182,27 @@ files:
159
182
  - test/salesforce/connection_test.rb
160
183
  - test/test_helper.rb
161
184
  homepage: http://github.com/appfolio/activeforce
162
- licenses:
185
+ licenses:
163
186
  - MIT
164
187
  metadata: {}
165
-
166
188
  post_install_message:
167
189
  rdoc_options: []
168
-
169
- require_paths:
190
+ require_paths:
170
191
  - lib
171
- required_ruby_version: !ruby/object:Gem::Requirement
172
- requirements:
173
- - *id004
174
- required_rubygems_version: !ruby/object:Gem::Requirement
175
- requirements:
176
- - *id004
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - '>='
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
197
+ required_rubygems_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - '>='
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
177
202
  requirements: []
178
-
179
203
  rubyforge_project:
180
- rubygems_version: 2.0.6
204
+ rubygems_version: 2.1.11
181
205
  signing_key:
182
206
  specification_version: 4
183
207
  summary: A Simple gem to interact with the Salesforce REST API
184
208
  test_files: []
185
-