gooddata 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -1
  3. data/CHANGELOG.markdown +6 -0
  4. data/README.md +1 -0
  5. data/gooddata.gemspec +2 -1
  6. data/lib/gooddata.rb +4 -1
  7. data/lib/gooddata/bricks/base_downloader.rb +33 -19
  8. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +49 -25
  9. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +36 -33
  10. data/lib/gooddata/cli/commands/project_cmd.rb +6 -4
  11. data/lib/gooddata/client.rb +1 -1
  12. data/lib/gooddata/commands/api.rb +1 -1
  13. data/lib/gooddata/commands/auth.rb +1 -1
  14. data/lib/gooddata/connection.rb +13 -10
  15. data/lib/gooddata/core/connection.rb +1 -1
  16. data/lib/gooddata/core/user.rb +11 -3
  17. data/lib/gooddata/exceptions/validation_error.rb +12 -0
  18. data/lib/gooddata/extensions/extensions.rb +6 -0
  19. data/lib/gooddata/goodzilla/goodzilla.rb +2 -2
  20. data/lib/gooddata/helpers/csv_helper.rb +57 -0
  21. data/lib/gooddata/{helpers.rb → helpers/global_helpers.rb} +0 -0
  22. data/lib/gooddata/helpers/helpers.rb +6 -0
  23. data/lib/gooddata/models/domain.rb +134 -24
  24. data/lib/gooddata/models/membership.rb +402 -0
  25. data/lib/gooddata/models/metadata.rb +64 -7
  26. data/lib/gooddata/models/metadata/attribute.rb +27 -12
  27. data/lib/gooddata/models/metadata/column.rb +1 -1
  28. data/lib/gooddata/models/metadata/dashboard.rb +7 -6
  29. data/lib/gooddata/models/metadata/display_form.rb +17 -2
  30. data/lib/gooddata/models/metadata/fact.rb +13 -7
  31. data/lib/gooddata/models/metadata/metric.rb +9 -9
  32. data/lib/gooddata/models/metadata/report.rb +7 -8
  33. data/lib/gooddata/models/metadata/report_definition.rb +10 -11
  34. data/lib/gooddata/models/metadata/schema.rb +1 -1
  35. data/lib/gooddata/models/model.rb +1 -1
  36. data/lib/gooddata/models/process.rb +44 -25
  37. data/lib/gooddata/models/profile.rb +365 -13
  38. data/lib/gooddata/models/project.rb +245 -35
  39. data/lib/gooddata/models/project_blueprint.rb +42 -18
  40. data/lib/gooddata/models/project_creator.rb +4 -1
  41. data/lib/gooddata/models/project_role.rb +7 -7
  42. data/lib/gooddata/models/schedule.rb +17 -1
  43. data/lib/gooddata/models/schema_blueprint.rb +19 -2
  44. data/lib/gooddata/version.rb +1 -1
  45. data/out.txt +0 -0
  46. data/spec/data/users.csv +12 -0
  47. data/spec/helpers/connection_helper.rb +1 -0
  48. data/spec/helpers/csv_helper.rb +12 -0
  49. data/spec/helpers/project_helper.rb +1 -1
  50. data/spec/integration/full_project_spec.rb +136 -3
  51. data/spec/spec_helper.rb +9 -0
  52. data/spec/unit/commands/command_user_spec.rb +1 -1
  53. data/spec/unit/extensions/hash_spec.rb +19 -0
  54. data/spec/unit/godzilla/goodzilla_spec.rb +15 -0
  55. data/spec/unit/helpers/csv_helper_spec.rb +18 -0
  56. data/spec/unit/models/domain_spec.rb +47 -4
  57. data/spec/unit/models/md_object_spec.rb +8 -0
  58. data/spec/unit/models/membership_spec.rb +128 -0
  59. data/spec/unit/models/metadata_spec.rb +38 -0
  60. data/spec/unit/models/profile_spec.rb +212 -0
  61. data/spec/unit/models/project_blueprint_spec.rb +35 -8
  62. data/spec/unit/models/project_role_spec.rb +6 -6
  63. data/spec/unit/models/project_spec.rb +226 -13
  64. data/spec/unit/models/schedule_spec.rb +58 -0
  65. data/tmp/.gitkeepme +0 -0
  66. metadata +36 -11
  67. data/lib/gooddata/models/account_settings.rb +0 -124
  68. data/lib/gooddata/models/user.rb +0 -165
  69. data/spec/unit/models/account_settings_spec.rb +0 -28
  70. data/spec/unit/models/user_spec.rb +0 -16
