activeinteractor 1.0.0.beta.3 → 1.0.0.beta.4

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.
@@ -0,0 +1,162 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe ActiveInteractor::Organizer::InteractorInterface do
6
+ describe '.new' do
7
+ subject(:instance) { described_class.new(interactor_class, options) }
8
+
9
+ context 'with an interactor that does not exist' do
10
+ let(:interactor_class) { :an_interactor_that_does_not_exist }
11
+ let(:options) { {} }
12
+
13
+ describe '#interactor_class' do
14
+ subject { instance.interactor_class }
15
+
16
+ it { is_expected.to be_nil }
17
+ end
18
+ end
19
+
20
+ RSpec.shared_examples 'an instance of InteractorInterface correctly parse options' do
21
+ context 'with options {:if => :some_method }' do
22
+ let(:options) { { if: :some_method } }
23
+
24
+ describe '#filters' do
25
+ subject { instance.filters }
26
+
27
+ it { is_expected.to eq(if: :some_method) }
28
+ end
29
+
30
+ describe '#perform_options' do
31
+ subject { instance.perform_options }
32
+
33
+ it { is_expected.to be_empty }
34
+ end
35
+ end
36
+
37
+ context 'with options {:if => -> { context.test == true } }' do
38
+ let(:options) { { if: -> { context.test == true } } }
39
+
40
+ describe '#filters' do
41
+ subject { instance.filters }
42
+
43
+ it { expect(subject[:if]).not_to be_nil }
44
+ it { expect(subject[:if]).to be_a Proc }
45
+ end
46
+
47
+ describe '#perform_options' do
48
+ subject { instance.perform_options }
49
+
50
+ it { is_expected.to be_empty }
51
+ end
52
+ end
53
+
54
+ context 'with options {:unless => :some_method }' do
55
+ let(:options) { { unless: :some_method } }
56
+
57
+ describe '#filters' do
58
+ subject { instance.filters }
59
+
60
+ it { is_expected.to eq(unless: :some_method) }
61
+ end
62
+
63
+ describe '#perform_options' do
64
+ subject { instance.perform_options }
65
+
66
+ it { is_expected.to be_empty }
67
+ end
68
+ end
69
+
70
+ context 'with options {:unless => -> { context.test == true } }' do
71
+ let(:options) { { unless: -> { context.test == true } } }
72
+
73
+ describe '#filters' do
74
+ subject { instance.filters }
75
+
76
+ it { expect(subject[:unless]).not_to be_nil }
77
+ it { expect(subject[:unless]).to be_a Proc }
78
+ end
79
+
80
+ describe '#perform_options' do
81
+ subject { instance.perform_options }
82
+
83
+ it { is_expected.to be_empty }
84
+ end
85
+ end
86
+
87
+ context 'with options { :validate => false }' do
88
+ let(:options) { { validate: false } }
89
+
90
+ describe '#filters' do
91
+ subject { instance.filters }
92
+
93
+ it { is_expected.to be_empty }
94
+ end
95
+
96
+ describe '#perform_options' do
97
+ subject { instance.perform_options }
98
+
99
+ it { is_expected.to eq(validate: false) }
100
+ end
101
+ end
102
+
103
+ context 'with options { :if => :some_method, :validate => false }' do
104
+ let(:options) { { if: :some_method, validate: false } }
105
+
106
+ describe '#filters' do
107
+ subject { instance.filters }
108
+
109
+ it { is_expected.to eq(if: :some_method) }
110
+ end
111
+
112
+ describe '#perform_options' do
113
+ subject { instance.perform_options }
114
+
115
+ it { is_expected.to eq(validate: false) }
116
+ end
117
+ end
118
+ end
119
+
120
+ context 'with an existing interactor' do
121
+ before { build_interactor }
122
+
123
+ context 'when interactors are passed as contants' do
124
+ let(:interactor_class) { TestInteractor }
125
+ let(:options) { {} }
126
+
127
+ include_examples 'an instance of InteractorInterface correctly parse options'
128
+
129
+ describe '#interactor_class' do
130
+ subject { instance.interactor_class }
131
+
132
+ it { is_expected.to eq TestInteractor }
133
+ end
134
+ end
135
+
136
+ context 'when interactors are passed as symbols' do
137
+ let(:interactor_class) { :test_interactor }
138
+ let(:options) { {} }
139
+
140
+ include_examples 'an instance of InteractorInterface correctly parse options'
141
+
142
+ describe '#interactor_class' do
143
+ subject { instance.interactor_class }
144
+
145
+ it { is_expected.to eq TestInteractor }
146
+ end
147
+ end
148
+
149
+ context 'when interactors are passed as strings' do
150
+ let(:interactor_class) { 'TestInteractor' }
151
+ let(:options) { {} }
152
+ include_examples 'an instance of InteractorInterface correctly parse options'
153
+
154
+ describe '#interactor_class' do
155
+ subject { instance.interactor_class }
156
+
157
+ it { is_expected.to eq TestInteractor }
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -51,58 +51,46 @@ RSpec.describe ActiveInteractor::Organizer do
51
51
  end
