gooddata 0.6.53 → 0.6.54

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 (139) hide show
  1. checksums.yaml +5 -5
  2. data/.flayignore +6 -0
  3. data/.gitignore +1 -0
  4. data/.pronto.yml +3 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +4 -1
  7. data/CHANGELOG.md +18 -0
  8. data/CONTRIBUTING.md +14 -1
  9. data/DEPENDENCIES.md +324 -253
  10. data/Dockerfile.jruby +5 -7
  11. data/Dockerfile.ruby +8 -8
  12. data/Rakefile +24 -0
  13. data/ci.rake +47 -0
  14. data/docker-compose.yml +34 -0
  15. data/gooddata.gemspec +8 -2
  16. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +0 -3
  17. data/lib/gooddata/helpers/data_helper.rb +10 -7
  18. data/lib/gooddata/helpers/global_helpers_params.rb +8 -3
  19. data/lib/gooddata/lcm/actions/apply_custom_maql.rb +2 -1
  20. data/lib/gooddata/lcm/actions/associate_clients.rb +10 -1
  21. data/lib/gooddata/lcm/actions/collect_client_projects.rb +78 -0
  22. data/lib/gooddata/lcm/actions/collect_clients.rb +20 -6
  23. data/lib/gooddata/lcm/actions/collect_data_product.rb +62 -0
  24. data/lib/gooddata/lcm/actions/collect_dynamic_schedule_params.rb +62 -0
  25. data/lib/gooddata/lcm/actions/{collect_attrs.rb → collect_ldm_objects.rb} +3 -3
  26. data/lib/gooddata/lcm/actions/collect_meta.rb +6 -3
  27. data/lib/gooddata/lcm/actions/collect_segment_clients.rb +2 -1
  28. data/lib/gooddata/lcm/actions/collect_segments.rb +6 -7
  29. data/lib/gooddata/lcm/actions/collect_tagged_objects.rb +7 -4
  30. data/lib/gooddata/lcm/actions/create_segment_masters.rb +7 -3
  31. data/lib/gooddata/lcm/actions/ensure_data_product.rb +53 -0
  32. data/lib/gooddata/lcm/actions/ensure_technical_users_domain.rb +6 -2
  33. data/lib/gooddata/lcm/actions/ensure_technical_users_project.rb +30 -18
  34. data/lib/gooddata/lcm/actions/execute_schedules.rb +128 -0
  35. data/lib/gooddata/lcm/actions/provision_clients.rb +32 -21
  36. data/lib/gooddata/lcm/actions/purge_clients.rb +25 -39
  37. data/lib/gooddata/lcm/actions/rename_existing_client_projects.rb +70 -0
  38. data/lib/gooddata/lcm/actions/segments_filter.rb +6 -0
  39. data/lib/gooddata/lcm/actions/synchronize_cas.rb +11 -0
  40. data/lib/gooddata/lcm/actions/synchronize_clients.rb +2 -1
  41. data/lib/gooddata/lcm/actions/synchronize_etls_in_segment.rb +34 -15
  42. data/lib/gooddata/lcm/actions/synchronize_ldm.rb +10 -1
  43. data/lib/gooddata/lcm/actions/synchronize_new_segments.rb +2 -1
  44. data/lib/gooddata/lcm/actions/synchronize_processes.rb +4 -7
  45. data/lib/gooddata/lcm/actions/synchronize_tag_objects.rb +8 -5
  46. data/lib/gooddata/lcm/actions/synchronize_user_filters.rb +224 -0
  47. data/lib/gooddata/lcm/actions/synchronize_user_groups.rb +53 -0
  48. data/lib/gooddata/lcm/actions/synchronize_users.rb +324 -0
  49. data/lib/gooddata/lcm/dsl/type_dsl.rb +1 -0
  50. data/lib/gooddata/lcm/helpers/check_helper.rb +4 -0
  51. data/lib/gooddata/lcm/helpers/tags_helper.rb +4 -3
  52. data/lib/gooddata/lcm/lcm2.rb +33 -1
  53. data/lib/gooddata/lcm/types/complex/segment.rb +3 -0
  54. data/lib/gooddata/lcm/types/complex/update_preference.rb +8 -2
  55. data/lib/gooddata/lcm/types/special/array.rb +1 -3
  56. data/lib/gooddata/lcm/types/special/enum.rb +1 -3
  57. data/lib/gooddata/mixins/md_id_to_uri.rb +0 -1
  58. data/lib/gooddata/mixins/md_json.rb +2 -2
  59. data/lib/gooddata/models/blueprint/project_blueprint.rb +15 -0
  60. data/lib/gooddata/models/blueprint/to_wire.rb +1 -0
  61. data/lib/gooddata/models/client.rb +21 -9
  62. data/lib/gooddata/models/data_product.rb +149 -0
  63. data/lib/gooddata/models/domain.rb +26 -72
  64. data/lib/gooddata/models/from_wire.rb +2 -0
  65. data/lib/gooddata/models/metadata/report.rb +9 -3
  66. data/lib/gooddata/models/metadata/report_definition.rb +2 -2
  67. data/lib/gooddata/models/model.rb +1 -1
  68. data/lib/gooddata/models/process.rb +4 -0
  69. data/lib/gooddata/models/project.rb +58 -35
  70. data/lib/gooddata/models/project_creator.rb +13 -0
  71. data/lib/gooddata/models/segment.rb +63 -16
  72. data/lib/gooddata/models/style_setting.rb +2 -15
  73. data/lib/gooddata/models/user_group.rb +2 -0
  74. data/lib/gooddata/rest/connection.rb +32 -9
  75. data/lib/gooddata/rest/object_factory.rb +0 -25
  76. data/lib/gooddata/version.rb +1 -1
  77. data/spec/data/blueprints/invalid_blueprint.json +2 -2
  78. data/spec/data/blueprints/test_project_model_spec.json +1 -1
  79. data/spec/data/dynamic_schedule_params_table.csv +7 -0
  80. data/spec/data/workspace_table.csv +3 -3
  81. data/spec/environment/staging.rb +3 -3
  82. data/spec/integration/ads_output_stage_spec.rb +0 -10
  83. data/spec/integration/clients_spec.rb +1 -1
  84. data/spec/{unit → integration}/commands/command_projects_spec.rb +0 -0
  85. data/spec/{unit → integration}/core/connection_spec.rb +0 -0
  86. data/spec/{unit → integration}/core/logging_spec.rb +0 -0
  87. data/spec/{unit → integration}/core/project_spec.rb +0 -0
  88. data/spec/integration/date_dim_switch_spec.rb +13 -0
  89. data/spec/integration/full_process_schedule_spec.rb +2 -2
  90. data/spec/integration/helpers_spec.rb +16 -0
  91. data/spec/integration/lcm_spec.rb +12 -2
  92. data/spec/integration/mixins/id_to_uri_spec.rb +44 -0
  93. data/spec/integration/models/data_product_spec.rb +71 -0
  94. data/spec/{unit → integration}/models/domain_spec.rb +2 -2
  95. data/spec/{unit → integration}/models/invitation_spec.rb +0 -0
  96. data/spec/{unit → integration}/models/membership_spec.rb +0 -0
  97. data/spec/{unit → integration}/models/params_spec.rb +0 -0
  98. data/spec/{unit → integration}/models/profile_spec.rb +0 -0
  99. data/spec/{unit → integration}/models/project_role_spec.rb +0 -0
  100. data/spec/integration/models/project_spec.rb +225 -0
  101. data/spec/{unit → integration}/models/schedule_spec.rb +0 -0
  102. data/spec/{unit → integration}/models/unit_project_spec.rb +0 -0
  103. data/spec/integration/project_spec.rb +40 -5
  104. data/spec/integration/segments_spec.rb +27 -26
  105. data/spec/integration/user_filters_spec.rb +1 -1
  106. data/spec/spec_helper.rb +15 -19
  107. data/spec/unit/actions/associate_clients_spec.rb +47 -0
  108. data/spec/unit/actions/collect_client_projects_spec.rb +47 -0
  109. data/spec/unit/actions/collect_clients_spec.rb +27 -0
  110. data/spec/unit/actions/collect_data_product_spec.rb +64 -0
  111. data/spec/unit/actions/collect_dynamic_schedule_params_spec.rb +56 -0
  112. data/spec/unit/actions/collect_meta_spec.rb +4 -4
  113. data/spec/unit/actions/collect_segment_clients_spec.rb +44 -3
  114. data/spec/unit/actions/collect_tagged_objects_spec.rb +20 -4
  115. data/spec/unit/actions/create_segment_masters_spec.rb +64 -0
  116. data/spec/unit/actions/ensure_data_product_spec.rb +38 -0
  117. data/spec/unit/actions/ensure_technical_users_domain_spec.rb +51 -0
  118. data/spec/unit/actions/ensure_technical_users_project_spec.rb +72 -0
  119. data/spec/unit/actions/execute_schedules_spec.rb +94 -0
  120. data/spec/unit/actions/provision_clients_spec.rb +45 -0
  121. data/spec/unit/actions/purge_clients_spec.rb +47 -0
  122. data/spec/unit/actions/rename_existing_client_projects_spec.rb +54 -0
  123. data/spec/unit/actions/segments_filter_spec.rb +46 -0
  124. data/spec/unit/actions/shared_examples_for_user_actions.rb +10 -0
  125. data/spec/unit/actions/synchronize_cas_spec.rb +58 -0
  126. data/spec/unit/actions/synchronize_etls_in_segment_spec.rb +174 -13
  127. data/spec/unit/actions/synchronize_ldm_spec.rb +57 -0
  128. data/spec/unit/actions/synchronize_user_filters_spec.rb +142 -0
  129. data/spec/unit/actions/synchronize_user_groups_spec.rb +49 -0
  130. data/spec/unit/actions/synchronize_users_spec.rb +76 -0
  131. data/spec/unit/helpers/data_helper_spec.rb +17 -0
  132. data/spec/unit/helpers/global_helpers_spec.rb +16 -0
  133. data/spec/unit/helpers_spec.rb +0 -6
  134. data/spec/unit/models/blueprint/project_blueprint_spec.rb +21 -4
  135. data/spec/unit/models/project_creator_spec.rb +16 -0
  136. data/spec/unit/models/project_spec.rb +66 -197
  137. metadata +202 -100
  138. data/PULL_REQUEST_TEMPLATE.md +0 -5
  139. data/lib/gooddata/bricks/middleware/params_inspect_middleware.rb +0 -21