@@ -18,12 +18,21 @@ RSpec.configure do |config|
18
18
  config.include BlueprintHelper
19
19
  config.include CliHelper
20
20
  config.include ConnectionHelper
21
+ config.include CsvHelper
21
22
  config.include ProjectHelper
22
23
  config.include SchemaHelper
23
24
 
24
25
  config.filter_run_excluding :broken => true
25
26
 
26
27
  config.before(:all) do
28
+ # TODO: Move this to some method.
29
+ # TODO Make more intelligent so two test suites can run at the same time.
30
+ # ConnectionHelper.create_default_connection
31
+ # users = GoodData::Domain.users_map(ConnectionHelper::DEFAULT_DOMAIN)
32
+ # users.each do |user|
33
+ # user.delete if user.email != ConnectionHelper::DEFAULT_USERNAME
34
+ # end
35
+
27
36
  # TODO: Fully setup global environment
28
37
  GoodData.logging_off
29
38
  end
@@ -9,7 +9,7 @@ describe GoodData::Command::User do
9
9
  GoodData.disconnect
10
10
  end
11
11
 
12
- it "Is Possible to create GoodData::Command::User instance" do
12
+ it "Is Possible to create GoodData::Command::Membership instance" do
13
13
  cmd = GoodData::Command::User.new()
14
14
  cmd.should be_a(GoodData::Command::User)
15
15
  end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+
3
+ describe Hash do
4
+
5
+ describe '#deep_dup' do
6
+ it 'should crete a deep copy' do
7
+ x = {
8
+ :a => {
9
+ :b => :c
10
+ }
11
+ }
12
+ y = x.dup
13
+ deep_y = x.deep_dup
14
+
15
+ y[:a].object_id.should === x[:a].object_id
16
+ deep_y[:a].object_id.should_not === x[:a].object_id
17
+ end
18
+ end
19
+ end
@@ -56,4 +56,19 @@ describe GoodData::SmallGoodZilla do
56
56
  interpolated.should == "SELECT SUM([a]) WHERE [d]=[x] AND [snap]=1"
57
57
  end
58
58
 
59
+ it "should be able to parse several ids correctly." do
60
+ metric = "SELECT SUM(
61
+ CASE
62
+ WHEN ![attr.customer_profiles.profile_id] = [/gdc/md/pxa3aic06undadkc5s7t5lxpne11vgyt/obj/257/elements?id=65] THEN ![fact.perfomance_by_campaign_id.general_score_1]
63
+ WHEN ![attr.customer_profiles.profile_id] = [/gdc/md/pxa3aic06undadkc5s7t5lxpne11vgyt/obj/257/elements?id=50] THEN ![fact.perfomance_by_campaign_id.general_score_5]
64
+ WHEN ![attr.customer_profiles.profile_id] = [/gdc/md/pxa3aic06undadkc5s7t5lxpne11vgyt/obj/257/elements?id=20] THEN ![fact.perfomance_by_campaign_id.general_score_12]
65
+ END)"
66
+ GoodData::SmallGoodZilla.get_ids(metric).should == [
67
+ "attr.customer_profiles.profile_id",
68
+ "fact.perfomance_by_campaign_id.general_score_1",
69
+ "fact.perfomance_by_campaign_id.general_score_5",
70
+ "fact.perfomance_by_campaign_id.general_score_12"
71
+ ]
72
+ end
73
+
59
74
  end
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'gooddata/helpers/csv_helper'
4
+
5
+ describe GoodData::Helpers::Csv do
6
+ describe '#read' do
7
+ it 'Reads data from CSV file' do
8
+ data = GoodData::Helpers::Csv.read(:path => CsvHelper::CSV_PATH_IMPORT)
9
+ end
10
+ end
11
+
12
+ describe '#write' do
13
+ it 'Writes data to CSV' do
14
+ data = []
15
+ GoodData::Helpers::Csv.write(:path => CsvHelper::CSV_PATH_EXPORT, :data => data)
16
+ end
17
+ end
18
+ end
@@ -13,7 +13,9 @@ describe GoodData::Domain do
13
13
 
