gooddata 0.6.11 → 0.6.12

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -0
  3. data/.travis.yml +5 -0
  4. data/CHANGELOG.md +34 -1
  5. data/CLI.md +1 -1
  6. data/authors.sh +4 -0
  7. data/lib/gooddata.rb +1 -1
  8. data/lib/gooddata/cli/commands/api_cmd.rb +0 -2
  9. data/lib/gooddata/cli/commands/auth_cmd.rb +0 -3
  10. data/lib/gooddata/cli/commands/console_cmd.rb +1 -2
  11. data/lib/gooddata/cli/commands/domain_cmd.rb +0 -2
  12. data/lib/gooddata/cli/commands/process_cmd.rb +0 -2
  13. data/lib/gooddata/cli/commands/project_cmd.rb +0 -2
  14. data/lib/gooddata/cli/commands/projects_cmd.rb +0 -2
  15. data/lib/gooddata/cli/commands/run_ruby_cmd.rb +2 -3
  16. data/lib/gooddata/cli/commands/scaffold_cmd.rb +0 -3
  17. data/lib/gooddata/cli/commands/user_cmd.rb +0 -2
  18. data/lib/gooddata/cli/shared.rb +1 -2
  19. data/lib/gooddata/commands/datawarehouse.rb +24 -0
  20. data/lib/gooddata/commands/process.rb +0 -1
  21. data/lib/gooddata/commands/project.rb +1 -1
  22. data/lib/gooddata/commands/scaffold.rb +0 -1
  23. data/lib/gooddata/core/connection.rb +376 -0
  24. data/lib/gooddata/core/logging.rb +13 -0
  25. data/lib/gooddata/core/rest.rb +40 -16
  26. data/lib/gooddata/exceptions/user_in_different_domain.rb +11 -0
  27. data/lib/gooddata/extensions/enumerable.rb +8 -0
  28. data/lib/gooddata/goodzilla/goodzilla.rb +24 -0
  29. data/lib/gooddata/helpers/global_helpers.rb +126 -12
  30. data/lib/gooddata/mixins/author.rb +11 -5
  31. data/lib/gooddata/mixins/is_dimension.rb +13 -0
  32. data/lib/gooddata/mixins/md_object_indexer.rb +17 -1
  33. data/lib/gooddata/mixins/md_object_query.rb +10 -2
  34. data/lib/gooddata/mixins/md_relations.rb +2 -2
  35. data/lib/gooddata/mixins/rest_resource.rb +1 -0
  36. data/lib/gooddata/models/data_result.rb +0 -1
  37. data/lib/gooddata/models/datawarehouse.rb +90 -0
  38. data/lib/gooddata/models/domain.rb +202 -76
  39. data/lib/gooddata/models/execution.rb +11 -0
  40. data/lib/gooddata/models/from_wire.rb +4 -4
  41. data/lib/gooddata/models/invitation.rb +0 -5
  42. data/lib/gooddata/models/membership.rb +121 -91
  43. data/lib/gooddata/models/metadata.rb +1 -2
  44. data/lib/gooddata/models/metadata/attribute.rb +7 -0
  45. data/lib/gooddata/models/metadata/dashboard.rb +1 -1
  46. data/lib/gooddata/models/metadata/dimension.rb +52 -0
  47. data/lib/gooddata/models/metadata/fact.rb +1 -1
  48. data/lib/gooddata/models/metadata/label.rb +21 -7
  49. data/lib/gooddata/models/metadata/metric.rb +1 -23
  50. data/lib/gooddata/models/metadata/report.rb +2 -2
  51. data/lib/gooddata/models/metadata/report_definition.rb +22 -2
  52. data/lib/gooddata/models/metadata/variable.rb +81 -0
  53. data/lib/gooddata/models/model.rb +2 -1
  54. data/lib/gooddata/models/process.rb +3 -4
  55. data/lib/gooddata/models/profile.rb +50 -82
  56. data/lib/gooddata/models/project.rb +170 -213
  57. data/lib/gooddata/models/project_blueprint.rb +14 -5
  58. data/lib/gooddata/models/project_creator.rb +2 -2
  59. data/lib/gooddata/models/schedule.rb +10 -8
  60. data/lib/gooddata/models/to_wire.rb +2 -2
  61. data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +67 -0
  62. data/lib/gooddata/models/user_filters/user_filter.rb +96 -0
  63. data/lib/gooddata/models/user_filters/user_filter_builder.rb +409 -0
  64. data/lib/gooddata/{rest/connections/connections.rb → models/user_filters/user_filters.rb} +1 -0
  65. data/lib/gooddata/models/user_filters/variable_user_filter.rb +14 -0
  66. data/lib/gooddata/rest/client.rb +32 -21
  67. data/lib/gooddata/rest/connection.rb +283 -11
  68. data/lib/gooddata/rest/connections/rest_client_connection.rb +47 -109
  69. data/lib/gooddata/version.rb +1 -1
  70. data/spec/data/column_based_permissions.csv +7 -0
  71. data/spec/data/column_based_permissions2.csv +6 -0
  72. data/spec/data/hello_world_process/hello_world.rb +3 -1
  73. data/spec/data/line_based_permissions.csv +3 -0
  74. data/spec/data/m_n_model/blueprint.json +76 -0
  75. data/spec/data/{model_view.json → wire_models/model_view.json} +0 -0
  76. data/spec/data/wire_models/nu_model.json +3046 -0
  77. data/spec/helpers/process_helper.rb +2 -2
  78. data/spec/helpers/project_helper.rb +29 -0
  79. data/spec/helpers/schedule_helper.rb +1 -1
  80. data/spec/integration/command_datawarehouse_spec.rb +32 -0
  81. data/spec/integration/create_project_spec.rb +0 -1
  82. data/spec/integration/full_process_schedule_spec.rb +13 -5
  83. data/spec/integration/full_project_spec.rb +2 -1
  84. data/spec/integration/over_to_user_filters_spec.rb +92 -0
  85. data/spec/integration/project_spec.rb +233 -0
  86. data/spec/integration/rest_spec.rb +209 -0
  87. data/spec/integration/user_filters_spec.rb +193 -0
  88. data/spec/integration/variables_spec.rb +196 -0
  89. data/spec/unit/commands/command_auth_spec.rb +0 -7
  90. data/spec/unit/commands/command_process_spec.rb +10 -13
  91. data/spec/unit/core/connection_spec.rb +0 -19
  92. data/spec/unit/helpers/global_helpers_spec.rb +57 -0
  93. data/spec/unit/models/domain_spec.rb +80 -40
  94. data/spec/unit/models/from_wire_spec.rb +8 -1
  95. data/spec/unit/models/params_spec.rb +6 -6
  96. data/spec/unit/models/profile_spec.rb +23 -22
  97. data/spec/unit/models/project_blueprint_spec.rb +1 -6
  98. data/spec/unit/models/project_spec.rb +331 -286
  99. data/spec/unit/models/schedule_spec.rb +39 -14
  100. data/spec/unit/models/user_filters_spec.rb +89 -0
  101. data/spec/unit/models/variable_spec.rb +259 -0
  102. metadata +31 -7
  103. data/lib/gooddata/rest/connections/dummy_connection.rb +0 -52
  104. data/spec/unit/core/rest_spec.rb +0 -106
