active_force 0.19.0 → 0.20.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 38ef881c292f8ecb12be07a0471f759a06b9155af5e3a49c26dbb69e024db87f
4
- data.tar.gz: 6a209feb04dc0c6a192c084a95c2e55c64696bbb54636496fc98dc8c56c7b653
3
+ metadata.gz: 1647fdc453090811c384514ae857c83b686dc966e2af5e47af3a6dc67e42059d
4
+ data.tar.gz: 515a98a5715c24359739d76730758b728a9cbf1b8c0cbf2b3c1bb5a355a21c9e
5
5
  SHA512:
6
- metadata.gz: 814f0f4844f94acea113a4eabf1e3afd366b2b00255fe5bcca5ccfccb0f5d862651548302373d078a7c070422d6db6c8cf971f33112c360f0d43f133d500c98a
7
- data.tar.gz: 48f595e34749ec49adeaeb8320c407911f8841d83fcd433cdd5e7e9bc5b6b8f37d01a0f30f6a96610d91949ab8e30e2cb4b0c3f9aa18692447fc31ed6d4b75fb
6
+ metadata.gz: 48115b7a0df0201a24f477ba2f658e692824337a78c0d288afd3c056b42fccaaf065e1e3ab296fa16bda1f2f2eaf82ff1322adcea6d9d6a9f82c2318cea15d98
7
+ data.tar.gz: a7b6dacca6775374b089cc9022462c470d8103d63792c7e7668ccd3e082446b0429a2d54d0e3392694c0e25ea25139916d11bc9f0080659faea6e7eaa0e41541
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .idea
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Not released
4
4
 
5
+ ## 0.20.0
6
+
7
+ - Change `.first` to not query the API if records have already been retrieved (https://github.com/Beyond-Finance/active_force/pull/73)
8
+ - Bugfix: Transform NULL values for SF Bulk API, which expects "#N/A" (https://github.com/Beyond-Finance/active_force/pull/74)
9
+
5
10
  ## 0.19.0
6
11
 
7
12
  - Bulk API methods. (https://github.com/Beyond-Finance/active_force/pull/65)
@@ -3,6 +3,8 @@ require 'csv'
3
3
  module ActiveForce
4
4
  module Bulk
5
5
  class Records
6
+ NULL_VALUE = '#N/A'.freeze
7
+
6
8
  attr_reader :headers, :data
7
9
  def initialize(headers:, data:)
8
10
  @headers = headers
@@ -16,10 +18,25 @@ module ActiveForce
16
18
  end
17
19
 
18
20
  def self.parse_from_attributes(records)
21
+ # Sorting ensures that the headers line up with the values for the CSV
19
22
  headers = records.first.keys.sort.map(&:to_s)
20
- data = records.map { |r| r.sort.pluck(-1) }
23
+ data = records.map do |r|
24
+ r.transform_values { |v| transform_value_for_sf(v) }.sort.pluck(-1)
25
+ end
21
26
  new(headers: headers, data: data)
22
27
  end
28
+
29
+ # SF expects a special value for setting a column to be NULL.
30
+ def self.transform_value_for_sf(value)
31
+ case value
32
+ when NilClass
33
+ NULL_VALUE
34
+ when Time
35
+ value.iso8601
36
+ else
37
+ value.to_s
38
+ end
39
+ end
23
40
  end
24
41
  end
25
42
  end
@@ -78,7 +78,15 @@ module ActiveForce
78
78
  end
79
79
 
80
80
  def first
81
- limit 1
81
+ if @records
82
+ clone_and_set_instance_variables(
83
+ size: 1,
84
+ records: [@records.first],
85
+ decorated_records: [@decorated_records&.first]
86
+ )
87
+ else
88
+ limit(1)
89
+ end
82
90
  end
83
91
 
84
92
  def last(limit = 1)
@@ -126,9 +134,9 @@ module ActiveForce
126
134
 
127
135
  def clone_and_set_instance_variables instance_variable_hash={}
128
136
  clone = self.clone
129
- clone.instance_variable_set(:@decorated_records, nil)
130
- clone.instance_variable_set(:@records, nil)
131
- instance_variable_hash.each { |k,v| clone.instance_variable_set("@#{k.to_s}", v) }
137
+ { decorated_records: nil, records: nil }
138
+ .merge(instance_variable_hash)
139
+ .each { |k,v| clone.instance_variable_set("@#{k.to_s}", v) }
132
140
  clone
133
141
  end
134
142
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveForce
4
- VERSION = '0.19.0'
4
+ VERSION = '0.20.0'
5
5
  end
@@ -9,11 +9,13 @@ describe ActiveForce::Bulk::Records do
9
9
  %w[value3 value4],
10
10
  ]
11
11
  end
12
+
12
13
  describe '#to_csv' do
13
14
  it 'returns CSV with headers' do
14
15
  expect(subject.to_csv).to eq "header1,header2\nvalue1,value2\nvalue3,value4\n"
15
16
  end
16
17
  end
18
+
17
19
  describe '::parse_from_attributes' do
18
20
  subject { described_class.parse_from_attributes(attributes) }
19
21
  let(:attributes) do
@@ -28,5 +30,25 @@ describe ActiveForce::Bulk::Records do
28
30
  expect(records.headers).to eq headers
29
31
  expect(records.data).to eq data
30
32
  end
33
+
34
+ context 'when there are NULL values' do
35
+ let(:attributes) do
36
+ [
37
+ { header1: nil, header2: 'value2'},
38
+ { header1: 'value3', header2: nil},
39
+ ]
40
+ end
41
+ let(:data) do
42
+ [
43
+ %w[#N/A value2],
44
+ %w[value3 #N/A],
45
+ ]
46
+ end
47
+
48
+ it 'substitutes the expected SF value for NULL' do
49
+ records = subject
50
+ expect(records.data).to eq data
51
+ end
52
+ end
31
53
  end
32
54
  end
@@ -165,6 +165,22 @@ describe ActiveForce::Query do
165
165
  expect(query.to_s).to eq "SELECT Id, name, etc FROM table_name"
166
166
  expect(new_query.to_s).to eq 'SELECT Id, name, etc FROM table_name LIMIT 1'
167
167
  end
168
+
169
+ it "does not query if records have already been fetched" do
170
+ query = ActiveForce::Query.new 'table_name'
171
+ query.instance_variable_set(:@records, %w[foo bar])
172
+ query.instance_variable_set(:@decorated_records, %w[foo bar])
173
+ expect(query).not_to receive(:limit)
174
+ expect(query).to receive(:clone_and_set_instance_variables).with(size: 1, records: ['foo'], decorated_records: ['foo'])
175
+ query.first
176
+ end
177
+
178
+ it 'queries the api if it has not been queried yet' do
179
+ query = ActiveForce::Query.new 'table_name'
180
+ query.instance_variable_set(:@records, nil)
181
+ expect(query).to receive(:limit)
182
+ query.first
183
+ end
168
184
  end
169
185
 
170
186
  describe '.last' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_force
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eloy Espinaco
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2023-11-15 00:00:00.000000000 Z
14
+ date: 2023-11-27 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activemodel