racf 0.6.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.
Files changed (63) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +18 -0
  4. data/Gemfile +14 -0
  5. data/Gemfile.lock +40 -0
  6. data/README.rdoc +56 -0
  7. data/Rakefile +9 -0
  8. data/TODO.txt +5 -0
  9. data/config/racf.yml.sample +27 -0
  10. data/lib/racf.rb +78 -0
  11. data/lib/racf/client.rb +138 -0
  12. data/lib/racf/commands/abstract_command.rb +13 -0
  13. data/lib/racf/commands/listgrp.rb +189 -0
  14. data/lib/racf/commands/listgrp/group_members_parser.rb +104 -0
  15. data/lib/racf/commands/listuser.rb +112 -0
  16. data/lib/racf/commands/rlist.rb +208 -0
  17. data/lib/racf/commands/search.rb +31 -0
  18. data/lib/racf/pagers/cached_ispf_pager.rb +91 -0
  19. data/lib/racf/pagers/ispf_pager.rb +57 -0
  20. data/lib/racf/s3270.rb +136 -0
  21. data/lib/racf/session.rb +149 -0
  22. data/lib/racf/version.rb +3 -0
  23. data/racf.gemspec +16 -0
  24. data/script/ci +3 -0
  25. data/spec/fixtures/config/racf.yml +9 -0
  26. data/spec/fixtures/listgrp/multiple_groups_multiple_members.txt +26 -0
  27. data/spec/fixtures/listgrp/multiple_members.txt +10 -0
  28. data/spec/fixtures/listgrp/no_members.txt +4 -0
  29. data/spec/fixtures/listgrp/not_found_groups.txt +21 -0
  30. data/spec/fixtures/listgrp/one_group.txt +7 -0
  31. data/spec/fixtures/listgrp/one_group_with_members.txt +13 -0
  32. data/spec/fixtures/listgrp/one_member.txt +7 -0
  33. data/spec/fixtures/listuser/all_users.txt +45 -0
  34. data/spec/fixtures/listuser/just_users_not_found.txt +3 -0
  35. data/spec/fixtures/listuser/one_user.txt +47 -0
  36. data/spec/fixtures/listuser/some_not_found_users.txt +88 -0
  37. data/spec/fixtures/racf_cache_dump.yml +9 -0
  38. data/spec/fixtures/rlist/gims.txt +135 -0
  39. data/spec/fixtures/rlist/gims_with_no_tims.txt +135 -0
  40. data/spec/fixtures/rlist/gims_with_not_found.txt +89 -0
  41. data/spec/fixtures/rlist/just_one_not_found.txt +1 -0
  42. data/spec/fixtures/rlist/multiple_not_found.txt +3 -0
  43. data/spec/fixtures/rlist/rlist_success.txt +50 -0
  44. data/spec/fixtures/rlist/tims_without_users.txt +119 -0
  45. data/spec/fixtures/search/gims.txt +30 -0
  46. data/spec/fixtures/search/tims.txt +30 -0
  47. data/spec/fixtures/session/screen_with_bottom_menu.txt +31 -0
  48. data/spec/fixtures/session/screen_with_top_and_bottom_menu.txt +47 -0
  49. data/spec/fixtures/session/screen_with_top_menu.txt +29 -0
  50. data/spec/fixtures/session/screen_without_menu.txt +13 -0
  51. data/spec/racf/client_spec.rb +155 -0
  52. data/spec/racf/commands/listgrp/group_members_parser_spec.rb +82 -0
  53. data/spec/racf/commands/listgrp_spec.rb +303 -0
  54. data/spec/racf/commands/listuser_spec.rb +123 -0
  55. data/spec/racf/commands/rlist_spec.rb +257 -0
  56. data/spec/racf/commands/search_spec.rb +66 -0
  57. data/spec/racf/pagers/cached_ispf_pager_spec.rb +212 -0
  58. data/spec/racf/pagers/ispf_pager_spec.rb +59 -0
  59. data/spec/racf/session_spec.rb +114 -0
  60. data/spec/racf_spec.rb +106 -0
  61. data/spec/spec_helper.rb +18 -0
  62. data/spec/support/helpers.rb +5 -0
  63. metadata +162 -0
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ require 'racf/commands/listuser'
4
+
5
+ describe Racf::Commands::Listuser do
6
+ context "#extract_resources" do
7
+ it "does not fail" do
8
+ command = Racf::Commands::Listuser.new(double("session"))
9
+
10
+ expect {
11
+ command.extract_resources
12
+ }.to_not raise_error(NotImplementedError)
13
+ end
14
+
15
+ context "when arguments are arrays" do
16
+ it "returns the group names" do
17
+ command = Racf::Commands::Listuser.new(double("session"))
18
+ resources = command.extract_resources([['TEST1', 'TEST2']])
19
+
20
+ resources.should eq(['TEST1', 'TEST2'])
21
+ end
22
+ end
23
+
24
+ context "when argument is a string" do
25
+ it "returns the single group wrapped in an array" do
26
+ command = Racf::Commands::Listuser.new(double("session"))
27
+ resources = command.extract_resources(['TEST1'])
28
+
29
+ resources.should eq(['TEST1'])
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "#run" do
35
+ context "when searching for just one user" do
36
+ before do
37
+ scraper_raw_output = read_fixture("listuser/one_user.txt")
38
+ @session = double("session")
39
+ @session.stub(:run_command => scraper_raw_output)
40
+ end
41
+
42
+ it "returns the user's name" do
43
+ command = Racf::Commands::Listuser.new(@session)
44
+ users = command.run("IB00025")
45
+
46
+ users[:IB00025][:name].should == "SATIE KURIKI"
47
+ end
48
+ end
49
+
50
+ context "when searching for all users" do
51
+ before do
52
+ scraper_raw_output = read_fixture("listuser/all_users.txt")
53
+ @session = double("session")
54
+ @session.stub(:run_command => scraper_raw_output)
55
+ end
56
+
57
+ it "returns the users' names" do
58
+ command = Racf::Commands::Listuser.new(@session)
59
+ users = command.run("*")
60
+
61
+ users.should have(3).users
62
+ users[:irrcerta][:name].should == "CERTAUTH Anchor"
63
+ users[:irrmulti][:name].should == "Criteria Anchor"
64
+
65
+ users[:irrsitec][:name].should == "SITE Anchor"
66
+ end
67
+ end
68
+
69
+ context "when there's some not found user" do
70
+ before do
71
+ scraper_raw_output = read_fixture("listuser/some_not_found_users.txt")
72
+ @session = double("session")
73
+ @session.stub(:run_command => scraper_raw_output)
74
+ end
75
+
76
+ it "process just the found users" do
77
+ command = Racf::Commands::Listuser.new(@session)
78
+ users = command.run("*")
79
+
80
+ users.should have(2).users
81
+ users[:AS93504][:name].should == "DIOGO UGOLINE"
82
+ users[:AS35892][:name].should == "VENEZIO LIMA"
83
+ end
84
+ end
85
+
86
+ context "when there's no user found" do
87
+ before do
88
+ scraper_raw_output = read_fixture("listuser/just_users_not_found.txt")
89
+ @session = double("session")
90
+ @session.stub(:run_command => scraper_raw_output)
91
+ end
92
+
93
+ it "returns {}" do
94
+ command = Racf::Commands::Listuser.new(@session)
95
+ users = command.run("*")
96
+
97
+ users.should == {}
98
+ end
99
+ end
100
+
101
+ context "running twice in a row" do
102
+ before do
103
+ one_user_raw_output = read_fixture("listuser/one_user.txt")
104
+ multiple_users_raw_output = read_fixture("listuser/all_users.txt")
105
+
106
+ @session = double("session")
107
+
108
+ @session.stub(:run_command).with("LISTUSER (IB00025)") { one_user_raw_output }
109
+ @session.stub(:run_command).with("LISTUSER (irrcerta irrmulti irrsitec)") { multiple_users_raw_output }
110
+ end
111
+
112
+ it "should not keep state between to calls using the same command instance" do
113
+ command = Racf::Commands::Listuser.new(@session)
114
+
115
+ first_user = "IB00025"
116
+ command.run(first_user)
117
+
118
+ other_users = command.run(["irrcerta", "irrmulti", "irrsitec"])
119
+ other_users.keys.should_not include(first_user.to_sym)
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,257 @@
1
+ require 'spec_helper'
2
+
3
+ require 'racf/commands/rlist'
4
+
5
+ describe Racf::Commands::Rlist do
6
+ context "#extract_resources" do
7
+ it "does not fail" do
8
+ command = Racf::Commands::Rlist.new(double("session"))
9
+
10
+ expect {
11
+ command.extract_resources
12
+ }.to_not raise_error(NotImplementedError)
13
+ end
14
+
15
+ context "when arguments are arrays" do
16
+ it "returns the group names" do
17
+ command = Racf::Commands::Rlist.new(double("session"))
18
+ resources = command.extract_resources(['TIMS', ['TEST1', 'TEST2']])
19
+
20
+ resources.should eq(['TEST1', 'TEST2'])
21
+ end
22
+ end
23
+
24
+ context "when argument is a string" do
25
+ it "returns the single group wrapped in an array" do
26
+ command = Racf::Commands::Rlist.new(double("session"))
27
+ resources = command.extract_resources(['TIMS', 'TEST1'])
28
+
29
+ resources.should eq(['TEST1'])
30
+ end
31
+ end
32
+ end
33
+
34
+ context "#run" do
35
+ context "when the resource is from the TIMS class" do
36
+ it "extracts info from a single resource" do
37
+ scraper_raw_output = read_fixture("rlist/rlist_success.txt")
38
+ session = double("session")
39
+ session.stub(:run_command => scraper_raw_output)
40
+
41
+ command = Racf::Commands::Rlist.new(session)
42
+ resource = command.run("TIMS", ["T1100111"])
43
+
44
+ resource.should == {
45
+ :T1100111 => {
46
+ :standard_access_list => [
47
+ {
48
+ :user_or_group => "FA25909",
49
+ :authority_level => "ALTER"
50
+ }
51
+ ],
52
+ :owner => "GUSISTEM"
53
+ }
54
+ }
55
+ end
56
+
57
+ it "extracts info when the resources don't have users in access list" do
58
+ scraper_raw_output = read_fixture("rlist/tims_without_users.txt")
59
+ session = double("session")
60
+ session.stub(:run_command => scraper_raw_output)
61
+
62
+ command = Racf::Commands::Rlist.new(session)
63
+ resources = command.run("TIMS", "*")
64
+
65
+ resources.should == {
66
+ :ACT01T01 => {
67
+ :owner => "GUASI002",
68
+ :standard_access_list => []
69
+ },
70
+ :ZIT03T01 => {
71
+ :owner => "GUASI326",
72
+ :standard_access_list => []
73
+ },
74
+ :T7142621 => {
75
+ :owner => "GUTESOU",
76
+ :standard_access_list => []
77
+ }
78
+ }
79
+ end
80
+ end
81
+
82
+ context "when the resource is from the GIMS class" do
83
+ it "deals with one resource not found" do
84
+ scraper_raw_output = read_fixture("rlist/just_one_not_found.txt")
85
+ session = double("session")
86
+ session.stub(:run_command => scraper_raw_output)
87
+
88
+ command = Racf::Commands::Rlist.new(session)
89
+ resources = command.run("GIMS", "*")
90
+
91
+ resources.should == {}
92
+ end
93
+
94
+ it "deals with multiple not found resources" do
95
+ scraper_raw_output = read_fixture("rlist/multiple_not_found.txt")
96
+ session = double("session")
97
+ session.stub(:run_command => scraper_raw_output)
98
+
99
+ command = Racf::Commands::Rlist.new(session)
100
+ resources = command.run("GIMS", "*")
101
+
102
+ resources.should == {}
103
+ end
104
+
105
+ it "extracts info from multiple GIMs resources" do
106
+ scraper_raw_output = read_fixture("rlist/gims.txt")
107
+ session = double("session")
108
+ session.stub(:run_command => scraper_raw_output)
109
+
110
+ command = Racf::Commands::Rlist.new(session)
111
+ resources = command.run("GIMS", ["GTAASCOL", "GTACANTO", "GTALMOXA"])
112
+
113
+ resources.should == {
114
+ :GTAASCOL => {
115
+ :tims => ["T8186001", "T8186011", "T8186021"],
116
+ :owner => "GUDRISI",
117
+ :standard_access_list => [
118
+ {
119
+ :user_or_group => "GUAASCOL",
120
+ :authority_level => "READ"
121
+ },
122
+ {
123
+ :user_or_group => "GUTAASCL",
124
+ :authority_level => "READ"
125
+ }
126
+ ]
127
+ },
128
+ :GTACANTO => {
129
+ :tims => ["GET05T01"],
130
+ :owner => "GUASI430",
131
+ :standard_access_list => [
132
+ {
133
+ :user_or_group => "GUSADAPE",
134
+ :authority_level => "READ"
135
+ }
136
+ ]
137
+ },
138
+ :GTALMOXA => {
139
+ :tims => ["T2690011", "T2690031", "T2690071", "T2691251", "T2691321", "T2691371"],
140
+ :owner => "GUCKDADM",
141
+ :standard_access_list => [
142
+ {
143
+ :user_or_group => "GUTALMOA",
144
+ :authority_level => "READ"
145
+ }
146
+ ]
147
+ }
148
+ }
149
+ end
150
+
151
+ it "deals with not found resources while searching for GIMS" do
152
+ scraper_raw_output = read_fixture("rlist/gims_with_not_found.txt")
153
+ session = double("session")
154
+ session.stub(:run_command => scraper_raw_output)
155
+
156
+ command = Racf::Commands::Rlist.new(session)
157
+ resources = command.run("GIMS", ["GTAASCOL", "NOTHING", "GTACANTO"])
158
+
159
+ resources.keys.should have(2).resources
160
+ resources.should == {
161
+ :GTAASCOL => {
162
+ :tims => ["T8186001", "T8186011", "T8186021"],
163
+ :owner => "GUDRISI",
164
+ :standard_access_list => [
165
+ {
166
+ :user_or_group => "GUAASCOL",
167
+ :authority_level => "READ"
168
+ },
169
+ {
170
+ :user_or_group => "GUTAASCL",
171
+ :authority_level => "READ"
172
+ }
173
+ ]
174
+ },
175
+ :GTACANTO => {
176
+ :tims => ["GET05T01"],
177
+ :owner => "GUASI430",
178
+ :standard_access_list => [
179
+ {
180
+ :user_or_group => "GUSADAPE",
181
+ :authority_level => "READ"
182
+ }
183
+ ]
184
+ }
185
+ }
186
+ end
187
+
188
+ it "extract info from GIMS that don't have TIMS" do
189
+ scraper_raw_output = read_fixture("rlist/gims_with_no_tims.txt")
190
+ session = double("session")
191
+ session.stub(:run_command => scraper_raw_output)
192
+
193
+ command = Racf::Commands::Rlist.new(session)
194
+ resources = command.run("GIMS", ["GTAASCOL", "GTACANTO", "GTALMOXA"])
195
+
196
+ resources.should == {
197
+ :GTAASCOL => {
198
+ :tims => ["T8186001", "T8186011", "T8186021"],
199
+ :owner => "GUDRISI",
200
+ :standard_access_list => [
201
+ {
202
+ :user_or_group => "GUAASCOL",
203
+ :authority_level => "READ"
204
+ },
205
+ {
206
+ :user_or_group => "GUTAASCL",
207
+ :authority_level => "READ"
208
+ }
209
+ ]
210
+ },
211
+ :GTACANTO => {
212
+ :tims => [],
213
+ :owner => "GUASI430",
214
+ :standard_access_list => [
215
+ {
216
+ :user_or_group => "GUSADAPE",
217
+ :authority_level => "READ"
218
+ }
219
+ ]
220
+ },
221
+ :GTALMOXA => {
222
+ :tims => ["T2690011", "T2690031", "T2690071", "T2691251", "T2691321", "T2691371"],
223
+ :owner => "GUCKDADM",
224
+ :standard_access_list => [
225
+ {
226
+ :user_or_group => "GUTALMOA",
227
+ :authority_level => "READ"
228
+ }
229
+ ]
230
+ }
231
+ }
232
+ end
233
+ end
234
+
235
+ context "running twice in a row" do
236
+ before do
237
+ tim_raw_output = read_fixture("rlist/rlist_success.txt")
238
+ gims_raw_output = read_fixture("rlist/gims.txt")
239
+
240
+ @session = double("session")
241
+
242
+ @session.stub(:run_command).with("RLIST TIMS (T1100111) AUTHUSER") { tim_raw_output }
243
+ @session.stub(:run_command).with("RLIST GIMS (GTAASCOL GTACANTO GTALMOXA) AUTHUSER") { gims_raw_output }
244
+ end
245
+
246
+ it "should not keep state between to calls using the same command instance" do
247
+ command = Racf::Commands::Rlist.new(@session)
248
+
249
+ tim_id = "T1100111"
250
+ command.run("TIMS", [tim_id])
251
+
252
+ gims = command.run("GIMS", ["GTAASCOL", "GTACANTO", "GTALMOXA"])
253
+ gims.keys.should_not include(tim_id.to_sym)
254
+ end
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ require 'racf/commands/search'
4
+
5
+ describe Racf::Commands::Search do
6
+ describe "#extract_resources" do
7
+ it "does not fail" do
8
+ command = Racf::Commands::Search.new(double("session"))
9
+
10
+ expect {
11
+ command.extract_resources
12
+ }.to_not raise_error(NotImplementedError)
13
+ end
14
+
15
+ it "returns empty because SEARCH is not cacheable" do
16
+ command = Racf::Commands::Search.new(double("session"))
17
+ command.extract_resources('GIMS').should eq([])
18
+ end
19
+ end
20
+
21
+ describe "#run" do
22
+ context "when searching for all GIMS profiles" do
23
+ before do
24
+ scraper_raw_output = read_fixture("search/gims.txt")
25
+ @session = double("session")
26
+ @session.stub(:run_command => scraper_raw_output)
27
+
28
+ command = Racf::Commands::Search.new(@session)
29
+ @resources = command.run("CLASS(GIMS)")
30
+ end
31
+
32
+ it "parses all the GIMS profiles" do
33
+ @resources.should have (30).gims
34
+ end
35
+
36
+ it "parses the profiles IDs" do
37
+ @resources.should include("GTAASCOL")
38
+ @resources.should include("GTADMAR1")
39
+ @resources.should include("GTAITS")
40
+ @resources.should include("GTANATRA")
41
+ end
42
+ end
43
+
44
+ context "when searching for all TIMS profiles" do
45
+ before do
46
+ scraper_raw_output = read_fixture("search/tims.txt")
47
+ @session = double("session")
48
+ @session.stub(:run_command => scraper_raw_output)
49
+
50
+ command = Racf::Commands::Search.new(@session)
51
+ @resources = command.run("CLASS(TIMS)")
52
+ end
53
+
54
+ it "parses all the TIMS profiles" do
55
+ @resources.should have (30).gims
56
+ end
57
+
58
+ it "parses the profiles' IDs" do
59
+ @resources.should include("ACT01T01")
60
+ @resources.should include("ADT01T01")
61
+ @resources.should include("ADT08B01")
62
+ @resources.should include("AFT01T01")
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,212 @@
1
+ require 'spec_helper'
2
+
3
+ require 'racf/pagers/cached_ispf_pager'
4
+
5
+ describe Racf::Pagers::CachedIspfPager do
6
+ let(:pager_double) { double("Pager") }
7
+ let(:pager_class_double) { double("Pager Class") }
8
+ let(:command_double) { double("Command") }
9
+
10
+ before(:each) do
11
+ pager_class_double.
12
+ should_receive(:new).
13
+ with(command_double).
14
+ and_return(pager_double)
15
+
16
+ Racf.logger = double.as_null_object
17
+ end
18
+
19
+ describe "#run" do
20
+ let(:ids) { %w{ID1 ID2 ID3 ID4 ID5} }
21
+
22
+ context "when not cached" do
23
+ it "calls the uncaching paging service" do
24
+ command_double.
25
+ should_receive(:extract_resources).
26
+ with([ids]).
27
+ and_return(ids)
28
+
29
+ pager_double.
30
+ should_receive(:run).
31
+ with(ids).
32
+ and_return({:result => 123})
33
+
34
+ caching_pager = described_class.new(command_double, pager_class_double)
35
+ caching_pager.run(ids)
36
+ end
37
+
38
+ it "caches the result" do
39
+ command_double.
40
+ should_receive(:extract_resources).
41
+ twice.
42
+ with([ids]).
43
+ and_return(ids)
44
+
45
+ pager_double.
46
+ should_receive(:run).
47
+ with(ids).
48
+ once.
49
+ and_return({
50
+ :ID1 => 123,
51
+ :ID2 => 123,
52
+ :ID3 => 123,
53
+ :ID4 => 123,
54
+ :ID5 => 123
55
+ })
56
+
57
+ caching_pager = described_class.new command_double, pager_class_double
58
+ caching_pager.run(ids)
59
+ caching_pager.run(ids)
60
+ end
61
+ end
62
+
63
+ context "when cached partially" do
64
+ let(:caching_pager) { described_class.new command_double, pager_class_double }
65
+
66
+ before(:each) do
67
+ command_double.
68
+ should_receive(:extract_resources).
69
+ with([%w{ID1 ID2 ID3}]).
70
+ and_return(%w{ID1 ID2 ID3})
71
+
72
+ pager_double.
73
+ should_receive(:run).
74
+ with(%w{ID1 ID2 ID3}).
75
+ once.
76
+ and_return({
77
+ :ID1 => 123,
78
+ :ID2 => 456,
79
+ :ID3 => 789,
80
+ })
81
+
82
+ caching_pager.run(%w{ID1 ID2 ID3})
83
+ end
84
+
85
+ it "does not call uncaching paging service for all elements" do
86
+ command_double.
87
+ should_receive(:extract_resources).
88
+ with([%w{ID1 ID4 ID5}]).
89
+ and_return(%w{ID1 ID4 ID5})
90
+
91
+ pager_double.
92
+ should_receive(:run).
93
+ with(%w{ID4 ID5}).
94
+ once.
95
+ and_return({
96
+ :ID4 => 321,
97
+ :ID5 => 654
98
+ })
99
+
100
+ caching_pager.run(%w{ID1 ID4 ID5})
101
+ end
102
+
103
+ it "merges the result from the uncached with the cached" do
104
+ command_double.
105
+ should_receive(:extract_resources).
106
+ with([%w{ID1 ID2 ID4 ID5}]).
107
+ and_return(%w{ID1 ID2 ID4 ID5})
108
+
109
+ pager_double.
110
+ should_receive(:run).
111
+ with(%w{ID4 ID5}).
112
+ once.
113
+ and_return({
114
+ :ID4 => 321,
115
+ :ID5 => 654
116
+ })
117
+
118
+ result = caching_pager.run(%w{ID1 ID2 ID4 ID5})
119
+
120
+ result[:ID1].should eq(123)
121
+ result[:ID2].should eq(456)
122
+ result[:ID4].should eq(321)
123
+ result[:ID5].should eq(654)
124
+ end
125
+ end
126
+
127
+ context "caching by other parameters" do
128
+ it "separates the parameters from the resources" do
129
+ command_double.
130
+ should_receive(:extract_resources).
131
+ with(['TIMS', ids]).
132
+ and_return(ids)
133
+
134
+ pager_double.
135
+ should_receive(:run).
136
+ with("TIMS", ids).
137
+ once.
138
+ and_return({:ID1 => 'abc'})
139
+
140
+ caching_pager = described_class.new command_double, pager_class_double
141
+ caching_pager.run("TIMS", ids)
142
+ end
143
+
144
+ context "same parameter" do
145
+ let(:caching_pager) { described_class.new command_double, pager_class_double }
146
+
147
+ before(:each) do
148
+ command_double.
149
+ should_receive(:extract_resources).
150
+ with(['TIMS', ids]).
151
+ and_return(ids)
152
+
153
+ pager_double.
154
+ should_receive(:run).
155
+ with("TIMS", ids).
156
+ once.
157
+ and_return({
158
+ :ID1 => 'abc',
159
+ :ID2 => 'def'
160
+ })
161
+
162
+ caching_pager.run("TIMS", ids)
163
+ end
164
+
165
+ it "hits cache" do
166
+ command_double.
167
+ should_receive(:extract_resources).
168
+ with(['TIMS', %w{ID1 ID2}]).
169
+ and_return(%w{ID1 ID2})
170
+
171
+ result = caching_pager.run("TIMS", %w{ID1 ID2})
172
+ result[:ID1].should eq('abc')
173
+ result[:ID2].should eq('def')
174
+ end
175
+ end
176
+
177
+ context "different parameter" do
178
+ let(:caching_pager) { described_class.new command_double, pager_class_double }
179
+
180
+ before(:each) do
181
+ command_double.
182
+ should_receive(:extract_resources).
183
+ with(['TIMS', ids]).
184
+ and_return(ids)
185
+
186
+ pager_double.
187
+ should_receive(:run).
188
+ with("TIMS", ids).
189
+ once.
190
+ and_return({:ID1 => 'abc'})
191
+
192
+ caching_pager.run("TIMS", ids)
193
+ end
194
+
195
+ it "does not hit cache" do
196
+ command_double.
197
+ should_receive(:extract_resources).
198
+ with(['GIMS', ids]).
199
+ and_return(ids)
200
+
201
+ pager_double.
202
+ should_receive(:run).
203
+ with("GIMS", ids).
204
+ once.
205
+ and_return({:ID1 => 'abc'})
206
+
207
+ caching_pager.run("GIMS", ids)
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end