@@ -0,0 +1,10 @@
1
+ shared_examples 'a user action' do
2
+ before do
3
+ allow(File).to receive(:open).and_return("client_id\n#{client_id}")
4
+ end
5
+
6
+ it 'uses client_id column' do
7
+ expect(domain).to receive(:clients).with(client_id, nil)
8
+ subject.class.call(params)
9
+ end
10
+ end
@@ -0,0 +1,58 @@
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
+ shared_examples 'a computed attributes synchronizer' do
8
+ it 'it synchronizes computed attributes' do
9
+ expect(project).to receive(:execute_maql).with('expected_maql')
10
+ result = subject.class.call(converted_params)
11
+ expect(result).not_to be_empty
12
+ end
13
+ end
14
+
15
+ describe GoodData::LCM2::SynchronizeComputedAttributes do
16
+ let(:gdc_gd_client) { double(GoodData::Rest::Client) }
17
+ let(:logger) { double(Logger) }
18
+ let(:project) { double(GoodData::Project) }
19
+ let(:synchronize) do
20
+ [{ from: 'foo', to: [{ ca_scripts: { 'maqlDdlChunks' => ['expected_maql'] } }] }]
21
+ end
22
+ let(:basic_params) do
23
+ {
24
+ gdc_gd_client: gdc_gd_client,
25
+ development_client: gdc_gd_client,
26
+ synchronize: synchronize,
27
+ gdc_logger: logger
28
+ }
29
+ end
30
+ let(:converted_params) do
31
+ GoodData::LCM2.convert_to_smart_hash(params)
32
+ end
33
+
34
+ before do
35
+ allow(gdc_gd_client).to receive(:projects).and_return(project)
36
+ allow(project).to receive(:title)
37
+ allow(project).to receive(:pid)
38
+ allow(logger).to receive(:info)
39
+ end
40
+
41
+ context 'when include_computed_attributes is not specified' do
42
+ let(:params) { basic_params }
43
+ it_behaves_like 'a computed attributes synchronizer'
44
+ end
45
+
46
+ context 'when include_computed_attributes is true' do
47
+ let(:params) { basic_params.merge(include_computed_attributes: 'true') }
48
+ it_behaves_like 'a computed attributes synchronizer'
49
+ end
50
+
51
+ context 'when include_computed_attributes is false' do
52
+ let(:params) { basic_params.merge(include_computed_attributes: 'false') }
53
+ it 'it does not synchronize computed attributes' do
54
+ result = subject.class.call(converted_params)
55
+ expect(result).to be_empty
56
+ end
57
+ end
58
+ end
@@ -11,6 +11,38 @@ describe GoodData::LCM2::SynchronizeETLsInSegment do
11
11
  let(:gdc_gd_client) { double('gdc_gd_client') }