@@ -17,18 +17,16 @@ describe GoodData::Schedule do
17
17
 
18
18
  before(:each) do
19
19
  @client = ConnectionHelper.create_default_connection
20
-
20
+
21
21
  @project = ProjectHelper.get_default_project(:client => @client)
22
-
23
- @project_executable = './graph/graph.grf'
24
-
22
+ @project_executable = 'graph/graph.grf'
25
23
  @test_data = {
26
24
  :timezone => 'UTC',
27
25
  :cron => '2 2 2 2 *',
28
26
  :client => @client,
29
27
  :project => @project
30
28
  }
31
-
29
+
32
30
  @test_data_with_optional_param = {
33
31
  :timezone => 'UTC',
34
32
  :cron => '2 2 2 2 *',
@@ -92,7 +90,7 @@ describe GoodData::Schedule do
92
90
  expect {
93
91
  sched = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data_with_optional_param)
94
92
  }.not_to raise_error
95
-
93
+
96
94
  sched.should_not be_nil
97
95
  sched.delete
98
96
  end
@@ -173,11 +171,11 @@ describe GoodData::Schedule do
173
171
  before(:each) do
174
172
  @schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
175
173
  end
176
-
174
+
177
175
  after(:each) do
178
176
  @schedule.delete
179
177
  end
180
-
178
+
181
179
  it 'Should return executable as string' do
182
180
  res = @schedule.executable
183
181
  res.should_not be_nil
@@ -204,6 +202,32 @@ describe GoodData::Schedule do
204
202
  end
205
203
  end
206
204
 