52
52
 
53
53
  describe '.organize' do
54
- subject { interactor_class }
55
54
  context 'with two existing interactors' do
56
55
  let!(:interactor1) { build_interactor('TestInteractor1') }
57
56
  let!(:interactor2) { build_interactor('TestInteractor2') }
58
57
 
59
- context 'when interactors are passed as contants' do
60
- let(:interactor_class) do
61
- build_organizer do
62
- organize TestInteractor1, TestInteractor2
63
- end
64
- end
65
-
66
- it { is_expected.to have_attributes(organized: [TestInteractor1, TestInteractor2]) }
67
- end
68
-
69
- context 'when interactors are passed as symbols' do
70
- let(:interactor_class) do
58
+ context 'when interactors are passed as args' do
59
+ let(:organizer) do
71
60
  build_organizer do
72
61
  organize :test_interactor_1, :test_interactor_2
73
62
  end
74
63
  end
75
64
 
76
- it { is_expected.to have_attributes(organized: [TestInteractor1, TestInteractor2]) }
65
+ describe '.organized' do
66
+ subject { organizer.organized }
77
67
 
78
- context 'having a non existance interactor' do
79
- let(:interactor_class) do
80
- build_organizer do
81
- organize :test_interactor_1, :interactor_that_doesnt_exist, :test_interactor_2
82
- end
68
+ it { expect(subject.collection).to all(be_a ActiveInteractor::Organizer::InteractorInterface) }
69
+ it 'is expected to organize the approriate interactors' do
70
+ expect(subject.collection.first.interactor_class).to eq TestInteractor1
71
+ expect(subject.collection.last.interactor_class).to eq TestInteractor2
83
72
  end
84
-
85
- it { is_expected.to have_attributes(organized: [TestInteractor1, TestInteractor2]) }
86
73
  end
87
74
  end
88
75
 
89
- context 'when interactors are passed as strings' do
90
- let(:interactor_class) do
76
+ context 'when a block is passed' do
77
+ let(:organizer) do
91
78
  build_organizer do
92
- organize 'TestInteractor1', 'TestInteractor2'
79
+ organize do
80
+ add :test_interactor_1
81
+ add :test_interactor_2
82
+ end
93
83
  end
94
84
  end
95
85
 
96
- it { is_expected.to have_attributes(organized: [TestInteractor1, TestInteractor2]) }
86
+ describe '.organized' do
87
+ subject { organizer.organized }
97
88
 
98
- context 'having a non existance interactor' do
99
- let(:interactor_class) do
100
- build_organizer do
101
- organize 'TestInteractor1', 'InteractorThatDoesntExist', 'TestInteractor2'
102
- end
89
+ it { expect(subject.collection).to all(be_a ActiveInteractor::Organizer::InteractorInterface) }
90
+ it 'is expected to organize the approriate interactors' do
91
+ expect(subject.collection.first.interactor_class).to eq TestInteractor1
92
+ expect(subject.collection.last.interactor_class).to eq TestInteractor2
103
93
  end
104
-
105
- it { is_expected.to have_attributes(organized: [TestInteractor1, TestInteractor2]) }
106
94
  end
107
95
  end
108
96
  end
@@ -126,6 +114,22 @@ RSpec.describe ActiveInteractor::Organizer do
126
114
  subject
127
115
  end
128
116
 
117
+ context 'with options :skip_each_perform_callbacks eq to true' do
118
+ subject { interactor_class.perform({}, skip_each_perform_callbacks: true) }
119
+
120
+ it { is_expected.to be_a interactor_class.context_class }
121
+ it 'is expected to invoke #perform on both interactors' do
122
+ expect_any_instance_of(interactor1).to receive(:perform)
123
+ expect_any_instance_of(interactor2).to receive(:perform)
124
+ subject
125
+ end
126
+ it 'is expected not to invoke #run_callbacks with :each_perform' do
127
+ expect_any_instance_of(interactor_class).not_to receive(:run_callbacks)
128
+ .with(:each_perform)
129
+ subject
130
+ end
131
+ end
132
+
129
133
  context 'when the first interactor context fails' do