12
12
  let(:domain) { double('domain') }
13
13
  let(:segment) { double('segment') }
14
+ let(:project) { double('project') }
15
+ let(:result) { { syncedResult: {} } }
16
+ let(:client_id) { 'foo_client' }
17
+ let(:data_product) { double('data_product') }
18
+ let(:params) do
19
+ params = {
20
+ gdc_gd_client: gdc_gd_client,
21
+ organization: domain,
22
+ synchronize: [{
23
+ segment_id: 'some_segment_ids',
24
+ to: [{ pid: 'foo', client_id: client_id }]
25
+ }],
26
+ data_product: data_product
27
+ }
28
+ GoodData::LCM2.convert_to_smart_hash(params)
29
+ end
30
+
31
+ before do
32
+ allow(gdc_gd_client).to receive(:domain) { domain }
33
+ allow(gdc_gd_client).to receive(:projects) { project }
34
+ allow(project).to receive(:schedules) { [] }
35
+ allow(data_product).to receive(:segments) { [segment] }
36
+ allow(segment).to receive(:synchronize_processes) { result }
37
+ allow(project).to receive(:set_metadata)
38
+ allow(segment).to receive(:segment_id) { 'some_segment_ids' }
39
+ end
40
+
41
+ it 'adds GOODOT_CUSTOM_PROJECT_ID to metadata' do
42
+ expect(project).to receive(:set_metadata)
43
+ .with('GOODOT_CUSTOM_PROJECT_ID', client_id)
44
+ subject.class.call(params)
45
+ end
14
46
 
