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.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +13 -1
  4. data/CONTRIBUTING.md +25 -0
  5. data/PULL_REQUEST_TEMPLATE.md +5 -0
  6. data/README.md +7 -4
  7. data/gooddata.gemspec +2 -3
  8. data/lib/gooddata.rb +1 -0
  9. data/lib/gooddata/bricks/base_downloader.rb +6 -6
  10. data/lib/gooddata/bricks/middleware/aws_middleware.rb +15 -5
  11. data/lib/gooddata/bricks/middleware/dwh_middleware.rb +15 -3
  12. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +13 -4
  13. data/lib/gooddata/bricks/middleware/logger_middleware.rb +3 -0
  14. data/lib/gooddata/exceptions/no_project_error.rb +5 -1
  15. data/lib/gooddata/goodzilla/goodzilla.rb +7 -6
  16. data/lib/gooddata/helpers/data_helper.rb +4 -4
  17. data/lib/gooddata/helpers/global_helpers_params.rb +61 -39
  18. data/lib/gooddata/lcm/actions/apply_custom_maql.rb +9 -0
  19. data/lib/gooddata/lcm/actions/associate_clients.rb +23 -4
  20. data/lib/gooddata/lcm/actions/collect_attrs.rb +56 -0
  21. data/lib/gooddata/lcm/actions/collect_ca_metrics.rb +53 -0
  22. data/lib/gooddata/lcm/actions/collect_clients.rb +25 -3
  23. data/lib/gooddata/lcm/actions/collect_meta.rb +83 -0
  24. data/lib/gooddata/lcm/actions/collect_segment_clients.rb +12 -4
  25. data/lib/gooddata/lcm/actions/collect_segments.rb +4 -4
  26. data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +74 -0
  27. data/lib/gooddata/lcm/actions/create_segment_masters.rb +16 -30
  28. data/lib/gooddata/lcm/actions/ensure_release_table.rb +0 -3
  29. data/lib/gooddata/lcm/actions/ensure_segments.rb +1 -4
  30. data/lib/gooddata/lcm/actions/ensure_technical_users_domain.rb +5 -5
  31. data/lib/gooddata/lcm/actions/ensure_technical_users_project.rb +8 -5
  32. data/lib/gooddata/lcm/actions/hello_world.rb +0 -3
  33. data/lib/gooddata/lcm/actions/import_object_collections.rb +60 -0
  34. data/lib/gooddata/lcm/actions/print_actions.rb +0 -3
  35. data/lib/gooddata/lcm/actions/print_modes.rb +0 -3
  36. data/lib/gooddata/lcm/actions/print_types.rb +1 -4
  37. data/lib/gooddata/lcm/actions/provision_clients.rb +5 -5
  38. data/lib/gooddata/lcm/actions/purge_clients.rb +4 -10
  39. data/lib/gooddata/lcm/actions/segments_filter.rb +0 -6
  40. data/lib/gooddata/lcm/actions/synchronize_attribute_drillpaths.rb +8 -4
  41. data/lib/gooddata/lcm/actions/synchronize_cas.rb +61 -0
  42. data/lib/gooddata/lcm/actions/synchronize_clients.rb +9 -3
  43. data/lib/gooddata/lcm/actions/synchronize_color_palette.rb +13 -5
  44. data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +71 -17
  45. data/lib/gooddata/lcm/actions/synchronize_label_types.rb +8 -5
  46. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +17 -8
  47. data/lib/gooddata/lcm/actions/synchronize_meta.rb +0 -3
  48. data/lib/gooddata/lcm/actions/synchronize_new_segments.rb +9 -4
  49. data/lib/gooddata/lcm/actions/synchronize_processes.rb +9 -5
  50. data/lib/gooddata/lcm/actions/synchronize_schedules.rb +15 -5
  51. data/lib/gooddata/lcm/actions/synchronize_tag_objects.rb +61 -0
  52. data/lib/gooddata/lcm/actions/update_release_table.rb +0 -3
  53. data/lib/gooddata/lcm/helpers/tags_helper.rb +35 -0
  54. data/lib/gooddata/lcm/lcm.rb +22 -4
  55. data/lib/gooddata/lcm/lcm2.rb +66 -13
  56. data/lib/gooddata/lcm/types/complex/update_preference.rb +1 -1
  57. data/lib/gooddata/mixins/md_finders.rb +4 -2
  58. data/lib/gooddata/mixins/md_object_indexer.rb +13 -3
  59. data/lib/gooddata/mixins/md_object_query.rb +8 -2
  60. data/lib/gooddata/models/blueprint/date_dimension.rb +6 -0
  61. data/lib/gooddata/models/blueprint/project_blueprint.rb +41 -11
  62. data/lib/gooddata/models/blueprint/project_builder.rb +20 -0
  63. data/lib/gooddata/models/blueprint/to_wire.rb +7 -0
  64. data/lib/gooddata/models/client.rb +6 -0
  65. data/lib/gooddata/models/domain.rb +6 -6
  66. data/lib/gooddata/models/from_wire.rb +5 -1
  67. data/lib/gooddata/models/metadata.rb +55 -9
  68. data/lib/gooddata/models/metadata/attribute.rb +19 -4
  69. data/lib/gooddata/models/metadata/dashboard.rb +15 -3
  70. data/lib/gooddata/models/metadata/dataset.rb +5 -2
  71. data/lib/gooddata/models/metadata/dimension.rb +4 -1
  72. data/lib/gooddata/models/metadata/fact.rb +9 -2
  73. data/lib/gooddata/models/metadata/folder.rb +4 -1
  74. data/lib/gooddata/models/metadata/metric.rb +11 -3
  75. data/lib/gooddata/models/metadata/report.rb +7 -2
  76. data/lib/gooddata/models/metadata/report_definition.rb +11 -4
  77. data/lib/gooddata/models/metadata/scheduled_mail.rb +4 -1
  78. data/lib/gooddata/models/metadata/variable.rb +7 -2
  79. data/lib/gooddata/models/model.rb +14 -3
  80. data/lib/gooddata/models/process.rb +10 -9
  81. data/lib/gooddata/models/project.rb +134 -36
  82. data/lib/gooddata/models/project_creator.rb +43 -20
  83. data/lib/gooddata/models/report_data_result.rb +6 -2
  84. data/lib/gooddata/models/schedule.rb +6 -3
  85. data/lib/gooddata/models/subscription.rb +8 -1
  86. data/lib/gooddata/models/user_filters/user_filter.rb +1 -0
  87. data/lib/gooddata/models/user_filters/user_filter_builder.rb +18 -4
  88. data/lib/gooddata/models/user_filters/variable_user_filter.rb +3 -1
  89. data/lib/gooddata/rest/client.rb +4 -6
  90. data/lib/gooddata/rest/connection.rb +10 -2
  91. data/lib/gooddata/version.rb +1 -1
  92. data/spec/data/blueprints/test_blueprint.json +1 -0
  93. data/spec/data/wire_models/test_blueprint.json +3 -0
  94. data/spec/data/workspace_table.csv +3 -0
  95. data/spec/environment/development.rb +4 -1
  96. data/spec/environment/environment.rb +1 -1
  97. data/spec/environment/staging.rb +5 -1
  98. data/spec/environment/testing.rb +5 -2
  99. data/spec/integration/blueprint_with_ca_spec.rb +56 -0
  100. data/spec/integration/clients_spec.rb +21 -0
  101. data/spec/integration/command_datawarehouse_spec.rb +7 -1
  102. data/spec/integration/create_from_template_spec.rb +9 -3
  103. data/spec/integration/project_spec.rb +7 -0
  104. data/spec/integration/segments_spec.rb +0 -53
  105. data/spec/integration/subscription_spec.rb +29 -4
  106. data/spec/integration/urn_date_dim_spec.rb +53 -0
  107. data/spec/integration/user_filters_spec.rb +6 -0
  108. data/spec/integration/variables_spec.rb +1 -2
  109. data/spec/spec_helper.rb +5 -30
  110. data/spec/unit/actions/collect_clients_spec.rb +38 -0
  111. data/spec/unit/actions/collect_meta_spec.rb +87 -0
  112. data/spec/unit/actions/collect_segment_clients_spec.rb +40 -0
  113. data/spec/unit/actions/collect_tagged_objects_spec.rb +110 -0
  114. data/spec/unit/actions/synchronize_etls_in_segment_spec.rb +51 -0
  115. data/spec/unit/bricks/middleware/aws_middelware_spec.rb +55 -1
  116. data/spec/unit/bricks/middleware/logger_middleware_spec.rb +15 -0
  117. data/spec/unit/helpers/data_helper_spec.rb +3 -5
  118. data/spec/unit/helpers/global_helpers_spec.rb +29 -0
  119. data/spec/unit/helpers_spec.rb +18 -1
  120. data/spec/unit/models/blueprint/project_blueprint_spec.rb +1 -23
  121. data/spec/unit/models/domain_spec.rb +19 -0
  122. data/spec/unit/models/metadata_spec.rb +34 -0
  123. data/spec/unit/models/schedule_spec.rb +31 -0
  124. data/spec/unit/models/to_manifest_spec.rb +10 -2
  125. data/spec/unit/models/unit_project_spec.rb +6 -1
  126. data/spec/unit/rest/polling_spec.rb +13 -1
  127. 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. It is looking for the whole row. If the headers are getting in the way use #without_left_headers or #without_top_headers
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. It is looking for the whole row. If the headers are getting in the way use #without_left_headers or #without_top_headers
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 && @title == other.title && @process == other.process && @channels == other.channels && @message == other.message && @subject == other.subject && @project_events == other.project_events && @timer_event == other.timer_event
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
@@ -32,6 +32,7 @@ module GoodData
32
32
  # @return [GoodData::Project | GoodData::Profile] Related object
