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.
- checksums.yaml +4 -4
- data/.gitignore +6 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +34 -1
- data/CLI.md +1 -1
- data/authors.sh +4 -0
- data/lib/gooddata.rb +1 -1
- data/lib/gooddata/cli/commands/api_cmd.rb +0 -2
- data/lib/gooddata/cli/commands/auth_cmd.rb +0 -3
- data/lib/gooddata/cli/commands/console_cmd.rb +1 -2
- data/lib/gooddata/cli/commands/domain_cmd.rb +0 -2
- data/lib/gooddata/cli/commands/process_cmd.rb +0 -2
- data/lib/gooddata/cli/commands/project_cmd.rb +0 -2
- data/lib/gooddata/cli/commands/projects_cmd.rb +0 -2
- data/lib/gooddata/cli/commands/run_ruby_cmd.rb +2 -3
- data/lib/gooddata/cli/commands/scaffold_cmd.rb +0 -3
- data/lib/gooddata/cli/commands/user_cmd.rb +0 -2
- data/lib/gooddata/cli/shared.rb +1 -2
- data/lib/gooddata/commands/datawarehouse.rb +24 -0
- data/lib/gooddata/commands/process.rb +0 -1
- data/lib/gooddata/commands/project.rb +1 -1
- data/lib/gooddata/commands/scaffold.rb +0 -1
- data/lib/gooddata/core/connection.rb +376 -0
- data/lib/gooddata/core/logging.rb +13 -0
- data/lib/gooddata/core/rest.rb +40 -16
- data/lib/gooddata/exceptions/user_in_different_domain.rb +11 -0
- data/lib/gooddata/extensions/enumerable.rb +8 -0
- data/lib/gooddata/goodzilla/goodzilla.rb +24 -0
- data/lib/gooddata/helpers/global_helpers.rb +126 -12
- data/lib/gooddata/mixins/author.rb +11 -5
- data/lib/gooddata/mixins/is_dimension.rb +13 -0
- data/lib/gooddata/mixins/md_object_indexer.rb +17 -1
- data/lib/gooddata/mixins/md_object_query.rb +10 -2
- data/lib/gooddata/mixins/md_relations.rb +2 -2
- data/lib/gooddata/mixins/rest_resource.rb +1 -0
- data/lib/gooddata/models/data_result.rb +0 -1
- data/lib/gooddata/models/datawarehouse.rb +90 -0
- data/lib/gooddata/models/domain.rb +202 -76
- data/lib/gooddata/models/execution.rb +11 -0
- data/lib/gooddata/models/from_wire.rb +4 -4
- data/lib/gooddata/models/invitation.rb +0 -5
- data/lib/gooddata/models/membership.rb +121 -91
- data/lib/gooddata/models/metadata.rb +1 -2
- data/lib/gooddata/models/metadata/attribute.rb +7 -0
- data/lib/gooddata/models/metadata/dashboard.rb +1 -1
- data/lib/gooddata/models/metadata/dimension.rb +52 -0
- data/lib/gooddata/models/metadata/fact.rb +1 -1
- data/lib/gooddata/models/metadata/label.rb +21 -7
- data/lib/gooddata/models/metadata/metric.rb +1 -23
- data/lib/gooddata/models/metadata/report.rb +2 -2
- data/lib/gooddata/models/metadata/report_definition.rb +22 -2
- data/lib/gooddata/models/metadata/variable.rb +81 -0
- data/lib/gooddata/models/model.rb +2 -1
- data/lib/gooddata/models/process.rb +3 -4
- data/lib/gooddata/models/profile.rb +50 -82
- data/lib/gooddata/models/project.rb +170 -213
- data/lib/gooddata/models/project_blueprint.rb +14 -5
- data/lib/gooddata/models/project_creator.rb +2 -2
- data/lib/gooddata/models/schedule.rb +10 -8
- data/lib/gooddata/models/to_wire.rb +2 -2
- data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +67 -0
- data/lib/gooddata/models/user_filters/user_filter.rb +96 -0
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +409 -0
- data/lib/gooddata/{rest/connections/connections.rb → models/user_filters/user_filters.rb} +1 -0
- data/lib/gooddata/models/user_filters/variable_user_filter.rb +14 -0
- data/lib/gooddata/rest/client.rb +32 -21
- data/lib/gooddata/rest/connection.rb +283 -11
- data/lib/gooddata/rest/connections/rest_client_connection.rb +47 -109
- data/lib/gooddata/version.rb +1 -1
- data/spec/data/column_based_permissions.csv +7 -0
- data/spec/data/column_based_permissions2.csv +6 -0
- data/spec/data/hello_world_process/hello_world.rb +3 -1
- data/spec/data/line_based_permissions.csv +3 -0
- data/spec/data/m_n_model/blueprint.json +76 -0
- data/spec/data/{model_view.json → wire_models/model_view.json} +0 -0
- data/spec/data/wire_models/nu_model.json +3046 -0
- data/spec/helpers/process_helper.rb +2 -2
- data/spec/helpers/project_helper.rb +29 -0
- data/spec/helpers/schedule_helper.rb +1 -1
- data/spec/integration/command_datawarehouse_spec.rb +32 -0
- data/spec/integration/create_project_spec.rb +0 -1
- data/spec/integration/full_process_schedule_spec.rb +13 -5
- data/spec/integration/full_project_spec.rb +2 -1
- data/spec/integration/over_to_user_filters_spec.rb +92 -0
- data/spec/integration/project_spec.rb +233 -0
- data/spec/integration/rest_spec.rb +209 -0
- data/spec/integration/user_filters_spec.rb +193 -0
- data/spec/integration/variables_spec.rb +196 -0
- data/spec/unit/commands/command_auth_spec.rb +0 -7
- data/spec/unit/commands/command_process_spec.rb +10 -13
- data/spec/unit/core/connection_spec.rb +0 -19
- data/spec/unit/helpers/global_helpers_spec.rb +57 -0
- data/spec/unit/models/domain_spec.rb +80 -40
- data/spec/unit/models/from_wire_spec.rb +8 -1
- data/spec/unit/models/params_spec.rb +6 -6
- data/spec/unit/models/profile_spec.rb +23 -22
- data/spec/unit/models/project_blueprint_spec.rb +1 -6
- data/spec/unit/models/project_spec.rb +331 -286
- data/spec/unit/models/schedule_spec.rb +39 -14
- data/spec/unit/models/user_filters_spec.rb +89 -0
- data/spec/unit/models/variable_spec.rb +259 -0
- metadata +31 -7
- data/lib/gooddata/rest/connections/dummy_connection.rb +0 -52
- data/spec/unit/core/rest_spec.rb +0 -106
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require 'tempfile'
|
|
3
|
+
|
|
4
|
+
require 'gooddata/core/rest'
|
|
5
|
+
|
|
6
|
+
describe GoodData do
|
|
7
|
+
before(:each) do
|
|
8
|
+
@client = ConnectionHelper.create_default_connection
|
|
9
|
+
# @project = ProjectHelper.get_default_project(:client => @client)
|
|
10
|
+
@project = @client.create_project(title: 'Project for schedule testing', auth_token: ConnectionHelper::GD_PROJECT_TOKEN)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after(:each) do
|
|
14
|
+
@project && @project.delete
|
|
15
|
+
@client.disconnect
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '#get_project_webdav_path' do
|
|
19
|
+
it 'Returns path' do
|
|
20
|
+
@client.get_project_webdav_path('test-file.csv', :project => @project)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_webdav_upload(params)
|
|
25
|
+
GoodData.with_project(@project, :client => @client) do
|
|
26
|
+
|
|
27
|
+
# use current timestamp as a directory name on webdav
|
|
28
|
+
dir = params[:no_dir] ? nil : Time.now.to_i.to_s
|
|
29
|
+
dir = "#{dir}/#{dir}" if params[:nested_dir]
|
|
30
|
+
dir = "#{dir}/" if params[:slash_in_dir]
|
|
31
|
+
|
|
32
|
+
# local file path
|
|
33
|
+
path = 'spec/data/test-ci-data.csv'
|
|
34
|
+
|
|
35
|
+
if params[:special_chars]
|
|
36
|
+
source_file = Tempfile.new('abc-16:55:29+ha#he.csv')
|
|
37
|
+
FileUtils.cp(path, source_file)
|
|
38
|
+
path = source_file.path
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
path = File.expand_path(path) if params[:absolute_path]
|
|
42
|
+
|
|
43
|
+
# upload it there
|
|
44
|
+
upload_method = GoodData.method(params[:upload_method])
|
|
45
|
+
upload_method.call(path, directory: dir)
|
|
46
|
+
|
|
47
|
+
# download it from there
|
|
48
|
+
temp_file = Tempfile.new('foo.csv')
|
|
49
|
+
expect(temp_file.size).to be == 0
|
|
50
|
+
|
|
51
|
+
download_method = GoodData.method(params[:download_method])
|
|
52
|
+
|
|
53
|
+
file_basename = File.basename(path)
|
|
54
|
+
file_basename = "NOTTHERE_#{file_basename}" if params[:unknown_file]
|
|
55
|
+
|
|
56
|
+
download_block = proc do
|
|
57
|
+
if params[:path_in_file]
|
|
58
|
+
# pass the dir directly in the first param
|
|
59
|
+
# e.g. GoodData.download_from_project_webdav('1234/test-ci-data.csv', '/tmp/myfile.csv')
|
|
60
|
+
download_method.call(File.join(dir, file_basename).to_s, temp_file)
|
|
61
|
+
else
|
|
62
|
+
# pass the dir in the :directory option
|
|
63
|
+
# e.g. GoodData.download_from_project_webdav('test-ci-data.csv', '/tmp/myfile.csv', :directory => '1234')
|
|
64
|
+
download_method.call(file_basename, temp_file, directory: dir)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# if it's unknown it should raise an error, otherwise it should download the right stuff
|
|
69
|
+
if params[:unknown_file]
|
|
70
|
+
expect{ download_block.call }.to raise_error(ArgumentError)
|
|
71
|
+
else
|
|
72
|
+
download_block.call
|
|
73
|
+
|
|
74
|
+
expect(temp_file.size).to be > 0
|
|
75
|
+
|
|
76
|
+
# expect the contents of the original file and the downloaded file are the same
|
|
77
|
+
expect(IO.read(temp_file)).to be == IO.read(path)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe '#download_from_project_webdav' do
|
|
83
|
+
it "Works with directory directly in the 'file' param for project" do
|
|
84
|
+
test_webdav_upload(
|
|
85
|
+
upload_method: 'upload_to_project_webdav',
|
|
86
|
+
download_method: 'download_from_project_webdav',
|
|
87
|
+
path_in_file: true
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
it "Works with directory directly in the 'file' param for user" do
|
|
91
|
+
test_webdav_upload(
|
|
92
|
+
upload_method: 'upload_to_user_webdav',
|
|
93
|
+
download_method: 'download_from_user_webdav',
|
|
94
|
+
path_in_file: true
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
it "Works with directories with slash at the end for project" do
|
|
98
|
+
test_webdav_upload(
|
|
99
|
+
upload_method: 'upload_to_project_webdav',
|
|
100
|
+
download_method: 'download_from_project_webdav',
|
|
101
|
+
slash_in_dir: true
|
|
102
|
+
)
|
|
103
|
+
end
|
|
104
|
+
it "Works with directories with slash at the end for user" do
|
|
105
|
+
test_webdav_upload(
|
|
106
|
+
upload_method: 'upload_to_user_webdav',
|
|
107
|
+
download_method: 'download_from_user_webdav',
|
|
108
|
+
slash_in_dir: true
|
|
109
|
+
)
|
|
110
|
+
end
|
|
111
|
+
it "Fails for non-existing file for project" do
|
|
112
|
+
test_webdav_upload(
|
|
113
|
+
upload_method: 'upload_to_project_webdav',
|
|
114
|
+
download_method: 'download_from_project_webdav',
|
|
115
|
+
unknown_file: true
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
it "Fails for non-existing file for user" do
|
|
119
|
+
test_webdav_upload(
|
|
120
|
+
upload_method: 'upload_to_user_webdav',
|
|
121
|
+
download_method: 'download_from_user_webdav',
|
|
122
|
+
unknown_file: true
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
it 'Works with nested directories for project' do
|
|
126
|
+
test_webdav_upload(
|
|
127
|
+
upload_method: 'upload_to_project_webdav',
|
|
128
|
+
download_method: 'download_from_project_webdav',
|
|
129
|
+
nested_dir: true
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
it 'Works with nested directories for user' do
|
|
133
|
+
test_webdav_upload(
|
|
134
|
+
upload_method: 'upload_to_user_webdav',
|
|
135
|
+
download_method: 'download_from_user_webdav',
|
|
136
|
+
nested_dir: true
|
|
137
|
+
)
|
|
138
|
+
end
|
|
139
|
+
it 'Works with no directory for user' do
|
|
140
|
+
test_webdav_upload(
|
|
141
|
+
upload_method: 'upload_to_user_webdav',
|
|
142
|
+
download_method: 'download_from_user_webdav',
|
|
143
|
+
no_dir: true
|
|
144
|
+
)
|
|
145
|
+
end
|
|
146
|
+
it 'Works with no directory for project' do
|
|
147
|
+
test_webdav_upload(
|
|
148
|
+
upload_method: 'upload_to_project_webdav',
|
|
149
|
+
download_method: 'download_from_project_webdav',
|
|
150
|
+
no_dir: true
|
|
151
|
+
)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
describe '#upload_to_project_webdav' do
|
|
155
|
+
it 'Uploads file with relative path to a dir' do
|
|
156
|
+
test_webdav_upload(
|
|
157
|
+
upload_method: 'upload_to_project_webdav',
|
|
158
|
+
download_method: 'download_from_project_webdav'
|
|
159
|
+
)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it 'Uploads file with absolute path to a dir' do
|
|
163
|
+
test_webdav_upload(
|
|
164
|
+
absolute_path: true,
|
|
165
|
+
upload_method: 'upload_to_project_webdav',
|
|
166
|
+
download_method: 'download_from_project_webdav'
|
|
167
|
+
)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it 'Uploads file with special chars in filename' do
|
|
171
|
+
test_webdav_upload(
|
|
172
|
+
special_chars: true,
|
|
173
|
+
upload_method: 'upload_to_project_webdav',
|
|
174
|
+
download_method: 'download_from_project_webdav'
|
|
175
|
+
)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
describe '#upload_to_user_webdav' do
|
|
180
|
+
it 'Uploads file with relative path to a dir' do
|
|
181
|
+
test_webdav_upload(
|
|
182
|
+
upload_method: 'upload_to_user_webdav',
|
|
183
|
+
download_method: 'download_from_user_webdav'
|
|
184
|
+
)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it 'Uploads file with absolute path to a dir' do
|
|
188
|
+
test_webdav_upload(
|
|
189
|
+
absolute_path: true,
|
|
190
|
+
upload_method: 'upload_to_user_webdav',
|
|
191
|
+
download_method: 'download_from_user_webdav'
|
|
192
|
+
)
|
|
193
|
+
end
|
|
194
|
+
it 'Uploads file with special chars in filename' do
|
|
195
|
+
test_webdav_upload(
|
|
196
|
+
special_chars: true,
|
|
197
|
+
upload_method: 'upload_to_user_webdav',
|
|
198
|
+
download_method: 'download_from_user_webdav'
|
|
199
|
+
)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
describe '#get_user_webdav_path' do
|
|
205
|
+
it 'Gets the path' do
|
|
206
|
+
@client.get_user_webdav_path('test.csv', :project => @project)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
require 'gooddata'
|
|
2
|
+
|
|
3
|
+
describe "User filters implementation", :constraint => 'slow' do
|
|
4
|
+
before(:all) do
|
|
5
|
+
@spec = JSON.parse(File.read("./spec/data/test_project_model_spec.json"), :symbolize_names => true)
|
|
6
|
+
@client = ConnectionHelper::create_default_connection
|
|
7
|
+
@project = @client.create_project_from_blueprint(@spec, :auth_token => ConnectionHelper::GD_PROJECT_TOKEN)
|
|
8
|
+
@domain = @client.domain(ConnectionHelper::DEFAULT_DOMAIN)
|
|
9
|
+
|
|
10
|
+
GoodData.with_project(@project) do |p|
|
|
11
|
+
@label = GoodData::Attribute.find_first_by_title('Dev', client: @client, project: @project).label_by_name('email')
|
|
12
|
+
|
|
13
|
+
blueprint = GoodData::Model::ProjectBlueprint.new(@spec)
|
|
14
|
+
commits_data = [
|
|
15
|
+
["lines_changed","committed_on","dev_id","repo_id"],
|
|
16
|
+
[1,"01/01/2014",1,1],
|
|
17
|
+
[3,"01/02/2014",2,2],
|
|
18
|
+
[5,"05/02/2014",3,1]]
|
|
19
|
+
GoodData::Model.upload_data(commits_data, blueprint, 'commits', :client => @client, :project => @project)
|
|
20
|
+
# blueprint.find_dataset('commits').upload(commits_data)
|
|
21
|
+
|
|
22
|
+
devs_data = [
|
|
23
|
+
["dev_id", "email"],
|
|
24
|
+
[1, "tomas@gooddata.com"],
|
|
25
|
+
[2, "petr@gooddata.com"],
|
|
26
|
+
[3, "jirka@gooddata.com"]]
|
|
27
|
+
GoodData::Model.upload_data(devs_data, blueprint, 'devs', :client => @client, :project => @project)
|
|
28
|
+
# blueprint.find_dataset('devs').upload(devs_data)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
after(:all) do
|
|
33
|
+
@project.delete if @project
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
after(:each) do
|
|
37
|
+
@project.data_permissions.pmap &:delete
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should create a mandatory user filter" do
|
|
41
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, 'tomas@gooddata.com', 'jirka@gooddata.com']]
|
|
42
|
+
|
|
43
|
+
metric = @project.create_metric("SELECT SUM(#\"Lines Changed\")", :title => 'x')
|
|
44
|
+
# [jirka@gooddata.com | petr@gooddata.com | tomas@gooddata.com]
|
|
45
|
+
# [5.0 | 3.0 | 1.0 ]
|
|
46
|
+
|
|
47
|
+
metric.execute.should == 9
|
|
48
|
+
@project.add_data_permissions(filters)
|
|
49
|
+
metric.execute.should == 6
|
|
50
|
+
r = @project.compute_report(left: [metric], top: [@label.attribute])
|
|
51
|
+
r.include_column?(['tomas@gooddata.com', 1]).should == true
|
|
52
|
+
|
|
53
|
+
r.include_column?(['tomas@gooddata.com', 1]).should == true
|
|
54
|
+
r.include_column?(['jirka@gooddata.com', 5]).should == true
|
|
55
|
+
r.include_column?(['petr@gooddata.com', 3]).should == false
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should fail when asked to set a user not in project. No filters should be set up." do
|
|
59
|
+
filters = [
|
|
60
|
+
['nonexistent_user@gooddata.com', @label.uri, "tomas@gooddata.com"],
|
|
61
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com"]
|
|
62
|
+
]
|
|
63
|
+
expect do
|
|
64
|
+
@project.add_data_permissions(filters)
|
|
65
|
+
end.to raise_error
|
|
66
|
+
expect(@project.data_permissions.count).to eq 0
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should pass and set users that are in the projects" do
|
|
70
|
+
filters = [
|
|
71
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com"]
|
|
72
|
+
]
|
|
73
|
+
@project.add_data_permissions(filters)
|
|
74
|
+
expect(@project.data_permissions.count).to eq 1
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should pass and set only users that are in the projects if asked" do
|
|
78
|
+
filters = [
|
|
79
|
+
['nonexistent_user@gooddata.com', @label.uri, 'tomas@gooddata.com'],
|
|
80
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, 'tomas@gooddata.com']
|
|
81
|
+
]
|
|
82
|
+
@project.add_data_permissions(filters, users_must_exist: false)
|
|
83
|
+
expect(@project.data_permissions.count).to eq 1
|
|
84
|
+
expect(@project.data_permissions.first.pretty_expression).to eq "[Dev] IN ([tomas@gooddata.com])"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "should fail when asked to set a value not in the proejct" do
|
|
88
|
+
filters = [
|
|
89
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, '%^&*( nonexistent value', 'tomas@gooddata.com'],
|
|
90
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, 'tomas@gooddata.com']]
|
|
91
|
+
expect do
|
|
92
|
+
@project.add_data_permissions(filters)
|
|
93
|
+
end.to raise_error
|
|
94
|
+
expect(@project.data_permissions.count).to eq 0
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should add a filter with nonexistent values when asked" do
|
|
98
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, '%^&*( nonexistent value', 'jirka@gooddata.com']]
|
|
99
|
+
@project.add_data_permissions(filters, ignore_missing_values: true)
|
|
100
|
+
|
|
101
|
+
expect(@project.data_permissions.pmap {|m| m.pretty_expression}).to eq ["[Dev] IN ([jirka@gooddata.com])"]
|
|
102
|
+
expect(@project.data_permissions.count).to eq 1
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "should be able to add mandatory filter to a user not in the project if domain is provided" do
|
|
106
|
+
domain = @client.domain(ConnectionHelper::DEFAULT_DOMAIN)
|
|
107
|
+
u = domain.users.find { |u| u.login != ConnectionHelper::DEFAULT_USERNAME }
|
|
108
|
+
|
|
109
|
+
filters = [[u.login, @label.uri, "tomas@gooddata.com"]]
|
|
110
|
+
expect do
|
|
111
|
+
@project.add_data_permissions(filters)
|
|
112
|
+
end.to raise_error
|
|
113
|
+
@project.add_data_permissions(filters, :domain => domain)
|
|
114
|
+
filters = @project.data_permissions
|
|
115
|
+
expect(filters.first.related.login).to eq u.login
|
|
116
|
+
expect(filters.count).to eq 1
|
|
117
|
+
expect(filters.first.pretty_expression).to eq "[Dev] IN ([tomas@gooddata.com])"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "should be able to print data permissions in a human readable form" do
|
|
121
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com"]]
|
|
122
|
+
@project.add_data_permissions(filters)
|
|
123
|
+
perms = @project.data_permissions
|
|
124
|
+
pretty = perms.pmap {|f| [f.related.login, f.pretty_expression]}
|
|
125
|
+
expect(perms.first.related).to eq @client.user
|
|
126
|
+
expect(pretty).to eq [["svarovsky+gem_tester@gooddata.com", "[Dev] IN ([tomas@gooddata.com])"]]
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "sets up mandatory users based on the state given as an end state by default." do
|
|
130
|
+
# first let's prepare some user filters
|
|
131
|
+
user_with_already_set_up_filter = @project.get_user(ConnectionHelper::DEFAULT_USERNAME)
|
|
132
|
+
|
|
133
|
+
filters = [
|
|
134
|
+
[user_with_already_set_up_filter.login, @label.uri, "tomas@gooddata.com"]
|
|
135
|
+
]
|
|
136
|
+
@project.add_data_permissions(filters)
|
|
137
|
+
expect(@project.data_permissions.map {|f| [f.related.login, f.pretty_expression] })
|
|
138
|
+
.to eq [[ConnectionHelper::DEFAULT_USERNAME, "[Dev] IN ([tomas@gooddata.com])"]]
|
|
139
|
+
|
|
140
|
+
# Now let's add user filter to a different user. If we do not explicitely state that
|
|
141
|
+
# user_with_already_set_up_filter should keep his filter it will be removed
|
|
142
|
+
another_user = @domain.users.find { |u| u.login != ConnectionHelper::DEFAULT_USERNAME }
|
|
143
|
+
@project.add_user(another_user, 'Admin', domain: @domain)
|
|
144
|
+
new_filters = [
|
|
145
|
+
[another_user.login, @label.uri, "tomas@gooddata.com"]
|
|
146
|
+
]
|
|
147
|
+
@project.add_data_permissions(new_filters)
|
|
148
|
+
expect(@project.data_permissions.map {|f| [f.related.login, f.pretty_expression] })
|
|
149
|
+
.to eq [[another_user.login, "[Dev] IN ([tomas@gooddata.com])"]]
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should set up false if all values are nonexistent" do
|
|
153
|
+
metric = GoodData::Fact.find_first_by_title('Lines Changed', client: @client, project: @project).create_metric
|
|
154
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "NONEXISTENT1", "NONEXISTENT2", "NONEXISTENT3"]]
|
|
155
|
+
@project.add_data_permissions(filters, ignore_missing_values: true)
|
|
156
|
+
expect(metric.execute).to eq 9
|
|
157
|
+
@project.add_data_permissions(filters, ignore_missing_values: true, restrict_if_missing_all_values: true)
|
|
158
|
+
expect(metric.execute).to eq nil
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "you can switch the updates. Whatever is not mentioned will not be touched" do
|
|
162
|
+
# first let's prepare some user filters
|
|
163
|
+
user_with_already_set_up_filter = @project.get_user(ConnectionHelper::DEFAULT_USERNAME)
|
|
164
|
+
|
|
165
|
+
filters = [
|
|
166
|
+
[user_with_already_set_up_filter.login, @label.uri, "tomas@gooddata.com"]
|
|
167
|
+
]
|
|
168
|
+
@project.add_data_permissions(filters)
|
|
169
|
+
expect(@project.data_permissions.map {|f| [f.related.login, f.pretty_expression] })
|
|
170
|
+
.to eq [[ConnectionHelper::DEFAULT_USERNAME, "[Dev] IN ([tomas@gooddata.com])"]]
|
|
171
|
+
|
|
172
|
+
# Now let's add user filter to a different user. If we do not explicitely state that
|
|
173
|
+
# user_with_already_set_up_filter should keep his filter it will be removed
|
|
174
|
+
another_user = @domain.users.find { |u| u.login != ConnectionHelper::DEFAULT_USERNAME }
|
|
175
|
+
@project.add_user(another_user, 'Admin', domain: @domain)
|
|
176
|
+
new_filters = [
|
|
177
|
+
[another_user.login, @label.uri, "tomas@gooddata.com"]
|
|
178
|
+
]
|
|
179
|
+
@project.add_data_permissions(new_filters, do_not_touch_filters_that_are_not_mentioned: true)
|
|
180
|
+
expect(@project.data_permissions.map {|f| [f.related.login, f.pretty_expression] })
|
|
181
|
+
.to include([ConnectionHelper::DEFAULT_USERNAME, "[Dev] IN ([tomas@gooddata.com])"], [another_user.login, "[Dev] IN ([tomas@gooddata.com])"])
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should be able to update the filter value" do
|
|
185
|
+
pending('We cannot swap filters yet')
|
|
186
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com", "jirka@gooddata.com"]]
|
|
187
|
+
@project.add_data_permissions(filters)
|
|
188
|
+
perm = @project.data_permissions.first
|
|
189
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com"]]
|
|
190
|
+
@project.add_data_permissions(filters)
|
|
191
|
+
expect(perm.reload!.pretty_expression).to eq '[Dev] IN ([tomas@gooddata.com, jirka@gooddata.com])'
|
|
192
|
+
end
|
|
193
|
+
end
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
require 'gooddata'
|
|
2
|
+
|
|
3
|
+
describe "Variables implementation", :constraint => 'slow' do
|
|
4
|
+
before(:all) do
|
|
5
|
+
@spec = JSON.parse(File.read("./spec/data/test_project_model_spec.json"), :symbolize_names => true)
|
|
6
|
+
@client = ConnectionHelper::create_default_connection
|
|
7
|
+
@project = @client.create_project_from_blueprint(@spec, :auth_token => ConnectionHelper::GD_PROJECT_TOKEN)
|
|
8
|
+
@domain = @client.domain(ConnectionHelper::DEFAULT_DOMAIN)
|
|
9
|
+
|
|
10
|
+
@label = GoodData::Attribute.find_first_by_title('Dev', client: @client, project: @project).label_by_name('email')
|
|
11
|
+
|
|
12
|
+
blueprint = GoodData::Model::ProjectBlueprint.new(@spec)
|
|
13
|
+
commits_data = [
|
|
14
|
+
["lines_changed","committed_on","dev_id","repo_id"],
|
|
15
|
+
[1,"01/01/2014",1,1],
|
|
16
|
+
[3,"01/02/2014",2,2],
|
|
17
|
+
[5,"05/02/2014",3,1]]
|
|
18
|
+
GoodData::Model.upload_data(commits_data, blueprint, 'commits', :client => @client, :project => @project)
|
|
19
|
+
# blueprint.find_dataset('commits').upload(commits_data)
|
|
20
|
+
|
|
21
|
+
devs_data = [
|
|
22
|
+
["dev_id", "email"],
|
|
23
|
+
[1, "tomas@gooddata.com"],
|
|
24
|
+
[2, "petr@gooddata.com"],
|
|
25
|
+
[3, "jirka@gooddata.com"]]
|
|
26
|
+
GoodData::Model.upload_data(devs_data, blueprint, 'devs', :client => @client, :project => @project)
|
|
27
|
+
# blueprint.find_dataset('devs').upload(devs_data)
|
|
28
|
+
|
|
29
|
+
@variable = @project.create_variable(title: 'uaaa', attribute: @label.attribute).save
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
after(:all) do
|
|
34
|
+
@project.delete if @project
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
after(:each) do
|
|
38
|
+
@variable.user_values.select {|x| x.level == :user}.pmap &:delete
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should create a variable filter" do
|
|
42
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, 'tomas@gooddata.com', 'jirka@gooddata.com']]
|
|
43
|
+
|
|
44
|
+
metric = @project.create_metric("SELECT SUM(#\"Lines Changed\")", :title => 'x')
|
|
45
|
+
|
|
46
|
+
# [jirka@gooddata.com | petr@gooddata.com | tomas@gooddata.com]
|
|
47
|
+
# [5.0 | 3.0 | 1.0 ]
|
|
48
|
+
@project.add_variable_permissions(filters, @variable)
|
|
49
|
+
r = @project.compute_report(left: [metric], top: [@label.attribute], filters: [@variable])
|
|
50
|
+
r.include_column?(['tomas@gooddata.com', 1]).should == true
|
|
51
|
+
r.include_column?(['jirka@gooddata.com', 5]).should == true
|
|
52
|
+
r.include_column?(['petr@gooddata.com', 3]).should == false
|
|
53
|
+
|
|
54
|
+
r = @project.compute_report(left: [metric], top: [@label.attribute])
|
|
55
|
+
r.include_column?(['tomas@gooddata.com', 1]).should == true
|
|
56
|
+
r.include_column?(['jirka@gooddata.com', 5]).should == true
|
|
57
|
+
r.include_column?(['petr@gooddata.com', 3]).should == true
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should fail when asked to set a user not in project. No filters should be set up." do
|
|
61
|
+
filters = [
|
|
62
|
+
['nonexistent_user@gooddata.com', @label.uri, "tomas@gooddata.com"],
|
|
63
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com"]
|
|
64
|
+
]
|
|
65
|
+
expect do
|
|
66
|
+
@project.add_variable_permissions(filters, @variable)
|
|
67
|
+
end.to raise_error
|
|
68
|
+
expect(@variable.user_values.count).to eq 0
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should pass and set users that are in the projects" do
|
|
72
|
+
filters = [
|
|
73
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com"]
|
|
74
|
+
]
|
|
75
|
+
@project.add_variable_permissions(filters, @variable)
|
|
76
|
+
expect(@variable.user_values.count).to eq 1
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should pass and set only users that are in the projects if asked" do
|
|
80
|
+
filters = [
|
|
81
|
+
['nonexistent_user@gooddata.com', @label.uri, 'tomas@gooddata.com'],
|
|
82
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, 'tomas@gooddata.com']
|
|
83
|
+
]
|
|
84
|
+
@project.add_variable_permissions(filters, @variable, users_must_exist: false)
|
|
85
|
+
expect(@variable.user_values.count).to eq 1
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should fail when asked to set a value not in the proejct" do
|
|
89
|
+
filters = [
|
|
90
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, '%^&*( nonexistent value', 'tomas@gooddata.com'],
|
|
91
|
+
[ConnectionHelper::DEFAULT_USERNAME, @label.uri, 'tomas@gooddata.com']]
|
|
92
|
+
expect do
|
|
93
|
+
@project.add_variable_permissions(filters, @variable)
|
|
94
|
+
end.to raise_error
|
|
95
|
+
expect(@variable.user_values.count).to eq 0
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should add a filter with nonexistent values when asked" do
|
|
99
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, '%^&*( nonexistent value', 'jirka@gooddata.com']]
|
|
100
|
+
@project.add_variable_permissions(filters, @variable, ignore_missing_values: true)
|
|
101
|
+
|
|
102
|
+
expect(@variable.user_values.pmap {|m| m.pretty_expression}).to eq ["[Dev] IN ([jirka@gooddata.com])"]
|
|
103
|
+
expect(@variable.user_values.count).to eq 1
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "should be able to add mandatory filter to a user not in the project if domain is provided" do
|
|
107
|
+
domain = @client.domain(ConnectionHelper::DEFAULT_DOMAIN)
|
|
108
|
+
u = domain.users.find { |u| u.login != ConnectionHelper::DEFAULT_USERNAME }
|
|
109
|
+
filters = [[u.login, @label.uri, "tomas@gooddata.com"]]
|
|
110
|
+
expect do
|
|
111
|
+
@project.add_variable_permissions(filters, @variable)
|
|
112
|
+
end.to raise_error
|
|
113
|
+
@project.add_variable_permissions(filters, @variable, :domain => domain)
|
|
114
|
+
filters = @variable.user_values
|
|
115
|
+
expect(filters.first.related.login).to eq u.login
|
|
116
|
+
expect(filters.count).to eq 1
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should be able to print data permissions in a human readable form" do
|
|
120
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com"]]
|
|
121
|
+
@project.add_variable_permissions(filters, @variable)
|
|
122
|
+
perms = @variable.user_values
|
|
123
|
+
pretty = perms.pmap {|f| [f.related.login, f.pretty_expression]}
|
|
124
|
+
expect(perms.first.related).to eq @client.user
|
|
125
|
+
expect(pretty).to eq [["svarovsky+gem_tester@gooddata.com", "[Dev] IN ([tomas@gooddata.com])"]]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "sets up mandatory users based on the state given as an end state by default." do
|
|
129
|
+
# first let's prepare some user filters
|
|
130
|
+
user_with_already_set_up_filter = @project.get_user(ConnectionHelper::DEFAULT_USERNAME)
|
|
131
|
+
|
|
132
|
+
filters = [
|
|
133
|
+
[user_with_already_set_up_filter.login, @label.uri, "tomas@gooddata.com"]
|
|
134
|
+
]
|
|
135
|
+
@project.add_variable_permissions(filters, @variable)
|
|
136
|
+
expect(@variable.user_values.map {|f| [f.related.login, f.pretty_expression] })
|
|
137
|
+
.to eq [[ConnectionHelper::DEFAULT_USERNAME, "[Dev] IN ([tomas@gooddata.com])"]]
|
|
138
|
+
|
|
139
|
+
# Now let's add user filter to a different user. If we do not explicitely state that
|
|
140
|
+
# user_with_already_set_up_filter should keep his filter it will be removed
|
|
141
|
+
another_user = @domain.users.find { |u| u.login != ConnectionHelper::DEFAULT_USERNAME }
|
|
142
|
+
@project.add_user(another_user, 'Admin', domain: @domain)
|
|
143
|
+
new_filters = [
|
|
144
|
+
[another_user.login, @label.uri, "tomas@gooddata.com"]
|
|
145
|
+
]
|
|
146
|
+
@project.add_variable_permissions(new_filters, @variable)
|
|
147
|
+
expect(@variable.user_values.map {|f| [f.related.login, f.pretty_expression] })
|
|
148
|
+
.to eq [[another_user.login, "[Dev] IN ([tomas@gooddata.com])"]]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "should set up false if all values are nonexistent" do
|
|
152
|
+
metric = GoodData::Fact.find_first_by_title('Lines Changed', client: @client, project: @project).create_metric
|
|
153
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "NONEXISTENT1", "NONEXISTENT2", "NONEXISTENT3"]]
|
|
154
|
+
@project.add_variable_permissions(filters, @variable, ignore_missing_values: true)
|
|
155
|
+
# expect(metric.execute).to eq 9
|
|
156
|
+
expect(@variable.user_values.map {|f| [f.related.login, f.pretty_expression] })
|
|
157
|
+
.to eq [[ConnectionHelper::DEFAULT_USERNAME, "TRUE"]]
|
|
158
|
+
|
|
159
|
+
@project.add_variable_permissions(filters, @variable, ignore_missing_values: true, restrict_if_missing_all_values: true)
|
|
160
|
+
# expect(metric.execute).to eq nil
|
|
161
|
+
expect(@variable.user_values.count).to eq 0
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it "you can switch the updates. Whatever is not mentioned will not be touched" do
|
|
165
|
+
# first let's prepare some user filters
|
|
166
|
+
user_with_already_set_up_filter = @project.get_user(ConnectionHelper::DEFAULT_USERNAME)
|
|
167
|
+
|
|
168
|
+
filters = [
|
|
169
|
+
[user_with_already_set_up_filter.login, @label.uri, "tomas@gooddata.com"]
|
|
170
|
+
]
|
|
171
|
+
@project.add_variable_permissions(filters, @variable)
|
|
172
|
+
expect(@variable.user_values.map {|f| [f.related.login, f.pretty_expression] })
|
|
173
|
+
.to eq [[ConnectionHelper::DEFAULT_USERNAME, "[Dev] IN ([tomas@gooddata.com])"]]
|
|
174
|
+
# Now let's add user filter to a different user. If we do not explicitely state that
|
|
175
|
+
# user_with_already_set_up_filter should keep his filter it will be removed
|
|
176
|
+
another_user = @domain.users.find { |u| u.login != ConnectionHelper::DEFAULT_USERNAME }
|
|
177
|
+
@project.add_user(another_user, 'Admin', domain: @domain)
|
|
178
|
+
new_filters = [
|
|
179
|
+
[another_user.login, @label.uri, "tomas@gooddata.com"]
|
|
180
|
+
]
|
|
181
|
+
@project.add_variable_permissions(new_filters, @variable, do_not_touch_filters_that_are_not_mentioned: true)
|
|
182
|
+
expect(@variable.user_values.map {|f| [f.related.login, f.pretty_expression] })
|
|
183
|
+
.to include([ConnectionHelper::DEFAULT_USERNAME, "[Dev] IN ([tomas@gooddata.com])"],
|
|
184
|
+
[another_user.login, "[Dev] IN ([tomas@gooddata.com])"])
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "should be able to update the filter value in place" do
|
|
188
|
+
pending('We cannot swap filters yet')
|
|
189
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com", "jirka@gooddata.com"]]
|
|
190
|
+
@project.add_variable_permissions(filters, @variable)
|
|
191
|
+
perm = @variable.user_values.first
|
|
192
|
+
filters = [[ConnectionHelper::DEFAULT_USERNAME, @label.uri, "tomas@gooddata.com"]]
|
|
193
|
+
@project.add_variable_permissions(filters, @variable)
|
|
194
|
+
expect(perm.reload!.pretty_expression).to eq '[Dev] IN ([tomas@gooddata.com, jirka@gooddata.com])'
|
|
195
|
+
end
|
|
196
|
+
end
|