15
47
  context 'when sync processes/schedules has problem' do
16
48
  let(:result) do
@@ -28,24 +60,153 @@ describe GoodData::LCM2::SynchronizeETLsInSegment do
28
60
  }
29
61
  end
30
62
 
31
- let(:params) do
32
- params = {
33
- gdc_gd_client: gdc_gd_client,
34
- organization: domain,
35
- synchronize: [{ segment_id: 'some_segment_ids' }]
36
-
37
- }
38
- GoodData::LCM2.convert_to_smart_hash(params)
63
+ it 'raise error' do
64
+ expect { subject.class.call(params) }.to raise_error
39
65
  end
66
+ end
67
+
68
+ context 'when user passes dynamic schedule parameters' do
69
+ let(:project) { double(:project) }
70
+ let(:schedule1) { double(:schedule1) }
71
+ let(:schedule2) { double(:schedule2) }
40
72
 
41
73
  before do
42
- allow(gdc_gd_client).to receive(:domain) { domain }
43
- allow(domain).to receive(:segments) { segment }
44
- allow(segment).to receive(:synchronize_processes) { result }
74
+ allow(segment).to receive(:synchronize_processes).and_return(
75
+ syncedResult: {
76
+ clients: [
77
+ client: {
78
+ id: 'foo',
79
+ project: 'bar'
80
+ }
81
+ ]
82
+ }
83
+ )
84
+ allow(segment).to receive(:master_project_id)
85
+ allow(schedule1).to receive(:update_hidden_params)
86
+ allow(schedule1).to receive(:enable)
87
+ allow(schedule1).to receive(:save)
88
+ allow(schedule1).to receive(:name) { 'Schedule1' }
89
+ allow(schedule2).to receive(:update_hidden_params)
90
+ allow(schedule2).to receive(:enable)
91
+ allow(schedule2).to receive(:save)
92
+ allow(schedule2).to receive(:name) { 'Schedule2' }
93
+ allow(project).to receive(:schedules) { [schedule1, schedule2] }
94
+ allow(gdc_gd_client).to receive(:projects) { project }
45
95
  end