33
33
  def related
34
34
  uri = related_uri
35
+ return unless uri
35
36
  level == :project ? client.projects(uri) : client.create(GoodData::Profile, client.get(uri))
36
37
  end
37
38
 
@@ -130,7 +130,11 @@ module GoodData
130
130
  next true if domain_user
131
131
  false
132
132
  end
133
- fail "#{missing_users.count} users are not part of the project and variable cannot be resolved since :users_must_exist is set to true (#{missing_users.join(', ')})" unless missing_users.empty?
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
- GoodData.logger.warn("Data permissions computed: #{to_create.count} to create and #{to_delete.count} to delete")
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 { |k, v| v.map { |r| { status: k.to_sym, user: r, type: :create } } }.map { |result| result[:status] == :failed ? result.merge(GoodData::Helpers.symbolize_keys(result[:user])) : result }
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. Can be used to replace any values but it is typically used to replace the URIs. Returns a new object of the same type.
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]
@@ -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
- fail 'Using monkey patched version of RestClient::AbstractResponse#follow_redirection which is guaranteed to be compatible only with RestClient 1.8.0' if RestClient::VERSION != '1.8.0'
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}', %r{/gdc/domains/[\w]+/segments/[\w-]+/synchronizeClients/results/[\w]+/details/\?offset=[\d]+&limit=[\d]+}],
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-]+}],
@@ -6,7 +6,7 @@
6
6
 
