cumulusci-plus 5.0.24__py3-none-any.whl → 5.0.26__py3-none-any.whl
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.
Potentially problematic release.
This version of cumulusci-plus might be problematic. Click here for more details.
- cumulusci/__about__.py +1 -1
- cumulusci/cli/task.py +17 -0
- cumulusci/cli/tests/test_error.py +3 -1
- cumulusci/cli/tests/test_task.py +88 -2
- cumulusci/core/github.py +1 -1
- cumulusci/core/sfdx.py +3 -1
- cumulusci/cumulusci.yml +20 -0
- cumulusci/robotframework/pageobjects/ObjectManagerPageObject.py +1 -1
- cumulusci/salesforce_api/rest_deploy.py +1 -1
- cumulusci/tasks/apex/anon.py +1 -1
- cumulusci/tasks/apex/testrunner.py +6 -1
- cumulusci/tasks/bulkdata/extract.py +0 -1
- cumulusci/tasks/bulkdata/tests/test_load.py +0 -2
- cumulusci/tasks/bulkdata/tests/test_select_utils.py +6 -0
- cumulusci/tasks/metadata_etl/base.py +7 -3
- cumulusci/tasks/push/README.md +15 -17
- cumulusci/tasks/release_notes/README.md +13 -13
- cumulusci/tasks/robotframework/tests/test_robotframework.py +1 -1
- cumulusci/tasks/salesforce/Deploy.py +5 -1
- cumulusci/tasks/salesforce/composite.py +1 -1
- cumulusci/tasks/salesforce/custom_settings_wait.py +1 -1
- cumulusci/tasks/salesforce/enable_prediction.py +5 -1
- cumulusci/tasks/salesforce/sourcetracking.py +1 -1
- cumulusci/tasks/salesforce/tests/test_update_external_credential.py +912 -0
- cumulusci/tasks/salesforce/tests/test_update_named_credential.py +1042 -0
- cumulusci/tasks/salesforce/update_external_credential.py +562 -0
- cumulusci/tasks/salesforce/update_named_credential.py +441 -0
- cumulusci/tasks/salesforce/update_profile.py +17 -13
- cumulusci/tasks/salesforce/users/permsets.py +70 -2
- cumulusci/tasks/salesforce/users/tests/test_permsets.py +184 -0
- cumulusci/tasks/sfdmu/__init__.py +0 -0
- cumulusci/tasks/sfdmu/sfdmu.py +256 -0
- cumulusci/tasks/sfdmu/tests/__init__.py +1 -0
- cumulusci/tasks/sfdmu/tests/test_runner.py +212 -0
- cumulusci/tasks/sfdmu/tests/test_sfdmu.py +443 -0
- cumulusci/tasks/utility/credentialManager.py +256 -0
- cumulusci/tasks/utility/directoryRecreator.py +30 -0
- cumulusci/tasks/utility/secretsToEnv.py +130 -0
- cumulusci/tasks/utility/tests/test_credentialManager.py +564 -0
- cumulusci/tasks/utility/tests/test_directoryRecreator.py +439 -0
- cumulusci/tasks/utility/tests/test_secretsToEnv.py +1091 -0
- cumulusci/utils/__init__.py +23 -1
- cumulusci/utils/http/tests/cassettes/ManualEditTestCompositeParallelSalesforce.test_http_headers.yaml +31 -30
- cumulusci/utils/yaml/tests/test_model_parser.py +2 -2
- {cumulusci_plus-5.0.24.dist-info → cumulusci_plus-5.0.26.dist-info}/METADATA +7 -9
- {cumulusci_plus-5.0.24.dist-info → cumulusci_plus-5.0.26.dist-info}/RECORD +50 -35
- {cumulusci_plus-5.0.24.dist-info → cumulusci_plus-5.0.26.dist-info}/WHEEL +0 -0
- {cumulusci_plus-5.0.24.dist-info → cumulusci_plus-5.0.26.dist-info}/entry_points.txt +0 -0
- {cumulusci_plus-5.0.24.dist-info → cumulusci_plus-5.0.26.dist-info}/licenses/AUTHORS.rst +0 -0
- {cumulusci_plus-5.0.24.dist-info → cumulusci_plus-5.0.26.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
"""Tests for SFDmu task."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import tempfile
|
|
5
|
+
from unittest import mock
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
from cumulusci.tasks.salesforce.tests.util import create_task
|
|
10
|
+
from cumulusci.tasks.sfdmu.sfdmu import SfdmuTask
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TestSfdmuTask:
|
|
14
|
+
"""Test cases for SfdmuTask."""
|
|
15
|
+
|
|
16
|
+
def test_init_options_validates_path(self):
|
|
17
|
+
"""Test that _init_options validates the path exists and contains export.json."""
|
|
18
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
19
|
+
# Create export.json file
|
|
20
|
+
export_json_path = os.path.join(temp_dir, "export.json")
|
|
21
|
+
with open(export_json_path, "w") as f:
|
|
22
|
+
f.write('{"test": "data"}')
|
|
23
|
+
|
|
24
|
+
# Test valid path using create_task helper
|
|
25
|
+
task = create_task(
|
|
26
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": temp_dir}
|
|
27
|
+
)
|
|
28
|
+
assert task.options["path"] == os.path.abspath(temp_dir)
|
|
29
|
+
|
|
30
|
+
def test_init_options_raises_error_for_missing_path(self):
|
|
31
|
+
"""Test that _init_options raises error for missing path."""
|
|
32
|
+
with pytest.raises(Exception): # TaskOptionsError
|
|
33
|
+
create_task(
|
|
34
|
+
SfdmuTask,
|
|
35
|
+
{"source": "dev", "target": "qa", "path": "/nonexistent/path"},
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def test_init_options_raises_error_for_missing_export_json(self):
|
|
39
|
+
"""Test that _init_options raises error for missing export.json."""
|
|
40
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
41
|
+
with pytest.raises(Exception): # TaskOptionsError
|
|
42
|
+
create_task(
|
|
43
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": temp_dir}
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def test_validate_org_csvfile(self):
|
|
47
|
+
"""Test that _validate_org returns None for csvfile."""
|
|
48
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
49
|
+
# Create export.json file
|
|
50
|
+
export_json_path = os.path.join(temp_dir, "export.json")
|
|
51
|
+
with open(export_json_path, "w") as f:
|
|
52
|
+
f.write('{"test": "data"}')
|
|
53
|
+
|
|
54
|
+
task = create_task(
|
|
55
|
+
SfdmuTask, {"source": "csvfile", "target": "csvfile", "path": temp_dir}
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
result = task._validate_org("csvfile")
|
|
59
|
+
assert result is None
|
|
60
|
+
|
|
61
|
+
def test_validate_org_missing_keychain(self):
|
|
62
|
+
"""Test that _validate_org raises error when keychain is None."""
|
|
63
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
64
|
+
# Create export.json file
|
|
65
|
+
export_json_path = os.path.join(temp_dir, "export.json")
|
|
66
|
+
with open(export_json_path, "w") as f:
|
|
67
|
+
f.write('{"test": "data"}')
|
|
68
|
+
|
|
69
|
+
task = create_task(
|
|
70
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": temp_dir}
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Mock the keychain to be None
|
|
74
|
+
task.project_config.keychain = None
|
|
75
|
+
|
|
76
|
+
with pytest.raises(Exception): # TaskOptionsError
|
|
77
|
+
task._validate_org("dev")
|
|
78
|
+
|
|
79
|
+
def test_get_sf_org_name_sfdx_alias(self):
|
|
80
|
+
"""Test _get_sf_org_name with sfdx_alias."""
|
|
81
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
82
|
+
# Create export.json file
|
|
83
|
+
export_json_path = os.path.join(temp_dir, "export.json")
|
|
84
|
+
with open(export_json_path, "w") as f:
|
|
85
|
+
f.write('{"test": "data"}')
|
|
86
|
+
|
|
87
|
+
task = create_task(
|
|
88
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": temp_dir}
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
mock_org_config = mock.Mock()
|
|
92
|
+
mock_org_config.sfdx_alias = "test_alias"
|
|
93
|
+
mock_org_config.username = "test@example.com"
|
|
94
|
+
|
|
95
|
+
result = task._get_sf_org_name(mock_org_config)
|
|
96
|
+
assert result == "test_alias"
|
|
97
|
+
|
|
98
|
+
def test_get_sf_org_name_username(self):
|
|
99
|
+
"""Test _get_sf_org_name with username fallback."""
|
|
100
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
101
|
+
# Create export.json file
|
|
102
|
+
export_json_path = os.path.join(temp_dir, "export.json")
|
|
103
|
+
with open(export_json_path, "w") as f:
|
|
104
|
+
f.write('{"test": "data"}')
|
|
105
|
+
|
|
106
|
+
task = create_task(
|
|
107
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": temp_dir}
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
mock_org_config = mock.Mock()
|
|
111
|
+
mock_org_config.sfdx_alias = None
|
|
112
|
+
mock_org_config.username = "test@example.com"
|
|
113
|
+
|
|
114
|
+
result = task._get_sf_org_name(mock_org_config)
|
|
115
|
+
assert result == "test@example.com"
|
|
116
|
+
|
|
117
|
+
def test_create_execute_directory(self):
|
|
118
|
+
"""Test _create_execute_directory creates directory and copies files."""
|
|
119
|
+
with tempfile.TemporaryDirectory() as base_dir:
|
|
120
|
+
# Create test files
|
|
121
|
+
export_json = os.path.join(base_dir, "export.json")
|
|
122
|
+
test_csv = os.path.join(base_dir, "test.csv")
|
|
123
|
+
test_txt = os.path.join(base_dir, "test.txt") # Should not be copied
|
|
124
|
+
|
|
125
|
+
with open(export_json, "w") as f:
|
|
126
|
+
f.write('{"test": "data"}')
|
|
127
|
+
with open(test_csv, "w") as f:
|
|
128
|
+
f.write("col1,col2\nval1,val2")
|
|
129
|
+
with open(test_txt, "w") as f:
|
|
130
|
+
f.write("text file")
|
|
131
|
+
|
|
132
|
+
# Create subdirectory (should not be copied)
|
|
133
|
+
subdir = os.path.join(base_dir, "subdir")
|
|
134
|
+
os.makedirs(subdir)
|
|
135
|
+
with open(os.path.join(subdir, "file.txt"), "w") as f:
|
|
136
|
+
f.write("subdir file")
|
|
137
|
+
|
|
138
|
+
task = create_task(
|
|
139
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": base_dir}
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
execute_path = task._create_execute_directory(base_dir)
|
|
143
|
+
|
|
144
|
+
# Check that execute directory was created
|
|
145
|
+
assert os.path.exists(execute_path)
|
|
146
|
+
assert execute_path == os.path.join(base_dir, "execute")
|
|
147
|
+
|
|
148
|
+
# Check that files were copied
|
|
149
|
+
assert os.path.exists(os.path.join(execute_path, "export.json"))
|
|
150
|
+
assert os.path.exists(os.path.join(execute_path, "test.csv"))
|
|
151
|
+
assert not os.path.exists(
|
|
152
|
+
os.path.join(execute_path, "test.txt")
|
|
153
|
+
) # Not a valid file type
|
|
154
|
+
assert not os.path.exists(
|
|
155
|
+
os.path.join(execute_path, "subdir")
|
|
156
|
+
) # Not a file
|
|
157
|
+
|
|
158
|
+
# Check file contents
|
|
159
|
+
with open(os.path.join(execute_path, "export.json"), "r") as f:
|
|
160
|
+
assert f.read() == '{"test": "data"}'
|
|
161
|
+
with open(os.path.join(execute_path, "test.csv"), "r") as f:
|
|
162
|
+
assert f.read() == "col1,col2\nval1,val2"
|
|
163
|
+
|
|
164
|
+
def test_create_execute_directory_removes_existing(self):
|
|
165
|
+
"""Test that _create_execute_directory removes existing execute directory."""
|
|
166
|
+
with tempfile.TemporaryDirectory() as base_dir:
|
|
167
|
+
# Create existing execute directory with files
|
|
168
|
+
execute_dir = os.path.join(base_dir, "execute")
|
|
169
|
+
os.makedirs(execute_dir)
|
|
170
|
+
with open(os.path.join(execute_dir, "old_file.json"), "w") as f:
|
|
171
|
+
f.write('{"old": "data"}')
|
|
172
|
+
|
|
173
|
+
# Create export.json in base directory
|
|
174
|
+
export_json = os.path.join(base_dir, "export.json")
|
|
175
|
+
with open(export_json, "w") as f:
|
|
176
|
+
f.write('{"test": "data"}')
|
|
177
|
+
|
|
178
|
+
task = create_task(
|
|
179
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": base_dir}
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
execute_path = task._create_execute_directory(base_dir)
|
|
183
|
+
|
|
184
|
+
# Check that old file was removed
|
|
185
|
+
assert not os.path.exists(os.path.join(execute_path, "old_file.json"))
|
|
186
|
+
# Check that new file was copied
|
|
187
|
+
assert os.path.exists(os.path.join(execute_path, "export.json"))
|
|
188
|
+
|
|
189
|
+
def test_inject_namespace_tokens_csvfile_target(self):
|
|
190
|
+
"""Test that namespace injection is skipped when target is csvfile."""
|
|
191
|
+
with tempfile.TemporaryDirectory() as execute_dir:
|
|
192
|
+
# Create test files
|
|
193
|
+
test_json = os.path.join(execute_dir, "test.json")
|
|
194
|
+
with open(test_json, "w") as f:
|
|
195
|
+
f.write('{"field": "%%%NAMESPACE%%%Test"}')
|
|
196
|
+
|
|
197
|
+
# Create export.json file
|
|
198
|
+
export_json_path = os.path.join(execute_dir, "export.json")
|
|
199
|
+
with open(export_json_path, "w") as f:
|
|
200
|
+
f.write('{"test": "data"}')
|
|
201
|
+
|
|
202
|
+
task = create_task(
|
|
203
|
+
SfdmuTask, {"source": "dev", "target": "csvfile", "path": execute_dir}
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
# Should not raise any errors and files should remain unchanged
|
|
207
|
+
task._inject_namespace_tokens(execute_dir, None)
|
|
208
|
+
|
|
209
|
+
# Check that file content was not changed
|
|
210
|
+
with open(test_json, "r") as f:
|
|
211
|
+
assert f.read() == '{"field": "%%%NAMESPACE%%%Test"}'
|
|
212
|
+
|
|
213
|
+
@mock.patch("cumulusci.tasks.sfdmu.sfdmu.determine_managed_mode")
|
|
214
|
+
def test_inject_namespace_tokens_managed_mode(self, mock_determine_managed):
|
|
215
|
+
"""Test namespace injection in managed mode."""
|
|
216
|
+
mock_determine_managed.return_value = True
|
|
217
|
+
|
|
218
|
+
with tempfile.TemporaryDirectory() as execute_dir:
|
|
219
|
+
# Create test files with namespace tokens
|
|
220
|
+
test_json = os.path.join(execute_dir, "test.json")
|
|
221
|
+
test_csv = os.path.join(execute_dir, "test.csv")
|
|
222
|
+
|
|
223
|
+
with open(test_json, "w") as f:
|
|
224
|
+
f.write(
|
|
225
|
+
'{"field": "%%%NAMESPACE%%%Test", "org": "%%%NAMESPACED_ORG%%%Value"}'
|
|
226
|
+
)
|
|
227
|
+
with open(test_csv, "w") as f:
|
|
228
|
+
f.write("Name,%%%NAMESPACE%%%Field\nTest,Value")
|
|
229
|
+
|
|
230
|
+
# Create filename with namespace token
|
|
231
|
+
filename_with_token = os.path.join(execute_dir, "___NAMESPACE___test.json")
|
|
232
|
+
with open(filename_with_token, "w") as f:
|
|
233
|
+
f.write('{"test": "data"}')
|
|
234
|
+
|
|
235
|
+
# Create export.json file
|
|
236
|
+
export_json_path = os.path.join(execute_dir, "export.json")
|
|
237
|
+
with open(export_json_path, "w") as f:
|
|
238
|
+
f.write('{"test": "data"}')
|
|
239
|
+
|
|
240
|
+
task = create_task(
|
|
241
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": execute_dir}
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# Mock the project config namespace
|
|
245
|
+
task.project_config.project__package__namespace = "testns"
|
|
246
|
+
|
|
247
|
+
mock_org_config = mock.Mock()
|
|
248
|
+
mock_org_config.namespace = "testns"
|
|
249
|
+
|
|
250
|
+
task._inject_namespace_tokens(execute_dir, mock_org_config)
|
|
251
|
+
|
|
252
|
+
# Check that namespace tokens were replaced in content
|
|
253
|
+
with open(test_json, "r") as f:
|
|
254
|
+
content = f.read()
|
|
255
|
+
assert "testns__Test" in content
|
|
256
|
+
assert "testns__Value" in content
|
|
257
|
+
|
|
258
|
+
with open(test_csv, "r") as f:
|
|
259
|
+
content = f.read()
|
|
260
|
+
assert "testns__Field" in content
|
|
261
|
+
|
|
262
|
+
# Check that filename token was replaced
|
|
263
|
+
expected_filename = os.path.join(execute_dir, "testns__test.json")
|
|
264
|
+
assert os.path.exists(expected_filename)
|
|
265
|
+
assert not os.path.exists(filename_with_token)
|
|
266
|
+
|
|
267
|
+
@mock.patch("cumulusci.tasks.sfdmu.sfdmu.determine_managed_mode")
|
|
268
|
+
def test_inject_namespace_tokens_unmanaged_mode(self, mock_determine_managed):
|
|
269
|
+
"""Test namespace injection in unmanaged mode."""
|
|
270
|
+
mock_determine_managed.return_value = False
|
|
271
|
+
|
|
272
|
+
with tempfile.TemporaryDirectory() as execute_dir:
|
|
273
|
+
# Create test files with namespace tokens
|
|
274
|
+
test_json = os.path.join(execute_dir, "test.json")
|
|
275
|
+
with open(test_json, "w") as f:
|
|
276
|
+
f.write(
|
|
277
|
+
'{"field": "%%%NAMESPACE%%%Test", "org": "%%%NAMESPACED_ORG%%%Value"}'
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Create export.json file
|
|
281
|
+
export_json_path = os.path.join(execute_dir, "export.json")
|
|
282
|
+
with open(export_json_path, "w") as f:
|
|
283
|
+
f.write('{"test": "data"}')
|
|
284
|
+
|
|
285
|
+
task = create_task(
|
|
286
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": execute_dir}
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
# Mock the project config namespace
|
|
290
|
+
task.project_config.project__package__namespace = "testns"
|
|
291
|
+
|
|
292
|
+
mock_org_config = mock.Mock()
|
|
293
|
+
mock_org_config.namespace = "testns"
|
|
294
|
+
|
|
295
|
+
task._inject_namespace_tokens(execute_dir, mock_org_config)
|
|
296
|
+
|
|
297
|
+
# Check that namespace tokens were replaced with empty strings
|
|
298
|
+
with open(test_json, "r") as f:
|
|
299
|
+
content = f.read()
|
|
300
|
+
assert "Test" in content # %%NAMESPACE%% removed
|
|
301
|
+
assert "Value" in content # %%NAMESPACED_ORG%% removed
|
|
302
|
+
assert "%%%NAMESPACE%%%" not in content
|
|
303
|
+
assert "%%%NAMESPACED_ORG%%%" not in content
|
|
304
|
+
|
|
305
|
+
@mock.patch("cumulusci.tasks.sfdmu.sfdmu.determine_managed_mode")
|
|
306
|
+
def test_inject_namespace_tokens_namespaced_org(self, mock_determine_managed):
|
|
307
|
+
"""Test namespace injection with namespaced org."""
|
|
308
|
+
mock_determine_managed.return_value = True
|
|
309
|
+
|
|
310
|
+
with tempfile.TemporaryDirectory() as execute_dir:
|
|
311
|
+
# Create test file with namespaced org token
|
|
312
|
+
test_json = os.path.join(execute_dir, "test.json")
|
|
313
|
+
with open(test_json, "w") as f:
|
|
314
|
+
f.write('{"field": "%%%NAMESPACED_ORG%%%Test"}')
|
|
315
|
+
|
|
316
|
+
# Create export.json file
|
|
317
|
+
export_json_path = os.path.join(execute_dir, "export.json")
|
|
318
|
+
with open(export_json_path, "w") as f:
|
|
319
|
+
f.write('{"test": "data"}')
|
|
320
|
+
|
|
321
|
+
task = create_task(
|
|
322
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": execute_dir}
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
# Mock the project config namespace
|
|
326
|
+
task.project_config.project__package__namespace = "testns"
|
|
327
|
+
|
|
328
|
+
mock_org_config = mock.Mock()
|
|
329
|
+
mock_org_config.namespace = (
|
|
330
|
+
"testns" # Same as project namespace = namespaced org
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
task._inject_namespace_tokens(execute_dir, mock_org_config)
|
|
334
|
+
|
|
335
|
+
# Check that namespaced org token was replaced
|
|
336
|
+
with open(test_json, "r") as f:
|
|
337
|
+
content = f.read()
|
|
338
|
+
assert "testns__Test" in content
|
|
339
|
+
assert "%%%NAMESPACED_ORG%%%" not in content
|
|
340
|
+
|
|
341
|
+
@mock.patch("cumulusci.tasks.sfdmu.sfdmu.determine_managed_mode")
|
|
342
|
+
def test_inject_namespace_tokens_non_namespaced_org(self, mock_determine_managed):
|
|
343
|
+
"""Test namespace injection with non-namespaced org."""
|
|
344
|
+
mock_determine_managed.return_value = True
|
|
345
|
+
|
|
346
|
+
with tempfile.TemporaryDirectory() as execute_dir:
|
|
347
|
+
# Create test file with namespaced org token
|
|
348
|
+
test_json = os.path.join(execute_dir, "test.json")
|
|
349
|
+
with open(test_json, "w") as f:
|
|
350
|
+
f.write('{"field": "%%%NAMESPACED_ORG%%%Test"}')
|
|
351
|
+
|
|
352
|
+
# Create export.json file
|
|
353
|
+
export_json_path = os.path.join(execute_dir, "export.json")
|
|
354
|
+
with open(export_json_path, "w") as f:
|
|
355
|
+
f.write('{"test": "data"}')
|
|
356
|
+
|
|
357
|
+
task = create_task(
|
|
358
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": execute_dir}
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
# Mock the project config namespace
|
|
362
|
+
task.project_config.project__package__namespace = "testns"
|
|
363
|
+
|
|
364
|
+
mock_org_config = mock.Mock()
|
|
365
|
+
mock_org_config.namespace = (
|
|
366
|
+
"differentns" # Different from project namespace
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
task._inject_namespace_tokens(execute_dir, mock_org_config)
|
|
370
|
+
|
|
371
|
+
# Check that namespaced org token was replaced with empty string
|
|
372
|
+
with open(test_json, "r") as f:
|
|
373
|
+
content = f.read()
|
|
374
|
+
assert "Test" in content # %%NAMESPACED_ORG%% removed
|
|
375
|
+
assert "%%%NAMESPACED_ORG%%%" not in content
|
|
376
|
+
assert "testns__" not in content # Should not have namespace prefix
|
|
377
|
+
|
|
378
|
+
def test_inject_namespace_tokens_no_namespace(self):
|
|
379
|
+
"""Test namespace injection when project has no namespace."""
|
|
380
|
+
with tempfile.TemporaryDirectory() as execute_dir:
|
|
381
|
+
# Create test file with namespace tokens
|
|
382
|
+
test_json = os.path.join(execute_dir, "test.json")
|
|
383
|
+
with open(test_json, "w") as f:
|
|
384
|
+
f.write('{"field": "%%%NAMESPACE%%%Test"}')
|
|
385
|
+
|
|
386
|
+
# Create export.json file
|
|
387
|
+
export_json_path = os.path.join(execute_dir, "export.json")
|
|
388
|
+
with open(export_json_path, "w") as f:
|
|
389
|
+
f.write('{"test": "data"}')
|
|
390
|
+
|
|
391
|
+
task = create_task(
|
|
392
|
+
SfdmuTask, {"source": "dev", "target": "qa", "path": execute_dir}
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
# Mock the project config namespace
|
|
396
|
+
task.project_config.project__package__namespace = None
|
|
397
|
+
|
|
398
|
+
mock_org_config = mock.Mock()
|
|
399
|
+
mock_org_config.namespace = None
|
|
400
|
+
|
|
401
|
+
task._inject_namespace_tokens(execute_dir, mock_org_config)
|
|
402
|
+
|
|
403
|
+
# Check that namespace tokens were not processed (due to circular import issue)
|
|
404
|
+
with open(test_json, "r") as f:
|
|
405
|
+
content = f.read()
|
|
406
|
+
assert (
|
|
407
|
+
"%%%NAMESPACE%%%Test" in content
|
|
408
|
+
) # Tokens remain unchanged due to import issue
|
|
409
|
+
|
|
410
|
+
def test_additional_params_option_exists(self):
|
|
411
|
+
"""Test that additional_params option is properly defined in task_options."""
|
|
412
|
+
# Check that the additional_params option is defined
|
|
413
|
+
assert "additional_params" in SfdmuTask.task_options
|
|
414
|
+
assert SfdmuTask.task_options["additional_params"]["required"] is False
|
|
415
|
+
assert (
|
|
416
|
+
"Additional parameters"
|
|
417
|
+
in SfdmuTask.task_options["additional_params"]["description"]
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
def test_additional_params_parsing_logic(self):
|
|
421
|
+
"""Test that additional_params parsing logic works correctly."""
|
|
422
|
+
# Test the splitting logic that would be used in the task
|
|
423
|
+
additional_params = "-no-warnings -m -t error"
|
|
424
|
+
additional_args = additional_params.split()
|
|
425
|
+
expected_args = ["-no-warnings", "-m", "-t", "error"]
|
|
426
|
+
assert additional_args == expected_args
|
|
427
|
+
|
|
428
|
+
def test_additional_params_empty_string_logic(self):
|
|
429
|
+
"""Test that empty additional_params are handled correctly."""
|
|
430
|
+
# Test the splitting logic with empty string
|
|
431
|
+
additional_params = ""
|
|
432
|
+
additional_args = additional_params.split()
|
|
433
|
+
assert additional_args == []
|
|
434
|
+
|
|
435
|
+
def test_additional_params_none_logic(self):
|
|
436
|
+
"""Test that None additional_params are handled correctly."""
|
|
437
|
+
# Test the logic that would be used in the task
|
|
438
|
+
additional_params = None
|
|
439
|
+
if additional_params:
|
|
440
|
+
additional_args = additional_params.split()
|
|
441
|
+
else:
|
|
442
|
+
additional_args = []
|
|
443
|
+
assert additional_args == []
|