gooddata 0.6.11 → 0.6.12

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -8,8 +8,8 @@ require 'pmap'
8
8
  require 'gooddata/models/models'
9
9
 
10
10
  module ProcessHelper
11
- PROCESS_ID = 'dc143d80-58a1-4acd-96b6-8d11fc4571de'
12
- DEPLOY_NAME = 'graph'
11
+ PROCESS_ID = '81fa71a4-69fd-4c58-aa09-66e7f53f4647'
12
+ DEPLOY_NAME = 'graph.grf'
13
13
 
14
14
  class << self
15
15
  def remove_old_processes(project)
@@ -15,4 +15,33 @@ module ProjectHelper
15
15
  def self.get_default_project(opts = { :client => GoodData.connection })
16
16
  GoodData::Project[PROJECT_ID, opts]
17
17
  end
18
+
19
+ def self.delete_old_projects(opts = {:client => GoodData.connection})
20
+ projects = opts[:client].projects
21
+ projects.each do |project|
22
+ next if project.json['project']['meta']['author'] != client.user.uri
23
+ next if project.pid == 'we1vvh4il93r0927r809i3agif50d7iz'
24
+ begin
25
+ puts "Deleting project #{project.title}"
26
+ project.delete
27
+ rescue e
28
+ puts 'ERROR: ' + e.to_s
29
+ end
30
+ end
31
+ end
32
+
33
+ def self.create_random_user(client)
34
+ num = rand(1e6)
35
+ login = "gemtest#{num}@gooddata.com"
36
+
37
+ GoodData::Membership.create({
38
+ email: login,
39
+ login: login,
40
+ first_name: 'the',
41
+ last_name: num.to_s,
42
+ role: 'editor',
43
+ password: CryptoHelper.generate_password,
44
+ domain: ConnectionHelper::DEFAULT_DOMAIN
45
+ }, client: client)
46
+ end
18
47
  end
@@ -5,7 +5,7 @@ require 'pmap'
5
5
  require_relative 'process_helper'
6
6
 
7
7
  module ScheduleHelper
8
- SCHEDULE_ID = '53e029bde4b035034ad4abb6'
8
+ SCHEDULE_ID = '54b90771e4b067429a27a549'
9
9
 
10
10
  class << self
11
11
  def remove_old_schedules(project)
@@ -0,0 +1,32 @@
1
+ require 'gooddata/commands/datawarehouse'
2
+
3
+ describe GoodData::Command::DataWarehouse do
4
+ before(:each) do
5
+ @client = ConnectionHelper.create_default_connection
6
+ end
7
+
8
+ after(:each) do
9
+ @client.disconnect
10
+ end
11
+
12
+ it "Is Possible to create GoodData::Command::DataWarehouse instance" do
13
+ cmd = GoodData::Command::DataWarehouse.new()
14
+ cmd.should be_a(GoodData::Command::DataWarehouse)
15
+ end
16
+
17
+ it "Can create a data warehouse" do
18
+ title = 'my warehouse'
19
+ summary = 'hahahaha'
20
+ dwh = nil
21
+
22
+ begin
23
+ dwh = GoodData::Command::DataWarehouse.create(title: title, summary: summary, token: ConnectionHelper::GD_PROJECT_TOKEN, client: @client)
24
+ expect(dwh.title).to eq(title)
25
+ expect(dwh.summary).to eq(summary)
26
+ expect(dwh.id).not_to be_nil
27
+ expect(dwh.status).to eq('ENABLED')
28
+ ensure
29
+ dwh.delete if dwh
30
+ end
31
+ end
32
+ end
@@ -15,5 +15,4 @@ describe 'Create project using GoodData client', :constraint => 'slow' do
15
15
  expect(project.title).to eq(project_title)
16
16
  project.delete
17
17
  end
18
-
19
18
  end
@@ -26,6 +26,7 @@ describe "Full process and schedule exercise", :constraint => 'slow' do
26
26
  @process = @project.deploy_process('./spec/data/ruby_process',
27
27
  type: 'RUBY',
28
28
  name: 'Test ETL Process')
29
+
29
30
  end
30
31
 
31
32
  after(:all) do
@@ -109,14 +110,14 @@ describe "Full process and schedule exercise", :constraint => 'slow' do
109
110
  expect(result.status).to eq :ok
110
111
  log = result.log
111
112
  expect(log.index('HELLO WORLD')).not_to eq nil
112
- expect(schedule.enabled?).to be_true
113
+ expect(schedule.enabled?).to be_truthy
113
114
  schedule.disable
