salespyforce 1.4.0.dev0__tar.gz → 1.4.0.dev1__tar.gz
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.
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/PKG-INFO +6 -2
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/README.md +5 -1
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/pyproject.toml +1 -1
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/log_utils.py +10 -9
- salespyforce-1.4.0.dev1/src/salespyforce/utils/tests/conftest.py +202 -0
- salespyforce-1.4.0.dev1/src/salespyforce/utils/tests/test_core_utils.py +195 -0
- salespyforce-1.4.0.dev1/src/salespyforce/utils/tests/test_instantiate_object.py +62 -0
- salespyforce-1.4.0.dev1/src/salespyforce/utils/tests/test_log_utils.py +79 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/test_sobjects.py +22 -15
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/test_soql.py +8 -8
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/test_sosl.py +9 -9
- salespyforce-1.4.0.dev1/src/salespyforce/utils/tests/test_version_utils.py +70 -0
- salespyforce-1.4.0.dev0/src/salespyforce/utils/tests/test_instantiate_object.py +0 -49
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/LICENSE +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/__init__.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/api.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/chatter.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/core.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/errors/__init__.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/errors/exceptions.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/errors/handlers.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/knowledge.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/__init__.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/core_utils.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/helper.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/__init__.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/resources.py +0 -0
- {salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: salespyforce
|
|
3
|
-
Version: 1.4.0.
|
|
3
|
+
Version: 1.4.0.dev1
|
|
4
4
|
Summary: A Python toolset for performing Salesforce API calls
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -63,7 +63,7 @@ A Python toolset for performing Salesforce API calls
|
|
|
63
63
|
<td>Latest Beta/RC Release</td>
|
|
64
64
|
<td>
|
|
65
65
|
<a href='https://pypi.org/project/salespyforce/#history'>
|
|
66
|
-
<img alt="PyPI" src="https://img.shields.io/badge/pypi-1.
|
|
66
|
+
<img alt="PyPI" src="https://img.shields.io/badge/pypi-1.4.0.dev1-blue">
|
|
67
67
|
</a>
|
|
68
68
|
</td>
|
|
69
69
|
</tr>
|
|
@@ -140,6 +140,10 @@ A Python toolset for performing Salesforce API calls
|
|
|
140
140
|
</tr>
|
|
141
141
|
</table>
|
|
142
142
|
|
|
143
|
+
## Overview
|
|
144
|
+
salespyforce is a Python toolkit focused on interacting with Salesforce APIs, with a primary `Salesforce` class
|
|
145
|
+
that centralizes authentication, version selection, and access to helper feature sets (Chatter, Knowledge).
|
|
146
|
+
|
|
143
147
|
## Installation
|
|
144
148
|
The package can be installed via pip using the syntax below.
|
|
145
149
|
|
|
@@ -14,7 +14,7 @@ A Python toolset for performing Salesforce API calls
|
|
|
14
14
|
<td>Latest Beta/RC Release</td>
|
|
15
15
|
<td>
|
|
16
16
|
<a href='https://pypi.org/project/salespyforce/#history'>
|
|
17
|
-
<img alt="PyPI" src="https://img.shields.io/badge/pypi-1.
|
|
17
|
+
<img alt="PyPI" src="https://img.shields.io/badge/pypi-1.4.0.dev1-blue">
|
|
18
18
|
</a>
|
|
19
19
|
</td>
|
|
20
20
|
</tr>
|
|
@@ -91,6 +91,10 @@ A Python toolset for performing Salesforce API calls
|
|
|
91
91
|
</tr>
|
|
92
92
|
</table>
|
|
93
93
|
|
|
94
|
+
## Overview
|
|
95
|
+
salespyforce is a Python toolkit focused on interacting with Salesforce APIs, with a primary `Salesforce` class
|
|
96
|
+
that centralizes authentication, version selection, and access to helper feature sets (Chatter, Knowledge).
|
|
97
|
+
|
|
94
98
|
## Installation
|
|
95
99
|
The package can be installed via pip using the syntax below.
|
|
96
100
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
:Example: ``logger = log_utils.initialize_logging(__name__)``
|
|
7
7
|
:Created By: Jeff Shurtliff
|
|
8
8
|
:Last Modified: Jeff Shurtliff
|
|
9
|
-
:Modified Date:
|
|
9
|
+
:Modified Date: 31 Dec 2025
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -59,7 +59,7 @@ class LessThanFilter(logging.Filter):
|
|
|
59
59
|
self.max_level = exclusive_maximum
|
|
60
60
|
|
|
61
61
|
def filter(self, record):
|
|
62
|
-
"""This method returns a Boolean integer value indicating whether
|
|
62
|
+
"""This method returns a Boolean integer value indicating whether a message should be logged.
|
|
63
63
|
|
|
64
64
|
.. note:: A non-zero return indicates that the message will be logged.
|
|
65
65
|
"""
|
|
@@ -69,6 +69,9 @@ class LessThanFilter(logging.Filter):
|
|
|
69
69
|
def _apply_defaults(_logger_name, _formatter, _debug, _log_level, _file_level, _console_level, _syslog_level):
|
|
70
70
|
"""This function applies default values to the configuration settings if not explicitly defined.
|
|
71
71
|
|
|
72
|
+
.. version-changed:: 1.4.0
|
|
73
|
+
The default logging level is now defined.
|
|
74
|
+
|
|
72
75
|
:param _logger_name: The name of the logger instance
|
|
73
76
|
:type _logger_name: str, None
|
|
74
77
|
:param _formatter: The log format to utilize for the logger instance
|
|
@@ -79,8 +82,9 @@ def _apply_defaults(_logger_name, _formatter, _debug, _log_level, _file_level, _
|
|
|
79
82
|
:type _log_level: str, None
|
|
80
83
|
:returns: The values that will be used for the configuration settings
|
|
81
84
|
"""
|
|
85
|
+
_default_log_level = LOGGING_DEFAULTS.get('log_level')
|
|
82
86
|
_log_levels = {
|
|
83
|
-
'general': _log_level,
|
|
87
|
+
'general': _log_level or _default_log_level,
|
|
84
88
|
'file': _file_level,
|
|
85
89
|
'console': _console_level,
|
|
86
90
|
'syslog': _syslog_level,
|
|
@@ -90,12 +94,9 @@ def _apply_defaults(_logger_name, _formatter, _debug, _log_level, _file_level, _
|
|
|
90
94
|
for _log_type in _log_levels:
|
|
91
95
|
_log_levels[_log_type] = 'debug'
|
|
92
96
|
else:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
_log_levels[_lvl_type] = _log_level
|
|
97
|
-
else:
|
|
98
|
-
_log_level = LOGGING_DEFAULTS.get('log_level')
|
|
97
|
+
for _lvl_type, _lvl_value in _log_levels.items():
|
|
98
|
+
if _lvl_value is None:
|
|
99
|
+
_log_levels[_lvl_type] = _log_levels['general']
|
|
99
100
|
if _formatter and isinstance(_formatter, str):
|
|
100
101
|
_formatter = logging.Formatter(_formatter)
|
|
101
102
|
_formatter = LOGGING_DEFAULTS.get('formatter') if not _formatter else _formatter
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Module: salespyforce.utils.tests.conftest
|
|
4
|
+
:Synopsis: Configuration for performing unit testing with pytest
|
|
5
|
+
:Usage: Leveraged by pytest in test modules
|
|
6
|
+
:Example: ``soql_response = salesforce_unit.soql_query(soql_statement)``
|
|
7
|
+
:Created By: Jeff Shurtliff
|
|
8
|
+
:Last Modified: Jeff Shurtliff
|
|
9
|
+
:Modified Date: 13 Dec 2025
|
|
10
|
+
|
|
11
|
+
Pytest fixtures for ``salespyforce.utils.tests``.
|
|
12
|
+
|
|
13
|
+
This module centralizes helpers used across the test suite to avoid
|
|
14
|
+
repeated setup in individual test files. It introduces two key fixtures:
|
|
15
|
+
|
|
16
|
+
* ``salesforce_integration`` — Instantiates the real ``Salesforce``
|
|
17
|
+
client when a helper file is available. Tests using this fixture are
|
|
18
|
+
marked as ``integration`` and are skipped unless ``--integration`` is
|
|
19
|
+
provided.
|
|
20
|
+
* ``salesforce_unit`` — Provides a lightweight stub that mimics the
|
|
21
|
+
public API used by existing tests without performing any network I/O.
|
|
22
|
+
|
|
23
|
+
The goal is to make it easy to switch between fast, isolated unit tests
|
|
24
|
+
and opt-in integration runs against a real Salesforce org. Additional
|
|
25
|
+
fixtures can be added here to share common mocking or configuration.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
import os
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
from types import SimpleNamespace
|
|
33
|
+
from typing import Iterator
|
|
34
|
+
|
|
35
|
+
import pytest
|
|
36
|
+
|
|
37
|
+
from salespyforce.core import Salesforce
|
|
38
|
+
|
|
39
|
+
# Define constants
|
|
40
|
+
HELPER_FILE_NAME = "helper_dm_conn.yml"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# -----------------------------
|
|
44
|
+
# Pytest configuration hooks
|
|
45
|
+
# -----------------------------
|
|
46
|
+
|
|
47
|
+
def pytest_addoption(parser: pytest.Parser) -> None:
|
|
48
|
+
"""This function registers custom CLI options.
|
|
49
|
+
|
|
50
|
+
.. version-added:: 1.4.0
|
|
51
|
+
|
|
52
|
+
``--integration`` enables tests that require access to a real
|
|
53
|
+
Salesforce org. Keeping this opt-in protects routine runs from
|
|
54
|
+
network or credential dependencies.
|
|
55
|
+
"""
|
|
56
|
+
parser.addoption(
|
|
57
|
+
"--integration",
|
|
58
|
+
action="store_true",
|
|
59
|
+
default=False,
|
|
60
|
+
help="run tests that require a Salesforce helper file",
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def pytest_configure(config: pytest.Config) -> None:
|
|
65
|
+
"""This function declares custom markers so pytest will not warn during collection.
|
|
66
|
+
|
|
67
|
+
.. version-added:: 1.4.0
|
|
68
|
+
"""
|
|
69
|
+
config.addinivalue_line(
|
|
70
|
+
"markers",
|
|
71
|
+
"integration: marks tests that require a real Salesforce org",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def pytest_collection_modifyitems(
|
|
76
|
+
config: pytest.Config, items: list[pytest.Item]
|
|
77
|
+
) -> None:
|
|
78
|
+
"""This function skips integration tests when ``--integration`` is not provided.
|
|
79
|
+
|
|
80
|
+
.. version-added:: 1.4.0
|
|
81
|
+
"""
|
|
82
|
+
if config.getoption("--integration"):
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
skip_integration = pytest.mark.skip(
|
|
86
|
+
reason="requires --integration to run against a Salesforce org"
|
|
87
|
+
)
|
|
88
|
+
for item in items:
|
|
89
|
+
if "integration" in item.keywords:
|
|
90
|
+
item.add_marker(skip_integration)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# -----------------------------
|
|
94
|
+
# Helper utilities
|
|
95
|
+
# -----------------------------
|
|
96
|
+
|
|
97
|
+
def _find_helper_file() -> Path | None:
|
|
98
|
+
"""This function locates a helper file in common locations used by this project.
|
|
99
|
+
|
|
100
|
+
.. version-added:: 1.4.0
|
|
101
|
+
"""
|
|
102
|
+
helper_locations = [
|
|
103
|
+
Path(os.environ.get("HOME", "")) / "secrets" / HELPER_FILE_NAME,
|
|
104
|
+
Path("local") / HELPER_FILE_NAME,
|
|
105
|
+
]
|
|
106
|
+
for helper_path in helper_locations:
|
|
107
|
+
if helper_path.is_file():
|
|
108
|
+
return helper_path.resolve()
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
# -----------------------------
|
|
113
|
+
# Fixtures
|
|
114
|
+
# -----------------------------
|
|
115
|
+
|
|
116
|
+
@pytest.fixture(scope="session")
|
|
117
|
+
def integration_helper_file() -> Path:
|
|
118
|
+
"""This fixture returns the helper file path or skips the test if none is available.
|
|
119
|
+
|
|
120
|
+
.. version-added:: 1.4.0
|
|
121
|
+
|
|
122
|
+
Keeping this lookup in a session-scoped fixture ensures we only
|
|
123
|
+
perform filesystem checks once per test run and provides a single
|
|
124
|
+
source of truth for integration tests.
|
|
125
|
+
"""
|
|
126
|
+
helper_path = _find_helper_file()
|
|
127
|
+
if helper_path is None:
|
|
128
|
+
pytest.skip("No Salesforce helper file found for integration tests")
|
|
129
|
+
return helper_path
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@pytest.fixture(scope="session")
|
|
133
|
+
def salesforce_integration(integration_helper_file: Path) -> Iterator[Salesforce]:
|
|
134
|
+
"""This fixture instantiates the real Salesforce client for integration tests.
|
|
135
|
+
|
|
136
|
+
.. version-added:: 1.4.0
|
|
137
|
+
|
|
138
|
+
The fixture is session-scoped to avoid repeated authentication and
|
|
139
|
+
to reuse connections across tests. It is intended only for tests
|
|
140
|
+
marked with ``@pytest.mark.integration``.
|
|
141
|
+
"""
|
|
142
|
+
client = Salesforce(helper=str(integration_helper_file))
|
|
143
|
+
yield client
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@pytest.fixture()
|
|
147
|
+
def salesforce_unit(monkeypatch: pytest.MonkeyPatch) -> SimpleNamespace:
|
|
148
|
+
"""This fixture provides a lightweight stub that mimics the ``Salesforce`` API.
|
|
149
|
+
|
|
150
|
+
.. version-added:: 1.4.0
|
|
151
|
+
|
|
152
|
+
This fixture avoids network calls by supplying deterministic return
|
|
153
|
+
values for the subset of methods exercised by the current tests.
|
|
154
|
+
It can be extended as coverage grows to keep unit tests fast and
|
|
155
|
+
self-contained.
|
|
156
|
+
"""
|
|
157
|
+
# Minimal data used across tests
|
|
158
|
+
sample_urls = {
|
|
159
|
+
"base_url": "https://example.force.com",
|
|
160
|
+
"rest_resources": {"metadata": "available"},
|
|
161
|
+
"org_limits": {"DailyApiRequests": {"Remaining": 15000}},
|
|
162
|
+
"sobjects": {"sobjects": []},
|
|
163
|
+
"account": {
|
|
164
|
+
"objectDescribe": {},
|
|
165
|
+
"activateable": False,
|
|
166
|
+
},
|
|
167
|
+
"soql_result": {
|
|
168
|
+
"done": True,
|
|
169
|
+
"totalSize": 1,
|
|
170
|
+
"records": [{"Id": "001XX000003NGqqYAG"}],
|
|
171
|
+
},
|
|
172
|
+
"sosl_result": {
|
|
173
|
+
"searchRecords": [
|
|
174
|
+
{"attributes": {"type": "Account"}, "Id": "001XX000003NGqqYAG"}
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
def _create_response(**overrides):
|
|
180
|
+
"""This function creates an API response payload mimicking the Salesforce REST API responses.
|
|
181
|
+
|
|
182
|
+
.. version-added:: 1.4.0
|
|
183
|
+
"""
|
|
184
|
+
response = {"id": "001D000000IqhSLIAZ", "success": True, "errors": []}
|
|
185
|
+
response.update(overrides)
|
|
186
|
+
return response
|
|
187
|
+
|
|
188
|
+
stub = SimpleNamespace()
|
|
189
|
+
stub.base_url = sample_urls["base_url"]
|
|
190
|
+
stub.get_api_versions = lambda: [{"version": "v65.0"}]
|
|
191
|
+
stub.get_rest_resources = lambda: sample_urls["rest_resources"]
|
|
192
|
+
stub.get_org_limits = lambda: sample_urls["org_limits"]
|
|
193
|
+
stub.get_all_sobjects = lambda: sample_urls["sobjects"]
|
|
194
|
+
stub.get_sobject = lambda *_args, **_kwargs: sample_urls["account"]
|
|
195
|
+
stub.describe_object = lambda *_args, **_kwargs: sample_urls["account"]
|
|
196
|
+
stub.create_sobject_record = (
|
|
197
|
+
lambda *_args, **_kwargs: _create_response()
|
|
198
|
+
)
|
|
199
|
+
stub.soql_query = lambda *_args, **_kwargs: sample_urls["soql_result"]
|
|
200
|
+
stub.search_string = lambda *_args, **_kwargs: sample_urls["sosl_result"]
|
|
201
|
+
|
|
202
|
+
return stub
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# bandit: skip=B101
|
|
3
|
+
"""
|
|
4
|
+
:Module: salespyforce.utils.tests.test_core_utils
|
|
5
|
+
:Synopsis: This module is used by pytest to test core utility functions
|
|
6
|
+
:Created By: Jeff Shurtliff
|
|
7
|
+
:Last Modified: Jeff Shurtliff
|
|
8
|
+
:Modified Date: 20 Dec 2025
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import pathlib
|
|
13
|
+
import warnings
|
|
14
|
+
|
|
15
|
+
import pytest
|
|
16
|
+
|
|
17
|
+
from salespyforce import errors
|
|
18
|
+
from salespyforce.utils import core_utils
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_url_encode_and_decode_round_trip():
|
|
22
|
+
"""This function tests URL encoding and decoding helper functions.
|
|
23
|
+
|
|
24
|
+
.. version-added:: 1.4.0
|
|
25
|
+
"""
|
|
26
|
+
raw_string = "My sample string with spaces & symbols!"
|
|
27
|
+
encoded = core_utils.url_encode(raw_string)
|
|
28
|
+
assert "%26" in encoded and "+" in encoded
|
|
29
|
+
decoded = core_utils.url_decode(encoded)
|
|
30
|
+
assert decoded == raw_string
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_display_warning_emits_userwarning():
|
|
34
|
+
"""This function tests that display_warning emits a UserWarning.
|
|
35
|
+
|
|
36
|
+
.. version-added:: 1.4.0
|
|
37
|
+
"""
|
|
38
|
+
warn_msg = "testing warning"
|
|
39
|
+
with pytest.warns(UserWarning, match=warn_msg):
|
|
40
|
+
core_utils.display_warning(warn_msg)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_get_file_type_detects_json_extension(tmp_path):
|
|
44
|
+
"""This function tests get_file_type with a JSON extension.
|
|
45
|
+
|
|
46
|
+
.. version-added:: 1.4.0
|
|
47
|
+
"""
|
|
48
|
+
json_path = tmp_path / "config.json"
|
|
49
|
+
json_path.write_text('{"key": "value"}')
|
|
50
|
+
assert core_utils.get_file_type(str(json_path)) == "json"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_get_file_type_detects_yaml_extension(tmp_path):
|
|
54
|
+
"""This function tests get_file_type with a YAML extension.
|
|
55
|
+
|
|
56
|
+
.. version-added:: 1.4.0
|
|
57
|
+
"""
|
|
58
|
+
yaml_path = tmp_path / "config.yaml"
|
|
59
|
+
yaml_path.write_text("key: value")
|
|
60
|
+
assert core_utils.get_file_type(str(yaml_path)) == "yaml"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_get_file_type_reads_unknown_extension_with_warning(tmp_path):
|
|
64
|
+
"""This function tests get_file_type fallback detection on unknown extensions.
|
|
65
|
+
|
|
66
|
+
.. version-added:: 1.4.0
|
|
67
|
+
"""
|
|
68
|
+
txt_path = tmp_path / "config.txt"
|
|
69
|
+
txt_path.write_text("# comment line\n{json: true}")
|
|
70
|
+
with warnings.catch_warnings(record=True) as captured_warnings:
|
|
71
|
+
file_type = core_utils.get_file_type(str(txt_path))
|
|
72
|
+
assert file_type == "json"
|
|
73
|
+
assert any(
|
|
74
|
+
warning.category is UserWarning for warning in captured_warnings
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_get_file_type_raises_for_unknown_content(tmp_path):
|
|
79
|
+
"""This function tests get_file_type when content is unrecognized.
|
|
80
|
+
|
|
81
|
+
.. version-added:: 1.4.0
|
|
82
|
+
"""
|
|
83
|
+
bad_path = tmp_path / "config.data"
|
|
84
|
+
bad_path.write_text("plain text content")
|
|
85
|
+
with pytest.warns(UserWarning):
|
|
86
|
+
with pytest.raises(errors.exceptions.UnknownFileTypeError):
|
|
87
|
+
core_utils.get_file_type(str(bad_path))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_get_file_type_raises_for_missing_file():
|
|
91
|
+
"""This function tests get_file_type when a file is missing.
|
|
92
|
+
|
|
93
|
+
.. version-added:: 1.4.0
|
|
94
|
+
"""
|
|
95
|
+
missing_path = "does/not/exist.json"
|
|
96
|
+
with pytest.raises(FileNotFoundError):
|
|
97
|
+
core_utils.get_file_type(missing_path)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_get_random_string_returns_expected_length(monkeypatch):
|
|
101
|
+
"""This function tests get_random_string length and prefix handling.
|
|
102
|
+
|
|
103
|
+
.. version-added:: 1.4.0
|
|
104
|
+
"""
|
|
105
|
+
alphabet = "abc123"
|
|
106
|
+
monkeypatch.setattr(core_utils, "random", core_utils.random)
|
|
107
|
+
monkeypatch.setattr(
|
|
108
|
+
core_utils,
|
|
109
|
+
"string",
|
|
110
|
+
type("DummyString", (), {"ascii_letters": alphabet, "digits": alphabet}),
|
|
111
|
+
)
|
|
112
|
+
result = core_utils.get_random_string(length=5, prefix_string="pre_")
|
|
113
|
+
assert result.startswith("pre_")
|
|
114
|
+
assert len(result) == 5 + len("pre_")
|
|
115
|
+
assert all(char in alphabet for char in result.replace("pre_", ""))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def test_get_image_ref_id_parses_query_param():
|
|
119
|
+
"""This function tests get_image_ref_id parsing.
|
|
120
|
+
|
|
121
|
+
.. version-added:: 1.4.0
|
|
122
|
+
"""
|
|
123
|
+
image_url = (
|
|
124
|
+
"https://example.force.com/servlet/servlet.ImageServer"
|
|
125
|
+
"?oid=00Dxx0000001gPFEAY&refid=abc123&lastMod=123"
|
|
126
|
+
)
|
|
127
|
+
assert core_utils.get_image_ref_id(image_url) == "abc123"
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_download_image_raises_without_input():
|
|
131
|
+
"""This function tests download_image when neither URL nor response is provided.
|
|
132
|
+
|
|
133
|
+
.. version-added:: 1.4.0
|
|
134
|
+
"""
|
|
135
|
+
with pytest.raises(RuntimeError):
|
|
136
|
+
core_utils.download_image()
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def test_download_image_raises_on_bad_status(monkeypatch, tmp_path):
|
|
140
|
+
"""This function tests download_image when the response is unsuccessful.
|
|
141
|
+
|
|
142
|
+
.. version-added:: 1.4.0
|
|
143
|
+
"""
|
|
144
|
+
class DummyResponse:
|
|
145
|
+
status_code = 404
|
|
146
|
+
content = b""
|
|
147
|
+
|
|
148
|
+
monkeypatch.setattr(core_utils.requests, "get", lambda *_args, **_kwargs: DummyResponse())
|
|
149
|
+
with pytest.raises(RuntimeError):
|
|
150
|
+
core_utils.download_image(image_url="https://example.com/image", file_path=str(tmp_path))
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def test_download_image_writes_response_content(tmp_path):
|
|
154
|
+
"""This function tests download_image writing provided response content.
|
|
155
|
+
|
|
156
|
+
.. version-added:: 1.4.0
|
|
157
|
+
"""
|
|
158
|
+
file_path = tmp_path / "images"
|
|
159
|
+
os.makedirs(file_path, exist_ok=True)
|
|
160
|
+
|
|
161
|
+
class DummyResponse:
|
|
162
|
+
status_code = 200
|
|
163
|
+
content = b"image-bytes"
|
|
164
|
+
|
|
165
|
+
destination = core_utils.download_image(
|
|
166
|
+
image_url="https://example.com/image",
|
|
167
|
+
file_name="logo.png",
|
|
168
|
+
file_path=str(file_path),
|
|
169
|
+
response=DummyResponse(),
|
|
170
|
+
)
|
|
171
|
+
saved_path = pathlib.Path(destination)
|
|
172
|
+
assert saved_path.name == "logo.png"
|
|
173
|
+
assert saved_path.parent == file_path
|
|
174
|
+
assert saved_path.read_bytes() == DummyResponse.content
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def test_download_image_generates_file_name(monkeypatch, tmp_path):
|
|
178
|
+
"""This function tests download_image generates a file name when not provided.
|
|
179
|
+
|
|
180
|
+
.. version-added:: 1.4.0
|
|
181
|
+
"""
|
|
182
|
+
class DummyResponse:
|
|
183
|
+
status_code = 200
|
|
184
|
+
content = b"bytes"
|
|
185
|
+
|
|
186
|
+
monkeypatch.setattr(core_utils, "get_random_string", lambda *_args, **_kwargs: "image_stub")
|
|
187
|
+
destination = core_utils.download_image(
|
|
188
|
+
image_url="https://example.com/image",
|
|
189
|
+
file_path=str(tmp_path),
|
|
190
|
+
response=DummyResponse(),
|
|
191
|
+
extension="png",
|
|
192
|
+
)
|
|
193
|
+
assert destination.startswith(f"{tmp_path}{os.sep}image_stub")
|
|
194
|
+
assert destination.endswith("png")
|
|
195
|
+
assert pathlib.Path(destination).read_bytes() == DummyResponse.content
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# bandit: skip=B101
|
|
3
|
+
"""
|
|
4
|
+
:Module: salespyforce.utils.tests.test_instantiate_object
|
|
5
|
+
:Synopsis: This module is used by pytest to test instantiating the core object
|
|
6
|
+
:Created By: Jeff Shurtliff
|
|
7
|
+
:Last Modified: Jeff Shurtliff
|
|
8
|
+
:Modified Date: 20 Dec 2025
|
|
9
|
+
|
|
10
|
+
These tests rely on the ``salesforce_unit`` fixture defined in
|
|
11
|
+
``conftest.py`` to keep them fast and deterministic. When you want to
|
|
12
|
+
verify behavior against a real org, add ``@pytest.mark.integration``
|
|
13
|
+
and switch the fixture parameter to ``salesforce_integration``.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_instantiate_core_object(salesforce_unit):
|
|
18
|
+
"""This function tests the ability to instantiate the core object.
|
|
19
|
+
|
|
20
|
+
.. version-added:: 1.1.0
|
|
21
|
+
|
|
22
|
+
.. version-changed:: 1.4.0
|
|
23
|
+
The function now utilizes the ``salesforce_unit`` fixture.
|
|
24
|
+
"""
|
|
25
|
+
sfdc_object = salesforce_unit
|
|
26
|
+
assert 'force.com' in sfdc_object.base_url
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_get_api_versions(salesforce_unit):
|
|
30
|
+
"""This function tests the get_api_versions() method in the core object.
|
|
31
|
+
|
|
32
|
+
.. version-added:: 1.1.0
|
|
33
|
+
|
|
34
|
+
.. version-changed:: 1.4.0
|
|
35
|
+
The function now utilizes the ``salesforce_unit`` fixture.
|
|
36
|
+
"""
|
|
37
|
+
api_versions = salesforce_unit.get_api_versions()
|
|
38
|
+
assert isinstance(api_versions, list) and 'version' in api_versions[0]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_get_rest_resources(salesforce_unit):
|
|
42
|
+
"""This function tests the get_rest_resources() method in the core object.
|
|
43
|
+
|
|
44
|
+
.. version-added:: 1.1.0
|
|
45
|
+
|
|
46
|
+
.. version-changed:: 1.4.0
|
|
47
|
+
The function now utilizes the ``salesforce_unit`` fixture.
|
|
48
|
+
"""
|
|
49
|
+
rest_resources = salesforce_unit.get_rest_resources()
|
|
50
|
+
assert 'metadata' in rest_resources
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_get_org_limits(salesforce_unit):
|
|
54
|
+
"""This function tests the get_org_limits() method in the core object.
|
|
55
|
+
|
|
56
|
+
.. version-added:: 1.1.0
|
|
57
|
+
|
|
58
|
+
.. version-changed:: 1.4.0
|
|
59
|
+
The function now utilizes the ``salesforce_unit`` fixture.
|
|
60
|
+
"""
|
|
61
|
+
org_limits = salesforce_unit.get_org_limits()
|
|
62
|
+
assert 'DailyApiRequests' in org_limits
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# bandit: skip=B101
|
|
3
|
+
"""
|
|
4
|
+
:Module: salespyforce.utils.tests.test_log_utils
|
|
5
|
+
:Synopsis: This module is used by pytest to test the logging functionality
|
|
6
|
+
:Created By: Jeff Shurtliff
|
|
7
|
+
:Last Modified: Jeff Shurtliff
|
|
8
|
+
:Modified Date: 31 Dec 2025
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
import pytest
|
|
15
|
+
|
|
16
|
+
from salespyforce.utils import log_utils
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _cleanup_logger(logger: logging.Logger) -> None:
|
|
20
|
+
"""This function removes and closes handlers for a logger.
|
|
21
|
+
|
|
22
|
+
.. version-added:: 1.4.0
|
|
23
|
+
|
|
24
|
+
:param logger: The logger instance to clean up
|
|
25
|
+
:type logger: logging.Logger
|
|
26
|
+
:returns: None
|
|
27
|
+
"""
|
|
28
|
+
for handler in list(logger.handlers):
|
|
29
|
+
logger.removeHandler(handler)
|
|
30
|
+
handler.close()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_initialize_logging_defaults_to_info_level() -> None:
|
|
34
|
+
"""This function verifies that initialize_logging() defaults logger level to INFO.
|
|
35
|
+
|
|
36
|
+
.. version-added:: 1.4.0
|
|
37
|
+
|
|
38
|
+
:returns: None
|
|
39
|
+
"""
|
|
40
|
+
logger_name = "salespyforce.test.default.info"
|
|
41
|
+
logger = log_utils.initialize_logging(logger_name)
|
|
42
|
+
try:
|
|
43
|
+
assert logger.level == logging.INFO
|
|
44
|
+
finally:
|
|
45
|
+
_cleanup_logger(logger)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_initialize_logging_applies_default_level_to_console_handler(caplog: pytest.LogCaptureFixture) -> None:
|
|
49
|
+
"""This function ensures console handlers inherit the default INFO level.
|
|
50
|
+
|
|
51
|
+
.. version-added:: 1.4.0
|
|
52
|
+
|
|
53
|
+
:param caplog: Pytest fixture capturing log records for assertions
|
|
54
|
+
:type caplog: pytest.LogCaptureFixture
|
|
55
|
+
:returns: None
|
|
56
|
+
"""
|
|
57
|
+
logger_name = "salespyforce.test.console.default"
|
|
58
|
+
logger = log_utils.initialize_logging(logger_name, console_output=True)
|
|
59
|
+
message = "default info message"
|
|
60
|
+
try:
|
|
61
|
+
with caplog.at_level(logging.INFO, logger=logger_name):
|
|
62
|
+
logger.info(message)
|
|
63
|
+
|
|
64
|
+
stdout_handlers = [
|
|
65
|
+
handler
|
|
66
|
+
for handler in logger.handlers
|
|
67
|
+
if isinstance(handler, logging.StreamHandler)
|
|
68
|
+
and getattr(handler, "stream", None) is sys.stdout
|
|
69
|
+
]
|
|
70
|
+
assert stdout_handlers
|
|
71
|
+
for handler in stdout_handlers:
|
|
72
|
+
assert handler.level == logging.INFO
|
|
73
|
+
|
|
74
|
+
assert any(
|
|
75
|
+
record.levelno == logging.INFO and record.message == message
|
|
76
|
+
for record in caplog.records
|
|
77
|
+
)
|
|
78
|
+
finally:
|
|
79
|
+
_cleanup_logger(logger)
|
{salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/test_sobjects.py
RENAMED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
# bandit: skip=B101
|
|
2
3
|
"""
|
|
3
4
|
:Module: salespyforce.utils.tests.test_sobjects
|
|
4
5
|
:Synopsis: This module is used by pytest to test basic sObject-related methods
|
|
5
6
|
:Created By: Jeff Shurtliff
|
|
6
7
|
:Last Modified: Jeff Shurtliff
|
|
7
|
-
:Modified Date:
|
|
8
|
+
:Modified Date: 20 Dec 2025
|
|
8
9
|
"""
|
|
9
10
|
|
|
10
11
|
import requests
|
|
@@ -12,41 +13,47 @@ import requests
|
|
|
12
13
|
from . import resources
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
def test_get_all_sobjects():
|
|
16
|
+
def test_get_all_sobjects(salesforce_unit):
|
|
16
17
|
"""This function tests the get_all_sobjects() method in the core object.
|
|
17
18
|
|
|
18
19
|
.. versionadded:: 1.1.0
|
|
20
|
+
|
|
21
|
+
.. version-changed:: 1.4.0
|
|
22
|
+
The function now utilizes the ``salesforce_unit`` fixture.
|
|
19
23
|
"""
|
|
20
|
-
|
|
21
|
-
all_sobjects = sfdc_object.get_all_sobjects()
|
|
24
|
+
all_sobjects = salesforce_unit.get_all_sobjects()
|
|
22
25
|
assert 'sobjects' in all_sobjects
|
|
23
26
|
|
|
24
27
|
|
|
25
|
-
def test_get_and_describe_sobject():
|
|
28
|
+
def test_get_and_describe_sobject(salesforce_unit):
|
|
26
29
|
"""This function tests the get_sobject() and describe_object() methods in the core object.
|
|
27
30
|
|
|
28
31
|
.. versionadded:: 1.1.0
|
|
29
|
-
"""
|
|
30
|
-
# Instantiate the core object
|
|
31
|
-
sfdc_object = resources.get_core_object()
|
|
32
32
|
|
|
33
|
+
.. version-changed:: 1.4.0
|
|
34
|
+
The function now utilizes the ``salesforce_unit`` fixture.
|
|
35
|
+
"""
|
|
33
36
|
# Test the default query (non-describe)
|
|
34
|
-
account_sobject =
|
|
37
|
+
account_sobject = salesforce_unit.get_sobject('Account')
|
|
35
38
|
assert 'objectDescribe' in account_sobject
|
|
36
39
|
|
|
37
40
|
# Test with describe enabled
|
|
38
|
-
account_sobject_describe =
|
|
41
|
+
account_sobject_describe = salesforce_unit.get_sobject('Account', describe=True)
|
|
39
42
|
assert 'activateable' in account_sobject_describe
|
|
40
43
|
|
|
41
44
|
# Test the describe_object() method
|
|
42
|
-
account_describe =
|
|
45
|
+
account_describe = salesforce_unit.describe_object('Account')
|
|
43
46
|
assert 'activateable' in account_describe
|
|
44
47
|
|
|
45
48
|
|
|
46
|
-
def test_create_record(monkeypatch):
|
|
47
|
-
|
|
48
|
-
sfdc_object = resources.get_core_object()
|
|
49
|
+
def test_create_record(monkeypatch, salesforce_unit):
|
|
50
|
+
"""This function tests creating a Salesforce object record.
|
|
49
51
|
|
|
52
|
+
.. versionadded:: 1.1.0
|
|
53
|
+
|
|
54
|
+
.. version-changed:: 1.4.0
|
|
55
|
+
The function now utilizes the ``salesforce_unit`` fixture.
|
|
56
|
+
"""
|
|
50
57
|
# Overwrite the requests.post functionality with the mock_success_post() function
|
|
51
58
|
monkeypatch.setattr(requests, 'post', resources.mock_success_post)
|
|
52
59
|
|
|
@@ -54,5 +61,5 @@ def test_create_record(monkeypatch):
|
|
|
54
61
|
payload = {
|
|
55
62
|
"Name": "Express Logistics and Transport"
|
|
56
63
|
}
|
|
57
|
-
response =
|
|
64
|
+
response = salesforce_unit.create_sobject_record('Account', payload)
|
|
58
65
|
assert 'success' in response and response.get('success') is True and 'id' in response
|
{salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/test_soql.py
RENAMED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
# bandit: skip=B101
|
|
2
3
|
"""
|
|
3
|
-
:Module: salespyforce.utils.tests.
|
|
4
|
+
:Module: salespyforce.utils.tests.test_soql
|
|
4
5
|
:Synopsis: This module is used by pytest to test performing SOQL queries
|
|
5
6
|
:Created By: Jeff Shurtliff
|
|
6
7
|
:Last Modified: Jeff Shurtliff
|
|
7
|
-
:Modified Date:
|
|
8
|
+
:Modified Date: 20 Dec 2025
|
|
8
9
|
"""
|
|
9
10
|
|
|
10
|
-
from . import resources
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
def test_soql_query():
|
|
12
|
+
def test_soql_query(salesforce_unit):
|
|
14
13
|
"""This function tests the ability to perform a SOQL query.
|
|
15
14
|
|
|
16
15
|
.. versionadded:: 1.1.0
|
|
16
|
+
|
|
17
|
+
.. version-changed:: 1.4.0
|
|
18
|
+
The function now utilizes the ``salesforce_unit`` fixture.
|
|
17
19
|
"""
|
|
18
|
-
sfdc_object = resources.get_core_object()
|
|
19
20
|
soql_statement = 'SELECT Id FROM Account LIMIT 1'
|
|
20
|
-
soql_response =
|
|
21
|
+
soql_response = salesforce_unit.soql_query(soql_statement)
|
|
21
22
|
assert 'done' in soql_response and soql_response.get('done') is True
|
|
22
23
|
assert 'totalSize' in soql_response and 'records' in soql_response
|
|
23
|
-
|
{salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/test_sosl.py
RENAMED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
# bandit: skip=B101
|
|
2
3
|
"""
|
|
3
|
-
:Module: salespyforce.utils.tests.
|
|
4
|
-
:Synopsis: This module is used by pytest to test performing
|
|
4
|
+
:Module: salespyforce.utils.tests.test_sosl
|
|
5
|
+
:Synopsis: This module is used by pytest to test performing SOSL queries
|
|
5
6
|
:Created By: Jeff Shurtliff
|
|
6
7
|
:Last Modified: Jeff Shurtliff
|
|
7
|
-
:Modified Date:
|
|
8
|
+
:Modified Date: 20 Dec 2025
|
|
8
9
|
"""
|
|
9
10
|
|
|
10
11
|
import requests
|
|
@@ -12,18 +13,17 @@ import requests
|
|
|
12
13
|
from . import resources
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
def test_search_string(monkeypatch):
|
|
16
|
+
def test_search_string(monkeypatch, salesforce_unit):
|
|
16
17
|
"""This function tests the ability to search for a string using an SOSL query.
|
|
17
18
|
|
|
18
19
|
.. versionadded:: 1.1.0
|
|
19
|
-
"""
|
|
20
|
-
# Instantiate the core object
|
|
21
|
-
sfdc_object = resources.get_core_object()
|
|
22
20
|
|
|
21
|
+
.. version-changed:: 1.4.0
|
|
22
|
+
The function now utilizes the ``salesforce_unit`` fixture.
|
|
23
|
+
"""
|
|
23
24
|
# Overwrite the requests.post functionality with the mock_success_post() function
|
|
24
25
|
monkeypatch.setattr(requests, 'get', resources.mock_sosl_get)
|
|
25
26
|
|
|
26
27
|
# Perform the mock API call
|
|
27
|
-
result =
|
|
28
|
+
result = salesforce_unit.search_string('Account')
|
|
28
29
|
assert 'searchRecords' in result
|
|
29
|
-
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# bandit: skip=B101
|
|
3
|
+
"""
|
|
4
|
+
:Module: salespyforce.utils.tests.test_version_utils
|
|
5
|
+
:Synopsis: Pytest suite for salespyforce.utils.version helpers
|
|
6
|
+
:Created By: Jeff Shurtliff
|
|
7
|
+
:Last Modified: Jeff Shurtliff
|
|
8
|
+
:Modified Date: 20 Dec 2025
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import importlib
|
|
12
|
+
import importlib.metadata as importlib_metadata
|
|
13
|
+
|
|
14
|
+
from salespyforce.utils import version as version_utils
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_get_full_version_returns_metadata(monkeypatch):
|
|
18
|
+
"""This function tests get_full_version returns the package metadata."""
|
|
19
|
+
expected_version = "1.2.3"
|
|
20
|
+
monkeypatch.setattr(
|
|
21
|
+
version_utils, "version", lambda package: expected_version
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
assert version_utils.get_full_version() == expected_version
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_get_full_version_handles_missing_package(monkeypatch, caplog):
|
|
28
|
+
"""This function tests get_full_version fallback when package is missing."""
|
|
29
|
+
def raise_not_found(_package):
|
|
30
|
+
raise version_utils.PackageNotFoundError("salespyforce")
|
|
31
|
+
|
|
32
|
+
monkeypatch.setattr(version_utils, "version", raise_not_found)
|
|
33
|
+
|
|
34
|
+
with caplog.at_level("WARNING"):
|
|
35
|
+
version_string = version_utils.get_full_version()
|
|
36
|
+
|
|
37
|
+
assert version_string == "0.0.0"
|
|
38
|
+
assert any("falling back to '0.0.0'" in message for message in caplog.messages)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_get_major_minor_version_returns_two_components(monkeypatch):
|
|
42
|
+
"""This function tests extracting the major.minor version components."""
|
|
43
|
+
monkeypatch.setattr(
|
|
44
|
+
version_utils, "get_full_version", lambda: "2.3.4"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
assert version_utils.get_major_minor_version() == "2.3"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_get_major_minor_version_returns_full_when_missing_minor(monkeypatch):
|
|
51
|
+
"""This function tests get_major_minor_version with a single-part version."""
|
|
52
|
+
monkeypatch.setattr(version_utils, "get_full_version", lambda: "7")
|
|
53
|
+
|
|
54
|
+
assert version_utils.get_major_minor_version() == "7"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_dunder_version_matches_full_version(monkeypatch):
|
|
58
|
+
"""This function tests __version__ initialization uses get_full_version."""
|
|
59
|
+
real_version_function = importlib_metadata.version
|
|
60
|
+
expected_version = "9.8.7"
|
|
61
|
+
monkeypatch.setattr(
|
|
62
|
+
importlib_metadata, "version", lambda package: expected_version
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
reloaded_module = importlib.reload(version_utils)
|
|
66
|
+
assert reloaded_module.__version__ == expected_version
|
|
67
|
+
assert reloaded_module.get_full_version() == expected_version
|
|
68
|
+
|
|
69
|
+
importlib_metadata.version = real_version_function
|
|
70
|
+
importlib.reload(version_utils)
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
:Module: salespyforce.utils.tests.test_instantiate_object
|
|
4
|
-
:Synopsis: This module is used by pytest to test instantiating the core object
|
|
5
|
-
:Created By: Jeff Shurtliff
|
|
6
|
-
:Last Modified: Jeff Shurtliff
|
|
7
|
-
:Modified Date: 29 May 2023
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from . import resources
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def test_instantiate_core_object():
|
|
14
|
-
"""This function tests the ability to instantiate the core object.
|
|
15
|
-
|
|
16
|
-
.. versionadded:: 1.1.0
|
|
17
|
-
"""
|
|
18
|
-
sfdc_object = resources.get_core_object()
|
|
19
|
-
assert 'force.com' in sfdc_object.base_url
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def test_get_api_versions():
|
|
23
|
-
"""This function tests the get_api_versions() method in the core object.
|
|
24
|
-
|
|
25
|
-
.. versionadded:: 1.1.0
|
|
26
|
-
"""
|
|
27
|
-
sfdc_object = resources.get_core_object()
|
|
28
|
-
api_versions = sfdc_object.get_api_versions()
|
|
29
|
-
assert isinstance(api_versions, list) and 'version' in api_versions[0]
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def test_get_rest_resources():
|
|
33
|
-
"""This function tests the get_rest_resources() method in the core object.
|
|
34
|
-
|
|
35
|
-
.. versionadded:: 1.1.0
|
|
36
|
-
"""
|
|
37
|
-
sfdc_object = resources.get_core_object()
|
|
38
|
-
rest_resources = sfdc_object.get_rest_resources()
|
|
39
|
-
assert 'metadata' in rest_resources
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def test_get_org_limits():
|
|
43
|
-
"""This function tests the get_org_limits() method in the core object.
|
|
44
|
-
|
|
45
|
-
.. versionadded:: 1.1.0
|
|
46
|
-
"""
|
|
47
|
-
sfdc_object = resources.get_core_object()
|
|
48
|
-
org_limits = sfdc_object.get_org_limits()
|
|
49
|
-
assert 'DailyApiRequests' in org_limits
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/__init__.py
RENAMED
|
File without changes
|
{salespyforce-1.4.0.dev0 → salespyforce-1.4.0.dev1}/src/salespyforce/utils/tests/resources.py
RENAMED
|
File without changes
|
|
File without changes
|