gooddata 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/CHANGELOG.markdown +6 -0
- data/README.md +1 -0
- data/gooddata.gemspec +2 -1
- data/lib/gooddata.rb +4 -1
- data/lib/gooddata/bricks/base_downloader.rb +33 -19
- data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +49 -25
- data/lib/gooddata/bricks/middleware/restforce_middleware.rb +36 -33
- data/lib/gooddata/cli/commands/project_cmd.rb +6 -4
- data/lib/gooddata/client.rb +1 -1
- data/lib/gooddata/commands/api.rb +1 -1
- data/lib/gooddata/commands/auth.rb +1 -1
- data/lib/gooddata/connection.rb +13 -10
- data/lib/gooddata/core/connection.rb +1 -1
- data/lib/gooddata/core/user.rb +11 -3
- data/lib/gooddata/exceptions/validation_error.rb +12 -0
- data/lib/gooddata/extensions/extensions.rb +6 -0
- data/lib/gooddata/goodzilla/goodzilla.rb +2 -2
- data/lib/gooddata/helpers/csv_helper.rb +57 -0
- data/lib/gooddata/{helpers.rb → helpers/global_helpers.rb} +0 -0
- data/lib/gooddata/helpers/helpers.rb +6 -0
- data/lib/gooddata/models/domain.rb +134 -24
- data/lib/gooddata/models/membership.rb +402 -0
- data/lib/gooddata/models/metadata.rb +64 -7
- data/lib/gooddata/models/metadata/attribute.rb +27 -12
- data/lib/gooddata/models/metadata/column.rb +1 -1
- data/lib/gooddata/models/metadata/dashboard.rb +7 -6
- data/lib/gooddata/models/metadata/display_form.rb +17 -2
- data/lib/gooddata/models/metadata/fact.rb +13 -7
- data/lib/gooddata/models/metadata/metric.rb +9 -9
- data/lib/gooddata/models/metadata/report.rb +7 -8
- data/lib/gooddata/models/metadata/report_definition.rb +10 -11
- data/lib/gooddata/models/metadata/schema.rb +1 -1
- data/lib/gooddata/models/model.rb +1 -1
- data/lib/gooddata/models/process.rb +44 -25
- data/lib/gooddata/models/profile.rb +365 -13
- data/lib/gooddata/models/project.rb +245 -35
- data/lib/gooddata/models/project_blueprint.rb +42 -18
- data/lib/gooddata/models/project_creator.rb +4 -1
- data/lib/gooddata/models/project_role.rb +7 -7
- data/lib/gooddata/models/schedule.rb +17 -1
- data/lib/gooddata/models/schema_blueprint.rb +19 -2
- data/lib/gooddata/version.rb +1 -1
- data/out.txt +0 -0
- data/spec/data/users.csv +12 -0
- data/spec/helpers/connection_helper.rb +1 -0
- data/spec/helpers/csv_helper.rb +12 -0
- data/spec/helpers/project_helper.rb +1 -1
- data/spec/integration/full_project_spec.rb +136 -3
- data/spec/spec_helper.rb +9 -0
- data/spec/unit/commands/command_user_spec.rb +1 -1
- data/spec/unit/extensions/hash_spec.rb +19 -0
- data/spec/unit/godzilla/goodzilla_spec.rb +15 -0
- data/spec/unit/helpers/csv_helper_spec.rb +18 -0
- data/spec/unit/models/domain_spec.rb +47 -4
- data/spec/unit/models/md_object_spec.rb +8 -0
- data/spec/unit/models/membership_spec.rb +128 -0
- data/spec/unit/models/metadata_spec.rb +38 -0
- data/spec/unit/models/profile_spec.rb +212 -0
- data/spec/unit/models/project_blueprint_spec.rb +35 -8
- data/spec/unit/models/project_role_spec.rb +6 -6
- data/spec/unit/models/project_spec.rb +226 -13
- data/spec/unit/models/schedule_spec.rb +58 -0
- data/tmp/.gitkeepme +0 -0
- metadata +36 -11
- data/lib/gooddata/models/account_settings.rb +0 -124
- data/lib/gooddata/models/user.rb +0 -165
- data/spec/unit/models/account_settings_spec.rb +0 -28
- data/spec/unit/models/user_spec.rb +0 -16
@@ -7,7 +7,11 @@ module GoodData
|
|
7
7
|
|
8
8
|
def self.from_json(spec)
|
9
9
|
if spec.is_a?(String)
|
10
|
-
|
10
|
+
if File.file?(spec)
|
11
|
+
ProjectBlueprint.new(MultiJson.load(File.read(spec), :symbolize_keys => true))
|
12
|
+
else
|
13
|
+
ProjectBlueprint.new(MultiJson.load(spec, :symbolize_keys => true))
|
14
|
+
end
|
11
15
|
else
|
12
16
|
ProjectBlueprint.new(spec)
|
13
17
|
end
|
@@ -21,7 +25,8 @@ module GoodData
|
|
21
25
|
end
|
22
26
|
|
23
27
|
def datasets
|
24
|
-
data[:datasets]
|
28
|
+
sets = data[:datasets] || []
|
29
|
+
sets.map { |d| DatasetBlueprint.new(d) }
|
25
30
|
end
|
26
31
|
|
27
32
|
def add_dataset(a_dataset, index = nil)
|
@@ -38,6 +43,13 @@ module GoodData
|
|
38
43
|
data[:datasets].delete_at(index)
|
39
44
|
end
|
40
45
|
|
46
|
+
# Is this a project blueprint?
|
47
|
+
#
|
48
|
+
# @return [Boolean] if it is
|
49
|
+
def project_blueprint?
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
41
53
|
def date_dimensions
|
42
54
|
data[:date_dimensions]
|
43
55
|
end
|
@@ -53,10 +65,24 @@ module GoodData
|
|
53
65
|
DatasetBlueprint.new(ds)
|
54
66
|
end
|
55
67
|
|
68
|
+
# Constructor
|
69
|
+
#
|
70
|
+
# @param init_data [ProjectBlueprint | Hash] Blueprint or a blueprint definition. If passed a hash it is used as data for new instance. If there is a ProjectBlueprint passed it is duplicated and a new instance is created.
|
71
|
+
# @return [ProjectBlueprint] A new project blueprint instance
|
56
72
|
def initialize(init_data)
|
57
|
-
|
58
|
-
|
59
|
-
|
73
|
+
some_data = if init_data.respond_to?(:project_blueprint?) && init_data.project_blueprint?
|
74
|
+
init_data.to_hash
|
75
|
+
elsif init_data.respond_to?(:to_blueprint)
|
76
|
+
init_data.to_blueprint.to_hash
|
77
|
+
else
|
78
|
+
init_data
|
79
|
+
end
|
80
|
+
@data = some_data.deep_dup
|
81
|
+
end
|
82
|
+
|
83
|
+
# Validate the blueprint in particular if all references reference existing datasets and valid fields inside them.
|
84
|
+
#
|
85
|
+
# @return [Array] array of errors
|
60
86
|
def validate_references
|
61
87
|
if datasets.count == 1
|
62
88
|
[]
|
@@ -71,21 +97,20 @@ module GoodData
|
|
71
97
|
end
|
72
98
|
end
|
73
99
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
def validate_model
|
100
|
+
# Validate the blueprint and all its datasets return array of errors that are found.
|
101
|
+
#
|
102
|
+
# @return [Array] array of errors
|
103
|
+
def validate
|
79
104
|
refs_errors = validate_references
|
80
|
-
labels_errors =
|
105
|
+
labels_errors = datasets.reduce([]) { |a, e| a.concat(e.validate) }
|
81
106
|
refs_errors.concat(labels_errors)
|
82
107
|
end
|
83
108
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
109
|
+
# Validate the blueprint and all its datasets and return true if model is valid. False otherwise.
|
110
|
+
#
|
111
|
+
# @return [Boolean] is model valid?
|
112
|
+
def valid?
|
113
|
+
validate.empty?
|
89
114
|
end
|
90
115
|
|
91
116
|
def referenced_by(dataset)
|
@@ -185,8 +210,7 @@ module GoodData
|
|
185
210
|
end
|
186
211
|
|
187
212
|
def dup
|
188
|
-
|
189
|
-
ProjectBlueprint.new(deep_copy)
|
213
|
+
ProjectBlueprint.new(data.deep_dup)
|
190
214
|
end
|
191
215
|
|
192
216
|
def title
|
@@ -11,7 +11,10 @@ module GoodData
|
|
11
11
|
class << self
|
12
12
|
def migrate(options = {})
|
13
13
|
spec = options[:spec] || fail('You need to provide spec for migration')
|
14
|
-
|
14
|
+
bp = ProjectBlueprint.new(spec)
|
15
|
+
spec = bp.to_hash
|
16
|
+
|
17
|
+
fail GoodData::ValidationError, "Blueprint is invalid #{bp.validate.inspect}" unless bp.valid?
|
15
18
|
|
16
19
|
token = options[:token]
|
17
20
|
project = options[:project] || GoodData::Project.create(:title => spec[:title], :auth_token => token)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'profile'
|
4
4
|
|
5
5
|
module GoodData
|
6
6
|
class ProjectRole
|
@@ -17,20 +17,20 @@ module GoodData
|
|
17
17
|
|
18
18
|
# Gets Project Role Author
|
19
19
|
#
|
20
|
-
# @return [GoodData::
|
20
|
+
# @return [GoodData::Profile] Project Role author
|
21
21
|
def author
|
22
22
|
url = @json['projectRole']['meta']['author']
|
23
23
|
tmp = GoodData.get url
|
24
|
-
GoodData::
|
24
|
+
GoodData::Profile.new(tmp)
|
25
25
|
end
|
26
26
|
|
27
27
|
# Gets Project Role Contributor
|
28
28
|
#
|
29
|
-
# @return [GoodData::
|
29
|
+
# @return [GoodData::Profile] Project Role Contributor
|
30
30
|
def contributor
|
31
31
|
url = @json['projectRole']['meta']['contributor']
|
32
32
|
tmp = GoodData.get url
|
33
|
-
GoodData::
|
33
|
+
GoodData::Profile.new(tmp)
|
34
34
|
end
|
35
35
|
|
36
36
|
# Gets DateTime time when created
|
@@ -70,14 +70,14 @@ module GoodData
|
|
70
70
|
|
71
71
|
# Gets Users with this Role
|
72
72
|
#
|
73
|
-
# @return [Array<GoodData::
|
73
|
+
# @return [Array<GoodData::Profile>] List of users
|
74
74
|
def users
|
75
75
|
res = []
|
76
76
|
url = @json['projectRole']['links']['roleUsers']
|
77
77
|
tmp = GoodData.get url
|
78
78
|
tmp['associatedUsers']['users'].each do |user_url|
|
79
79
|
user = GoodData.get user_url
|
80
|
-
res << GoodData::
|
80
|
+
res << GoodData::Profile.new(user)
|
81
81
|
end
|
82
82
|
res
|
83
83
|
end
|
@@ -48,6 +48,7 @@ module GoodData
|
|
48
48
|
},
|
49
49
|
:hidden_params => {}
|
50
50
|
}
|
51
|
+
default_opts.merge!(:reschedule => options[:reschedule])
|
51
52
|
|
52
53
|
inject_schema = {
|
53
54
|
:hidden_params => 'hiddenParams'
|
@@ -183,6 +184,21 @@ module GoodData
|
|
183
184
|
@dirty = true
|
184
185
|
end
|
185
186
|
|
187
|
+
# Returns reschedule settings
|
188
|
+
#
|
189
|
+
# @return [Integer] Reschedule settings
|
190
|
+
def reschedule
|
191
|
+
@json['schedule']['reschedule']
|
192
|
+
end
|
193
|
+
|
194
|
+
# Assigns execution reschedule settings
|
195
|
+
#
|
196
|
+
# @param new_reschedule [Integer] Reschedule settings to be set
|
197
|
+
def reschedule=(new_reschedule)
|
198
|
+
@json['schedule']['reschedule'] = new_reschedule
|
199
|
+
@dirty = true
|
200
|
+
end
|
201
|
+
|
186
202
|
# Returns execution process ID
|
187
203
|
#
|
188
204
|
# @return [String] Process ID
|
@@ -265,8 +281,8 @@ module GoodData
|
|
265
281
|
'hiddenParams' => @json['schedule']['hiddenParams']
|
266
282
|
}
|
267
283
|
}
|
284
|
+
update_json['schedule'].merge!('reschedule' => @json['schedule']['reschedule'])
|
268
285
|
res = GoodData.put uri, update_json
|
269
|
-
|
270
286
|
@json = res
|
271
287
|
@dirty = false
|
272
288
|
return true
|
@@ -120,8 +120,7 @@ module GoodData
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def dup
|
123
|
-
|
124
|
-
DatasetBlueprint.new(deep_copy)
|
123
|
+
DatasetBlueprint.new(data.deep_dup)
|
125
124
|
end
|
126
125
|
|
127
126
|
def to_wire_model
|
@@ -148,6 +147,24 @@ module GoodData
|
|
148
147
|
end
|
149
148
|
end
|
150
149
|
|
150
|
+
# Validate the blueprint return array of errors that are found.
|
151
|
+
#
|
152
|
+
# @return [Array] array of errors
|
153
|
+
def validate
|
154
|
+
more_than_one_anchor = find_column_by_type(:anchor, :all).count > 1 ? [{ :anchor => 2 }] : []
|
155
|
+
validate_label_references.concat(more_than_one_anchor)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Validate the blueprint and return true if model is valid. False otherwise.
|
159
|
+
#
|
160
|
+
# @return [Boolean] is model valid?
|
161
|
+
def valid?
|
162
|
+
validate.empty?
|
163
|
+
end
|
164
|
+
|
165
|
+
# Validate the that any labels are pointing to the existing attribute. If not returns the list of errors. Currently just violating labels.
|
166
|
+
#
|
167
|
+
# @return [Array] array of errors
|
151
168
|
def validate_label_references
|
152
169
|
labels.select do |label|
|
153
170
|
find_column_by_name(label[:reference]).empty?
|
data/lib/gooddata/version.rb
CHANGED
data/out.txt
ADDED
File without changes
|
data/spec/data/users.csv
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
First Name,Last Name,Email,Password,MUF,MUF ID,Role,Role ID,Project ID,Domain
|
2
|
+
Gem,Tester,svarovsky+gem_tester@gooddata.com,jindrisska,Edit,,adminRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
3
|
+
Test,User0,test.user.110@example.com,password0,Full,,adminRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
4
|
+
Test,User1,test.user.111@example.com,password1,Full,,connectorsSystemRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
5
|
+
Test,User2,test.user.112@example.com,password2,Full,,editorRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
6
|
+
Test,User3,test.user.113@example.com,password3,Full,,dashboardOnlyRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
7
|
+
Test,User4,test.user.114@example.com,password4,Full,,unverifiedAdminRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
8
|
+
Test,User5,test.user.115@example.com,password5,Full,,readOnlyUserRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
9
|
+
Test,User6,test.user.116@example.com,password6,Full,,adminRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
10
|
+
Test,User7,test.user.117@example.com,password7,Full,,connectorsSystemRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
11
|
+
Test,User8,test.user.118@example.com,password8,Full,,editorRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
12
|
+
Test,User9,test.user.119@example.com,password9,Full,,dashboardOnlyRole,5,wgqhml3se0035s8n5byqdq0j0ob5jam4,gooddata-tomas-svarovsky
|
@@ -6,6 +6,7 @@ module ConnectionHelper
|
|
6
6
|
DEFAULT_USERNAME = "svarovsky+gem_tester@gooddata.com"
|
7
7
|
DEFAULT_PASSWORD = "jindrisska"
|
8
8
|
DEFAULT_DOMAIN = 'gooddata-tomas-svarovsky'
|
9
|
+
DEFAULT_USER_URL = '/gdc/account/profile/3cea1102d5584813506352a2a2a00d95'
|
9
10
|
|
10
11
|
# Creates connection using default credentials or supplied one
|
11
12
|
#
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Global requires
|
4
|
+
require 'multi_json'
|
5
|
+
|
6
|
+
# Local requires
|
7
|
+
require 'gooddata/models/models'
|
8
|
+
|
9
|
+
module CsvHelper
|
10
|
+
CSV_PATH_EXPORT = 'out.txt'
|
11
|
+
CSV_PATH_IMPORT = File.join(File.dirname(__FILE__), '..', 'data', 'users.csv')
|
12
|
+
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
require 'gooddata'
|
2
2
|
|
3
|
-
describe "
|
3
|
+
describe "Full project implementation", :constraint => 'slow' do
|
4
4
|
before(:all) do
|
5
5
|
@spec = JSON.parse(File.read("./spec/data/test_project_model_spec.json"), :symbolize_names => true)
|
6
|
+
@invalid_spec = JSON.parse(File.read("./spec/data/blueprint_invalid.json"), :symbolize_names => true)
|
6
7
|
ConnectionHelper::create_default_connection
|
7
8
|
@project = GoodData::Model::ProjectCreator.migrate({:spec => @spec, :token => ConnectionHelper::GD_PROJECT_TOKEN})
|
8
9
|
end
|
@@ -11,6 +12,12 @@ describe "Ful project implementation", :constraint => 'slow' do
|
|
11
12
|
@project.delete unless @project.nil?
|
12
13
|
end
|
13
14
|
|
15
|
+
it "should not build an invalid model" do
|
16
|
+
expect {
|
17
|
+
GoodData::Model::ProjectCreator.migrate({:spec => @invalid_spec, :token => ConnectionHelper::GD_PROJECT_TOKEN})
|
18
|
+
}.to raise_error(GoodData::ValidationError)
|
19
|
+
end
|
20
|
+
|
14
21
|
it "should contain datasets" do
|
15
22
|
GoodData.with_project(@project) do |p|
|
16
23
|
p.datasets.count.should == 4
|
@@ -79,10 +86,62 @@ describe "Ful project implementation", :constraint => 'slow' do
|
|
79
86
|
end
|
80
87
|
end
|
81
88
|
|
89
|
+
it "should throw an exception if trying to access object without explicitely specifying a project" do
|
90
|
+
expect do
|
91
|
+
GoodData::Metric[:all]
|
92
|
+
end.to raise_exception(GoodData::NoProjectError)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be possible to get all metrics" do
|
96
|
+
GoodData.with_project(@project) do |p|
|
97
|
+
metrics1 = GoodData::Metric[:all]
|
98
|
+
metrics2 = GoodData::Metric.all
|
99
|
+
metrics1.should == metrics2
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should be possible to get all metrics with full objects" do
|
104
|
+
GoodData.with_project(@project) do |p|
|
105
|
+
metrics1 = GoodData::Metric[:all, :full => true]
|
106
|
+
metrics2 = GoodData::Metric.all :full => true
|
107
|
+
metrics1.should == metrics2
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should be able to get a metric by identifier" do
|
112
|
+
GoodData.with_project(@project) do |p|
|
113
|
+
metrics = GoodData::Metric.all :full => true
|
114
|
+
metric = GoodData::Metric[metrics.first.identifier]
|
115
|
+
metric.identifier == metrics.first.identifier
|
116
|
+
metrics.first == metric
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should be able to get a metric by uri" do
|
121
|
+
GoodData.with_project(@project) do |p|
|
122
|
+
metrics = GoodData::Metric.all :full => true
|
123
|
+
metric = GoodData::Metric[metrics.first.uri]
|
124
|
+
metric.uri == metrics.first.uri
|
125
|
+
metrics.first == metric
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should be able to get a metric by object id" do
|
130
|
+
GoodData.with_project(@project) do |p|
|
131
|
+
metrics = GoodData::Metric.all :full => true
|
132
|
+
metric = GoodData::Metric[metrics.first.obj_id]
|
133
|
+
metric.obj_id == metrics.first.obj_id
|
134
|
+
metrics.first == metric
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
82
138
|
it "should exercise the object relations and getting them in various ways" do
|
83
139
|
GoodData.with_project(@project) do |p|
|
140
|
+
|
84
141
|
# Find a metric by name
|
85
142
|
metric = GoodData::Metric.find_first_by_title('My metric')
|
143
|
+
the_same_metric = GoodData::Metric[metric]
|
144
|
+
metric.should == metric
|
86
145
|
|
87
146
|
# grab fact in several different ways
|
88
147
|
fact1 = GoodData::Fact.find_first_by_title('Lines changed')
|
@@ -148,6 +207,11 @@ describe "Ful project implementation", :constraint => 'slow' do
|
|
148
207
|
|
149
208
|
res = GoodData::Metric.execute("SELECT SUM(![fact.commits.lines_changed])", :extended_notation => true)
|
150
209
|
res.should == 9
|
210
|
+
|
211
|
+
fact = GoodData::Fact.find_first_by_title('Lines changed')
|
212
|
+
fact.fact?.should == true
|
213
|
+
res = fact.create_metric(:type => :sum).execute
|
214
|
+
res.should == 9
|
151
215
|
end
|
152
216
|
end
|
153
217
|
|
@@ -163,7 +227,9 @@ describe "Ful project implementation", :constraint => 'slow' do
|
|
163
227
|
|
164
228
|
it "should have more users" do
|
165
229
|
GoodData.with_project(@project) do |p|
|
166
|
-
GoodData::Attribute['attr.devs.dev_id']
|
230
|
+
attribute = GoodData::Attribute['attr.devs.dev_id']
|
231
|
+
attribute.attribute?.should == true
|
232
|
+
attribute.create_metric.execute.should == 4
|
167
233
|
end
|
168
234
|
end
|
169
235
|
|
@@ -188,6 +254,14 @@ describe "Ful project implementation", :constraint => 'slow' do
|
|
188
254
|
end
|
189
255
|
end
|
190
256
|
|
257
|
+
it "Should be able to compute count o different datasets" do
|
258
|
+
GoodData.with_project(@project) do |p|
|
259
|
+
attribute = GoodData::Attribute['attr.devs.dev_id']
|
260
|
+
dataset_attribute = GoodData::Attribute['attr.commits.id']
|
261
|
+
attribute.create_metric(:attribute => dataset_attribute).execute.should == 3
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
191
265
|
it "should be able to tell you if a value is contained in a metric" do
|
192
266
|
GoodData.with_project(@project) do |p|
|
193
267
|
attribute = GoodData::Attribute['attr.devs.dev_id']
|
@@ -213,10 +287,69 @@ describe "Ful project implementation", :constraint => 'slow' do
|
|
213
287
|
end
|
214
288
|
end
|
215
289
|
|
216
|
-
it "should be able to lookup the attributes by regexp and return a
|
290
|
+
it "should be able to lookup the attributes by regexp and return a collection" do
|
217
291
|
GoodData.with_project(@project) do |p|
|
218
292
|
attrs = GoodData::Attribute.find_by_title(/Date/i)
|
219
293
|
attrs.count.should == 1
|
220
294
|
end
|
221
295
|
end
|
296
|
+
|
297
|
+
it "should be able to give you values of the label as an array of hashes" do
|
298
|
+
GoodData.with_project(@project) do |p|
|
299
|
+
attribute = GoodData::Attribute['attr.devs.dev_id']
|
300
|
+
label = attribute.primary_label
|
301
|
+
label.values.map {|v| v[:value]}.should == [
|
302
|
+
'jirka@gooddata.com',
|
303
|
+
'josh@gooddata.com',
|
304
|
+
'petr@gooddata.com',
|
305
|
+
'tomas@gooddata.com'
|
306
|
+
]
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should be able to give you values for" do
|
311
|
+
GoodData.with_project(@project) do |p|
|
312
|
+
attribute = GoodData::Attribute['attr.devs.dev_id']
|
313
|
+
attribute.values_for(2).should == ["tomas@gooddata.com", "1"]
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
it "should be able to find specific element and give you the primary label value" do
|
318
|
+
GoodData.with_project(@project) do |p|
|
319
|
+
attribute = GoodData::Attribute['attr.devs.dev_id']
|
320
|
+
GoodData::Attribute.find_element_value("#{attribute.uri}/elements?id=2").should == 'tomas@gooddata.com'
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
it "should be able to give you label by name" do
|
325
|
+
GoodData.with_project(@project) do |p|
|
326
|
+
attribute = GoodData::Attribute['attr.devs.dev_id']
|
327
|
+
label = attribute.label_by_name('email')
|
328
|
+
label.label?.should == true
|
329
|
+
label.title.should == 'Email'
|
330
|
+
label.identifier.should == "label.devs.dev_id.email"
|
331
|
+
label.attribute_uri.should == attribute.uri
|
332
|
+
label.attribute.should == attribute
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
it "should be able to return values of the attribute for inspection" do
|
337
|
+
GoodData.with_project(@project) do |p|
|
338
|
+
attribute = GoodData::Attribute['attr.devs.dev_id']
|
339
|
+
vals = attribute.values
|
340
|
+
vals.count.should == 4
|
341
|
+
vals.first.count.should == 2
|
342
|
+
vals.first.first[:value].should == "jirka@gooddata.com"
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should be able to save_as a metric" do
|
347
|
+
GoodData.with_project(@project) do |p|
|
348
|
+
m = GoodData::Metric.find_first_by_title("My test metric")
|
349
|
+
cloned = m.save_as
|
350
|
+
m_cloned = GoodData::Metric.find_first_by_title("Clone of My test metric")
|
351
|
+
m_cloned.should == cloned
|
352
|
+
m_cloned.execute.should == cloned.execute
|
353
|
+
end
|
354
|
+
end
|
222
355
|
end
|