114
115
  schedule.save
115
- expect(schedule.enabled?).to be_false
116
- expect(schedule.disabled?).to be_true
116
+ expect(schedule.enabled?).to be_falsey
117
+ expect(schedule.disabled?).to be_truthy
117
118
  schedule.enable
118
119
  schedule.save
119
- expect(schedule.enabled?).to be_true
120
+ expect(schedule.enabled?).to be_truthy
120
121
  ensure
121
122
  schedule && schedule.delete
122
123
  process && process.delete
@@ -151,7 +152,7 @@ describe "Full process and schedule exercise", :constraint => 'slow' do
151
152
  result = schedule.execute
152
153
  expect(result.status).to eq :ok
153
154
  log = result.log
154
- expect(log.index(GoodData::VERSION)).not_to eq nil
155
+ expect(log.index('GoodData::VERSION - 0.6.')).not_to eq nil
155
156
  expect(process.schedules.count).to eq 1
156
157
  ensure
157
158
  schedule && schedule.delete
@@ -210,4 +211,11 @@ describe "Full process and schedule exercise", :constraint => 'slow' do
210
211
  process && process.delete
211
212
  end
212
213
  end
214
+
215
+ it "should be able to redeploy via project" do
216
+ process = @project.deploy_process('./spec/data/hello_world_process/hello_world.zip',
217
+ type: 'RUBY',
218
+ name: 'Test ETL zipped file Process',
219
+ process_id: @process.obj_id)
220
+ end
213
221
  end
@@ -147,6 +147,7 @@ describe "Full project implementation", :constraint => 'slow' do
147
147
  r = @project.create_report(top: [m], title: 'xy')
148
148
  rd = r.latest_report_definition
149
149
  rd.content['chart'] = { 'styles' => { 'global' => { 'colorMapping' => 1 } } }
150
+
150
151
  expect(GoodData::Helpers.get_path(rd.content, %w(chart styles global))).to eq ({ 'colorMapping' => 1 })
151
152
  rd.reset_color_mapping!
152
153
  expect(GoodData::Helpers.get_path(rd.content, %w(chart styles global))).to eq ({ 'colorMapping' => [] })
@@ -237,7 +238,7 @@ describe "Full project implementation", :constraint => 'slow' do
237
238
 
238
239
  it "should try setting and getting by tags" do
239
240
  fact = @project.fact_by_title('Lines Changed')
240
- expect(fact.tags.empty?).to be_true
241
+ expect(fact.tags.empty?).to be_truthy
241
242
 
242
243
  fact.tags = "tag1,tag2,tag3"
243
244
  fact.save