205
+ describe '#execute' do
206
+ before(:each) do
207
+ @schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
208
+ @process = @project.deploy_process('./spec/data/gooddata_version_process/gooddata_version.zip',
209
+ type: 'RUBY',
210
+ name: 'Test ETL zipped file GoodData Process')
211
+ @schedule = @process.create_schedule('0 15 27 7 *', @process.executables.first)
212
+ end
213
+
214
+ after(:each) do
215
+ @schedule.delete
216
+ end
217
+
218
+ it 'Waits for execution result by default' do
219
+ res = @schedule.execute
220
+ expect(res).to be_an_instance_of(GoodData::Execution)
221
+ expect([:ok, :error].include?(res.status)).to be_truthy
222
+ end
223
+
224
+ it 'can be overridden to do not wait for execution result' do
225
+ res = @schedule.execute(:wait => false)
226
+ expect(res).to be_an_instance_of(GoodData::Execution)
227
+ expect([:scheduled, :running].include?(res.status)).to be_truthy
228
+ end
229
+ end
230
+
207
231
  describe '#execution_url' do
208
232
  before(:each) do
209
233
  @schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
@@ -222,6 +246,7 @@ describe GoodData::Schedule do
222
246
  end
223
247
 
224
248
  describe '#type' do
249
+
225
250
  before(:each) do
226
251
  @schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data)
227
252
  end
@@ -455,11 +480,11 @@ describe GoodData::Schedule do
455
480
  before(:each) do
456
481
  @schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data_with_optional_param)
457
482
  end
458
-
483
+
459
484
  after(:each) do
460
485
  @schedule.delete
461
486
  end
462
-
487
+
463
488
  it 'Should return reschedule as integer' do
464
489
  res = @schedule.reschedule
465
490
  res.should_not be_nil
@@ -471,17 +496,17 @@ describe GoodData::Schedule do
471
496
  before(:each) do
472
497
  @schedule = @project.create_schedule(ProcessHelper::PROCESS_ID, @test_cron, @project_executable, @test_data_with_optional_param)
473
498
  end
474
-
499
+
475
500
  after(:each) do
476
501
  @schedule.delete
477
502
  end
478
-
503
+
479
504
  it 'Assigns the reschedule and marks the object dirty' do
480
505
  test_reschedule = 45
481
-
506
+
482
507
  @schedule.reschedule = test_reschedule
483
508
  expect(@schedule.reschedule).to eq(test_reschedule)
484
509
  expect(@schedule.dirty).to eq(true)
485
510
  end
486
511
  end