14
14
  describe '#add_user' do
15
15
  it 'Should add user' do
16
- GoodData::Domain.add_user(ConnectionHelper::DEFAULT_DOMAIN, "gemtest#{rand(1e6)}@gooddata.com", 'password')
16
+ user = GoodData::Domain.add_user(:domain => ConnectionHelper::DEFAULT_DOMAIN, :login => "gemtest#{rand(1e6)}@gooddata.com", :password => 'password')
17
+ expect(user).to be_an_instance_of(GoodData::Profile)
18
+ user.delete
17
19
  end
18
20
  end
19
21
 
@@ -22,7 +24,7 @@ describe GoodData::Domain do
22
24
  users = GoodData::Domain.users(ConnectionHelper::DEFAULT_DOMAIN)
23
25
  expect(users).to be_instance_of(Array)
24
26
  users.each do |user|
25
- expect(user).to be_an_instance_of(GoodData::AccountSettings)
27
+ expect(user).to be_an_instance_of(GoodData::Profile)
26
28
  end
27
29
  end
28
30
 
@@ -30,7 +32,7 @@ describe GoodData::Domain do
30
32
  users = GoodData::Domain.users(ConnectionHelper::DEFAULT_DOMAIN, {:limit =>1})
31
33
  expect(users).to be_instance_of(Array)
32
34
  users.each do |user|
33
- expect(user).to be_an_instance_of(GoodData::AccountSettings)
35
+ expect(user).to be_an_instance_of(GoodData::Profile)
34
36
  end
35
37
  end
36
38
 
@@ -38,7 +40,48 @@ describe GoodData::Domain do
38
40
  users = GoodData::Domain.users(ConnectionHelper::DEFAULT_DOMAIN, {:offset => 1})
39
41
  expect(users).to be_instance_of(Array)
40
42
  users.each do |user|
41
- expect(user).to be_an_instance_of(GoodData::AccountSettings)
43
+ expect(user).to be_an_instance_of(GoodData::Profile)
44
+ end
45
+ end
46
+ end
47
+
48
+ describe '#users_create' do
49
+ it 'Creates new users from list' do
50
+ list = []
51
+ (0...10).each do |i|
52
+ num = rand(1e6)
53
+ login = "gemtest#{num}@gooddata.com"
54
+
55
+ json = {
56
+ 'user' => {
57
+ 'content' => {
58
+ 'email' => login,
59
+ 'login' => login,
60
+ 'firstname' => 'the',
61
+ 'lastname' => num.to_s,
62
+
63
+ # Following lines are ugly hack
64
+ 'role' => 'admin',
65
+ 'password' => 'password',
66
+ 'domain' => ConnectionHelper::DEFAULT_DOMAIN,
67
+
68
+ # And following lines are even much more ugly hack
69
+ # 'sso_provider' => '',
70
+ # 'authentication_modes' => ['sso', 'password']
71
+ },
72
+ 'meta' => {}
73
+ }
74
+ }
75
+ user = GoodData::Membership.new(json)
76
+ list << user
77
+ end
78
+
79
+ res = GoodData::Domain.users_create(list, ConnectionHelper::DEFAULT_DOMAIN)
80
+
81
+ expect(res).to be_an_instance_of(Array)
82
+ res.each do |r|
83
+ expect(r).to be_an_instance_of(GoodData::Profile)
84
+ r.delete
42
85
  end
43
86
  end
44
87
  end
@@ -44,4 +44,12 @@ describe GoodData::Model::MdObject do
44
44
  result.should == be_an_instance_of(String)
45
45
  end
46
46
  end