46
96
 
47
- it 'raise error' do
48
- expect { subject.class.call(params) }.to raise_error
97
+ context 'to each schedules' do
98
+ let(:params) do
99
+ params = {
100
+ gdc_gd_client: gdc_gd_client,
101
+ organization: domain,
102
+ synchronize: [
103
+ {
104
+ segment_id: 'some_segment_ids',
105
+ from: 'from project',
106
+ to: [
107
+ pid: '123',
108
+ client_id: 'foo'
109
+ ]
110
+ }
111
+ ],
112
+ schedule_params: {
113
+ all_clients: {
114
+ 'Schedule1' => {
115
+ 'HELLO' => 'hi'
116
+ },
117
+ 'Schedule2' => {
118
+ 'BYE' => 'bye'
119
+ }
120
+ }
121
+ },
122
+ data_product: data_product
123
+ }
124
+ GoodData::LCM2.convert_to_smart_hash(params)
125
+ end
126
+
127
+ it 'each schedules must have different parameters' do
128
+ schedule1.should_receive(:update_params).once.ordered.with(CLIENT_ID: 'foo', GOODOT_CUSTOM_PROJECT_ID: 'foo')
129
+ schedule1.should_receive(:update_params).once.ordered.with('HELLO' => 'hi')
130
+ schedule2.should_receive(:update_params).once.ordered.with(CLIENT_ID: 'foo', GOODOT_CUSTOM_PROJECT_ID: 'foo')
131
+ schedule2.should_receive(:update_params).once.ordered.with('BYE' => 'bye')
132
+ subject.class.call(params)
133
+ end
134
+ end
135
+
136
+ context 'to all schedules' do
137
+ let(:params) do
138
+ params = {
139
+ gdc_gd_client: gdc_gd_client,
140
+ organization: domain,
141
+ synchronize: [
142
+ {
143
+ segment_id: 'some_segment_ids',
144
+ from: 'from project',
145
+ to: [
146
+ pid: '123',
147
+ client_id: 'foo'
148
+ ]
149
+ }
150
+ ],
151
+ schedule_params: {
152
+ all_clients: {
153
+ all_schedules: {
154
+ 'HELLO' => 'hi'
155
+ }
156
+ }
157
+ },
158
+ data_product: data_product
159
+ }
160
+ GoodData::LCM2.convert_to_smart_hash(params)
161
+ end
162
+
163
+ it 'all schedules must have the parameter' do
164
+ schedule1.should_receive(:update_params).once.ordered.with(CLIENT_ID: 'foo', GOODOT_CUSTOM_PROJECT_ID: 'foo')
165
+ schedule1.should_receive(:update_params).once.ordered.with('HELLO' => 'hi')
166
+ schedule2.should_receive(:update_params).once.ordered.with(CLIENT_ID: 'foo', GOODOT_CUSTOM_PROJECT_ID: 'foo')
167
+ schedule2.should_receive(:update_params).once.ordered.with('HELLO' => 'hi')
168
+ subject.class.call(params)
169
+ end
170
+ end
171
+
172
+ context 'to each schedules in each clients' do
173
+ let(:params) do
174
+ params = {
175
+ gdc_gd_client: gdc_gd_client,
176
+ organization: domain,
177
+ synchronize: [
178
+ {
179
+ segment_id: 'some_segment_ids',
180
+ from: 'from project',
181
+ to: [
182
+ pid: '123',
183
+ client_id: 'foo'
184
+ ]
185
+ }
186
+ ],
187
+ schedule_params: {
188
+ 'foo' => {
189
+ 'Schedule1' => {
190
+ 'HELLO' => 'hi'
191
+ }
192
+ },
193
+ 'bar' => {
194
+ 'Schedule2' => {
195
+ 'BYE' => 'bye'
196
+ }
197
+ }
198
+ },
199
+ data_product: data_product
200
+ }
201
+ GoodData::LCM2.convert_to_smart_hash(params)
202
+ end
203
+
204
+ it 'parameters should be passed to the correct client project and schedule' do
205
+ schedule1.should_receive(:update_params).once.ordered.with(CLIENT_ID: 'foo', GOODOT_CUSTOM_PROJECT_ID: 'foo')
206
+ schedule1.should_receive(:update_params).once.ordered.with('HELLO' => 'hi')
207
+ schedule2.should_receive(:update_params).once.ordered.with(CLIENT_ID: 'foo', GOODOT_CUSTOM_PROJECT_ID: 'foo')
208
+ subject.class.call(params)
209
+ end
49
210
  end
