appsignal 1.1.0.beta.6 → 1.1.0.beta.7
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/CHANGELOG.md +10 -0
- data/ext/agent.yml +7 -7
- data/ext/appsignal_extension.c +7 -5
- data/ext/extconf.rb +9 -2
- data/lib/appsignal/config.rb +5 -2
- data/lib/appsignal/event_formatter.rb +2 -0
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +1 -47
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +88 -0
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +6 -7
- data/lib/appsignal/event_formatter/sequel/sql_formatter.rb +13 -0
- data/lib/appsignal/hooks/sequel.rb +4 -7
- data/lib/appsignal/integrations/capistrano/appsignal.cap +1 -1
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +9 -5
- data/lib/appsignal/js_exception_transaction.rb +2 -2
- data/lib/appsignal/subscriber.rb +3 -2
- data/lib/appsignal/transaction.rb +8 -2
- data/lib/appsignal/transmitter.rb +1 -1
- data/lib/appsignal/utils.rb +38 -4
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/capistrano3_spec.rb +21 -1
- data/spec/lib/appsignal/config_spec.rb +12 -0
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +1 -1
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +14 -186
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +115 -0
- data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +4 -4
- data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +22 -0
- data/spec/lib/appsignal/extension_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/sequel_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +8 -5
- data/spec/lib/appsignal/subscriber_spec.rb +23 -5
- data/spec/lib/appsignal/transaction_spec.rb +21 -0
- data/spec/lib/appsignal/utils_spec.rb +48 -0
- data/spec/support/helpers/env_helpers.rb +1 -0
- metadata +8 -2
@@ -28,7 +28,7 @@ module Appsignal
|
|
28
28
|
@transaction_index,
|
29
29
|
@data['name'],
|
30
30
|
@data['message'],
|
31
|
-
|
31
|
+
Appsignal::Utils.json_generate(@data['backtrace'])
|
32
32
|
)
|
33
33
|
end
|
34
34
|
|
@@ -43,7 +43,7 @@ module Appsignal
|
|
43
43
|
Appsignal::Extension.set_transaction_sample_data(
|
44
44
|
@transaction_index,
|
45
45
|
key.to_s,
|
46
|
-
|
46
|
+
Appsignal::Utils.json_generate(data)
|
47
47
|
)
|
48
48
|
rescue JSON::GeneratorError=>e
|
49
49
|
Appsignal.logger.error("JSON generate error (#{e.message}) for '#{data.inspect}'")
|
data/lib/appsignal/subscriber.rb
CHANGED
@@ -45,12 +45,13 @@ module Appsignal
|
|
45
45
|
return unless transaction = Appsignal::Transaction.current
|
46
46
|
return if transaction.nil_transaction? || transaction.paused?
|
47
47
|
|
48
|
-
title, body = Appsignal::EventFormatter.format(name, payload)
|
48
|
+
title, body, body_format = Appsignal::EventFormatter.format(name, payload)
|
49
49
|
Appsignal::Extension.finish_event(
|
50
50
|
transaction.transaction_index,
|
51
51
|
name,
|
52
52
|
title || BLANK,
|
53
|
-
body || BLANK
|
53
|
+
body || BLANK,
|
54
|
+
body_format || 0
|
54
55
|
)
|
55
56
|
end
|
56
57
|
end
|
@@ -113,7 +113,7 @@ module Appsignal
|
|
113
113
|
Appsignal::Extension.set_transaction_sample_data(
|
114
114
|
transaction_index,
|
115
115
|
key.to_s,
|
116
|
-
|
116
|
+
Appsignal::Utils.json_generate(data)
|
117
117
|
)
|
118
118
|
rescue JSON::GeneratorError=>e
|
119
119
|
Appsignal.logger.error("JSON generate error (#{e.message}) for '#{data.inspect}'")
|
@@ -124,6 +124,7 @@ module Appsignal
|
|
124
124
|
:params => sanitized_params,
|
125
125
|
:environment => sanitized_environment,
|
126
126
|
:session_data => sanitized_session_data,
|
127
|
+
:metadata => metadata,
|
127
128
|
:tags => sanitized_tags
|
128
129
|
}.each do |key, data|
|
129
130
|
set_sample_data(key, data)
|
@@ -141,7 +142,7 @@ module Appsignal
|
|
141
142
|
transaction_index,
|
142
143
|
error.class.name,
|
143
144
|
error.message,
|
144
|
-
backtrace ?
|
145
|
+
backtrace ? Appsignal::Utils.json_generate(backtrace) : ''
|
145
146
|
)
|
146
147
|
rescue JSON::GeneratorError=>e
|
147
148
|
Appsignal.logger.error("JSON generate error (#{e.message}) for '#{backtrace.inspect}'")
|
@@ -212,6 +213,11 @@ module Appsignal
|
|
212
213
|
Appsignal::ParamsSanitizer.sanitize(session.to_hash)
|
213
214
|
end
|
214
215
|
|
216
|
+
def metadata
|
217
|
+
return unless request.env
|
218
|
+
request.env[:metadata]
|
219
|
+
end
|
220
|
+
|
215
221
|
# Only keep tags if they meet the following criteria:
|
216
222
|
# * Key is a symbol or string with less then 100 chars
|
217
223
|
# * Value is a symbol or string with less then 100 chars
|
@@ -53,7 +53,7 @@ module Appsignal
|
|
53
53
|
request['Content-Type'] = CONTENT_TYPE
|
54
54
|
request['Content-Encoding'] = CONTENT_ENCODING
|
55
55
|
request.body = Zlib::Deflate.deflate(
|
56
|
-
|
56
|
+
Appsignal::Utils.json_generate(payload),
|
57
57
|
Zlib::BEST_SPEED
|
58
58
|
)
|
59
59
|
end
|
data/lib/appsignal/utils.rb
CHANGED
@@ -1,25 +1,59 @@
|
|
1
1
|
module Appsignal
|
2
2
|
module Utils
|
3
|
-
def self.sanitize(params, only_top_level=false)
|
3
|
+
def self.sanitize(params, only_top_level=false, key_sanitizer=nil)
|
4
4
|
if params.is_a?(Hash)
|
5
5
|
{}.tap do |hsh|
|
6
6
|
params.each do |key, val|
|
7
|
-
hsh[key] =
|
7
|
+
hsh[self.sanitize_key(key, key_sanitizer)] = if only_top_level
|
8
|
+
'?'
|
9
|
+
else
|
10
|
+
sanitize(val, only_top_level, key_sanitizer=nil)
|
11
|
+
end
|
8
12
|
end
|
9
13
|
end
|
10
14
|
elsif params.is_a?(Array)
|
11
15
|
if only_top_level
|
12
|
-
sanitize(params[0], only_top_level)
|
16
|
+
sanitize(params[0], only_top_level, key_sanitizer=nil)
|
13
17
|
elsif params.first.is_a?(String)
|
14
18
|
['?']
|
15
19
|
else
|
16
20
|
params.map do |item|
|
17
|
-
sanitize(item, only_top_level)
|
21
|
+
sanitize(item, only_top_level, key_sanitizer=nil)
|
18
22
|
end
|
19
23
|
end
|
20
24
|
else
|
21
25
|
'?'
|
22
26
|
end
|
23
27
|
end
|
28
|
+
|
29
|
+
def self.sanitize_key(key, sanitizer)
|
30
|
+
case sanitizer
|
31
|
+
when :mongodb then key.to_s.gsub(/(\..+)/, '.?')
|
32
|
+
else key
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.json_generate(body)
|
37
|
+
JSON.generate(jsonify(body))
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.jsonify(value)
|
41
|
+
case value
|
42
|
+
when String
|
43
|
+
value.encode(
|
44
|
+
'utf-8',
|
45
|
+
:invalid => :replace,
|
46
|
+
:undef => :replace
|
47
|
+
)
|
48
|
+
when Numeric, NilClass, TrueClass, FalseClass
|
49
|
+
value
|
50
|
+
when Hash
|
51
|
+
Hash[value.map { |k, v| [jsonify(k), jsonify(v)] }]
|
52
|
+
when Array
|
53
|
+
value.map { |v| jsonify(v) }
|
54
|
+
else
|
55
|
+
jsonify(value.to_s)
|
56
|
+
end
|
57
|
+
end
|
24
58
|
end
|
25
59
|
end
|
data/lib/appsignal/version.rb
CHANGED
@@ -80,9 +80,29 @@ if capistrano3_present?
|
|
80
80
|
)
|
81
81
|
end
|
82
82
|
end
|
83
|
+
|
84
|
+
context "when stage is used instead of rack_env / rails_env" do
|
85
|
+
before do
|
86
|
+
@capistrano_config.delete(:rails_env)
|
87
|
+
@capistrano_config.set(:stage, 'stage_production')
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should be instantiated with the right params" do
|
91
|
+
Appsignal::Config.should_receive(:new).with(
|
92
|
+
project_fixture_path,
|
93
|
+
'stage_production',
|
94
|
+
{:name => 'AppName'},
|
95
|
+
kind_of(Logger)
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
83
99
|
end
|
84
100
|
|
85
|
-
after
|
101
|
+
after do
|
102
|
+
invoke('appsignal:deploy')
|
103
|
+
@capistrano_config.delete(:stage)
|
104
|
+
@capistrano_config.delete(:rack_env)
|
105
|
+
end
|
86
106
|
end
|
87
107
|
|
88
108
|
context "send marker" do
|
@@ -98,6 +98,18 @@ describe Appsignal::Config do
|
|
98
98
|
ENV['APPSIGNAL_HTTP_PROXY'].should == 'http://localhost'
|
99
99
|
ENV['APPSIGNAL_IGNORE_ACTIONS'].should == 'action1,action2'
|
100
100
|
ENV['APPSIGNAL_RUNNING_IN_CONTAINER'].should == 'false'
|
101
|
+
ENV['APPSIGNAL_WORKING_DIR_PATH'].should be_nil
|
102
|
+
end
|
103
|
+
|
104
|
+
context "if working_dir_path is set" do
|
105
|
+
before do
|
106
|
+
subject.config_hash[:working_dir_path] = '/tmp/appsignal2'
|
107
|
+
subject.write_to_environment
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should write the current config to env vars" do
|
111
|
+
ENV['APPSIGNAL_WORKING_DIR_PATH'].should == '/tmp/appsignal2'
|
112
|
+
end
|
101
113
|
end
|
102
114
|
end
|
103
115
|
|
@@ -4,7 +4,7 @@ describe Appsignal::EventFormatter::ActiveRecord::InstantiationFormatter do
|
|
4
4
|
let(:klass) { Appsignal::EventFormatter::ActiveRecord::InstantiationFormatter }
|
5
5
|
let(:formatter) { klass.new }
|
6
6
|
|
7
|
-
it "should register
|
7
|
+
it "should register instantiation.active_record" do
|
8
8
|
Appsignal::EventFormatter.registered?('instantiation.active_record', klass).should be_true
|
9
9
|
end
|
10
10
|
|
@@ -1,195 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
describe Appsignal::EventFormatter::ActiveRecord::InstantiationFormatter do
|
4
|
+
let(:klass) { Appsignal::EventFormatter::ActiveRecord::SqlFormatter }
|
5
|
+
let(:formatter) { klass.new }
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
let(:connection_config) { {} }
|
10
|
-
before do
|
11
|
-
if ActiveRecord::Base.respond_to?(:connection_config)
|
12
|
-
# Rails 3.1+
|
13
|
-
ActiveRecord::Base.stub(
|
14
|
-
:connection_config => connection_config
|
15
|
-
)
|
16
|
-
else
|
17
|
-
# Rails 3.0
|
18
|
-
spec = double(:config => connection_config)
|
19
|
-
ActiveRecord::Base.stub(
|
20
|
-
:connection_pool => double(:spec => spec)
|
21
|
-
)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
pending "should register sql.activerecord" do
|
26
|
-
Appsignal::EventFormatter.registered?('sql.active_record', klass).should be_true
|
27
|
-
end
|
28
|
-
|
29
|
-
context "if a connection cannot be established" do
|
30
|
-
before do
|
31
|
-
ActiveRecord::Base.stub(:connection_config).and_raise(ActiveRecord::ConnectionNotEstablished)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should log the error and unregister the formatter" do
|
35
|
-
Appsignal.logger.should_receive(:error).with(
|
36
|
-
'Error while getting ActiveRecord connection info, unregistering sql.active_record event formatter'
|
37
|
-
)
|
38
|
-
|
39
|
-
lambda {
|
40
|
-
formatter
|
41
|
-
}.should_not raise_error
|
42
|
-
|
43
|
-
Appsignal::EventFormatter.registered?('sql.active_record').should be_false
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe "#format" do
|
48
|
-
let(:name) { 'Model load' }
|
49
|
-
let(:payload) { {:sql => sql, :name => name} }
|
50
|
-
subject { formatter.format(payload) }
|
51
|
-
|
52
|
-
context "with backtick table names" do
|
53
|
-
before { formatter.stub(:adapter_uses_double_quoted_table_names => false) }
|
54
|
-
|
55
|
-
context "single quoted data value" do
|
56
|
-
let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret' ORDER BY `table`.`id` ASC LIMIT 1" }
|
57
|
-
|
58
|
-
it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ? ORDER BY `table`.`id` ASC LIMIT ?"] }
|
59
|
-
|
60
|
-
context "with escaped single quotes in the string" do
|
61
|
-
let(:sql) { "`id` = 'this is a \'big\' secret'" }
|
62
|
-
|
63
|
-
it { should == ['Model load', "`id` = ?"] }
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context "double quoted data value" do
|
68
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = "secret"' }
|
69
|
-
|
70
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
71
|
-
|
72
|
-
context "with escaped double quotes in the string" do
|
73
|
-
let(:sql) { '`id` = "this is a \"big\" secret"' }
|
74
|
-
|
75
|
-
it { should == ['Model load', "`id` = ?"] }
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context "numeric parameter" do
|
80
|
-
context "integer" do
|
81
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = 1' }
|
82
|
-
|
83
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
84
|
-
end
|
85
|
-
|
86
|
-
context "float" do
|
87
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `value` = 10.0' }
|
88
|
-
|
89
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `value` = ?'] }
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
context "in operator with values" do
|
94
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` IN (1, 2)' }
|
95
|
-
|
96
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` IN (?)'] }
|
97
|
-
end
|
98
|
-
|
99
|
-
context "in operator with inner query" do
|
100
|
-
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` IN (SELECT `id` from `other_table` WHERE `value` = 10.0)' }
|
101
|
-
|
102
|
-
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` IN (SELECT `id` from `other_table` WHERE `value` = ?)'] }
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
context "with double quote style table names" do
|
107
|
-
let(:connection_config) { {:adapter => 'postgresql'} }
|
108
|
-
|
109
|
-
context "single quoted data value" do
|
110
|
-
let(:sql) { "SELECT \"table\".* FROM \"table\" WHERE \"id\" = 'secret' ORDER BY \"table\".\"id\" ASC LIMIT 1" }
|
111
|
-
|
112
|
-
it { should == ['Model load', "SELECT \"table\".* FROM \"table\" WHERE \"id\" = ? ORDER BY \"table\".\"id\" ASC LIMIT ?"] }
|
113
|
-
|
114
|
-
context "with an escaped single quote" do
|
115
|
-
let(:sql) { "\"id\" = 'this is a \'big\' secret'" }
|
116
|
-
|
117
|
-
it { should == ['Model load', "\"id\" = ?"] }
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context "numeric parameter" do
|
122
|
-
context "integer" do
|
123
|
-
let(:sql) { 'SELECT "table".* FROM "table" WHERE "id"=1' }
|
124
|
-
|
125
|
-
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "id"=?'] }
|
126
|
-
end
|
127
|
-
|
128
|
-
context "float" do
|
129
|
-
let(:sql) { 'SELECT "table".* FROM "table" WHERE "value"=10.0' }
|
130
|
-
|
131
|
-
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "value"=?'] }
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
context "return nil for schema queries" do
|
137
|
-
let(:name) { 'SCHEMA' }
|
138
|
-
let(:sql) { 'SET client_min_messages TO 22' }
|
139
|
-
|
140
|
-
it { should be_nil }
|
141
|
-
end
|
142
|
-
|
143
|
-
context "with a a frozen sql string" do
|
144
|
-
let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret'".freeze }
|
145
|
-
|
146
|
-
it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ?"] }
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
describe "#schema_query?" do
|
151
|
-
let(:payload) { {} }
|
152
|
-
subject { formatter.send(:schema_query?, payload) }
|
153
|
-
|
154
|
-
it { should be_false }
|
155
|
-
|
156
|
-
context "when name is schema" do
|
157
|
-
let(:payload) { {:name => 'SCHEMA'} }
|
7
|
+
it "should register sql.active_record" do
|
8
|
+
Appsignal::EventFormatter.registered?('sql.active_record', klass).should be_true
|
9
|
+
end
|
158
10
|
|
159
|
-
|
160
|
-
|
11
|
+
describe "#format" do
|
12
|
+
let(:payload) do
|
13
|
+
{
|
14
|
+
name: 'User load',
|
15
|
+
sql: 'SELECT * FROM users'
|
16
|
+
}
|
161
17
|
end
|
162
18
|
|
163
|
-
|
164
|
-
describe "#connection_config" do
|
165
|
-
let(:connection_config) { {:adapter => 'adapter'} }
|
166
|
-
|
167
|
-
subject { formatter.send(:connection_config) }
|
168
|
-
|
169
|
-
it { should == {:adapter => 'adapter'} }
|
170
|
-
end
|
171
|
-
|
172
|
-
describe "#adapter_uses_double_quoted_table_names" do
|
173
|
-
subject { formatter.adapter_uses_double_quoted_table_names }
|
19
|
+
subject { formatter.format(payload) }
|
174
20
|
|
175
|
-
|
176
|
-
let(:connection_config) { {:adapter => 'mysql'} }
|
177
|
-
|
178
|
-
it { should be_false }
|
179
|
-
end
|
180
|
-
|
181
|
-
context "when using postgresql" do
|
182
|
-
let(:connection_config) { {:adapter => 'postgresql'} }
|
183
|
-
|
184
|
-
it { should be_true }
|
185
|
-
end
|
186
|
-
|
187
|
-
context "when using sqlite" do
|
188
|
-
let(:connection_config) { {:adapter => 'sqlite'} }
|
189
|
-
|
190
|
-
it { should be_true }
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
21
|
+
it { should == ['User load', 'SELECT * FROM users', 1] }
|
194
22
|
end
|
195
23
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Appsignal::EventFormatter::MongoRubyDriver::QueryFormatter do
|
4
|
+
let(:formatter) { Appsignal::EventFormatter::MongoRubyDriver::QueryFormatter }
|
5
|
+
|
6
|
+
describe ".format" do
|
7
|
+
let(:strategy) { :find }
|
8
|
+
let(:command) do
|
9
|
+
{
|
10
|
+
"find" => "users",
|
11
|
+
"filter" => {"_id" => 1}
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should apply a strategy for each key" do
|
16
|
+
expect( formatter ).to receive(:apply_strategy)
|
17
|
+
.with(:sanitize_document, {"_id" => 1})
|
18
|
+
|
19
|
+
expect( formatter ).to receive(:apply_strategy)
|
20
|
+
.with(:allow, "users")
|
21
|
+
|
22
|
+
formatter.format(strategy, command)
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when strategy is unkown" do
|
26
|
+
let(:strategy) { :bananas }
|
27
|
+
|
28
|
+
it "should return an empty hash" do
|
29
|
+
expect( formatter.format(strategy, command) ).to eql({})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when command is not a hash " do
|
34
|
+
let(:command) { :bananas }
|
35
|
+
|
36
|
+
it "should return an empty hash" do
|
37
|
+
expect( formatter.format(strategy, command) ).to eql({})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe ".apply_strategy" do
|
43
|
+
context "when strategy is allow" do
|
44
|
+
let(:strategy) { :allow }
|
45
|
+
let(:value) { {"_id" => 1} }
|
46
|
+
|
47
|
+
it "should return the given value" do
|
48
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql(value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when strategy is deny" do
|
53
|
+
let(:strategy) { :deny }
|
54
|
+
let(:value) { {"_id" => 1} }
|
55
|
+
|
56
|
+
it "should return a '?'" do
|
57
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql('?')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when strategy is deny_array" do
|
62
|
+
let(:strategy) { :deny_array }
|
63
|
+
let(:value) { {"_id" => 1} }
|
64
|
+
|
65
|
+
it "should return a sanitized array string" do
|
66
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql("[?]")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when strategy is sanitize_document" do
|
71
|
+
let(:strategy) { :sanitize_document }
|
72
|
+
let(:value) { {"_id" => 1} }
|
73
|
+
|
74
|
+
it "should return a sanitized document" do
|
75
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql({"_id" => '?'})
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when strategy is sanitize_bulk" do
|
80
|
+
let(:strategy) { :sanitize_bulk }
|
81
|
+
let(:value) { [{"q" => {"_id" => 1}, "u" => [{"foo" => "bar"}]}] }
|
82
|
+
|
83
|
+
it "should return an array of sanitized bulk documents" do
|
84
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql([
|
85
|
+
{"q" => {"_id" => '?'}, "u" => '[?]'}
|
86
|
+
])
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when bulk has more than one update" do
|
90
|
+
let(:value) do
|
91
|
+
[
|
92
|
+
{"q" => {"_id" => 1}, "u" => [{"foo" => "bar"}]},
|
93
|
+
{"q" => {"_id" => 2}, "u" => [{"foo" => "baz"}]},
|
94
|
+
]
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should return only the first value of sanitized bulk documents" do
|
98
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql([
|
99
|
+
{"q" => {"_id" => '?'}, "u" => '[?]'},
|
100
|
+
"[...]"
|
101
|
+
])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "when strategy is missing" do
|
107
|
+
let(:strategy) { nil }
|
108
|
+
let(:value) { {"_id" => 1} }
|
109
|
+
|
110
|
+
it "should return a '?'" do
|
111
|
+
expect( formatter.apply_strategy(strategy, value) ).to eql('?')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|