7
7
  # GoodData Module
8
8
  module GoodData
9
- VERSION = '0.6.51'
9
+ VERSION = '0.6.52'
10
10
 
11
11
  class << self
12
12
  # Version
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "title": "Devs module",
3
+ "include_ca": false,
3
4
  "datasets": [
4
5
  {
5
6
  "type": "dataset",
@@ -2,6 +2,9 @@
2
2
  "diffRequest": {
3
3
  "targetModel": {
4
4
  "projectModel": {
5
+ "modelMetadata": {
6
+ "containCA": false
7
+ },
5
8
  "datasets": [
6
9
  {
7
10
  "dataset": {
@@ -0,0 +1,3 @@
1
+ client_id,segment_id,project_title
2
+ client_foo,segment_foo,project_foo
3
+ client_bar,segment_bar,project_bar
@@ -7,7 +7,10 @@
7
7
  module GoodData
8
8
  module Environment
9
9
  module ConnectionHelper
10
- set_const :GD_PROJECT_TOKEN, GoodData::Helpers.decrypt("cfO9ifFYQVJw3q6Kf8/pVf/uLPLGnUJ/9nfvBxeGf/ILoj8N4ymWGgvryWEK\nHDMu\n", ENV['GD_SPEC_PASSWORD'] || ENV['BIA_ENCRYPTION_KEY'])
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'
@@ -12,7 +12,7 @@ module GoodData
12
12
  hotfix: 'production'
13
13
  }
14
14
 
15
- def load(env = ENV['GD_ENV'] || 'development')
15
+ def load(env = ENV['GD_ENV'] || 'testing')
16
16
  require_relative 'default'
17
17
  env = branch_to_environment(env)
18
18
 
@@ -7,7 +7,11 @@
7
7
  module GoodData
8
8
  module Environment
9
9
  module ConnectionHelper
10
- set_const :GD_PROJECT_TOKEN, GoodData::Helpers.decrypt("YC+foKO2M8rIfB5gxF/sVvop5dRA7d/zLO/zzUlBr9ZimnoYeLFyAqU20U4k\ncRYb\n", ENV['GD_SPEC_PASSWORD'] || ENV['BIA_ENCRYPTION_KEY'])
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'
@@ -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("DIRchLbHH1fovLSVEfo3f5aQwHHQ432+PxF3uR5IuNn+iYWz+HZrLtaZ3LVE\n0ZNc\n", ENV['GD_SPEC_PASSWORD'] || ENV['BIA_ENCRYPTION_KEY'])
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://na1-staging2-di.intgdc.com/uploads/'
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(title: title, summary: summary, token: ConnectionHelper::GD_PROJECT_TOKEN, environment: ProjectHelper::ENVIRONMENT, client: @client)
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 "Spin a project from template", :constraint => 'slow' do
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 "should spin a project from a template that does not exist. It should throw an error" do
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(:title => "Test project", :template => "/some/nonexisting/template/uri", :auth_token => ConnectionHelper::GD_PROJECT_TOKEN, environment: ProjectHelper::ENVIRONMENT, :client => @client)
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