click_session 0.0.1

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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +286 -0
  7. data/Rakefile +1 -0
  8. data/click_session.gemspec +36 -0
  9. data/lib/click_session/async.rb +45 -0
  10. data/lib/click_session/click_session_processor.rb +64 -0
  11. data/lib/click_session/configuration.rb +142 -0
  12. data/lib/click_session/exceptions.rb +12 -0
  13. data/lib/click_session/failure_status_reporter.rb +15 -0
  14. data/lib/click_session/notifier.rb +23 -0
  15. data/lib/click_session/response_serializer.rb +34 -0
  16. data/lib/click_session/s3_connection.rb +34 -0
  17. data/lib/click_session/s3_file_uploader.rb +24 -0
  18. data/lib/click_session/session_state.rb +64 -0
  19. data/lib/click_session/status_reporter.rb +81 -0
  20. data/lib/click_session/successful_status_reporter.rb +15 -0
  21. data/lib/click_session/sync.rb +76 -0
  22. data/lib/click_session/version.rb +3 -0
  23. data/lib/click_session/web_runner.rb +60 -0
  24. data/lib/click_session/web_runner_processor.rb +65 -0
  25. data/lib/click_session/webhook.rb +24 -0
  26. data/lib/click_session/webhook_model_serializer.rb +7 -0
  27. data/lib/click_session.rb +34 -0
  28. data/lib/generators/click_session/db/migration/create_session_states.rb +13 -0
  29. data/lib/generators/click_session/initializers/click_session.rb +4 -0
  30. data/lib/generators/click_session/install_generator.rb +54 -0
  31. data/lib/tasks/click_session.rake +52 -0
  32. data/spec/click_session/async_spec.rb +66 -0
  33. data/spec/click_session/click_session_processor_spec.rb +292 -0
  34. data/spec/click_session/configuration_spec.rb +168 -0
  35. data/spec/click_session/failure_status_reporter_spec.rb +87 -0
  36. data/spec/click_session/notifier_spec.rb +72 -0
  37. data/spec/click_session/response_serializer_spec.rb +50 -0
  38. data/spec/click_session/s3_file_uploader_spec.rb +24 -0
  39. data/spec/click_session/session_state_spec.rb +54 -0
  40. data/spec/click_session/status_reporter_spec.rb +199 -0
  41. data/spec/click_session/successful_status_reporter_spec.rb +85 -0
  42. data/spec/click_session/sync_spec.rb +259 -0
  43. data/spec/click_session/web_runner_processor_spec.rb +143 -0
  44. data/spec/click_session/web_runner_spec.rb +77 -0
  45. data/spec/click_session/webhook_spec.rb +75 -0
  46. data/spec/factories/test_unit_model_factory.rb +5 -0
  47. data/spec/spec_helper.rb +42 -0
  48. data/spec/support/click_session_runner.rb +5 -0
  49. data/spec/support/dummy_web_runner.rb +2 -0
  50. data/spec/support/schema.rb +16 -0
  51. data/spec/support/test_unit_model.rb +3 -0
  52. metadata +310 -0
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'click_session/configuration'
3
+ require 'click_session/exceptions'
4
+ require 'support/test_unit_model'
5
+
6
+ describe ClickSession::Async do
7
+ describe "#run" do
8
+ let(:model) {
9
+ create(:test_unit_model)
10
+ }
11
+
12
+ describe "guard clauses" do
13
+ context "when no callback urls has been configured" do
14
+ it "raises a friendly error" do
15
+ async_click_session = ClickSession::Async.new(model)
16
+
17
+ expect { async_click_session.run }.to raise_error(ClickSession::ConfigurationError)
18
+ end
19
+ end
20
+ end
21
+
22
+ context 'when processing is successful' do
23
+ before do
24
+ mock_configuration_model_class_with(model)
25
+ end
26
+
27
+ before :each do
28
+ mock_configuration_callback_urls
29
+ disable_screenshots
30
+ end
31
+
32
+ it "saves the session_state" do
33
+ async_click_session = ClickSession::Async.new(model)
34
+
35
+ expect { async_click_session.run }.
36
+ to change { ClickSession::SessionState.count }.by(1)
37
+ end
38
+
39
+ it "returns a serialized OK response without the model" do
40
+ async_click_session = ClickSession::Async.new(model)
41
+
42
+ response = async_click_session.run
43
+
44
+ expect(response[:id]).to be_a(Integer)
45
+ expect(response[:status][:success]).to be(true)
46
+ expect(response[:data]).to eql(model.as_json)
47
+ end
48
+ end
49
+ end
50
+
51
+ def mock_configuration_callback_urls
52
+ allow(ClickSession.configuration).
53
+ to receive(:success_callback_url).
54
+ and_return("http://success.callback.url")
55
+
56
+ allow(ClickSession.configuration).
57
+ to receive(:failure_callback_url).
58
+ and_return("http://failure.callback.url")
59
+ end
60
+
61
+ def disable_screenshots
62
+ allow(ClickSession.configuration).
63
+ to receive(:screenshot_enabled?).
64
+ and_return(false)
65
+ end
66
+ end
@@ -0,0 +1,292 @@
1
+ require 'spec_helper'
2
+ require 'click_session/configuration'
3
+ require 'support/test_unit_model'
4
+ require 'support/dummy_web_runner'
5
+
6
+ describe ClickSession::ClickSessionProcessor do
7
+ describe "#process" do
8
+ let(:model) {
9
+ create(:test_unit_model)
10
+ }
11
+
12
+ let(:session_state) do
13
+ ClickSession::SessionState.new(model: model)
14
+ end
15
+
16
+ before do
17
+ mock_model_class_in_in_configuration(model)
18
+ end
19
+
20
+ context 'when processing is successful' do
21
+ before do
22
+ @web_runner_processor_mock = mock_succesful_web_runner_processor
23
+ @notifier_mock = mock_for_notifier
24
+ end
25
+
26
+ it "processes the model" do
27
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
28
+ session_state,
29
+ @web_runner_processor_mock,
30
+ @notifier_mock
31
+ )
32
+
33
+ click_session_processor.process
34
+
35
+ expect(@web_runner_processor_mock).to have_received(:process).with(model)
36
+ end
37
+
38
+ it "changes the state of the session_state to 'processed'" do
39
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
40
+ session_state,
41
+ @web_runner_processor_mock,
42
+ @notifier_mock
43
+ )
44
+
45
+ click_session_processor.process
46
+
47
+ expect(ClickSession::SessionState.last.state_name).to eql(:processed)
48
+ end
49
+
50
+ it "returns the session_state" do
51
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
52
+ session_state,
53
+ @web_runner_processor_mock,
54
+ @notifier_mock
55
+ )
56
+
57
+ response = click_session_processor.process
58
+
59
+ expect(response).to be_a(ClickSession::SessionState)
60
+ end
61
+
62
+ it "sends a notification of the success" do
63
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
64
+ session_state,
65
+ @web_runner_processor_mock,
66
+ @notifier_mock
67
+ )
68
+
69
+ response = click_session_processor.process
70
+
71
+ expect(@notifier_mock).
72
+ to have_received(:session_successful).
73
+ with(session_state)
74
+ end
75
+
76
+
77
+ it "guards against faulty screenshot configurations" do
78
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
79
+ session_state,
80
+ @web_runner_processor_mock,
81
+ @notifier_mock,
82
+ screenshot_enabled: true,
83
+ screnshot: nil
84
+ )
85
+
86
+ expect { click_session_processor.process }.to raise_error(ClickSession::ConfigurationError)
87
+ end
88
+
89
+ context 'when saving screenshots is enabled' do
90
+ it "records the url of the screenshot" do
91
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
92
+ session_state,
93
+ @web_runner_processor_mock,
94
+ @notifier_mock,
95
+ screenshot_enabled: true,
96
+ screenshot_options: {
97
+ s3_bucket: "unit-s3",
98
+ s3_key_id: "unit-s3-key",
99
+ s3_access_key: "unit_s3_access_key"
100
+ }
101
+ )
102
+
103
+ response = click_session_processor.process
104
+
105
+ expect(@web_runner_processor_mock).to have_received(:save_screenshot)
106
+ expect(ClickSession::SessionState.last.screenshot_url).to be_a(String)
107
+ end
108
+ end
109
+
110
+ context "when saving screenshot is disabled" do
111
+ it "does not save the screenshot" do
112
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
113
+ session_state,
114
+ @web_runner_processor_mock,
115
+ @notifier_mock
116
+ )
117
+
118
+ response = click_session_processor.process
119
+
120
+ expect(@web_runner_processor_mock).not_to have_received(:save_screenshot)
121
+ expect(ClickSession::SessionState.last.screenshot_url).to be_nil
122
+ end
123
+ end
124
+ end
125
+
126
+ context 'when processing fails' do
127
+ before do
128
+ @web_runner_processor_mock = mock_failing_web_runner_processor
129
+ @notifier_mock = mock_for_notifier
130
+ end
131
+
132
+ it "processes the model" do
133
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
134
+ session_state,
135
+ @web_runner_processor_mock,
136
+ @notifier_mock
137
+ )
138
+
139
+ begin
140
+ click_session_processor.process
141
+ rescue ClickSession::TooManyRetriesError => e
142
+ expect(@web_runner_processor_mock).to have_received(:process).with(model)
143
+ end
144
+ end
145
+
146
+ it "changes the state of the session_state to 'failed_to_process'" do
147
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
148
+ session_state,
149
+ @web_runner_processor_mock,
150
+ @notifier_mock
151
+ )
152
+
153
+ begin
154
+ click_session_processor.process
155
+ rescue ClickSession::TooManyRetriesError => e
156
+ expect(ClickSession::SessionState.last.state_name).to eql(:failed_to_process)
157
+ end
158
+ end
159
+
160
+ it "raises a TooManyRetriesError" do
161
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
162
+ session_state,
163
+ @web_runner_processor_mock,
164
+ @notifier_mock
165
+ )
166
+
167
+ expect { click_session_processor.process }.
168
+ to raise_error(ClickSession::TooManyRetriesError)
169
+ end
170
+
171
+ it "sends a notification of the failure" do
172
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
173
+ session_state,
174
+ @web_runner_processor_mock,
175
+ @notifier_mock
176
+ )
177
+
178
+ begin
179
+ click_session_processor.process
180
+ rescue ClickSession::TooManyRetriesError => e
181
+ expect(@notifier_mock).
182
+ to have_received(:session_failed).
183
+ with(session_state)
184
+ end
185
+ end
186
+
187
+ context 'when saving screenshots is enabled' do
188
+ it "records the url of the screenshot" do
189
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
190
+ session_state,
191
+ @web_runner_processor_mock,
192
+ @notifier_mock,
193
+ screenshot_enabled: true,
194
+ screenshot_options: {
195
+ s3_bucket: "unit-s3",
196
+ s3_key_id: "unit-s3-key",
197
+ s3_access_key: "unit_s3_access_key"
198
+ }
199
+ )
200
+
201
+ begin
202
+ click_session_processor.process
203
+ rescue ClickSession::TooManyRetriesError => e
204
+ expect(@web_runner_processor_mock).to have_received(:save_screenshot)
205
+ expect(ClickSession::SessionState.last.screenshot_url).to be_a(String)
206
+ end
207
+ end
208
+ end
209
+
210
+ context "when saving screenshot is disabled" do
211
+ it "does not save the screenshot" do
212
+ click_session_processor = ClickSession::ClickSessionProcessor.new(
213
+ session_state,
214
+ @web_runner_processor_mock,
215
+ @notifier_mock
216
+ )
217
+
218
+ begin
219
+ click_session_processor.process
220
+ rescue ClickSession::TooManyRetriesError => e
221
+ expect(@web_runner_processor_mock).not_to have_received(:save_screenshot)
222
+ expect(ClickSession::SessionState.last.screenshot_url).to be_nil
223
+ end
224
+ end
225
+ end
226
+ end
227
+
228
+ def mock_succesful_web_runner_processor
229
+ processor_stub = DummyWebRunner.new
230
+ web_runner_processor_mock = ClickSession::WebRunnerProcessor.new(processor_stub)
231
+
232
+ allow(web_runner_processor_mock).
233
+ to receive(:process).
234
+ with(model).
235
+ and_return(model)
236
+
237
+ allow(web_runner_processor_mock).
238
+ to receive(:save_screenshot).
239
+ and_return("http://url.to/success-screenshot")
240
+
241
+ allow(ClickSession::WebRunnerProcessor).
242
+ to receive(:new).
243
+ and_return(web_runner_processor_mock)
244
+
245
+ web_runner_processor_mock
246
+ end
247
+
248
+ def mock_failing_web_runner_processor
249
+ processor_stub = DummyWebRunner.new
250
+ web_runner_processor_mock = ClickSession::WebRunnerProcessor.new(processor_stub)
251
+
252
+ allow(web_runner_processor_mock).
253
+ to receive(:process).
254
+ with(model).
255
+ and_raise(ClickSession::TooManyRetriesError, "Error in unit test")
256
+
257
+ allow(web_runner_processor_mock).
258
+ to receive(:save_screenshot).
259
+ and_return("http://url.to/failure-screenshot")
260
+
261
+ allow(ClickSession::WebRunnerProcessor).
262
+ to receive(:new).
263
+ and_return(web_runner_processor_mock)
264
+
265
+ web_runner_processor_mock
266
+ end
267
+
268
+ def mock_model_class_in_in_configuration(model_stub)
269
+ model_double = class_double(TestUnitModel)
270
+
271
+ # Mock the model_class from the configuration
272
+ allow(model_double).
273
+ to receive(:find_by_id).
274
+ with(model_stub.id).
275
+ and_return(model_stub)
276
+
277
+ allow(ClickSession.configuration).
278
+ to receive(:model_class).
279
+ and_return(model_double)
280
+ end
281
+
282
+ def mock_for_notifier
283
+ notifier_mock = ClickSession::Notifier.new
284
+
285
+ allow(notifier_mock).to receive(:session_failed)
286
+ allow(notifier_mock).to receive(:session_successful)
287
+ allow(notifier_mock).to receive(:rescued_error)
288
+
289
+ notifier_mock
290
+ end
291
+ end
292
+ end
@@ -0,0 +1,168 @@
1
+ require 'spec_helper'
2
+ require 'support/click_session_runner'
3
+
4
+ describe ClickSession::Configuration do
5
+ context 'no congifuration given' do
6
+ before do
7
+ ClickSession.configure
8
+ end
9
+
10
+ it 'provides defaults' do
11
+ expect(ClickSession.configuration.processor_class).to eq(ClickSessionRunner)
12
+ expect(ClickSession.configuration.serializer_class).to eq(ClickSession::WebhookModelSerializer)
13
+ expect(ClickSession.configuration.notifier_class).to eq(ClickSession::Notifier)
14
+ expect(ClickSession.configuration.driver_client).to eq(:poltergeist)
15
+ expect(ClickSession.configuration.screenshot_enabled?).to eq(false)
16
+ expect{ ClickSession.configuration.screenshot }.to raise_error
17
+ end
18
+
19
+ it 'raises a helpful error if model_class_name is undefined' do
20
+ expect { ClickSession.configuration.model_class }.
21
+ to raise_error(NameError, %r{https://github\.com/talltorp/click_session})
22
+ end
23
+
24
+ it 'raises a helpful error if ClickSessionRunner is undefined' do
25
+ allow(Kernel).to receive_messages(const_defined?: false)
26
+
27
+ expect { ClickSession.configuration.processor_class }.
28
+ to raise_error(NameError, %r{https://github\.com/talltorp/click_session})
29
+ end
30
+ end
31
+
32
+ context 'with config block' do
33
+ after do
34
+ ClickSession.configure
35
+ end
36
+
37
+ it "stores the model_class" do
38
+ class DummyModelClass
39
+ end
40
+
41
+ ClickSession.configure do | config |
42
+ config.model_class = DummyModelClass
43
+ end
44
+
45
+ expect(ClickSession.configuration.model_class).to eq(DummyModelClass)
46
+ end
47
+
48
+ it "stores the processor_class" do
49
+ class DummyProcessorClass
50
+ end
51
+
52
+ ClickSession.configure do | config |
53
+ config.processor_class = DummyProcessorClass
54
+ end
55
+
56
+ expect(ClickSession.configuration.processor_class).to eq(DummyProcessorClass)
57
+ end
58
+
59
+ it "stores the serializer_class" do
60
+ class DummySerializerClass
61
+ end
62
+
63
+ ClickSession.configure do | config |
64
+ config.serializer_class = DummySerializerClass
65
+ end
66
+
67
+ expect(ClickSession.configuration.serializer_class).to eq(DummySerializerClass)
68
+ end
69
+
70
+ it "stores the notifier_class" do
71
+ class DummyNotifierClass < ClickSession::Notifier
72
+ end
73
+
74
+ ClickSession.configure do | config |
75
+ config.notifier_class = DummyNotifierClass
76
+ end
77
+
78
+ expect(ClickSession.configuration.notifier_class).to eq(DummyNotifierClass)
79
+ end
80
+
81
+ context 'when the provided notifier_class does not extend the base Notifier' do
82
+ it "raises an helpful message" do
83
+ class SerializerNotExtendingBaseNotifer
84
+ def session_successful
85
+ end
86
+ end
87
+
88
+ ClickSession.configure do | config |
89
+ config.notifier_class = SerializerNotExtendingBaseNotifer
90
+ end
91
+
92
+ expect{ ClickSession.configuration.notifier_class }.
93
+ to raise_error(ArgumentError)
94
+ end
95
+ end
96
+
97
+ it "stores the driver_client" do
98
+ ClickSession.configure do | config |
99
+ config.driver_client = :selenium
100
+ end
101
+
102
+ expect(ClickSession.configuration.driver_client).to eq(:selenium)
103
+ end
104
+
105
+ it "stores the enable_screenshot flag" do
106
+ ClickSession.configure do | config |
107
+ config.enable_screenshot = true
108
+ end
109
+
110
+ expect(ClickSession.configuration.screenshot_enabled?).to eq(true)
111
+ end
112
+
113
+ context 'with complete screenshot information' do
114
+ it "stores the screenshot information" do
115
+ ClickSession.configure do | config |
116
+ config.screenshot = {
117
+ s3_bucket: "unit-bucket",
118
+ s3_key_id: "unit-key-id",
119
+ s3_access_key: "unit-access-key",
120
+ }
121
+ end
122
+
123
+ expect(ClickSession.configuration.screenshot).not_to be_nil
124
+ end
125
+ end
126
+
127
+ context 'with incomplete screenshot information' do
128
+ context 'with no :s3_bucket' do
129
+ it "raises an ArgumentError" do
130
+ expect do
131
+ ClickSession.configure do | config |
132
+ config.screenshot = {
133
+ s3_key_id: "unit-key-id",
134
+ s3_access_key: "unit-access-key",
135
+ }
136
+ end
137
+ end.to raise_error(ArgumentError)
138
+ end
139
+ end
140
+
141
+ context 'with no :s3_key_id' do
142
+ it "raises an ArgumentError" do
143
+ expect do
144
+ ClickSession.configure do | config |
145
+ config.screenshot = {
146
+ s3_bucket: "unit-bucket",
147
+ s3_access_key: "unit-access-key",
148
+ }
149
+ end
150
+ end.to raise_error(ArgumentError)
151
+ end
152
+ end
153
+
154
+ context 'with no :s3_access_key' do
155
+ it "raises an ArgumentError" do
156
+ expect do
157
+ ClickSession.configure do | config |
158
+ config.screenshot = {
159
+ s3_bucket: "unit-bucket",
160
+ s3_key_id: "unit-key-id",
161
+ }
162
+ end
163
+ end.to raise_error(ArgumentError)
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,87 @@
1
+ require "spec_helper"
2
+ require "click_session/configuration"
3
+ require "support/test_unit_model"
4
+
5
+ describe ClickSession::FailureStatusReporter do
6
+ describe "#report" do
7
+ let(:model) do
8
+ create(:test_unit_model)
9
+ end
10
+
11
+ before do
12
+ stub_notifier_in_configuration
13
+ end
14
+
15
+ it "rejects shippings not processed" do
16
+ session_state = build_session_state_in_not_processed_state
17
+ status_reporter = ClickSession::FailureStatusReporter.new
18
+
19
+ expect { status_reporter.report(session_state) }.
20
+ to raise_error(ArgumentError)
21
+ end
22
+
23
+ it "rejects shippings successfully processed" do
24
+ session_state = build_session_state_in_successfully_processed_state
25
+ status_reporter = ClickSession::FailureStatusReporter.new
26
+
27
+ expect { status_reporter.report(session_state) }.
28
+ to raise_error(ArgumentError)
29
+ end
30
+
31
+ it "reports with an ERROR status" do
32
+ stub_notifier_in_configuration
33
+ session_state = build_session_state_in_failed_state
34
+ webhook_stub = ClickSession::Webhook.new("failure.url")
35
+ allow(webhook_stub).to receive(:call)
36
+
37
+ status_reporter = ClickSession::FailureStatusReporter.new(
38
+ webhook_stub
39
+ )
40
+
41
+ status_reporter.report(session_state)
42
+
43
+ expect(webhook_stub).
44
+ to have_received(:call).
45
+ with({
46
+ id: session_state.id,
47
+ status: {
48
+ success: false,
49
+ message: "See error logs"
50
+ }
51
+ })
52
+ end
53
+
54
+ def stub_notifier_in_configuration
55
+ notifier_double = class_double(ClickSession::Notifier)
56
+ notifier_stub = ClickSession::Notifier.new
57
+
58
+ # Stub the methods
59
+ allow(notifier_stub).
60
+ to receive(:session_reported)
61
+
62
+ # Add the stub to the double
63
+ allow(notifier_double).
64
+ to receive(:new).
65
+ and_return(notifier_stub)
66
+
67
+ # Make the configuration return our double
68
+ allow(ClickSession.configuration).
69
+ to receive(:notifier_class).
70
+ and_return(notifier_double)
71
+
72
+ notifier_stub
73
+ end
74
+
75
+ def build_session_state_in_successfully_processed_state
76
+ ClickSession::SessionState.create(state: 1, model_record: model.id)
77
+ end
78
+
79
+ def build_session_state_in_failed_state
80
+ ClickSession::SessionState.create(state: 2, model_record: model.id)
81
+ end
82
+
83
+ def build_session_state_in_not_processed_state
84
+ ClickSession::SessionState.create(state: 0, model_record: model.id)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'support/test_unit_model'
3
+
4
+ describe ClickSession::Notifier do
5
+ describe "#session_successful" do
6
+ it "logs success information about the click_session to stdout" do
7
+ session_state = ClickSession::SessionState.create({
8
+ state: 1,
9
+ model: build(:test_unit_model)
10
+ })
11
+ notifier = ClickSession::Notifier.new
12
+
13
+ expect { notifier.session_successful(session_state) }.
14
+ to output(/SUCCESS(.*)#{session_state.id}/).
15
+ to_stdout
16
+ end
17
+ end
18
+
19
+ describe "#session_failed" do
20
+ it "logs failure information about the click_session to stdout" do
21
+ session_state = ClickSession::SessionState.create({
22
+ state: 2,
23
+ model: build(:test_unit_model)
24
+ })
25
+ notifier = ClickSession::Notifier.new
26
+
27
+ expect { notifier.session_failed(session_state) }.
28
+ to output(/FAILURE(.*)#{session_state.id}/).
29
+ to_stderr
30
+ end
31
+ end
32
+
33
+ describe "#session_reported" do
34
+ it "logs report success information about the click_session to stdout" do
35
+ session_state = ClickSession::SessionState.create({
36
+ state: 1,
37
+ model: build(:test_unit_model)
38
+ })
39
+ notifier = ClickSession::Notifier.new
40
+
41
+ expect { notifier.session_reported(session_state) }.
42
+ to output(/REPORTED(.*)#{session_state.id}/).
43
+ to_stdout
44
+ end
45
+ end
46
+
47
+ describe "#session_failed_to_report" do
48
+ it "logs that the report failed for the click_session to stdout" do
49
+ session_state = ClickSession::SessionState.create({
50
+ state: 2,
51
+ model: build(:test_unit_model)
52
+ })
53
+ notifier = ClickSession::Notifier.new
54
+
55
+ expect { notifier.session_failed_to_report(session_state) }.
56
+ to output(/REPORT_FAIL(.*)#{session_state.id}/).
57
+ to_stderr
58
+ end
59
+ end
60
+
61
+ describe "#rescued_error" do
62
+ it "logs the exception to stdout" do
63
+ exception = ArgumentError.new("unit argument error")
64
+
65
+ notifier = ClickSession::Notifier.new
66
+
67
+ expect { notifier.rescued_error(exception) }.
68
+ to output(/ArgumentError/).
69
+ to_stdout
70
+ end
71
+ end
72
+ end