130
134
  let!(:interactor1) do
131
135
  build_interactor('TestInteractor1') do
@@ -115,12 +115,6 @@ RSpec.describe 'Basic Integration', type: :integration do
115
115
  it { is_expected.to be < ActiveInteractor::Context::Base }
116
116
  end
117
117
 
118
- describe '.organized' do
119
- subject { interactor_class.organized }
120
-
121
- it { is_expected.to eq [TestInteractor1, TestInteractor2] }
122
- end
123
-
124
118
  describe '.perform' do
125
119
  subject { interactor_class.perform }
126
120
 
@@ -254,12 +248,6 @@ RSpec.describe 'Basic Integration', type: :integration do
254
248
  it { is_expected.to be < ActiveInteractor::Context::Base }
255
249
  end
256
250
 
257
- describe '.organized' do
258
- subject { interactor_class.organized }
259
-
260
- it { is_expected.to eq [TestInteractor1, TestInteractor2] }
261
- end
262
-
263
251
  describe '.perform' do
264
252
  subject { interactor_class.perform }
265
253
 
@@ -268,4 +256,315 @@ RSpec.describe 'Basic Integration', type: :integration do
268
256
  it { is_expected.to have_attributes(test_field_1: 'test 1', test_field_2: 'test 2') }
269
257
  end
270
258
  end
