gooddata 0.6.3 → 0.6.4
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/.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
|