50
211
  end
51
212
  end
@@ -0,0 +1,57 @@
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
+ shared_examples 'a computed attributes synchronizer' do
8
+ it 'diffs LDM with computed attributes' do
9
+ expect(project).to receive(:blueprint).with(include_ca: true)
10
+ subject.class.call(converted_params)
11
+ end
12
+ end
13
+
14
+ describe GoodData::LCM2::SynchronizeLdm do
15
+ let(:gdc_gd_client) { double(GoodData::Rest::Client) }
16
+ let(:logger) { double(Logger) }
17
+ let(:project) { double(GoodData::Project) }
18
+ let(:synchronize) do
19
+ [{ from: 'foo', to: [] }]
20
+ end
21
+ let(:basic_params) do
22
+ {
23
+ gdc_gd_client: gdc_gd_client,
24
+ development_client: gdc_gd_client,
25
+ synchronize: synchronize,
26
+ gdc_logger: logger
27
+ }
28
+ end
29
+ let(:converted_params) do
30
+ GoodData::LCM2.convert_to_smart_hash(params)
31
+ end
32
+
33
+ before do
34
+ allow(gdc_gd_client).to receive(:projects).and_return(project)
35
+ allow(project).to receive(:title)
36
+ allow(project).to receive(:pid)
37
+ allow(logger).to receive(:info)
38
+ end
39
+
40
+ context 'when include_computed_attributes is not specified' do
41
+ let(:params) { basic_params }
42
+ it_behaves_like 'a computed attributes synchronizer'
43
+ end
44
+
45
+ context 'when include_computed_attributes is true' do
46
+ let(:params) { basic_params.merge(include_computed_attributes: 'true') }
47
+ it_behaves_like 'a computed attributes synchronizer'
48
+ end
49
+
50
+ context 'when include_computed_attributes is false' do
51
+ let(:params) { basic_params.merge(include_computed_attributes: 'false') }
52
+ it 'diffs LDM without computed attributes' do
53
+ expect(project).to receive(:blueprint).with(include_ca: false)
54
+ subject.class.call(converted_params)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,142 @@
1
+ require 'active_support/core_ext/hash'
2
+ require 'gooddata/lcm/lcm2'
3
+
4
+ require_relative 'shared_examples_for_user_actions'
5
+
6
+ describe GoodData::LCM2::SynchronizeUserFilters do
7
+ let(:client) { double('client') }
8
+ let(:user) { double('user') }
9
+ let(:data_source) { double('user') }
10
+ let(:domain) { double('domain') }
11
+ let(:project) { double('project') }
12
+ let(:organization) { double('organization') }
13
+ let(:logger) { double(Logger) }
14
+
15
+ before do
16
+ allow(client).to receive(:projects).and_return(project)
17
+ allow(client).to receive(:domain).and_return(domain)
18
+ allow(organization).to receive(:project_uri)
19
+ allow(project).to receive(:add_data_permissions).and_return([{}])
20
+ allow(project).to receive(:pid).and_return('123456789')
21
+ allow(user).to receive(:login).and_return('my_login')
22
+ allow(GoodData::Helpers::DataSource).to receive(:new).and_return(data_source)
23
+ allow(logger).to receive(:warn)
24
+ end
25
+
26
+ context 'when multiple_projects_column not specified' do
27
+ before do
28
+ allow(project).to receive(:metadata).and_return({})
29
+ allow(project).to receive(:uri)
30
+ allow(data_source).to receive(:realize)
31
+ allow(organization).to receive(:id).and_return('client123')
32
+ allow(organization).to receive(:project).and_return(project)
33
+ end
34
+ context 'when mode requires client_id' do
35
+ before do
36
+ allow(domain).to receive(:clients).and_return(organization)
37
+ end
38
+ let(:mode) { 'sync_multiple_projects_based_on_custom_id' }
39
+ let(:params) do
40
+ params = {
41
+ GDC_GD_CLIENT: client,
42
+ input_source: 'foo',
43
+ domain: 'bar',
44
+ filters_config: { labels: [] },
45
+ sync_mode: mode,
46
+ gdc_logger: logger
47
+ }
48
+ GoodData::LCM2.convert_to_smart_hash(params)
49
+ end
50
+
51
+ it_behaves_like 'a user action' do
52
+ let(:client_id) { '123456789' }
53
+ end
54
+
55
+ context 'when mode is sync_domain_client_workspaces' do
56
+ let(:mode) { 'sync_domain_client_workspaces' }
57
+ let(:clients) { [] }
58
+ before do
59
+ allow(domain).to receive(:clients).with(:all, nil).and_return([organization])
60
+ allow(domain).to receive(:clients).with(123_456_789).and_return(organization)
61
+ allow(organization).to receive(:project).and_return(project)
62
+ allow(organization).to receive(:client_id).and_return(123_456_789)
63
+ allow(File).to receive(:open).and_return("client_id\n123456789")
64
+ allow(project).to receive(:deleted?).and_return false
65
+ end
66
+ it 'returns results' do
67
+ result = subject.class.call(params)
68
+ expect(result).to eq(results: [[{}]])
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'when using sync_one_project_based_on_custom_id mode with multiple_projects_column' do
75
+ let(:params) do
76
+ params = {
77
+ GDC_GD_CLIENT: client,
78
+ input_source: 'foo',
79
+ domain: 'bar',
80
+ filters_config: { labels: [] },
81
+ multiple_projects_column: 'id_column',
82
+ sync_mode: 'sync_one_project_based_on_custom_id',
83
+ gdc_logger: logger
84
+ }
85
+ GoodData::LCM2.convert_to_smart_hash(params)
86
+ end
87
+ let(:CSV) { double('CSV') }
88
+
89
+ before do
90
+ allow(project).to receive(:metadata).and_return(
91
+ 'GOODOT_CUSTOM_PROJECT_ID' => 'project-123'
92
+ )
93
+ allow(project).to receive(:uri).and_return('project-uri')
94
+ allow(project).to receive(:add_data_permissions)
95
+ allow(domain).to receive(:clients).and_return([])
96
+ allow(data_source).to receive(:realize).and_return('filepath')
97
+ end
98
+
99
+ context 'when params do not match client data in domain' do
100
+ before do
101
+ allow(project).to receive(:metadata).and_return({})
102
+ allow(project).to receive(:uri).and_return('project-uri')
103
+ allow(domain).to receive(:clients).and_return([])
104
+ end
105
+
106
+ it 'fails when unable to get filter value for selecting filters' do
107
+ expect { subject.class.call(params) }.to raise_exception(/does not contain key GOODOT_CUSTOM_PROJECT_ID/)
108
+ end
109
+ end
110
+
111
+ context 'when params match a client in the domain' do
112
+ it 'adds filters matching the client' do
113
+ expect(File).to receive(:open)
114
+ csv_data = [
115
+ {
116
+ 'id_column' => 'project-123'
117
+ },
118
+ {
119
+ 'id_column' => 'another-project'
120
+ }
121
+ ]
122
+ expect(CSV).to receive(:foreach).and_yield(csv_data[0]).and_yield(csv_data[1])
123
+ expect(GoodData::UserFilterBuilder).to receive(:get_filters) do |filters, _|
124
+ filters.each do |filter|
125
+ expect(filter['id_column']).to eq 'project-123'
126
+ end
127
+ end
128
+ subject.class.call(params)
129
+ end
130
+ end
131
+
132
+ context 'when the input set does not contain data for the current project' do
133
+ it 'does not fail and logs a warning' do
134
+ expect(File).to receive(:open)
135
+ expect(CSV).to receive(:foreach).and_yield({})
136
+ expect(project).to receive(:add_data_permissions)
137
+ expect(logger).to receive(:warn)
138
+ expect { subject.class.call(params) }.to_not raise_error
139
+ end
140
+ end
141
+ end
142
+ end