-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathtest_cli.py
More file actions
221 lines (186 loc) · 8.81 KB
/
test_cli.py
File metadata and controls
221 lines (186 loc) · 8.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
import json
import os
from unittest.mock import mock_open, patch
from click.testing import CliRunner
from datacustomcode.cli import deploy, init
from datacustomcode.deploy import AccessTokenResponse
from datacustomcode.scan import write_sdk_config
class TestInit:
@patch("datacustomcode.template.copy_script_template")
@patch("datacustomcode.scan.update_config")
@patch("datacustomcode.scan.dc_config_json_from_file")
@patch("datacustomcode.scan.write_sdk_config")
@patch("builtins.open", new_callable=mock_open)
def test_init_command(
self, mock_file, mock_write_sdk, mock_scan, mock_update, mock_copy
):
"""Test init command."""
mock_scan.return_value = {
"sdkVersion": "1.0.0",
"entryPoint": "entrypoint.py",
"dataspace": "default",
"permissions": {
"read": {"dlo": ["input_dlo"]},
"write": {"dlo": ["output_dlo"]},
},
}
mock_update.return_value = {
"sdkVersion": "1.0.0",
"entryPoint": "entrypoint.py",
"dataspace": "default",
"permissions": {
"read": {"dlo": ["input_dlo"]},
"write": {"dlo": ["output_dlo"]},
},
}
runner = CliRunner()
with runner.isolated_filesystem():
# Create test directory structure
os.makedirs(os.path.join("test_dir", "payload"), exist_ok=True)
result = runner.invoke(init, ["test_dir", "--code-type", "script"])
assert result.exit_code == 0
mock_copy.assert_called_once_with("test_dir")
# Verify SDK config was written
mock_write_sdk.assert_called_once_with("test_dir", {"type": "script"})
mock_scan.assert_called_once_with(
os.path.join("test_dir", "payload", "entrypoint.py"), "script"
)
mock_update.assert_called_once_with(
os.path.join("test_dir", "payload", "entrypoint.py")
)
# Verify the config.json was written with the correct content
mock_file.assert_any_call(
os.path.join("test_dir", "payload", "config.json"), "w"
)
# Get all write calls and join them to get the complete written content
written_content = "".join(
call.args[0] for call in mock_file().write.call_args_list
)
# The last write should be the updated config
expected_content = json.dumps(mock_update.return_value, indent=2)
assert expected_content in written_content
class TestDeploy:
@patch("datacustomcode.deploy.deploy_full")
@patch("datacustomcode.credentials.Credentials.from_available")
def test_deploy_command_success(self, mock_credentials, mock_deploy_full):
"""Test successful deploy command."""
# Mock credentials
mock_creds = mock_credentials.return_value
runner = CliRunner()
with runner.isolated_filesystem():
# Create test payload directory
os.makedirs("payload", exist_ok=True)
result = runner.invoke(deploy, ["--name", "test-job", "--version", "1.0.0"])
assert result.exit_code == 0
mock_credentials.assert_called_once()
mock_deploy_full.assert_called_once()
# Check that deploy_full was called with correct arguments
call_args = mock_deploy_full.call_args
assert call_args[0][0] == "payload" # path
assert (
call_args[0][1].name == "test_job"
) # metadata (hyphen sanitized to underscore)
assert call_args[0][1].version == "1.0.0"
assert call_args[0][1].description == "Custom Data Transform Code"
assert call_args[0][2] == mock_creds # credentials
@patch("datacustomcode.deploy.deploy_full")
@patch("datacustomcode.credentials.Credentials.from_available")
def test_deploy_command_function_invoke_options(
self, mock_credentials, mock_deploy_full
):
"""Test deploy command with function invoke options."""
runner = CliRunner()
with runner.isolated_filesystem():
# Create test payload directory
os.makedirs("payload", exist_ok=True)
sdk_config = {"type": "function"}
write_sdk_config(".", sdk_config)
result = runner.invoke(
deploy,
["--name", "test-job", "--function-invoke-opt", "option1,option2"],
)
assert result.exit_code == 0
mock_deploy_full.assert_called_once()
# Check that deploy_full was called with function invoke options
call_args = mock_deploy_full.call_args
assert call_args[0][1].functionInvokeOptions == ["option1", "option2"]
@patch("datacustomcode.credentials.Credentials.from_available")
def test_deploy_command_credentials_error(self, mock_credentials):
"""Test deploy command when credentials are not available."""
# Mock credentials to raise ValueError
mock_credentials.side_effect = ValueError(
"Credentials not found in env or ini file. "
"Run `datacustomcode configure` to create a credentials file."
)
runner = CliRunner()
with runner.isolated_filesystem():
# Create test payload directory
os.makedirs("payload", exist_ok=True)
result = runner.invoke(deploy, ["--name", "test-job"])
assert result.exit_code == 1
assert "Error: Credentials not found in env or ini file" in result.output
@patch("datacustomcode.deploy.deploy_full")
@patch("datacustomcode.credentials.Credentials.from_available")
def test_deploy_command_custom_path(self, mock_credentials, mock_deploy_full):
"""Test deploy command with custom path."""
runner = CliRunner()
with runner.isolated_filesystem():
# Create test directory
os.makedirs("custom_path", exist_ok=True)
result = runner.invoke(
deploy, ["--path", "custom_path", "--name", "test-job"]
)
assert result.exit_code == 0
mock_deploy_full.assert_called_once()
# Check that deploy_full was called with custom path
call_args = mock_deploy_full.call_args
assert call_args[0][0] == "custom_path" # path
@patch("datacustomcode.deploy.deploy_full")
@patch("datacustomcode.credentials.Credentials.from_available")
def test_deploy_command_custom_description(
self, mock_credentials, mock_deploy_full
):
"""Test deploy command with custom description."""
runner = CliRunner()
with runner.isolated_filesystem():
# Create test payload directory
os.makedirs("payload", exist_ok=True)
result = runner.invoke(
deploy, ["--name", "test-job", "--description", "Custom description"]
)
assert result.exit_code == 0
mock_deploy_full.assert_called_once()
# Check that deploy_full was called with custom description
call_args = mock_deploy_full.call_args
assert call_args[0][1].description == "Custom description"
@patch("datacustomcode.deploy.deploy_full")
@patch("datacustomcode.deploy._retrieve_access_token_from_sf_cli")
def test_deploy_command_sf_cli_org(self, mock_sf_cli_token, mock_deploy_full):
"""Test deploy command with --sf-cli-org flag."""
mock_token = AccessTokenResponse(
access_token="test_token", instance_url="https://test.salesforce.com"
)
mock_sf_cli_token.return_value = mock_token
runner = CliRunner()
with runner.isolated_filesystem():
os.makedirs("payload", exist_ok=True)
result = runner.invoke(
deploy, ["--name", "test-job", "--sf-cli-org", "my-org"]
)
assert result.exit_code == 0
mock_sf_cli_token.assert_called_once_with("my-org")
mock_deploy_full.assert_called_once()
call_args = mock_deploy_full.call_args
assert call_args[0][2] == mock_token # AccessTokenResponse passed directly
@patch("datacustomcode.deploy._retrieve_access_token_from_sf_cli")
def test_deploy_command_sf_cli_org_error(self, mock_sf_cli_token):
"""Test deploy command when --sf-cli-org fails."""
mock_sf_cli_token.side_effect = RuntimeError("sf command not found")
runner = CliRunner()
with runner.isolated_filesystem():
os.makedirs("payload", exist_ok=True)
result = runner.invoke(
deploy, ["--name", "test-job", "--sf-cli-org", "bad-org"]
)
assert result.exit_code == 1
assert "sf command not found" in result.output