@@ -0,0 +1,92 @@
1
+ require 'gooddata'
2
+
3
+ describe "Variables implementation", :constraint => 'slow' do
4
+ before(:all) do
5
+ @spec = JSON.parse(File.read("./spec/data/m_n_model/blueprint.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('Perm User', client: @client, project: @project).label_by_name('email')
11
+
12
+ @blueprint = GoodData::Model::ProjectBlueprint.new(@spec)
13
+ commits_data = [
14
+ ['commit_id', 'lines_changed', 'user_id'],
15
+ [1, 1, 1],
16
+ [2, 3, 2],
17
+ [3, 5, 3]]
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
+ ["user_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, 'users', :client => @client, :project => @project)
27
+
28
+ devs_data = [
29
+ ["perm_user_id", "email"],
30
+ [1, "tomas@gooddata.com"],
31
+ [2, "petr@gooddata.com"],
32
+ [3, "jirka@gooddata.com"]]
33
+ GoodData::Model.upload_data(devs_data, @blueprint, 'permission_users', :client => @client, :project => @project)
34
+ # blueprint.find_dataset('devs').upload(devs_data)
35
+
36
+ devs_data = [
37
+ ['visibility_id', 'perm_user_id', 'commit_id'],
38
+ [1, 1, 1],
39
+ # [2, 1, 2],
40
+ [3, 1, 3]]
41
+ GoodData::Model.upload_data(devs_data, @blueprint, 'visibility', :client => @client, :project => @project)
42
+
43
+ @variable = @project.create_variable(title: 'uaaa', attribute: @label.attribute).save
44
+
45
+ @attr1 = GoodData::Attribute.find_first_by_title('Visibility', client: @client, project: @project)
46
+ @attr2 = GoodData::Attribute.find_first_by_title('Commit', client: @client, project: @project)
47
+
48
+ @filters = [
49
+ {
50
+ login: ConnectionHelper::DEFAULT_USERNAME,
51
+ filters: [
52
+ { label: @label.uri, values: ["tomas@gooddata.com"], over: @attr1.uri, to: @attr2.uri}
53
+ ]
54
+ }
55
+ ]
56
+ end
57
+
58
+ after(:all) do
59
+ @project.delete if @project
60
+ end
61
+
62
+ after(:each) do
63
+ @project.data_permissions.pmap &:delete
64
+ end
65
+
66
+ it "should fail if you are specifying OVER TO filter and variables. Variables do not support OVER TO" do
67
+ expect do
68
+ @project.add_variable_permissions(@filters, @variable)
69
+ end.to raise_exception
70
+ end
71
+
72
+ it "should create an over to filter transparently" do
73
+ metric = @project.create_metric("SELECT SUM(#\"Lines Changed\")", :title => 'x')
74
+ expect(metric.execute).to eq 9
75
+ @project.add_data_permissions(@filters)
76
+ expect(metric.execute).to eq 6
77
+
78
+ r = @project.compute_report(left: [metric], top: @project.attributes('attr.users.user_id'))
79
+ expect(r.include_column?(['tomas@gooddata.com', 1])).to eq true
80
+ expect(r.include_column?(['jirka@gooddata.com', 5])).to eq true
81
+ expect(r.include_column?(['petr@gooddata.com', 3])).to eq false
82
+
83
+ devs_data = [['visibility_id', 'perm_user_id', 'commit_id'], [1, 1, 1]]
84
+ GoodData::Model.upload_data(devs_data, @blueprint, 'visibility', :client => @client, :project => @project)
85
+
86
+ expect(metric.execute).to eq 1
87
+ r = @project.compute_report(left: [metric], top: @project.attributes('attr.users.user_id'))
88
+ expect(r.include_column?(['tomas@gooddata.com', 1])).to eq true
89
+ expect(r.include_column?(['jirka@gooddata.com', 5])).to eq false
90
+ expect(r.include_column?(['petr@gooddata.com', 3])).to eq false
91
+ end
92
+ end
@@ -0,0 +1,233 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'pmap'
4
+ require 'gooddata'
5
+
6
+ describe GoodData::Project, :constraint => 'slow' do
7
+ before(:all) do
8
+ @client = ConnectionHelper::create_default_connection
9
+ @project = @client.create_project(title: ProjectHelper::PROJECT_TITLE, auth_token: ConnectionHelper::GD_PROJECT_TOKEN)
10
+ @domain = @client.domain(ConnectionHelper::DEFAULT_DOMAIN)
11
+ end
12
+
13
+ after(:all) do
14
+ @project && @project.delete
15
+ @client.disconnect
16
+ end
17
+
18
+ describe '#add_user' do
19
+ it 'Adding user without domain should fail if it is not in the domain' do
20
+ user = ProjectHelper.create_random_user(@client)
21
+ expect do
22
+ @project.add_user(user, 'Admin')
23
+ end.to raise_exception(ArgumentError)
24
+ end
25
+
26
+ it 'Adding user with domain should be added to a project' do
27
+ user = ProjectHelper.create_random_user(@client)
28
+ @domain.create_users([user])
29
+ res = @project.add_user(user, 'Admin', domain: @domain)
30
+ expect(@project.member?(res['projectUsersUpdateResult']['successful'].first)).to be_truthy
31
+ end
32
+ end
33
+
34
+ describe '#add_users' do
35
+ it 'Adding user without domain should fail if it is not in the project' do
36
+ users = (1..5).to_a.map do |x|
37
+ {
38
+ user: ProjectHelper.create_random_user(@client),
39
+ role: 'Admin'
40
+ }
41
+ end
42
+ res = @project.add_users(users)
43
+ expect(res.all? { |x| x[:type] == :error }).to eq true
44
+ end
45
+
46
+ it 'Adding users with domain should pass and users should be added to domain' do
47
+ users = (1..5).to_a.map do |x|
48
+ {
49
+ user: ProjectHelper.create_random_user(@client),
50
+ role: 'Admin'
51
+ }
52
+ end
53
+ @domain.create_users(users.map {|u| u[:user]})
54
+ res = @project.add_users(users, domain: @domain)
55
+ links = res.map {|i| i[:result]['projectUsersUpdateResult']['successful'].first}
56
+ expect(@project.members?(links).all?).to be_truthy
57
+ # users.map { |r| r[:user] }.each { |u| u.delete }
58
+ end
59
+ end
60
+
61
+ describe '#import_users' do
62
+ it "Updates user's name and surname and removes the users" do
63
+ users = (1..2).to_a.map { |x| ProjectHelper.create_random_user(@client) }
64
+ @project.import_users(users, domain: @domain, whitelists: [/gem_tester@gooddata.com/])
65
+ expect(@domain.members?(users)).to be_truthy
66
+ expect(@project.members?(users)).to be_truthy
67
+ expect(@project.members.count).to eq 3
68
+ # update some user stuff
69
+ bill = users[0]
70
+ bill.first_name = 'buffalo'
71
+ bill.last_name = 'bill'
72
+ # import
73
+ @project.import_users(users, domain: @domain, whitelists: [/gem_tester@gooddata.com/])
74
+ # it should be updated
75
+ bill_changed = @domain.get_user(bill)
76
+ expect(bill_changed.first_name).to eql('buffalo')
77
+ expect(bill_changed.last_name).to eql('bill')
78
+ expect(@project.members?(users)).to be_truthy
79
+ expect(@project.members.count).to eq 3
80
+ expect(@project.member?(bill_changed)).to be_truthy
81
+
82
+ # remove everybody but buffalo bill.
83
+ @project.import_users([bill], domain: @domain, whitelists: [/gem_tester@gooddata.com/])
84
+ expect(@project.members.count).to eq 2
85
+ expect(@project.member?(bill)).to be_truthy
86
+ expect(@project.members?(users - [bill]).any?).to be_falsey
87
+
88
+ # Add additional user while changing Buffalos surname and role.
89
+ bill.last_name = 'Billie'
90
+ other_guy = ProjectHelper.create_random_user(@client)
91
+
92
+ additional_batch = [bill, other_guy].map { |u| {user: u, role: u.role} }
93
+ @project.import_users(additional_batch, domain: @domain, whitelists: [/gem_tester@gooddata.com/])
94
+ expect(@project.members.count).to eq 3
95
+ expect(@project.member?(bill)).to be_truthy
96
+ expect(@project.members?(users - additional_batch.map {|x| x[:user]}).any?).to be_falsey
97
+ end
98
+
99
+ it "Updates user's role in a project" do
100
+ users = (1..5).to_a.map { |x| ProjectHelper.create_random_user(@client).to_hash }
101
+ @project.import_users(users, domain: @domain, whitelists: [/gem_tester@gooddata.com/])
102
+
103
+ expect(@project.members?(users)).to be_truthy
104
+ user_role_changed = users[1]
105
+ users_unchanged = users - [user_role_changed]
106
+ new_role = users[1][:role] = users[1][:role] == "admin" ? "editor" : "admin"
107
+ @project.import_users(users, domain: @domain, whitelists: [/gem_tester@gooddata.com/])
108
+ expect(@project.get_user(user_role_changed).role.identifier).to eql("#{new_role}Role")
109
+ expect(users_unchanged.map {|u| @project.get_user(u)}.map(&:role).map(&:title).uniq).to eq ['Editor']
110
+ end
111
+
112
+ it "ignores user from both project and end state batch when whitelisted" do
113
+ u = @project.get_user(ConnectionHelper::DEFAULT_USERNAME)
114
+ uh = u.to_hash
115
+ uh[:role] = 'editor'
116
+
117
+ users = (1..5).to_a.map { |x| ProjectHelper.create_random_user(@client).to_hash } + [uh]
118
+ expect(@project.member?(u)).to be_truthy
119
+ expect(u.role.title).to eq 'Admin'
120
+ @project.import_users(users, domain: @domain, whitelists: [/gem_tester@gooddata.com/])
121
+ expect(@project.member?(u)).to be_truthy
122
+ expect(@project.members?(users).all?).to be_truthy
123
+ expect(@project.get_user(ConnectionHelper::DEFAULT_USERNAME).role.title).to eq 'Admin'
124
+ end
125
+
126
+ end
127
+
128
+ describe '#set_user_roles' do
129
+ it 'Properly updates user roles as needed' do
130
+ users_to_import = @domain.users.sample(5).map {|u| { user: u, role: 'admin' }}
131
+ @project.import_users(users_to_import, domain: @domain, whitelists: [/gem_tester@gooddata.com/])
132
+ users_without_owner = @project.users.reject { |u| u.login == ConnectionHelper::DEFAULT_USERNAME }.pselect { |u| u.role.title == 'Admin' }
133
+
134
+ user_to_change = users_without_owner.sample
135
+ @project.set_user_roles(user_to_change, 'editor')
136
+ expect(user_to_change.role.title).to eq 'Editor'
137
+ @project.set_user_roles(user_to_change, 'admin')
138
+ expect(user_to_change.role.title).to eq 'Admin'
139
+
140
+ # Try different notation
141
+ @project.set_users_roles([user: user_to_change, role: 'editor'])
142
+ expect(user_to_change.role.title).to eq 'Editor'
143
+ @project.set_users_roles([user: user_to_change, role: 'admin'])
144
+ expect(user_to_change.role.title).to eq 'Admin'
145
+ end
146
+
147
+ it 'Properly updates user roles when user specified by email and :roles specified as array of string with role names' do
148
+ # pick non deleted users that are not owner and have other roles than admin or editor
149
+ users = @project.users
150
+ users_without_owner = users
151
+ .reject { |u| u.login == ConnectionHelper::DEFAULT_USERNAME }
152
+ .reject { |u| u.login =~ /^deleted/ }
153
+ .pselect { |u| u.role.title =~ /^(Admin|Editor)/ }
154
+
155
+ # take 10 users that we will exercise
156
+ users_to_change = users_without_owner.sample(10)
157
+
158
+ # alternate roles and prepare structure
159
+ logins = users_to_change.map(&:login)
160
+ roles = users_to_change.map { |u| u.role.title == 'Admin' ? ['Editor'] : ['Admin'] }
161
+
162
+ list = users_to_change.map do |u|
163
+ {
164
+ :user => u.login,
165
+ :roles => u.role.title == 'Admin' ? ['Editor'] : ['Admin']
166
+ }
167
+ end
168
+
169
+ # set the roles
170
+ res = @project.set_users_roles(list)
171
+ expect(res.length).to equal(list.length)
172
+ expect(logins.map {|l| users.find {|u| u.login == l}}.pmap {|u| u.role.title}).to eq roles.flatten
173
+ end
174
+
175
+ it 'Properly updates user roles when user specified by email and :roles specified as string with role name' do
176
+ users = @project.users
177
+ users_without_owner = users
178
+ .reject { |u| u.login == ConnectionHelper::DEFAULT_USERNAME }
179
+ .reject(&:deleted?)
180
+ .pselect { |u| u.role.title =~ /^(Admin|Editor)/ }
181
+
182
+ users_to_change = users_without_owner.sample(10)
183
+
184
+ logins = users_to_change.map(&:login)
185
+ roles = users_to_change.map { |u| u.role.title == 'Admin' ? 'Editor' : 'Admin' }
186
+
187
+ list = users_to_change.map do |u|
188
+ {
189
+ :user => u.login,
190
+ :roles => u.role.title == 'Admin' ? 'Editor' : 'Admin'
191
+ }
192
+ end
193
+
194
+ res = @project.set_users_roles(list)
195
+ expect(res.length).to equal(list.length)
196
+ expect(logins.map {|l| users.find {|u| u.login == l}}.pmap {|u| u.role.title}).to eq roles.flatten
197
+
198
+ end
199
+ end
200
+
201
+ describe '#summary' do
202
+ it 'Properly gets summary of project' do
203
+ res = @project.summary
204
+ expect(res).to include(ProjectHelper::PROJECT_SUMMARY)
205
+ end
206
+ end
207
+
208
+ describe '#title' do
209
+ it 'Properly gets title of project' do
210
+ res = @project.title
211
+ expect(res).to include(ProjectHelper::PROJECT_TITLE)
212
+ end
213
+ end
214
+
215
+ describe 'enabling and disabling users' do
216
+ it 'should be able to enable and disable a user' do
217
+ users_without_owner = @project.users
218
+ .reject { |u| u.login == ConnectionHelper::DEFAULT_USERNAME }
219
+ .reject(&:deleted?)
220
+ .select(&:enabled?)
221
+ user = users_without_owner.sample
222
+ expect(user.enabled?).to be_truthy
223
+ expect(user.disabled?).to be_falsey
224
+ user.disable
225
+ expect(user.disabled?).to be_truthy
226
+ expect(user.enabled?).to be_falsey
227
+ user.enable
228
+ expect(user.enabled?).to be_truthy
229
+ expect(user.disabled?).to be_falsey
230
+ expect(user.project).not_to be_nil
231
+ end
232
+ end
233
+ end