gooddata 0.6.51 → 0.6.52
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/.rubocop.yml +1 -1
- data/CHANGELOG.md +13 -1
- data/CONTRIBUTING.md +25 -0
- data/PULL_REQUEST_TEMPLATE.md +5 -0
- data/README.md +7 -4
- data/gooddata.gemspec +2 -3
- data/lib/gooddata.rb +1 -0
- data/lib/gooddata/bricks/base_downloader.rb +6 -6
- data/lib/gooddata/bricks/middleware/aws_middleware.rb +15 -5
- data/lib/gooddata/bricks/middleware/dwh_middleware.rb +15 -3
- data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +13 -4
- data/lib/gooddata/bricks/middleware/logger_middleware.rb +3 -0
- data/lib/gooddata/exceptions/no_project_error.rb +5 -1
- data/lib/gooddata/goodzilla/goodzilla.rb +7 -6
- data/lib/gooddata/helpers/data_helper.rb +4 -4
- data/lib/gooddata/helpers/global_helpers_params.rb +61 -39
- data/lib/gooddata/lcm/actions/apply_custom_maql.rb +9 -0
- data/lib/gooddata/lcm/actions/associate_clients.rb +23 -4
- data/lib/gooddata/lcm/actions/collect_attrs.rb +56 -0
- data/lib/gooddata/lcm/actions/collect_ca_metrics.rb +53 -0
- data/lib/gooddata/lcm/actions/collect_clients.rb +25 -3
- data/lib/gooddata/lcm/actions/collect_meta.rb +83 -0
- data/lib/gooddata/lcm/actions/collect_segment_clients.rb +12 -4
- data/lib/gooddata/lcm/actions/collect_segments.rb +4 -4
- data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +74 -0
- data/lib/gooddata/lcm/actions/create_segment_masters.rb +16 -30
- data/lib/gooddata/lcm/actions/ensure_release_table.rb +0 -3
- data/lib/gooddata/lcm/actions/ensure_segments.rb +1 -4
- data/lib/gooddata/lcm/actions/ensure_technical_users_domain.rb +5 -5
- data/lib/gooddata/lcm/actions/ensure_technical_users_project.rb +8 -5
- data/lib/gooddata/lcm/actions/hello_world.rb +0 -3
- data/lib/gooddata/lcm/actions/import_object_collections.rb +60 -0
- data/lib/gooddata/lcm/actions/print_actions.rb +0 -3
- data/lib/gooddata/lcm/actions/print_modes.rb +0 -3
- data/lib/gooddata/lcm/actions/print_types.rb +1 -4
- data/lib/gooddata/lcm/actions/provision_clients.rb +5 -5
- data/lib/gooddata/lcm/actions/purge_clients.rb +4 -10
- data/lib/gooddata/lcm/actions/segments_filter.rb +0 -6
- data/lib/gooddata/lcm/actions/synchronize_attribute_drillpaths.rb +8 -4
- data/lib/gooddata/lcm/actions/synchronize_cas.rb +61 -0
- data/lib/gooddata/lcm/actions/synchronize_clients.rb +9 -3
- data/lib/gooddata/lcm/actions/synchronize_color_palette.rb +13 -5
- data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +71 -17
- data/lib/gooddata/lcm/actions/synchronize_label_types.rb +8 -5
- data/lib/gooddata/lcm/actions/synchronize_ldm.rb +17 -8
- data/lib/gooddata/lcm/actions/synchronize_meta.rb +0 -3
- data/lib/gooddata/lcm/actions/synchronize_new_segments.rb +9 -4
- data/lib/gooddata/lcm/actions/synchronize_processes.rb +9 -5
- data/lib/gooddata/lcm/actions/synchronize_schedules.rb +15 -5
- data/lib/gooddata/lcm/actions/synchronize_tag_objects.rb +61 -0
- data/lib/gooddata/lcm/actions/update_release_table.rb +0 -3
- data/lib/gooddata/lcm/helpers/tags_helper.rb +35 -0
- data/lib/gooddata/lcm/lcm.rb +22 -4
- data/lib/gooddata/lcm/lcm2.rb +66 -13
- data/lib/gooddata/lcm/types/complex/update_preference.rb +1 -1
- data/lib/gooddata/mixins/md_finders.rb +4 -2
- data/lib/gooddata/mixins/md_object_indexer.rb +13 -3
- data/lib/gooddata/mixins/md_object_query.rb +8 -2
- data/lib/gooddata/models/blueprint/date_dimension.rb +6 -0
- data/lib/gooddata/models/blueprint/project_blueprint.rb +41 -11
- data/lib/gooddata/models/blueprint/project_builder.rb +20 -0
- data/lib/gooddata/models/blueprint/to_wire.rb +7 -0
- data/lib/gooddata/models/client.rb +6 -0
- data/lib/gooddata/models/domain.rb +6 -6
- data/lib/gooddata/models/from_wire.rb +5 -1
- data/lib/gooddata/models/metadata.rb +55 -9
- data/lib/gooddata/models/metadata/attribute.rb +19 -4
- data/lib/gooddata/models/metadata/dashboard.rb +15 -3
- data/lib/gooddata/models/metadata/dataset.rb +5 -2
- data/lib/gooddata/models/metadata/dimension.rb +4 -1
- data/lib/gooddata/models/metadata/fact.rb +9 -2
- data/lib/gooddata/models/metadata/folder.rb +4 -1
- data/lib/gooddata/models/metadata/metric.rb +11 -3
- data/lib/gooddata/models/metadata/report.rb +7 -2
- data/lib/gooddata/models/metadata/report_definition.rb +11 -4
- data/lib/gooddata/models/metadata/scheduled_mail.rb +4 -1
- data/lib/gooddata/models/metadata/variable.rb +7 -2
- data/lib/gooddata/models/model.rb +14 -3
- data/lib/gooddata/models/process.rb +10 -9
- data/lib/gooddata/models/project.rb +134 -36
- data/lib/gooddata/models/project_creator.rb +43 -20
- data/lib/gooddata/models/report_data_result.rb +6 -2
- data/lib/gooddata/models/schedule.rb +6 -3
- data/lib/gooddata/models/subscription.rb +8 -1
- data/lib/gooddata/models/user_filters/user_filter.rb +1 -0
- data/lib/gooddata/models/user_filters/user_filter_builder.rb +18 -4
- data/lib/gooddata/models/user_filters/variable_user_filter.rb +3 -1
- data/lib/gooddata/rest/client.rb +4 -6
- data/lib/gooddata/rest/connection.rb +10 -2
- data/lib/gooddata/version.rb +1 -1
- data/spec/data/blueprints/test_blueprint.json +1 -0
- data/spec/data/wire_models/test_blueprint.json +3 -0
- data/spec/data/workspace_table.csv +3 -0
- data/spec/environment/development.rb +4 -1
- data/spec/environment/environment.rb +1 -1
- data/spec/environment/staging.rb +5 -1
- data/spec/environment/testing.rb +5 -2
- data/spec/integration/blueprint_with_ca_spec.rb +56 -0
- data/spec/integration/clients_spec.rb +21 -0
- data/spec/integration/command_datawarehouse_spec.rb +7 -1
- data/spec/integration/create_from_template_spec.rb +9 -3
- data/spec/integration/project_spec.rb +7 -0
- data/spec/integration/segments_spec.rb +0 -53
- data/spec/integration/subscription_spec.rb +29 -4
- data/spec/integration/urn_date_dim_spec.rb +53 -0
- data/spec/integration/user_filters_spec.rb +6 -0
- data/spec/integration/variables_spec.rb +1 -2
- data/spec/spec_helper.rb +5 -30
- data/spec/unit/actions/collect_clients_spec.rb +38 -0
- data/spec/unit/actions/collect_meta_spec.rb +87 -0
- data/spec/unit/actions/collect_segment_clients_spec.rb +40 -0
- data/spec/unit/actions/collect_tagged_objects_spec.rb +110 -0
- data/spec/unit/actions/synchronize_etls_in_segment_spec.rb +51 -0
- data/spec/unit/bricks/middleware/aws_middelware_spec.rb +55 -1
- data/spec/unit/bricks/middleware/logger_middleware_spec.rb +15 -0
- data/spec/unit/helpers/data_helper_spec.rb +3 -5
- data/spec/unit/helpers/global_helpers_spec.rb +29 -0
- data/spec/unit/helpers_spec.rb +18 -1
- data/spec/unit/models/blueprint/project_blueprint_spec.rb +1 -23
- data/spec/unit/models/domain_spec.rb +19 -0
- data/spec/unit/models/metadata_spec.rb +34 -0
- data/spec/unit/models/schedule_spec.rb +31 -0
- data/spec/unit/models/to_manifest_spec.rb +10 -2
- data/spec/unit/models/unit_project_spec.rb +6 -1
- data/spec/unit/rest/polling_spec.rb +13 -1
- metadata +49 -31
|
@@ -180,7 +180,9 @@ module GoodData
|
|
|
180
180
|
|
|
181
181
|
# Allows you to test if a report contains a row.
|
|
182
182
|
#
|
|
183
|
-
# @param [Array<String | Number>] row Row that you want to test.
|
|
183
|
+
# @param [Array<String | Number>] row Row that you want to test.
|
|
184
|
+
# It is looking for the whole row. If the headers are getting in the way
|
|
185
|
+
# use #without_left_headers or #without_top_headers
|
|
184
186
|
# @return [Array] Returns true if data are inside a report
|
|
185
187
|
def include_row?(row)
|
|
186
188
|
@data.include?(row)
|
|
@@ -188,7 +190,9 @@ module GoodData
|
|
|
188
190
|
|
|
189
191
|
# Allows you to test if a report contains a column.
|
|
190
192
|
#
|
|
191
|
-
# @param [Array<String | Number>] row Row that you want to test.
|
|
193
|
+
# @param [Array<String | Number>] row Row that you want to test.
|
|
194
|
+
# It is looking for the whole row. If the headers are getting in the way
|
|
195
|
+
# use #without_left_headers or #without_top_headers
|
|
192
196
|
# @return [Array] Returns true if data are inside a report
|
|
193
197
|
def include_column?(col)
|
|
194
198
|
transpose.include_row?(col)
|
|
@@ -74,7 +74,6 @@ module GoodData
|
|
|
74
74
|
dataload_datasets = '[]' unless dataload_datasets
|
|
75
75
|
|
|
76
76
|
de_synchronize_all = options[:de_synchronize_all] || options['GDC_DE_SYNCHRONIZE_ALL']
|
|
77
|
-
de_synchronize_all = 'true' unless de_synchronize_all
|
|
78
77
|
else
|
|
79
78
|
fail 'Executable has to be provided' if executable.blank?
|
|
80
79
|
end
|
|
@@ -85,7 +84,7 @@ module GoodData
|
|
|
85
84
|
params = { 'PROCESS_ID' => process_id }
|
|
86
85
|
if is_dataload_process
|
|
87
86
|
params['GDC_DATALOAD_DATASETS'] = dataload_datasets
|
|
88
|
-
params['GDC_DE_SYNCHRONIZE_ALL'] = de_synchronize_all
|
|
87
|
+
params['GDC_DE_SYNCHRONIZE_ALL'] = de_synchronize_all if de_synchronize_all
|
|
89
88
|
else
|
|
90
89
|
params['EXECUTABLE'] = executable
|
|
91
90
|
end
|
|
@@ -396,6 +395,10 @@ module GoodData
|
|
|
396
395
|
self
|
|
397
396
|
end
|
|
398
397
|
|
|
398
|
+
def rewrite_deprecated_params
|
|
399
|
+
params['EXECUTABLE'] = params.delete('GRAPH') if params['GRAPH']
|
|
400
|
+
end
|
|
401
|
+
|
|
399
402
|
# Saves object if dirty
|
|
400
403
|
#
|
|
401
404
|
# @return [Boolean] True if saved
|
|
@@ -403,9 +406,9 @@ module GoodData
|
|
|
403
406
|
fail 'trigger schedule has to be provided' if cron.blank? && trigger_id.blank?
|
|
404
407
|
fail 'A timezone has to be provided' if timezone.blank?
|
|
405
408
|
fail 'Schedule type has to be provided' if schedule_type.blank?
|
|
409
|
+
rewrite_deprecated_params
|
|
406
410
|
if @dirty
|
|
407
411
|
if saved?
|
|
408
|
-
puts JSON.pretty_generate(to_update_payload)
|
|
409
412
|
res = client.put(uri, to_update_payload)
|
|
410
413
|
@json = Schedule.new(res).json
|
|
411
414
|
else
|
|
@@ -175,7 +175,14 @@ module GoodData
|
|
|
175
175
|
|
|
176
176
|
def ==(other)
|
|
177
177
|
return false unless [:project, :title, :process, :channels, :message, :subject, :project_events, :timer_event].all? { |m| other.respond_to?(m) }
|
|
178
|
-
@project == other.project &&
|
|
178
|
+
@project == other.project &&
|
|
179
|
+
@title == other.title &&
|
|
180
|
+
@process == other.process &&
|
|
181
|
+
@channels == other.channels &&
|
|
182
|
+
@message == other.message &&
|
|
183
|
+
@subject == other.subject &&
|
|
184
|
+
@project_events == other.project_events &&
|
|
185
|
+
@timer_event == other.timer_event
|
|
179
186
|
end
|
|
180
187
|
end
|
|
181
188
|
end
|
|
@@ -130,7 +130,11 @@ module GoodData
|
|
|
130
130
|
next true if domain_user
|
|
131
131
|
false
|
|
132
132
|
end
|
|
133
|
-
|
|
133
|
+
unless missing_users.empty?
|
|
134
|
+
fail "#{missing_users.count} users are not part of the project and " \
|
|
135
|
+
"variable cannot be resolved since :users_must_exist is set " \
|
|
136
|
+
"to true (#{missing_users.join(', ')})"
|
|
137
|
+
end
|
|
134
138
|
end
|
|
135
139
|
end
|
|
136
140
|
|
|
@@ -280,7 +284,7 @@ module GoodData
|
|
|
280
284
|
fail 'Unsuported type in maqlify_filters.'
|
|
281
285
|
end
|
|
282
286
|
|
|
283
|
-
if profiles_uri && expression
|
|
287
|
+
if profiles_uri && expression && expression != 'TRUE'
|
|
284
288
|
[create_user_filter(expression, profiles_uri)] + errors
|
|
285
289
|
else
|
|
286
290
|
[] + errors
|
|
@@ -376,7 +380,11 @@ module GoodData
|
|
|
376
380
|
filters = user_filters.map { |data| client.create(MandatoryUserFilter, data, project: project) }
|
|
377
381
|
to_create, to_delete = resolve_user_filters(filters, project.data_permissions)
|
|
378
382
|
|
|
379
|
-
|
|
383
|
+
if options[:do_not_touch_filters_that_are_not_mentioned]
|
|
384
|
+
GoodData.logger.warn("Data permissions computed: #{to_create.count} to create")
|
|
385
|
+
else
|
|
386
|
+
GoodData.logger.warn("Data permissions computed: #{to_create.count} to create and #{to_delete.count} to delete")
|
|
387
|
+
end
|
|
380
388
|
return { created: to_create, deleted: to_delete } if dry_run
|
|
381
389
|
|
|
382
390
|
create_results = to_create.each_slice(100).flat_map do |batch|
|
|
@@ -396,7 +404,13 @@ module GoodData
|
|
|
396
404
|
res = client.post("/gdc/md/#{project.pid}/userfilters", payload)
|
|
397
405
|
|
|
398
406
|
# turn the errors from hashes into array of hashes
|
|
399
|
-
res['userFiltersUpdateResult'].flat_map
|
|
407
|
+
update_result = res['userFiltersUpdateResult'].flat_map do |k, v|
|
|
408
|
+
v.map { |r| { status: k.to_sym, user: r, type: :create } }
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
update_result.map do |result|
|
|
412
|
+
result[:status] == :failed ? result.merge(GoodData::Helpers.symbolize_keys(result[:user])) : result
|
|
413
|
+
end
|
|
400
414
|
end
|
|
401
415
|
end
|
|
402
416
|
|
|
@@ -17,7 +17,9 @@ module GoodData
|
|
|
17
17
|
self
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# Method used for replacing values in their state according to mapping.
|
|
20
|
+
# Method used for replacing values in their state according to mapping.
|
|
21
|
+
# Can be used to replace any values but it is typically used to replace
|
|
22
|
+
# the URIs. Returns a new object of the same type.
|
|
21
23
|
#
|
|
22
24
|
# @param [Array<Array>]Mapping specifying what should be exchanged for what. As mapping should be used output of GoodData::Helpers.prepare_mapping.
|
|
23
25
|
# @return [GoodData::VariableUserFilter]
|
data/lib/gooddata/rest/client.rb
CHANGED
|
@@ -106,12 +106,6 @@ module GoodData
|
|
|
106
106
|
client = Client.new(new_opts)
|
|
107
107
|
GoodData.logger.info("Connected to server with webdav path #{client.user_webdav_path}")
|
|
108
108
|
|
|
109
|
-
if client
|
|
110
|
-
at_exit do
|
|
111
|
-
puts client.connection.stats_table if client && client.connection && (GoodData.stats_on? || client.stats_on?)
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
109
|
# HACK: This line assigns class instance # if not done yet
|
|
116
110
|
@@instance = client # rubocop:disable ClassVars
|
|
117
111
|
end
|
|
@@ -197,6 +191,10 @@ module GoodData
|
|
|
197
191
|
end
|
|
198
192
|
|
|
199
193
|
def disconnect
|
|
194
|
+
if stats_on?
|
|
195
|
+
puts "API call statistics to server #{@connection.server}"
|
|
196
|
+
puts @connection.stats_table
|
|
197
|
+
end
|
|
200
198
|
@connection.disconnect
|
|
201
199
|
end
|
|
202
200
|
|
|
@@ -19,7 +19,11 @@ module RestClient
|
|
|
19
19
|
module AbstractResponse
|
|
20
20
|
alias_method :old_follow_redirection, :follow_redirection
|
|
21
21
|
def follow_redirection(request = nil, result = nil, &block)
|
|
22
|
-
|
|
22
|
+
if RestClient::VERSION != '1.8.0'
|
|
23
|
+
fail 'Using monkey patched version of RestClient::AbstractResponse#' \
|
|
24
|
+
'follow_redirection which is guaranteed to be compatible only ' \
|
|
25
|
+
'with RestClient 1.8.0'
|
|
26
|
+
end
|
|
23
27
|
|
|
24
28
|
new_args = @args.dup
|
|
25
29
|
|
|
@@ -508,6 +512,9 @@ module GoodData
|
|
|
508
512
|
return e unless e.respond_to?(:response)
|
|
509
513
|
error = MultiJson.load(e.response)
|
|
510
514
|
message = GoodData::Helpers.interpolate_error_message(error)
|
|
515
|
+
if error && error['error'] && error['error']['errorClass'] == 'com.gooddata.security.authorization.AuthorizationFailedException'
|
|
516
|
+
message = "#{message}, accessing with #{user['accountSetting']['login']}"
|
|
517
|
+
end
|
|
511
518
|
<<-ERR
|
|
512
519
|
|
|
513
520
|
#{e}: #{message}
|
|
@@ -631,7 +638,8 @@ ERR
|
|
|
631
638
|
['/gdc/datawarehouse/instances/{id}', %r{/gdc/datawarehouse/instances/[\w]+}],
|
|
632
639
|
['/gdc/datawarehouse/executions/{id}', %r{/gdc/datawarehouse/executions/[\w]+}],
|
|
633
640
|
|
|
634
|
-
['/gdc/domains/{id}/segments/{segment}/synchronizeClients/results/{result}/details?offset={offset}&limit={limit}',
|
|
641
|
+
['/gdc/domains/{id}/segments/{segment}/synchronizeClients/results/{result}/details?offset={offset}&limit={limit}',
|
|
642
|
+
%r{/gdc/domains/[\w]+/segments/[\w-]+/synchronizeClients/results/[\w]+/details/\?offset=[\d]+&limit=[\d]+}],
|
|
635
643
|
['/gdc/domains/{id}/segments/{segment}/synchronizeClients/results/{result}', %r{/gdc/domains/[\w]+/segments/[\w-]+/synchronizeClients/results/[\w]+}],
|
|
636
644
|
['/gdc/domains/{id}/segments/{segment}/', %r{/gdc/domains/[\w]+/segments/[\w-]+/}],
|
|
637
645
|
['/gdc/domains/{id}/segments/{segment}', %r{/gdc/domains/[\w]+/segments/[\w-]+}],
|
data/lib/gooddata/version.rb
CHANGED
|
@@ -7,7 +7,10 @@
|
|
|
7
7
|
module GoodData
|
|
8
8
|
module Environment
|
|
9
9
|
module ConnectionHelper
|
|
10
|
-
|
|
10
|
+
encrypted_token = "cfO9ifFYQVJw3q6Kf8/pVf/uLPLGnUJ/9nfvBxeGf/ILoj8N4ymWGgvryWEK\nHDMu\n"
|
|
11
|
+
key = ENV['GD_SPEC_PASSWORD'] || ENV['BIA_ENCRYPTION_KEY']
|
|
12
|
+
token = GoodData::Helpers.decrypt(encrypted_token, key)
|
|
13
|
+
set_const :GD_PROJECT_TOKEN, token
|
|
11
14
|
set_const :DEFAULT_DOMAIN, 'staging3-lcm-prod'
|
|
12
15
|
set_const :DEFAULT_SERVER, 'https://staging3-lcm-prod.intgdc.com'
|
|
13
16
|
set_const :DEFAULT_USER_URL, '/gdc/account/profile/a4c644d7b42b65c34e5a0f46809f7164'
|
data/spec/environment/staging.rb
CHANGED
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
module GoodData
|
|
8
8
|
module Environment
|
|
9
9
|
module ConnectionHelper
|
|
10
|
-
|
|
10
|
+
encrypted_token = 'YC+foKO2M8rIfB5gxF/sVvop5dRA7d/zLO/zzUlBr9ZimnoYe' \
|
|
11
|
+
'LFyAqU20U4k\ncRYb\n'
|
|
12
|
+
key = ENV['GD_SPEC_PASSWORD'] || ENV['BIA_ENCRYPTION_KEY']
|
|
13
|
+
token = GoodData::Helpers.decrypt(encrypted_token, key)
|
|
14
|
+
set_const :GD_PROJECT_TOKEN, token
|
|
11
15
|
set_const :DEFAULT_DOMAIN, 'staging-lcm-prod'
|
|
12
16
|
set_const :DEFAULT_SERVER, 'https://staging-lcm-prod.intgdc.com'
|
|
13
17
|
set_const :DEFAULT_USER_URL, '/gdc/account/profile/e306b64fb4178785c9cf29c29b5e498a'
|
data/spec/environment/testing.rb
CHANGED
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
module GoodData
|
|
8
8
|
module Environment
|
|
9
9
|
module ConnectionHelper
|
|
10
|
-
set_const :GD_PROJECT_TOKEN, GoodData::Helpers.decrypt(
|
|
10
|
+
set_const :GD_PROJECT_TOKEN, GoodData::Helpers.decrypt(
|
|
11
|
+
"DIRchLbHH1fovLSVEfo3f5aQwHHQ432+PxF3uR5IuNn+iYWz+HZrLtaZ3LVE\n0ZNc\n",
|
|
12
|
+
ENV['GD_SPEC_PASSWORD'] || ENV['BIA_ENCRYPTION_KEY']
|
|
13
|
+
)
|
|
11
14
|
set_const :DEFAULT_DOMAIN, 'staging2-lcm-prod'
|
|
12
15
|
set_const :DEFAULT_SERVER, 'https://staging2-lcm-prod.intgdc.com'
|
|
13
16
|
set_const :DEFAULT_USER_URL, '/gdc/account/profile/5ad80b895edcc438e5a4418e222733fa'
|
|
14
|
-
set_const :STAGING_URI, 'https://
|
|
17
|
+
set_const :STAGING_URI, 'https://staging2-lcm-prod.intgdc.com/gdc/uploads/'
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
module ProcessHelper
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2010-2017 GoodData Corporation. All rights reserved.
|
|
4
|
+
# This source code is licensed under the BSD-style license found in the
|
|
5
|
+
# LICENSE file in the root directory of this source tree.
|
|
6
|
+
|
|
7
|
+
require 'gooddata'
|
|
8
|
+
|
|
9
|
+
describe 'Create project using GoodData client', :constraint => 'slow' do
|
|
10
|
+
before(:all) do
|
|
11
|
+
@client = ConnectionHelper.create_default_connection
|
|
12
|
+
@blueprint = GoodData::Model::ProjectBlueprint.build("My project from blueprint") do |project_builder|
|
|
13
|
+
project_builder.add_dataset('dataset.users', title: 'Users Dataset') do |schema_builder|
|
|
14
|
+
schema_builder.add_anchor('attr.users.id')
|
|
15
|
+
schema_builder.add_label('label.users.id_label', reference: 'attr.users.id')
|
|
16
|
+
schema_builder.add_attribute('attr.users.another_attr')
|
|
17
|
+
schema_builder.add_label('label.users.another_attr_label', reference: 'attr.users.another_attr')
|
|
18
|
+
schema_builder.add_fact('fact.users.some_number')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
fail "blueprint is invalid" unless @blueprint.valid?
|
|
22
|
+
|
|
23
|
+
@project = @client.create_project_from_blueprint(@blueprint, auth_token: ConnectionHelper::GD_PROJECT_TOKEN)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
after(:all) do
|
|
27
|
+
@project && @project.delete
|
|
28
|
+
@client && @client.disconnect
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'Should create computed attribute' do
|
|
32
|
+
metric = @project.facts('fact.users.some_number').create_metric(title: 'Test')
|
|
33
|
+
metric.save
|
|
34
|
+
attribute = @project.attributes('attr.users.another_attr')
|
|
35
|
+
|
|
36
|
+
update = GoodData::Model::ProjectBlueprint.build('update') do |project_builder|
|
|
37
|
+
project_builder.add_computed_attribute(
|
|
38
|
+
'attr.comp.my_computed_attr',
|
|
39
|
+
title: 'My computed attribute',
|
|
40
|
+
metric: metric,
|
|
41
|
+
attribute: attribute,
|
|
42
|
+
buckets: [{ label: 'Small', highest_value: 1000 }, { label: 'Medium', highest_value: 2000 }, { label: 'High' }]
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
new_bp = @blueprint.merge(update)
|
|
47
|
+
fail "blueprint with computed attribute is invalid" unless new_bp.valid?
|
|
48
|
+
|
|
49
|
+
@project.update_from_blueprint(new_bp)
|
|
50
|
+
ca = @project.attributes.find { |a| a.title == 'My computed attribute' }
|
|
51
|
+
|
|
52
|
+
expect(ca).not_to be_nil
|
|
53
|
+
expect(ca.computed_attribute?).to be_truthy
|
|
54
|
+
expect(@project.computed_attributes.length).to eq 1
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -62,6 +62,27 @@ describe GoodData::Client do
|
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
+
describe '#dissociate' do
|
|
66
|
+
before(:all) do
|
|
67
|
+
client_id = SecureRandom.uuid
|
|
68
|
+
@client_project = @client.create_project(title: 'client_1 project', auth_token: ConnectionHelper::GD_PROJECT_TOKEN)
|
|
69
|
+
@segment_client = @segment.create_client(id: "tenant_#{client_id}", project: @client_project)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
after(:all) do
|
|
73
|
+
@client_project && @client_project.delete
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'Dissociate particular client and their project is not cleaned up' do
|
|
77
|
+
expect(@segment.clients.count).to eq 1
|
|
78
|
+
s = @segment.clients(@segment_client)
|
|
79
|
+
s.dissociate
|
|
80
|
+
expect(@segment.clients.count).to eq 0
|
|
81
|
+
expect(@client_project.reload!.state).to eq :enabled
|
|
82
|
+
@segment_client = nil
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
65
86
|
describe '#delete' do
|
|
66
87
|
before(:all) do
|
|
67
88
|
client_id = SecureRandom.uuid
|
|
@@ -26,7 +26,13 @@ describe GoodData::Command::DataWarehouse do
|
|
|
26
26
|
dwh = nil
|
|
27
27
|
|
|
28
28
|
begin
|
|
29
|
-
dwh = GoodData::Command::DataWarehouse.create(
|
|
29
|
+
dwh = GoodData::Command::DataWarehouse.create(
|
|
30
|
+
title: title,
|
|
31
|
+
summary: summary,
|
|
32
|
+
token: ConnectionHelper::GD_PROJECT_TOKEN,
|
|
33
|
+
environment: ProjectHelper::ENVIRONMENT,
|
|
34
|
+
client: @client
|
|
35
|
+
)
|
|
30
36
|
|
|
31
37
|
expect(dwh.title).to eq(title)
|
|
32
38
|
expect(dwh.summary).to eq(summary)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
require 'gooddata'
|
|
8
8
|
|
|
9
|
-
describe
|
|
9
|
+
describe 'Spin a project from template', :constraint => 'slow' do
|
|
10
10
|
before(:all) do
|
|
11
11
|
@client = ConnectionHelper.create_default_connection
|
|
12
12
|
end
|
|
@@ -15,9 +15,15 @@ describe "Spin a project from template", :constraint => 'slow' do
|
|
|
15
15
|
@client.disconnect
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
it
|
|
18
|
+
it 'should spin a project from a template that does not exist. It should throw an error' do
|
|
19
19
|
expect do
|
|
20
|
-
GoodData::Project.create(
|
|
20
|
+
GoodData::Project.create(
|
|
21
|
+
title: 'Test project',
|
|
22
|
+
template: '/some/nonexisting/template/uri',
|
|
23
|
+
auth_token: ConnectionHelper::GD_PROJECT_TOKEN,
|
|
24
|
+
environment: ProjectHelper::ENVIRONMENT,
|
|
25
|
+
client: @client
|
|
26
|
+
)
|
|
21
27
|
end.to raise_error
|
|
22
28
|
end
|
|
23
29
|
end
|
|
@@ -155,6 +155,13 @@ describe GoodData::Project, :constraint => 'slow' do
|
|
|
155
155
|
expect(@project.members?(users).all?).to be_truthy
|
|
156
156
|
expect(@project.get_user(ConnectionHelper::DEFAULT_USERNAME).role.title).to eq 'Admin'
|
|
157
157
|
end
|
|
158
|
+
|
|
159
|
+
it 'should downcase login' do
|
|
160
|
+
users = [ProjectHelper.create_random_user(@client, login: "#{rand(1e7)}+TMA-445+RubyDev+Admin@gooddata.com")]
|
|
161
|
+
@domain.create_users(users)
|
|
162
|
+
@project.import_users(users, domain: @domain, whitelists: ['rubydev+admin@gooddata.com'])
|
|
163
|
+
expect(@project.members?(users.map(&:to_hash).map { |u| u[:login].downcase! })).to be_truthy
|
|
164
|
+
end
|
|
158
165
|
end
|
|
159
166
|
|
|
160
167
|
describe '#set_user_roles' do
|
|
@@ -96,57 +96,4 @@ describe GoodData::Segment do
|
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
|
-
|
|
100
|
-
describe '#provision_client_projects' do
|
|
101
|
-
it 'can create a new client in a segment without project and then provision' do
|
|
102
|
-
begin
|
|
103
|
-
segment_client = @segment.create_client(id: 'tenant_1')
|
|
104
|
-
expect(segment_client).to be_an_instance_of(GoodData::Client)
|
|
105
|
-
expect(@segment.clients.count).to eq 1
|
|
106
|
-
@domain.synchronize_clients
|
|
107
|
-
@domain.provision_client_projects
|
|
108
|
-
expect(@domain.segments.flat_map { |s| s.clients.to_a }.all?(&:project?)).to be_truthy
|
|
109
|
-
ensure
|
|
110
|
-
segment_client && segment_client.delete
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
describe '#update_clients' do
|
|
116
|
-
it 'can create a new client in a segment without project and then provision' do
|
|
117
|
-
begin
|
|
118
|
-
uuid_2 = SecureRandom.uuid
|
|
119
|
-
master_project_2 = @client.create_project(title: "Test MASTER project for #{uuid_2}", auth_token: ConnectionHelper::GD_PROJECT_TOKEN)
|
|
120
|
-
segment_name_2 = "segment-#{uuid_2}"
|
|
121
|
-
segment_2 = @domain.create_segment(segment_id: segment_name_2, master_project: master_project_2)
|
|
122
|
-
|
|
123
|
-
client_1 = "client-#{SecureRandom.uuid}"
|
|
124
|
-
client_2 = "client-#{SecureRandom.uuid}"
|
|
125
|
-
data = [{ id: client_1, segment: segment_name_2 },
|
|
126
|
-
{ id: client_2, segment: @segment_name }]
|
|
127
|
-
@domain.update_clients(data)
|
|
128
|
-
expect(@domain.segments.map(&:id)).to include(@segment.id, segment_2.id)
|
|
129
|
-
expect(@domain.segments.pmapcat { |s| s.clients.to_a }.map(&:id)).to include(client_1, client_2)
|
|
130
|
-
|
|
131
|
-
client_3 = "client-#{SecureRandom.uuid}"
|
|
132
|
-
client_4 = "client-#{SecureRandom.uuid}"
|
|
133
|
-
data = [{ id: client_3, segment: segment_name_2 },
|
|
134
|
-
{ id: client_4, segment: @segment_name }]
|
|
135
|
-
@domain.update_clients(data)
|
|
136
|
-
expect(@domain.segments.pmapcat { |s| s.clients.to_a }.map(&:id)).to include(client_1, client_2, client_3, client_4)
|
|
137
|
-
|
|
138
|
-
# bring the projects
|
|
139
|
-
@domain.synchronize_clients
|
|
140
|
-
@domain.provision_client_projects
|
|
141
|
-
projects_to_delete = @domain.segments.pmapcat { |s| s.clients.to_a }.select { |c| [client_1, client_2].include?(c.id) }.map(&:project)
|
|
142
|
-
@domain.update_clients(data, delete_extra: true)
|
|
143
|
-
expect(@domain.segments.pmapcat { |s| s.clients.to_a }.map(&:id)).to include(client_3, client_4)
|
|
144
|
-
expect(@domain.segments.pmapcat { |s| s.clients.to_a }.map(&:id)).not_to include(client_1, client_2)
|
|
145
|
-
expect(projects_to_delete.pmap(&:reload!).map(&:state)).to eq [:deleted, :deleted]
|
|
146
|
-
ensure
|
|
147
|
-
master_project_2.delete if master_project_2
|
|
148
|
-
segment_2.delete(force: true) if segment_2
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
end
|
|
152
99
|
end
|