47
+
48
+ describe '#all' do
49
+ it 'Throws an error. This is implemented on subclasses' do
50
+ expect do
51
+ GoodData::MdObject.all
52
+ end.to raise_exception(NotImplementedError)
53
+ end
54
+ end
47
55
  end
@@ -0,0 +1,128 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'gooddata/models/domain'
4
+ require 'gooddata/models/membership'
5
+ require 'gooddata/models/project_role'
6
+
7
+ describe GoodData::Membership do
8
+ before(:all) do
9
+ ConnectionHelper.create_default_connection
10
+
11
+ @users = [
12
+ GoodData::Membership.new(
13
+ {
14
+ 'user' => {
15
+ 'content' => {
16
+ 'email' => 'petr.cvengros@gooddata.com',
17
+ 'firstname' => 'Petr',
18
+ 'lastname' => 'Cvengros'
19
+ },
20
+ 'meta' => {}
21
+ }
22
+ }
23
+ ),
24
+
25
+ GoodData::Membership.new(
26
+ {
27
+ 'user' => {
28
+ 'content' => {
29
+ 'email' => 'tomas.korcak@gooddata.com',
30
+ 'firstname' => 'Tomas',
31
+ 'lastname' => 'Korcak'
32
+ },
33
+ 'meta' => {}
34
+ }
35
+ }
36
+ ),
37
+
38
+ GoodData::Membership.new(
39
+ {
40
+ 'user' => {
41
+ 'content' => {
42
+ 'email' => 'patrick.mcconlogue@gooddata.com',
43
+ 'firstname' => 'Patrick',
44
+ 'lastname' => 'McConlogue'
45
+ },
46
+ 'meta' => {}
47
+ }
48
+ }
49
+ ),
50
+
51
+ GoodData::Membership.new(
52
+ {
53
+ 'user' => {
54
+ 'content' => {
55
+ 'email' => 'tomas.svarovsky@gooddata.com',
56
+ 'firstname' => 'Tomas',
57
+ 'lastname' => 'Svarovsky'
58
+ },
59
+ 'meta' => {}
60
+ }
61
+ }
62
+ ),
63
+ ]
64
+ end
65
+
66
+ after(:all) do
67
+ GoodData.disconnect
68
+ end
69
+
70
+ describe '#diff_list' do
71
+ it 'Returns empty diff for same arrays' do
72
+ l1 = [
73
+ @users[0]
74
+ ]
75
+
76
+ l2 = [
77
+ @users[0]
78
+ ]
79
+
80
+ diff = GoodData::Membership.diff_list(l1, l2)
81
+ diff[:added].length.should eql(0)
82
+ diff[:changed].length.should eql(0)
83
+ diff[:removed].length.should eql(0)
84
+ end
85
+
86
+ it 'Recognizes added element' do
87
+ l1 = []
88
+
89
+ l2 = [
90
+ @users[0]
91
+ ]
92
+
93
+ diff = GoodData::Membership.diff_list(l1, l2)
94
+ diff[:added].length.should eql(1)
95
+ diff[:changed].length.should eql(0)
96
+ diff[:removed].length.should eql(0)
97
+ end
98
+
99
+ it 'Recognizes changed element' do
100
+ l1 = [
101
+ @users[0]
102
+ ]
103
+
104
+ l2 = [
105
+ GoodData::Membership.new(@users[0].json.deep_dup)
106
+ ]
107
+ l2[0].first_name = 'Peter'
108
+
109
+ diff = GoodData::Membership.diff_list(l1, l2)
110
+ diff[:added].length.should eql(0)
111
+ diff[:changed].length.should eql(1)
112
+ diff[:removed].length.should eql(0)
113
+ end
114
+
115
+ it 'Recognizes removed element' do
116
+ l1 = [
117
+ @users[0]
118
+ ]
119
+
120
+ l2 = []
121
+
122
+ diff = GoodData::Membership.diff_list(l1, l2)
123
+ diff[:added].length.should eql(0)
124
+ diff[:changed].length.should eql(0)
125
+ diff[:removed].length.should eql(1)
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'gooddata'
4
+
5
+ RAW_DATA = {'metric'=>
6
+ {'content'=>
7
+ {'format'=>'#,##0',
8
+ 'expression'=> 'SELECT SUM([/gdc/md/ksjy0nr3goz6k8yrpklz97l0mych7nez/obj/700])'},
9
+ 'meta' =>
10
+ {'author'=>'/gdc/account/profile/4e1e8cacc4989228e0ae531b30853248',
11
+ 'uri'=>'/gdc/md/ksjy0nr3goz6k8yrpklz97l0mych7nez/obj/70',
12
+ 'tags'=>'a b cg r t',
13
+ 'created'=>'2014-04-30 22:47:57',
14
+ 'identifier'=>'afo7bx1VakCz',
15
+ 'deprecated'=>'0',
16
+ 'summary'=>'',
17
+ 'title'=>'sum of Lines changed',
18
+ 'category'=>'metric',
19
+ 'updated'=>'2014-05-05 20:00:42',
20
+ 'contributor'=>'/gdc/account/profile/4e1e8cacc4989228e0ae531b30853248'}}}
21
+
22
+
23
+ describe GoodData::MdObject do
24
+ before(:each) do
25
+ @instance = GoodData::MdObject.new(RAW_DATA)
26
+ end
27
+
28
+ describe '#identifier=' do
29
+ it 'Allows setting a new identifier' do
30
+ identifier = @instance.identifier
31
+ @instance.identifier = 'new_id'
32
+ new_identifier = @instance.identifier
33
+
34
+ new_identifier.should_not == identifier
35
+ new_identifier.should == 'new_id'
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,212 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ require 'gooddata/models/profile'
5
+ require 'gooddata/models/domain'
6
+ require 'gooddata/models/project'
7
+
8
+ describe GoodData::Profile do
9
+ before(:all) do
10
+ ConnectionHelper.create_default_connection
11
+ @user = GoodData::Domain.find_user_by_login(ConnectionHelper::DEFAULT_DOMAIN, ConnectionHelper::DEFAULT_USERNAME)
12
+
13
+ @users = [
14
+ GoodData::Profile.new(
15
+ {
16
+ 'accountSetting' => {
17
+ 'email' => 'petr.cvengros@gooddata.com',
18
+ 'firstName' => 'Petr',
19
+ 'lastName' => 'Cvengros'
20
+ }
21
+ }
22
+ ),
23
+
24
+ GoodData::Profile.new(
25
+ {
26
+ 'accountSetting' => {
27
+ 'email' => 'tomas.korcak@gooddata.com',
28
+ 'firstName' => 'Tomas',
29
+ 'lastName' => 'Korcak'
30
+ }
31
+ }
32
+ ),
33
+
34
+ GoodData::Profile.new(
35
+ {
36
+ 'accountSetting' => {
37
+ 'email' => 'patrick.mcconlogue@gooddata.com',
38
+ 'firstName' => 'Patrick',
39
+ 'lastName' => 'McConlogue'
40
+
41
+ }
42
+ }
43
+ ),
44
+
45
+ GoodData::Profile.new(
46
+ {
47
+ 'accountSetting' => {
48
+ 'email' => 'tomas.svarovsky@gooddata.com',
49
+ 'firstName' => 'Tomas',
50
+ 'lastName' => 'Svarovsky'
51
+ }
52
+ }
53
+ ),
54
+ ]
55
+ end
56
+
57
+ after(:all) do
58
+ GoodData.disconnect
59
+ end
60
+
61
+ describe '#==' do
62
+ it 'Returns true for same objects' do
63
+ user1 = GoodData.user.dup
64
+ user2 = GoodData.user.dup
65
+ res = user1 == user2
66
+ res.should be_true
67
+ end
68
+
69
+ it 'Returns false for different objects' do
70
+ user1 = GoodData.user.dup
71
+ user2 = GoodData.user.dup
72
+
73
+ # Do some little modification
74
+ user2.first_name = 'kokos'
75
+
76
+ res = user1 == user2
77
+ res.should be_false
78
+ end
79
+ end
80
+
81
+ describe '#!=' do
82
+ it 'Returns false for same objects' do
83
+ user1 = GoodData.user.dup
84
+ user2 = GoodData.user.dup
85
+ res = user1 != user2
86
+ res.should be_false
87
+ end
88
+
89
+ it 'Returns true for different objects' do
90
+ user1 = GoodData.user.dup
91
+ user2 = GoodData.user.dup
92
+
93
+ # Do some little modification
94
+ user2.first_name = 'kokos'
95
+
96
+ res = user1 != user2
97
+ res.should be_true
98
+ end
99
+ end
100
+
101
+ describe '#apply' do
102
+ it 'When diff of two objects applied to first result should be same as second object' do
103
+ user1 = GoodData.user.dup
104
+ user2 = GoodData.user.dup
105
+
106
+ # Do some little modification
107
+ user2.first_name = 'kokos'
108
+
109
+ diff = user1.diff(user2)
110
+
111
+ expect(diff).to be_instance_of(Hash)
112
+ diff.length.should_not eql(0)
113
+
114
+ user1.apply(diff)
115
+
116
+ res = user1 == user2
117
+ res.should be_true
118
+ end
119
+ end
120
+
121
+ describe '#diff' do
122
+ it 'Returns empty hash for same objects' do
123
+ user1 = GoodData.user.dup
124
+ user2 = GoodData.user.dup
125
+ res = user1.diff(user2)
126
+ expect(res).to be_instance_of(Hash)
127
+ res.length.should eql(0)
128
+ end
129
+
130
+ it 'Returns non empty hash for different objects' do
131
+ user1 = GoodData.user.dup
132
+ user2 = GoodData.user.dup
133
+
134
+ # Do some little modification
135
+ user2.first_name = 'kokos'
136
+
137
+ res = user1.diff(user2)
138
+ expect(res).to be_instance_of(Hash)
139
+ res.length.should_not eql(0)
140
+ end
141
+ end
142
+
143
+ describe '#diff_list' do
144
+ it 'Returns empty diff for same arrays' do
145
+ l1 = [
146
+ @users[0]
147
+ ]
148
+
149
+ l2 = [
150
+ @users[0]
151
+ ]
152
+
153
+ diff = GoodData::Profile.diff_list(l1, l2)
154
+ diff[:added].length.should eql(0)
155
+ diff[:changed].length.should eql(0)
156
+ diff[:removed].length.should eql(0)
157
+ end
158
+
159
+ it 'Recognizes added element' do
160
+ l1 = []
161
+
162
+ l2 = [
163
+ @users[0]
164
+ ]
165
+
166
+ diff = GoodData::Profile.diff_list(l1, l2)
167
+ diff[:added].length.should eql(1)
168
+ diff[:changed].length.should eql(0)
169
+ diff[:removed].length.should eql(0)
170
+ end
171
+
172
+ it 'Recognizes changed element' do
173
+ l1 = [
174
+ @users[0]
175
+ ]
176
+
177
+ l2 = [
178
+ GoodData::Profile.new(@users[0].json.deep_dup)
179
+ ]
180
+ l2[0].first_name = 'Peter'
181
+
182
+ diff = GoodData::Profile.diff_list(l1, l2)
183
+ diff[:added].length.should eql(0)
184
+ diff[:changed].length.should eql(1)
185
+ diff[:removed].length.should eql(0)
186
+ end
187
+
188
+ it 'Recognizes removed element' do
189
+ l1 = [
190
+ @users[0]
191
+ ]
192
+
193
+ l2 = []
194
+
195
+ diff = GoodData::Profile.diff_list(l1, l2)
196
+ diff[:added].length.should eql(0)
197
+ diff[:changed].length.should eql(0)
198
+ diff[:removed].length.should eql(1)
199
+ end
200
+ end
201
+
202
+ describe '#projects' do
203
+ it 'Returns user projects as array of GoodData::Project' do
204
+ projects = @user.projects
205
+ expect(projects).to be_an_instance_of(Array)
206
+
207
+ projects.each do |project|
208
+ expect(project).to be_an_instance_of(GoodData::Project)
209
+ end
210
+ end
211
+ end
212
+ end