487
- end
512
+ end
@@ -0,0 +1,89 @@
1
+ require 'gooddata'
2
+
3
+ def check_filters(filters)
4
+ filters.count.should == 2
5
+ filter = filters.first
6
+ filter[:login].should == "john.doe@example.com"
7
+ filter[:filters].count.should == 1
8
+ filter[:filters].first[:values].count.should == 4
9
+ filter[:filters].first[:values].should == ["USA", "Czech Republic", "Uganda", "Slovakia"]
10
+ filter = filters.last
11
+ filter[:login].should == "jane.doe@example.com"
12
+ filter[:filters].count.should == 1
13
+ filter[:filters].first[:values].count.should == 1
14
+ end
15
+
16
+ describe 'User filters implementation' do
17
+
18
+ it "should create user filters from a file using row based approach" do
19
+ filters = GoodData::UserFilterBuilder::get_filters('./spec/data/line_based_permissions.csv', {
20
+ :labels => [
21
+ {:label => "/gdc/md/lu292gm1077gtv7i383hjl149sva7o1e/obj/2719"},
22
+ ]
23
+ });
24
+ check_filters(filters)
25
+ end
26
+
27
+ it "should create user filters from a file using column based approach" do
28
+ filters = GoodData::UserFilterBuilder::get_filters('./spec/data/column_based_permissions.csv', {
29
+ :labels => [
30
+ {:label => "/gdc/md/lu292gm1077gtv7i383hjl149sva7o1e/obj/2719", :column => 'region'},
31
+ ]
32
+ });
33
+ check_filters(filters)
34
+ end
35
+
36
+ it "should treat empty like nil, empty value has to be enclosed in quotes" do
37
+ filters = GoodData::UserFilterBuilder::get_filters('./spec/data/column_based_permissions.csv', {
38
+ :labels => [
39
+ {:label => "some_label", :column => 'region'},
40
+ {:label => "other_label", :column => 'department'}
41
+ ]
42
+ });
43
+ filters.first[:filters].last[:values].count.should == 3
44
+ end
45
+
46
+ it "should be able to specify columns by number" do
47
+ filters = GoodData::UserFilterBuilder::get_filters('./spec/data/column_based_permissions2.csv', {
48
+ :user_column => 2,
49
+ :labels => [
50
+ {:label => "some_label", :column => 0},
51
+ {:label => "other_label", :column => 1}
52
+ ]
53
+ });
54
+ filters.first[:filters].last[:values].count.should == 2
55
+ end
56
+
57
+ it "should be able to specify columns by name" do
58
+ filters = GoodData::UserFilterBuilder::get_filters('./spec/data/column_based_permissions2.csv', {
59
+ :user_column => 'login',
60
+ :labels => [
61
+ {:label => 'some_label', :column => 'region'},
62
+ {:label => 'other_label', :column => 'department'}
63
+ ]
64
+ });
65
+ filters.first[:filters].last[:values].count.should == 2
66
+ end
67
+
68
+ it "should normalize simplifed filters" do
69
+ filters = [
70
+ [
71
+ "svarovsky+gem_tester@gooddata.com",
72
+ "/gdc/md/zndbmx87kh69vk8liods10mwxesaxn3k/obj/213",
73
+ "tomas@gooddata.com",
74
+ "jirka@gooddata.com"
75
+ ]
76
+ ]
77
+ GoodData::UserFilterBuilder.normalize_filters(filters).should == [
78
+ {
79
+ :login =>"svarovsky+gem_tester@gooddata.com",
80
+ :filters => [
81
+ {
82
+ :label => "/gdc/md/zndbmx87kh69vk8liods10mwxesaxn3k/obj/213",
83
+ :values => ["tomas@gooddata.com", "jirka@gooddata.com"]
84
+ }
85
+ ]
86
+ }
87
+ ]
88
+ end
89
+ end
@@ -0,0 +1,259 @@
1
+ require 'gooddata'
2
+
3
+ ROW_BASED_DATA = [
4
+ ['tomas@gooddata.com', 'US', 'CZ', 'KZ'],
5
+ ['petr@gooddata.com', 'US'],
6
+ ['petr@gooddata.com','KZ']
7
+ ]
8
+ COLUMN_BASED_DATA_WITH_HEADERS = [
9
+ {
10
+ :login => 'tomas@gooddata.com',
11
+ :country => 'US',
12
+ :age => 14
13
+ },
14
+ {
15
+ :login => 'petr@gooddata.com',
16
+ :country => 'US',
17
+ :age => 19
18
+ },
19
+ {
20
+ :login => 'petr@gooddata.com',
21
+ :country => 'KZ',
22
+ :age => 30
23
+ }
24
+ ]
25
+
26
+ COLUMN_BASED_DATA_WITH_HEADERS_AND_NIL_VAL = [
27
+ {
28
+ :login => 'tomas@gooddata.com',
29
+ :country => 'US',
30
+ :age => 14
31
+ },
32
+ {
33
+ :login => 'petr@gooddata.com',
34
+ :country => 'US',
35
+ :age => 19
36
+ },
37
+ {
38
+ :login => 'petr@gooddata.com',
39
+ :country => 'KZ',
40
+ :age => nil
41
+ }
42
+ ]
43
+
44
+ COLUMN_BASED_DATA_WITH_HEADERS_AND_EMPTY_VAL = [
45
+ {
46
+ :login => 'tomas@gooddata.com',
47
+ :country => 'US',
48
+ :age => 14
49
+ },
50
+ {
51
+ :login => 'petr@gooddata.com',
52
+ :country => 'US',
53
+ :age => 19
54
+ },
55
+ {
56
+ :login => 'petr@gooddata.com',
57
+ :country => 'KZ',
58
+ :age => ''
59
+ }
60
+ ]
61
+
62
+ describe "DSL" do
63
+ it "should pick the values from row based file" do
64
+ results = GoodData::UserFilterBuilder::get_values(ROW_BASED_DATA, {
65
+ :labels => [{:label => "label/34"}]
66
+ })
67
+ results.should == {
68
+ "tomas@gooddata.com"=>[
69
+ {:label=> "label/34", :values=>["US", "CZ", "KZ"], :over => nil, :to => nil}
70
+ ],
71
+ "petr@gooddata.com"=> [
72
+ {:label=> "label/34", :values=>["US"], :over => nil, :to => nil},
73
+ {:label=> "label/34", :values=>["KZ"], :over => nil, :to => nil}
74
+ ]
75
+ }
76
+ end
77
+
78
+ it "should pick the values from column based file" do
79
+ results = GoodData::UserFilterBuilder::get_values(COLUMN_BASED_DATA_WITH_HEADERS, {
80
+ :type => :filter,
81
+ :user_column => :login,
82
+ :labels => [{:label => "label/34", :column => :country}]
83
+ })
84
+ results.should == {
85
+ "tomas@gooddata.com"=>[
86
+ {:label => "label/34", :values=>["US"], :over => nil, :to => nil}
87
+ ],
88
+ "petr@gooddata.com"=> [
89
+ {:label=> "label/34", :values=>["US"], :over => nil, :to => nil},
90
+ {:label=> "label/34", :values=>["KZ"], :over => nil, :to => nil}
91
+ ]
92
+ }
93
+ end
94
+
95
+ it "should pick the values from column based file with multiple columns" do
96
+ results = GoodData::UserFilterBuilder::get_values(COLUMN_BASED_DATA_WITH_HEADERS, {
97
+ :type => :filter,
98
+ :user_column => :login,
99
+ :labels => [{:label => "label/34", :column => :country}, {:label => "label/99", :column => :age}]
100
+ })
101
+ results.should == {
102
+ "tomas@gooddata.com"=>[
103
+ {:label=> "label/34", :values=>["US"], :over => nil, :to => nil},
104
+ {:label=> "label/99", :values=>[14], :over => nil, :to => nil}
105
+ ],
106
+ "petr@gooddata.com"=> [
107
+ {:label=>"label/34", :values=>["US"], :over => nil, :to => nil},
108
+ {:label=>"label/99", :values=>[19], :over => nil, :to => nil},
109
+ {:label=>"label/34", :values=>["KZ"], :over => nil, :to => nil},
110
+ {:label=>"label/99", :values=>[30], :over => nil, :to => nil}
111
+ ]
112
+ }
113
+ end
114
+
115
+ it "should process end to end" do
116
+ result = GoodData::UserFilterBuilder::get_filters(COLUMN_BASED_DATA_WITH_HEADERS, {
117
+ :user_column => :login,
118
+ :labels => [{:label => {:uri => "label/34"}, :column => :country}, {:label => {:uri => "label/99"}, :column => :age}]
119
+ })
120
+ result.should == [
121
+ {
122
+ :login=>"tomas@gooddata.com",
123
+ :filters=> [
124
+ {:label=>{:uri=>"label/34"}, :values=>["US"], :over => nil, :to => nil},
125
+ {:label=>{:uri=>"label/99"}, :values=>[14], :over => nil, :to => nil}
126
+ ]
127
+ },
128
+ {
129
+ :login=>"petr@gooddata.com",
130
+ :filters => [
131
+ {:label=>{:uri=>"label/34"}, :values=>["US", "KZ"], :over => nil, :to => nil},
132
+ {:label=>{:uri=>"label/99"}, :values=>[19, 30], :over => nil, :to => nil}
133
+ ]
134
+ }
135
+ ]
136
+ end
137
+
138
+ it "should process end to end nil value should be ignored" do
139
+ result = GoodData::UserFilterBuilder::get_filters(COLUMN_BASED_DATA_WITH_HEADERS_AND_NIL_VAL, {
140
+ :user_column => :login,
141
+ :labels => [{:label => {:uri => "label/34"}, :column => :country}, {:label => {:uri => "label/99"}, :column => :age}]
142
+ })
143
+ result.should == [
144
+ {
145
+ :login=>"tomas@gooddata.com",
146
+ :filters=> [
147
+ {:label=>{:uri=>"label/34"}, :values=>["US"], :over => nil, :to => nil},
148
+ {:label=>{:uri=>"label/99"}, :values=>[14], :over => nil, :to => nil}
149
+ ]
150
+ },
151
+ {
152
+ :login=>"petr@gooddata.com",
153
+ :filters => [
154
+ {:label=>{:uri=>"label/34"}, :values=>["US", "KZ"], :over => nil, :to => nil},
155
+ {:label=>{:uri=>"label/99"}, :values=>[19], :over => nil, :to => nil}
156
+ ]
157
+ }
158
+ ]
159
+ end
160
+
161
+ it "should process end to end nil value should be ignored" do
162
+ result = GoodData::UserFilterBuilder::get_filters(COLUMN_BASED_DATA_WITH_HEADERS_AND_EMPTY_VAL, {
163
+ :user_column => :login,
164
+ :labels => [{:label => {:uri => "label/34"}, :column => :country}, {:label => {:uri => "label/99"}, :column => :age}]
165
+ })
166
+ result.should == [
167
+ {
168
+ :login=>"tomas@gooddata.com",
169
+ :filters=> [
170
+ {:label=>{:uri=>"label/34"}, :values=>["US"], :over => nil, :to => nil},
171
+ {:label=>{:uri=>"label/99"}, :values=>[14], :over => nil, :to => nil}
172
+ ]
173
+ },
174
+ {
175
+ :login=>"petr@gooddata.com",
176
+ :filters => [
177
+ {:label=>{:uri=>"label/34"}, :values=>["US", "KZ"], :over => nil, :to => nil},
178
+ {:label=>{:uri=>"label/99"}, :values=>[19, ""], :over => nil, :to => nil}
179
+ ]
180
+ }
181
+ ]
182
+ end
183
+
184
+ it "should collect values for every user" do
185
+ data = {
186
+ "tomas" => [
187
+ {:label=>"label/34", :values=>["US"]},
188
+ {:label=>"label/34", :values=>["KZ"]},
189
+ {:label=>"label/99", :values=>[18]},
190
+ {:label=>"label/99", :values=>[20]}
191
+ ],
192
+ "petr" => [
193
+ {:label=>"label/34", :values=>["US"]},
194
+ {:label=>"label/99", :values=>[2]},
195
+ {:label=>"label/99", :values=>[1]}
196
+ ]
197
+ }
198
+ result = GoodData::UserFilterBuilder.reduce_results(data)
199
+ result.should == [{:login=>"tomas",
200
+ :filters=>
201
+ [{:label=>"label/34", :values=>["US", "KZ"], :over => nil, :to => nil},
202
+ {:label=>"label/99", :values=>[18, 20], :over => nil, :to => nil}]},
203
+ {:login=>"petr",
204
+ :filters =>
205
+ [{:label=>"label/34", :values=>["US"], :over => nil, :to => nil},
206
+ {:label=>"label/99", :values=>[2, 1], :over => nil, :to => nil}]}]
207
+ end
208
+
209
+ it "should collect values for every label" do
210
+ data = [
211
+ {:label=>"label/34", :values=>["US"]},
212
+ {:label=>"label/34", :values=>["KZ"]},
213
+ {:label=>"label/99", :values=>[18]},
214
+ {:label=>"label/99", :values=>[20]}
215
+ ]
216
+ result = GoodData::UserFilterBuilder.collect_labels(data)
217
+ result.should == [{:label=>"label/34", :values=>["US", "KZ"], :over => nil, :to => nil},
218
+ {:label=>"label/99", :values=>[18, 20], :over => nil, :to => nil}]
219
+
220
+ end
221
+
222
+ it "should collect values" do
223
+ data = [
224
+ {:label=>"label/34", :values=>["US"]},
225
+ {:label=>"label/34", :values=>["KZ"]}
226
+ ]
227
+ results = GoodData::UserFilterBuilder.collect_values(data)
228
+ results.should == ["US", "KZ"]
229
+ end
230
+
231
+ it "should translate filters into MAQL filters" do
232
+ data = [
233
+ {
234
+ :login=>"tomas@gooddata.com",
235
+ :filters=> [
236
+ {:label => "label/34", :values=>["US"]},
237
+ {:label => "label/99", :values=>[14]}
238
+ ]
239
+ },
240
+ {
241
+ :login=>"petr@gooddata.com",
242
+ :filters => [
243
+ {:label => "label/34", :values=>["US", "KZ"]},
244
+ {:label=> "label/99", :values=>[19]}
245
+ ]
246
+ }
247
+ ]
248
+ results = data.map do |user_data|
249
+ {
250
+ :login => user_data[:login],
251
+ :maql_filter => user_data[:filters].map { |item| "[#{item[:label]}] IN (#{item[:values].join(', ')})" }.join(" AND ")
252
+ }
253
+ end
254
+ results.should == [
255
+ {:login=>"tomas@gooddata.com", :maql_filter=>"[label/34] IN (US) AND [label/99] IN (14)"},
256
+ {:login=>"petr@gooddata.com", :maql_filter=>"[label/34] IN (US, KZ) AND [label/99] IN (19)"}
257
+ ]
258
+ end
259
+ end