259
+
260
+ describe 'A basic with conditionally organized interactors' do
261
+ let!(:test_interactor_1) { build_interactor('TestInteractor1') }
262
+ let!(:test_interactor_2) { build_interactor('TestInteractor2') }
263
+
264
+ context 'with a condition on the first interactor { :if => -> { context.test_1 } } ' \
265
+ 'and a condition on the second interactor { :if => -> { context.test_2 } }' do
266
+ let(:interactor_class) do
267
+ build_organizer do
268
+ organize do
269
+ add :test_interactor_1, if: -> { context.test_1 }
270
+ add :test_interactor_2, if: -> { context.test_2 }
271
+ end
272
+ end
273
+ end
274
+
275
+ include_examples 'a class with interactor methods'
276
+ include_examples 'a class with interactor callback methods'
277
+ include_examples 'a class with interactor context methods'
278
+ include_examples 'a class with organizer callback methods'
279
+
280
+ describe '.perform' do
281
+ subject { interactor_class.perform(context_attributes) }
282
+
283
+ context 'with context_attributes test_1 and test_2 both eq to true' do
284
+ let(:context_attributes) { { test_1: true, test_2: true } }
285
+
286
+ it { is_expected.to be_a interactor_class.context_class }
287
+ it { is_expected.to be_successful }
288
+ it 'is expected to invoke #perform on both interactors' do
289
+ expect_any_instance_of(test_interactor_1).to receive(:perform)
290
+ expect_any_instance_of(test_interactor_2).to receive(:perform)
291
+ subject
292
+ end
293
+ end
294
+
295
+ context 'with context_attributes test_1 eq to true and test_2 eq to false' do
296
+ let(:context_attributes) { { test_1: true, test_2: false } }
297
+
298
+ it { is_expected.to be_a interactor_class.context_class }
299
+ it { is_expected.to be_successful }
300
+ it 'is expected to invoke #perform on the first interactor' do
301
+ expect_any_instance_of(test_interactor_1).to receive(:perform)
302
+ subject
303
+ end
304
+
305
+ it 'is expected not to invoke #perform on the first interactor' do
306
+ expect_any_instance_of(test_interactor_2).not_to receive(:perform)
307
+ subject
308
+ end
309
+ end
310
+
311
+ context 'with context_attributes test_1 eq to false and test_2 eq to true' do
312
+ let(:context_attributes) { { test_1: false, test_2: true } }
313
+
314
+ it { is_expected.to be_a interactor_class.context_class }
315
+ it { is_expected.to be_successful }
316
+ it 'is expected not to invoke #perform on the first interactor' do
317
+ expect_any_instance_of(test_interactor_1).not_to receive(:perform)
318
+ subject
319
+ end
320
+
321
+ it 'is expected to invoke #perform on the first interactor' do
322
+ expect_any_instance_of(test_interactor_2).to receive(:perform)
323
+ subject
324
+ end
325
+ end
326
+
327
+ context 'with context_attributes test_1 and test_2 both eq to false' do
328
+ let(:context_attributes) { { test_1: false, test_2: false } }
329
+
330
+ it { is_expected.to be_a interactor_class.context_class }
331
+ it { is_expected.to be_successful }
332
+ it 'is expected not to invoke #perform on the first interactor' do
333
+ expect_any_instance_of(test_interactor_1).not_to receive(:perform)
334
+ subject
335
+ end
336
+
337
+ it 'is expected not to invoke #perform on the first interactor' do
338
+ expect_any_instance_of(test_interactor_2).not_to receive(:perform)
339
+ subject
340
+ end
341
+ end
342
+ end
343
+ end
344
+
345
+ context 'with a condition on the first interactor { :unless => -> { context.test_1 } } ' \
346
+ 'and a condition on the second interactor { :unless => -> { context.test_2 } }' do
347
+ let(:interactor_class) do
348
+ build_organizer do
349
+ organize do
350
+ add :test_interactor_1, unless: -> { context.test_1 }
351
+ add :test_interactor_2, unless: -> { context.test_2 }
352
+ end
353
+ end
354
+ end
355
+
356
+ include_examples 'a class with interactor methods'
357
+ include_examples 'a class with interactor callback methods'
358
+ include_examples 'a class with interactor context methods'
359
+ include_examples 'a class with organizer callback methods'
360
+
361
+ describe '.perform' do
362
+ subject { interactor_class.perform(context_attributes) }
363
+
364
+ context 'with context_attributes test_1 and test_2 both eq to true' do
365
+ let(:context_attributes) { { test_1: true, test_2: true } }
366
+
367
+ it { is_expected.to be_a interactor_class.context_class }
368
+ it { is_expected.to be_successful }
369
+ it 'is expected not to invoke #perform on the first interactor' do
370
+ expect_any_instance_of(test_interactor_1).not_to receive(:perform)
371
+ subject
372
+ end
373
+
374
+ it 'is expected not to invoke #perform on the second interactor' do
375
+ expect_any_instance_of(test_interactor_2).not_to receive(:perform)
376
+ subject
377
+ end
378
+ end
379
+
380
+ context 'with context_attributes test_1 eq to true and test_2 eq to false' do
381
+ let(:context_attributes) { { test_1: true, test_2: false } }
382
+
383
+ it { is_expected.to be_a interactor_class.context_class }
384
+ it { is_expected.to be_successful }
385
+ it 'is expected not to invoke #perform on the first interactor' do
386
+ expect_any_instance_of(test_interactor_1).not_to receive(:perform)
387
+ subject
388
+ end
389
+
390
+ it 'is expected to invoke #perform on the second interactor' do
391
+ expect_any_instance_of(test_interactor_2).to receive(:perform)
392
+ subject
393
+ end
394
+ end
395
+
396
+ context 'with context_attributes test_1 eq to false and test_2 eq to true' do
397
+ let(:context_attributes) { { test_1: false, test_2: true } }
398
+
399
+ it { is_expected.to be_a interactor_class.context_class }
400
+ it { is_expected.to be_successful }
401
+ it 'is expected to invoke #perform on the first interactor' do
402
+ expect_any_instance_of(test_interactor_1).to receive(:perform)
403
+ subject
404
+ end
405
+
406
+ it 'is expected not to invoke #perform on the second interactor' do
407
+ expect_any_instance_of(test_interactor_2).not_to receive(:perform)
408
+ subject
409
+ end
410
+ end
411
+
412
+ context 'with context_attributes test_1 and test_2 both eq to false' do
413
+ let(:context_attributes) { { test_1: false, test_2: false } }
414
+
415
+ it { is_expected.to be_a interactor_class.context_class }
416
+ it { is_expected.to be_successful }
417
+ it 'is expected to invoke #perform on both interactors' do
418
+ expect_any_instance_of(test_interactor_1).to receive(:perform)
419
+ expect_any_instance_of(test_interactor_2).to receive(:perform)
420
+ subject
421
+ end
422
+ end
423
+ end
424
+ end
425
+
426
+ context 'with a condition on the first interactor { :if => :test_method } and :test_method returning true' do
427
+ let(:interactor_class) do
428
+ build_organizer do
429
+ organize do
430
+ add :test_interactor_1, if: :test_method
431
+ add :test_interactor_2
432
+ end
433
+
434
+ private
435
+
436
+ def test_method
437
+ true
438
+ end
439
+ end
440
+ end
441
+
442
+ include_examples 'a class with interactor methods'
443
+ include_examples 'a class with interactor callback methods'
444
+ include_examples 'a class with interactor context methods'
445
+ include_examples 'a class with organizer callback methods'
446
+
447
+ describe '.perform' do
448
+ subject { interactor_class.perform }
449
+
450
+ it { is_expected.to be_a interactor_class.context_class }
451
+ it { is_expected.to be_successful }
452
+ it 'is expected to invoke #perform on both interactors' do
453
+ expect_any_instance_of(test_interactor_1).to receive(:perform)
454
+ expect_any_instance_of(test_interactor_2).to receive(:perform)
455
+ subject
456
+ end
457
+ end
458
+ end
459
+
460
+ context 'with a condition on the first interactor { :if => :test_method } and :test_method returning false' do
461
+ let(:interactor_class) do
462
+ build_organizer do
463
+ organize do
464
+ add :test_interactor_1, if: :test_method
465
+ add :test_interactor_2
466
+ end
467
+
468
+ private
469
+
470
+ def test_method
471
+ false
472
+ end
473
+ end
474
+ end
475
+
476
+ include_examples 'a class with interactor methods'
477
+ include_examples 'a class with interactor callback methods'
478
+ include_examples 'a class with interactor context methods'
479
+ include_examples 'a class with organizer callback methods'
480
+
481
+ describe '.perform' do
482
+ subject { interactor_class.perform }
483
+
484
+ it { is_expected.to be_a interactor_class.context_class }
485
+ it { is_expected.to be_successful }
486
+ it 'is expected not to invoke #perform on the first interactor' do
487
+ expect_any_instance_of(test_interactor_1).not_to receive(:perform)
488
+ subject
489
+ end
490
+
491
+ it 'is expected to invoke #perform on the second interactor' do
492
+ expect_any_instance_of(test_interactor_2).to receive(:perform)
493
+ subject
494
+ end
495
+ end
496
+ end
497
+
498
+ context 'with a condition on the first interactor { :unless => :test_method } and :test_method returning true' do
499
+ let(:interactor_class) do
500
+ build_organizer do
501
+ organize do
502
+ add :test_interactor_1, unless: :test_method
503
+ add :test_interactor_2
504
+ end
505
+
506
+ private
507
+
508
+ def test_method
509
+ true
510
+ end
511
+ end
512
+ end
513
+
514
+ include_examples 'a class with interactor methods'
515
+ include_examples 'a class with interactor callback methods'
516
+ include_examples 'a class with interactor context methods'
517
+ include_examples 'a class with organizer callback methods'
518
+
519
+ describe '.perform' do
520
+ subject { interactor_class.perform }
521
+
522
+ it { is_expected.to be_a interactor_class.context_class }
523
+ it { is_expected.to be_successful }
524
+ it 'is expected not to invoke #perform on the first interactor' do
525
+ expect_any_instance_of(test_interactor_1).not_to receive(:perform)
526
+ subject
527
+ end
528
+
529
+ it 'is expected to invoke #perform on the second interactor' do
530
+ expect_any_instance_of(test_interactor_2).to receive(:perform)
531
+ subject
532
+ end
533
+ end
534
+ end
535
+
536
+ context 'with a condition on the first interactor { :unless => :test_method } and :test_method returning false' do
537
+ let(:interactor_class) do
538
+ build_organizer do
539
+ organize do
540
+ add :test_interactor_1, unless: :test_method
541
+ add :test_interactor_2
542
+ end
543
+
544
+ private
545
+
546
+ def test_method
547
+ false
548
+ end
549
+ end
550
+ end
551
+
552
+ include_examples 'a class with interactor methods'
553
+ include_examples 'a class with interactor callback methods'
554
+ include_examples 'a class with interactor context methods'
555
+ include_examples 'a class with organizer callback methods'
556
+
557
+ describe '.perform' do
558
+ subject { interactor_class.perform }
559
+
560
+ it { is_expected.to be_a interactor_class.context_class }
561
+ it { is_expected.to be_successful }
562
+ it 'is expected to invoke #perform on both interactors' do
563
+ expect_any_instance_of(test_interactor_1).to receive(:perform)
564
+ expect_any_instance_of(test_interactor_2).to receive(:perform)
565
+ subject
566
+ end
567
+ end
568
+ end
569
+ end
271
570
  end