channel-app 0.0.134__tar.gz → 0.0.135__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.
- {channel_app-0.0.134 → channel_app-0.0.135}/PKG-INFO +1 -1
- channel_app-0.0.135/channel_app/omnitron/commands/tests/test_products.py +494 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app.egg-info/PKG-INFO +1 -1
- {channel_app-0.0.134 → channel_app-0.0.135}/setup.py +1 -1
- channel_app-0.0.134/channel_app/omnitron/commands/tests/test_products.py +0 -247
- {channel_app-0.0.134 → channel_app-0.0.135}/.gitignore +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/.vscode/settings.json +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/Makefile +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/Procfile-dist +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/README.md +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/akinon.json-dist +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/bitbucket-pipelines.yml +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/build.sh-dist +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/order/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/order/service.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/product/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/product/service.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/product_image/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/product_image/service.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/product_price/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/product_price/service.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/product_stock/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/product_stock/service.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/setup/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/app/setup/service.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/orders/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/orders/orders.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/product_categories.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/product_images.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/product_prices.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/product_stocks.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/products.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/setup.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/integration.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/clients.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/commands.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/data.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/integration.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/products.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/settings.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/tests/test_clients.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/tests.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/core/utilities.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/batch_request.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/batch_requests.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/error_reports.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/integration_actions.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/orders/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/orders/addresses.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/orders/cargo_companies.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/orders/customers.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/orders/orders.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/product_categories.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/product_images.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/product_prices.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/product_stocks.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/products.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/setup.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/tests/__init__.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/constants.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/exceptions.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/integration.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app.egg-info/SOURCES.txt +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app.egg-info/dependency_links.txt +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app.egg-info/requires.txt +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/channel_app.egg-info/top_level.txt +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/Makefile +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/make.bat +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/requirements.txt +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/architecture.rst +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/command_reference.rst +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/conf.py +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/flows.rst +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/images/async.png +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/images/batch_request_state_machine.png +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/images/sync.png +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/index.rst +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/installation_and_usage.rst +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/docs/source/terminology.rst +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/requirements-dev.txt +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/requirements.txt +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/setup.cfg +0 -0
- {channel_app-0.0.134 → channel_app-0.0.135}/tox.ini +0 -0
@@ -0,0 +1,494 @@
|
|
1
|
+
from unittest.mock import MagicMock, patch
|
2
|
+
from omnisdk.base_client import BaseClient
|
3
|
+
from omnisdk.omnitron.endpoints import (
|
4
|
+
ChannelIntegrationActionEndpoint,
|
5
|
+
ChannelProductEndpoint,
|
6
|
+
)
|
7
|
+
from omnisdk.omnitron.models import ChannelAttributeConfig
|
8
|
+
|
9
|
+
from channel_app.core.commands import OmnitronCommandInterface
|
10
|
+
from channel_app.core.tests import BaseTestCaseMixin
|
11
|
+
from channel_app.omnitron.commands.products import (
|
12
|
+
GetDeletedProducts,
|
13
|
+
GetInsertedProducts,
|
14
|
+
GetUpdatedProducts,
|
15
|
+
Product, GetMappedProducts, GetProductPrices,
|
16
|
+
)
|
17
|
+
from channel_app.omnitron.constants import BatchRequestStatus
|
18
|
+
|
19
|
+
|
20
|
+
class TestGetInsertedProducts(BaseTestCaseMixin):
|
21
|
+
"""
|
22
|
+
Test case for GetInsertedProducts
|
23
|
+
|
24
|
+
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetInsertedProducts
|
25
|
+
"""
|
26
|
+
def setUp(self) -> None:
|
27
|
+
self.get_inserted_products = GetInsertedProducts(
|
28
|
+
integration=self.mock_integration
|
29
|
+
)
|
30
|
+
self.sample_products = [
|
31
|
+
Product(name='test', failed_reason_type=None),
|
32
|
+
Product(name='test2', failed_reason_type='error')
|
33
|
+
]
|
34
|
+
self.limit = 1
|
35
|
+
|
36
|
+
@patch.object(GetInsertedProducts, 'get_products')
|
37
|
+
def test_get_data(self, mock_get_products):
|
38
|
+
mock_get_products.return_value = [self.sample_products[0]]
|
39
|
+
self.get_inserted_products.BATCH_SIZE = self.limit
|
40
|
+
|
41
|
+
products = self.get_inserted_products.get_data()
|
42
|
+
|
43
|
+
self.assertEqual(len(products), 1)
|
44
|
+
self.assertEqual(products[0].name, 'test')
|
45
|
+
mock_get_products.assert_called_once_with(limit=self.limit)
|
46
|
+
|
47
|
+
@patch.object(GetInsertedProducts, 'get_products')
|
48
|
+
def test_get_data_with_limit_in_objects_dict(self, mock_get_products):
|
49
|
+
mock_get_products.return_value = [self.sample_products[0]]
|
50
|
+
self.get_inserted_products.objects = {'limit': self.limit}
|
51
|
+
|
52
|
+
products = self.get_inserted_products.get_data()
|
53
|
+
|
54
|
+
self.assertEqual(len(products), 1)
|
55
|
+
self.assertEqual(products[0].name, 'test')
|
56
|
+
mock_get_products.assert_called_once_with(limit=self.limit)
|
57
|
+
|
58
|
+
def test_update_state_property(self):
|
59
|
+
self.assertEqual(
|
60
|
+
self.get_inserted_products.update_state,
|
61
|
+
BatchRequestStatus.commit
|
62
|
+
)
|
63
|
+
|
64
|
+
def test_validated_data(self):
|
65
|
+
validated_products = self.get_inserted_products.validated_data(
|
66
|
+
self.sample_products
|
67
|
+
)
|
68
|
+
|
69
|
+
self.assertIn(self.sample_products[0], validated_products)
|
70
|
+
self.assertNotIn(self.sample_products[1], validated_products)
|
71
|
+
|
72
|
+
@patch('channel_app.core.clients.OmnitronApiClient')
|
73
|
+
@patch.object(BaseClient, 'get_instance')
|
74
|
+
@patch.object(GetInsertedProducts, 'update_batch_request')
|
75
|
+
@patch.object(GetInsertedProducts, 'create_batch_objects')
|
76
|
+
@patch.object(ChannelProductEndpoint, 'list')
|
77
|
+
def test_get_products(
|
78
|
+
self,
|
79
|
+
mock_list,
|
80
|
+
mock_create_batch_objects,
|
81
|
+
mock_update_batch_request,
|
82
|
+
mock_get_instance,
|
83
|
+
mock_omnitron_api_client,
|
84
|
+
):
|
85
|
+
mock_list.return_value = self.sample_products
|
86
|
+
|
87
|
+
products = self.get_inserted_products.get_products(
|
88
|
+
limit=self.limit + 1
|
89
|
+
)
|
90
|
+
|
91
|
+
self.assertEqual(len(products), 2)
|
92
|
+
self.assertEqual(products[0].name, 'test')
|
93
|
+
self.assertEqual(products[1].name, 'test2')
|
94
|
+
|
95
|
+
|
96
|
+
class TestGetUpdatedProducts(BaseTestCaseMixin):
|
97
|
+
"""
|
98
|
+
Test case for GetUpdatedProducts
|
99
|
+
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetUpdatedProducts
|
100
|
+
"""
|
101
|
+
def setUp(self):
|
102
|
+
self.get_inserted_products = GetInsertedProducts(
|
103
|
+
integration=self.mock_integration
|
104
|
+
)
|
105
|
+
self.get_updated_products = GetUpdatedProducts(
|
106
|
+
integration=self.mock_integration
|
107
|
+
)
|
108
|
+
self.sample_products = [
|
109
|
+
Product(
|
110
|
+
pk=1,
|
111
|
+
name='test',
|
112
|
+
failed_reason_type=None,
|
113
|
+
modified_date='2021-01-01T00:00:00Z'
|
114
|
+
),
|
115
|
+
Product(
|
116
|
+
pk=2,
|
117
|
+
name='test2',
|
118
|
+
failed_reason_type='error',
|
119
|
+
modified_date='2021-01-01T00:00:00Z'
|
120
|
+
)
|
121
|
+
]
|
122
|
+
|
123
|
+
@patch.object(GetInsertedProducts, 'get_products')
|
124
|
+
@patch.object(GetUpdatedProducts, 'get_integration_actions')
|
125
|
+
def test_get_data(self, mock_get_integration_actions, mock_get_products):
|
126
|
+
mock_get_integration_actions.return_value = self.sample_products
|
127
|
+
mock_get_products.return_value = [self.sample_products[0]]
|
128
|
+
products = self.get_updated_products.get_data()
|
129
|
+
|
130
|
+
self.assertEqual(len(products), 1)
|
131
|
+
self.assertEqual(products[0].name, 'test')
|
132
|
+
|
133
|
+
@patch('channel_app.core.clients.OmnitronApiClient')
|
134
|
+
@patch.object(BaseClient, 'get_instance')
|
135
|
+
@patch.object(ChannelIntegrationActionEndpoint, '_list')
|
136
|
+
def test_get_integration_actions(
|
137
|
+
self,
|
138
|
+
mock_list,
|
139
|
+
mock_get_instance,
|
140
|
+
mock_omnitron_api_client
|
141
|
+
):
|
142
|
+
example_response = MagicMock()
|
143
|
+
example_response.json.return_value = [
|
144
|
+
{
|
145
|
+
'id': 1,
|
146
|
+
'channel': 1,
|
147
|
+
'content_type': 'product',
|
148
|
+
'remote_id': 1,
|
149
|
+
'object_id': 1,
|
150
|
+
},
|
151
|
+
{
|
152
|
+
'id': 2,
|
153
|
+
'channel': 1,
|
154
|
+
'content_type': 'product',
|
155
|
+
'remote_id': 2,
|
156
|
+
'object_id': 2,
|
157
|
+
}
|
158
|
+
]
|
159
|
+
mock_list.return_value = example_response
|
160
|
+
|
161
|
+
products = self.get_updated_products.get_integration_actions(
|
162
|
+
self.sample_products
|
163
|
+
)
|
164
|
+
|
165
|
+
for product in products:
|
166
|
+
for key, value \
|
167
|
+
in example_response.json.return_value[product.pk - 1].items():
|
168
|
+
self.assertEqual(
|
169
|
+
getattr(product.integration_action, key),
|
170
|
+
value
|
171
|
+
)
|
172
|
+
|
173
|
+
|
174
|
+
def test_get_integration_actions_without_product(self):
|
175
|
+
products = self.get_updated_products.get_integration_actions([])
|
176
|
+
self.assertEqual(products, [])
|
177
|
+
|
178
|
+
|
179
|
+
class TestGetInsertedOrUpdatedProducts(
|
180
|
+
TestGetInsertedProducts,
|
181
|
+
BaseTestCaseMixin
|
182
|
+
):
|
183
|
+
"""
|
184
|
+
Test case for GetInsertedOrUpdatedProducts
|
185
|
+
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetInsertedOrUpdatedProducts
|
186
|
+
"""
|
187
|
+
def setUp(self) -> None:
|
188
|
+
self.get_inserted_products = GetInsertedProducts(
|
189
|
+
integration=self.mock_integration
|
190
|
+
)
|
191
|
+
self.get_inserted_products.path = "inserts_or_updates"
|
192
|
+
return super().setUp()
|
193
|
+
|
194
|
+
|
195
|
+
class TestGetDeletedProducts(BaseTestCaseMixin):
|
196
|
+
"""
|
197
|
+
Test case for GetDeletedProducts
|
198
|
+
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetDeletedProducts
|
199
|
+
"""
|
200
|
+
|
201
|
+
def setUp(self) -> None:
|
202
|
+
self.get_deleted_products = GetDeletedProducts(
|
203
|
+
integration=self.mock_integration
|
204
|
+
)
|
205
|
+
self.products = [
|
206
|
+
{
|
207
|
+
"pk": 23,
|
208
|
+
"channel": 3,
|
209
|
+
"content_type": {
|
210
|
+
"id": 1,
|
211
|
+
"app_label": "products",
|
212
|
+
"model": "product"
|
213
|
+
},
|
214
|
+
"object_id": 1,
|
215
|
+
"remote_id": None,
|
216
|
+
"version_date": "2023-11-07T08:58:16.079727Z",
|
217
|
+
"state": {},
|
218
|
+
"modified_date": "2023-11-08T09:11:56.919937Z",
|
219
|
+
"local_batch_id": "7c43e5fb-32be-4a18-a6fa-539c9d2485ee",
|
220
|
+
"status": "processing",
|
221
|
+
"created_date": "2023-11-08T09:11:56.919929Z"
|
222
|
+
}
|
223
|
+
]
|
224
|
+
|
225
|
+
@patch.object(GetDeletedProducts, 'get_deleted_products_ia')
|
226
|
+
def test_get_data(self, mock_get_deleted_products_ia):
|
227
|
+
mock_get_deleted_products_ia.return_value = self.products
|
228
|
+
products = self.get_deleted_products.get_data()
|
229
|
+
self.assertEqual(len(products), 1)
|
230
|
+
|
231
|
+
product = products[0]
|
232
|
+
self.assertEqual(product.get('pk'), 23)
|
233
|
+
|
234
|
+
@patch('channel_app.core.clients.OmnitronApiClient')
|
235
|
+
@patch.object(BaseClient, 'get_instance')
|
236
|
+
@patch.object(ChannelIntegrationActionEndpoint, '_list')
|
237
|
+
def test_get_deleted_products_ia(
|
238
|
+
self,
|
239
|
+
mock_list,
|
240
|
+
mock_get_instance,
|
241
|
+
mock_omnitron_api_client
|
242
|
+
):
|
243
|
+
example_response = MagicMock()
|
244
|
+
example_response.json.return_value = self.products
|
245
|
+
mock_list.return_value = example_response
|
246
|
+
products_ia = self.get_deleted_products.get_deleted_products_ia()
|
247
|
+
self.assertEqual(len(products_ia), 1)
|
248
|
+
|
249
|
+
product = products_ia[0].get_parameters()
|
250
|
+
self.assertEqual(product.get('pk'), 23)
|
251
|
+
|
252
|
+
|
253
|
+
class TestGetMappedProducts(BaseTestCaseMixin):
|
254
|
+
"""
|
255
|
+
Test case for GetMappedProducts
|
256
|
+
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetMappedProducts
|
257
|
+
"""
|
258
|
+
|
259
|
+
def setUp(self) -> None:
|
260
|
+
self.get_mapped_products = GetMappedProducts(
|
261
|
+
integration=self.mock_integration
|
262
|
+
)
|
263
|
+
self.sample_products = [
|
264
|
+
Product(
|
265
|
+
pk=1,
|
266
|
+
name='test',
|
267
|
+
failed_reason_type=None,
|
268
|
+
modified_date='2021-01-01T00:00:00Z'
|
269
|
+
),
|
270
|
+
Product(
|
271
|
+
pk=2,
|
272
|
+
name='test2',
|
273
|
+
failed_reason_type='error',
|
274
|
+
modified_date='2021-01-01T00:00:00Z'
|
275
|
+
)
|
276
|
+
]
|
277
|
+
|
278
|
+
@patch.object(GetMappedProducts, 'get_mapping')
|
279
|
+
def test_get_data(self, mock_get_mapping):
|
280
|
+
mock_get_mapping.return_value = self.sample_products
|
281
|
+
result = self.get_mapped_products.get_data()
|
282
|
+
self.assertEqual(len(result), 2)
|
283
|
+
|
284
|
+
@patch.object(GetMappedProducts, 'check_product')
|
285
|
+
def test_validated_data(self, mock_check_product):
|
286
|
+
data = self.sample_products
|
287
|
+
self.get_mapped_products.validated_data(data)
|
288
|
+
self.assertEqual(mock_check_product.call_count, 2)
|
289
|
+
|
290
|
+
@patch.object(GetMappedProducts, 'get_attribute_config_list')
|
291
|
+
@patch.object(GetMappedProducts, 'update_and_check_product')
|
292
|
+
def test_check_product_gets_attribute_config_list(
|
293
|
+
self,
|
294
|
+
mock_update_and_check_product,
|
295
|
+
mock_get_attribute_config_list
|
296
|
+
):
|
297
|
+
product = Product()
|
298
|
+
product.mapped_attributes = MagicMock()
|
299
|
+
product.mapped_attributes.attribute_set_id = 1
|
300
|
+
product.mapped_attributes.mapped_attribute_values = {
|
301
|
+
"1": {
|
302
|
+
"value": "test"
|
303
|
+
}
|
304
|
+
}
|
305
|
+
mock_get_attribute_config_list.return_value = [
|
306
|
+
ChannelAttributeConfig()
|
307
|
+
]
|
308
|
+
self.get_mapped_products.check_product(
|
309
|
+
product,
|
310
|
+
{}
|
311
|
+
)
|
312
|
+
mock_get_attribute_config_list.assert_called_once()
|
313
|
+
|
314
|
+
@patch.object(GetMappedProducts, 'check_attribute_value_defined')
|
315
|
+
@patch.object(GetMappedProducts, 'check_required')
|
316
|
+
def test_update_and_check_product_checks_attribute_value_and_required(
|
317
|
+
self,
|
318
|
+
mock_check_required,
|
319
|
+
mock_check_attribute_value_defined
|
320
|
+
):
|
321
|
+
product = Product()
|
322
|
+
product.mapped_attributes = MagicMock()
|
323
|
+
product.mapped_attributes.mapped_attribute_values = {}
|
324
|
+
config = ChannelAttributeConfig()
|
325
|
+
config.attribute_remote_id = 1
|
326
|
+
config.is_required = True
|
327
|
+
config.is_variant = True
|
328
|
+
config.is_custom = True
|
329
|
+
config.is_meta = True
|
330
|
+
config.attribute = {
|
331
|
+
"pk": 1,
|
332
|
+
"name": "test",
|
333
|
+
}
|
334
|
+
result = self.get_mapped_products.update_and_check_product(
|
335
|
+
config,
|
336
|
+
product
|
337
|
+
)
|
338
|
+
self.assertFalse(result)
|
339
|
+
|
340
|
+
@patch.object(GetMappedProducts, 'check_attribute_value_defined')
|
341
|
+
@patch.object(GetMappedProducts, 'check_required')
|
342
|
+
def test_update_and_check_product(
|
343
|
+
self,
|
344
|
+
mock_check_required,
|
345
|
+
mock_check_attribute_value_defined
|
346
|
+
):
|
347
|
+
product = Product()
|
348
|
+
product.mapped_attributes = MagicMock()
|
349
|
+
product.mapped_attributes.mapped_attribute_values = {
|
350
|
+
"1": {
|
351
|
+
"value": "test"
|
352
|
+
}
|
353
|
+
}
|
354
|
+
config = ChannelAttributeConfig()
|
355
|
+
config.attribute_remote_id = 1
|
356
|
+
config.is_required = True
|
357
|
+
config.is_variant = True
|
358
|
+
config.is_custom = True
|
359
|
+
config.is_meta = True
|
360
|
+
config.attribute = {
|
361
|
+
"pk": 1,
|
362
|
+
"name": "test",
|
363
|
+
}
|
364
|
+
result = self.get_mapped_products.update_and_check_product(
|
365
|
+
config,
|
366
|
+
product
|
367
|
+
)
|
368
|
+
self.assertTrue(result)
|
369
|
+
|
370
|
+
@patch.object(GetMappedProducts, 'get_attribute_config_list')
|
371
|
+
def test_get_attribute_config_list_returns_configs_data(
|
372
|
+
self,
|
373
|
+
mock_get_attribute_config_list
|
374
|
+
):
|
375
|
+
config = ChannelAttributeConfig()
|
376
|
+
mock_get_attribute_config_list.return_value = [
|
377
|
+
config
|
378
|
+
]
|
379
|
+
result = self.get_mapped_products.get_attribute_config_list(
|
380
|
+
{"attribute_set": 1, "limit": 10}
|
381
|
+
)
|
382
|
+
self.assertEqual(result, [config])
|
383
|
+
|
384
|
+
def test_check_attribute_value_defined_raises_exception_when_mapped_value_not_defined(self):
|
385
|
+
mapped_attributes_obj = MagicMock()
|
386
|
+
mapped_attributes_obj.mapped_attributes = {"name": "value"}
|
387
|
+
mapped_attributes_obj.mapped_attribute_values = {}
|
388
|
+
config = ChannelAttributeConfig()
|
389
|
+
config.attribute = {"pk": 1, "name": "name"}
|
390
|
+
config.attribute_set = {"pk": 1, "name": "name"}
|
391
|
+
config.is_custom = False
|
392
|
+
with self.assertRaises(Exception):
|
393
|
+
self.get_mapped_products.check_attribute_value_defined(
|
394
|
+
config,
|
395
|
+
mapped_attributes_obj
|
396
|
+
)
|
397
|
+
|
398
|
+
def test_check_required_raises_exception_when_required_attribute_missing(self):
|
399
|
+
product = Product()
|
400
|
+
product.sku = "sku"
|
401
|
+
self.get_mapped_products.integration = MagicMock()
|
402
|
+
self.get_mapped_products.integration.channel_id = 1
|
403
|
+
mapped_attributes = {}
|
404
|
+
config = ChannelAttributeConfig()
|
405
|
+
config.attribute = {"name": "name"}
|
406
|
+
config.is_required = True
|
407
|
+
with self.assertRaises(Exception):
|
408
|
+
self.get_mapped_products.check_required(
|
409
|
+
product,
|
410
|
+
config,
|
411
|
+
mapped_attributes
|
412
|
+
)
|
413
|
+
|
414
|
+
@patch.object(GetMappedProducts, 'get_mapping')
|
415
|
+
def test_get_mapping_returns_mapped_products(self, mock_get_mapping):
|
416
|
+
product = Product()
|
417
|
+
mock_get_mapping.return_value = [product]
|
418
|
+
result = self.get_mapped_products.get_mapping([product])
|
419
|
+
self.assertEqual(result, [product])
|
420
|
+
|
421
|
+
@patch.object(GetMappedProducts, 'get_mapping')
|
422
|
+
def test_get_mapping_returns_empty_list_when_no_products(self, mock_get_mapping):
|
423
|
+
mock_get_mapping.return_value = []
|
424
|
+
result = self.get_mapped_products.get_mapping([])
|
425
|
+
self.assertEqual(result, [])
|
426
|
+
|
427
|
+
|
428
|
+
class TestGetMappedProductsWithOutCommit(TestGetMappedProducts):
|
429
|
+
pass
|
430
|
+
|
431
|
+
|
432
|
+
class TestGetProductPrices(BaseTestCaseMixin):
|
433
|
+
"""
|
434
|
+
Test case for GetProductPrices
|
435
|
+
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetProductPrices
|
436
|
+
"""
|
437
|
+
|
438
|
+
def setUp(self) -> None:
|
439
|
+
self.get_product_prices = GetProductPrices(
|
440
|
+
integration=self.mock_integration
|
441
|
+
)
|
442
|
+
|
443
|
+
@patch.object(BaseClient, 'get_instance')
|
444
|
+
@patch.object(GetProductPrices, 'get_prices')
|
445
|
+
def test_successful_product_price_retrieval(
|
446
|
+
self,
|
447
|
+
mock_get_instance,
|
448
|
+
mock_get_prices
|
449
|
+
):
|
450
|
+
products = [Product(pk=i, productprice=10) for i in range(1, 6)]
|
451
|
+
self.get_product_prices.objects = products
|
452
|
+
|
453
|
+
result = self.get_product_prices.get_data()
|
454
|
+
self.assertEqual(result, products)
|
455
|
+
|
456
|
+
@patch.object(GetProductPrices, 'get_prices')
|
457
|
+
@patch.object(BaseClient, 'get_instance')
|
458
|
+
def test_product_price_retrieval_with_successful_get_product_price(
|
459
|
+
self,
|
460
|
+
mock_get_instance,
|
461
|
+
mock_get_prices
|
462
|
+
):
|
463
|
+
products = [Product(pk=i) for i in range(1, 6)]
|
464
|
+
|
465
|
+
price_list = []
|
466
|
+
for product in products:
|
467
|
+
price = MagicMock()
|
468
|
+
price.product = product.pk
|
469
|
+
price_list.append(price)
|
470
|
+
|
471
|
+
mock_get_prices.return_value = price_list
|
472
|
+
result = self.get_product_prices.get_product_price(products)
|
473
|
+
self.assertEqual(result, products)
|
474
|
+
|
475
|
+
@patch.object(GetProductPrices, 'get_prices')
|
476
|
+
@patch.object(BaseClient, 'get_instance')
|
477
|
+
def test_product_price_retrieval_with_failed_get_product_price(
|
478
|
+
self,
|
479
|
+
mock_get_instance,
|
480
|
+
mock_get_prices
|
481
|
+
):
|
482
|
+
products = [Product(pk=i, product_price=0) for i in range(1, 6)]
|
483
|
+
|
484
|
+
price_list = []
|
485
|
+
for product in products:
|
486
|
+
price = MagicMock()
|
487
|
+
price.product = product.pk
|
488
|
+
|
489
|
+
if len(price_list) < len(products) - 1:
|
490
|
+
price_list.append(price)
|
491
|
+
|
492
|
+
mock_get_prices.return_value = price_list
|
493
|
+
result = self.get_product_prices.get_product_price(products)
|
494
|
+
self.assertFalse(hasattr(result[-1], 'productprice'))
|
@@ -1,247 +0,0 @@
|
|
1
|
-
from unittest.mock import MagicMock, patch
|
2
|
-
from omnisdk.base_client import BaseClient
|
3
|
-
from omnisdk.omnitron.endpoints import (
|
4
|
-
ChannelIntegrationActionEndpoint,
|
5
|
-
ChannelProductEndpoint,
|
6
|
-
)
|
7
|
-
from channel_app.core.tests import BaseTestCaseMixin
|
8
|
-
from channel_app.omnitron.commands.products import (
|
9
|
-
GetDeletedProducts,
|
10
|
-
GetInsertedProducts,
|
11
|
-
GetUpdatedProducts,
|
12
|
-
Product,
|
13
|
-
)
|
14
|
-
from channel_app.omnitron.constants import BatchRequestStatus
|
15
|
-
|
16
|
-
|
17
|
-
class TestGetInsertedProducts(BaseTestCaseMixin):
|
18
|
-
"""
|
19
|
-
Test case for GetInsertedProducts
|
20
|
-
|
21
|
-
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetInsertedProducts
|
22
|
-
"""
|
23
|
-
def setUp(self) -> None:
|
24
|
-
self.get_inserted_products = GetInsertedProducts(
|
25
|
-
integration=self.mock_integration
|
26
|
-
)
|
27
|
-
self.sample_products = [
|
28
|
-
Product(name='test', failed_reason_type=None),
|
29
|
-
Product(name='test2', failed_reason_type='error')
|
30
|
-
]
|
31
|
-
self.limit = 1
|
32
|
-
|
33
|
-
@patch.object(GetInsertedProducts, 'get_products')
|
34
|
-
def test_get_data(self, mock_get_products):
|
35
|
-
mock_get_products.return_value = [self.sample_products[0]]
|
36
|
-
self.get_inserted_products.BATCH_SIZE = self.limit
|
37
|
-
|
38
|
-
products = self.get_inserted_products.get_data()
|
39
|
-
|
40
|
-
self.assertEqual(len(products), 1)
|
41
|
-
self.assertEqual(products[0].name, 'test')
|
42
|
-
mock_get_products.assert_called_once_with(limit=self.limit)
|
43
|
-
|
44
|
-
@patch.object(GetInsertedProducts, 'get_products')
|
45
|
-
def test_get_data_with_limit_in_objects_dict(self, mock_get_products):
|
46
|
-
mock_get_products.return_value = [self.sample_products[0]]
|
47
|
-
self.get_inserted_products.objects = {'limit': self.limit}
|
48
|
-
|
49
|
-
products = self.get_inserted_products.get_data()
|
50
|
-
|
51
|
-
self.assertEqual(len(products), 1)
|
52
|
-
self.assertEqual(products[0].name, 'test')
|
53
|
-
mock_get_products.assert_called_once_with(limit=self.limit)
|
54
|
-
|
55
|
-
def test_update_state_property(self):
|
56
|
-
self.assertEqual(
|
57
|
-
self.get_inserted_products.update_state,
|
58
|
-
BatchRequestStatus.commit
|
59
|
-
)
|
60
|
-
|
61
|
-
def test_validated_data(self):
|
62
|
-
validated_products = self.get_inserted_products.validated_data(
|
63
|
-
self.sample_products
|
64
|
-
)
|
65
|
-
|
66
|
-
self.assertIn(self.sample_products[0], validated_products)
|
67
|
-
self.assertNotIn(self.sample_products[1], validated_products)
|
68
|
-
|
69
|
-
@patch('channel_app.core.clients.OmnitronApiClient')
|
70
|
-
@patch.object(BaseClient, 'get_instance')
|
71
|
-
@patch.object(GetInsertedProducts, 'update_batch_request')
|
72
|
-
@patch.object(GetInsertedProducts, 'create_batch_objects')
|
73
|
-
@patch.object(ChannelProductEndpoint, 'list')
|
74
|
-
def test_get_products(
|
75
|
-
self,
|
76
|
-
mock_list,
|
77
|
-
mock_create_batch_objects,
|
78
|
-
mock_update_batch_request,
|
79
|
-
mock_get_instance,
|
80
|
-
mock_omnitron_api_client,
|
81
|
-
):
|
82
|
-
mock_list.return_value = self.sample_products
|
83
|
-
|
84
|
-
products = self.get_inserted_products.get_products(
|
85
|
-
limit=self.limit + 1
|
86
|
-
)
|
87
|
-
|
88
|
-
self.assertEqual(len(products), 2)
|
89
|
-
self.assertEqual(products[0].name, 'test')
|
90
|
-
self.assertEqual(products[1].name, 'test2')
|
91
|
-
|
92
|
-
|
93
|
-
class TestGetUpdatedProducts(BaseTestCaseMixin):
|
94
|
-
"""
|
95
|
-
Test case for GetUpdatedProducts
|
96
|
-
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetUpdatedProducts
|
97
|
-
"""
|
98
|
-
def setUp(self):
|
99
|
-
self.get_inserted_products = GetInsertedProducts(
|
100
|
-
integration=self.mock_integration
|
101
|
-
)
|
102
|
-
self.get_updated_products = GetUpdatedProducts(
|
103
|
-
integration=self.mock_integration
|
104
|
-
)
|
105
|
-
self.sample_products = [
|
106
|
-
Product(
|
107
|
-
pk=1,
|
108
|
-
name='test',
|
109
|
-
failed_reason_type=None,
|
110
|
-
modified_date='2021-01-01T00:00:00Z'
|
111
|
-
),
|
112
|
-
Product(
|
113
|
-
pk=2,
|
114
|
-
name='test2',
|
115
|
-
failed_reason_type='error',
|
116
|
-
modified_date='2021-01-01T00:00:00Z'
|
117
|
-
)
|
118
|
-
]
|
119
|
-
|
120
|
-
@patch.object(GetInsertedProducts, 'get_products')
|
121
|
-
@patch.object(GetUpdatedProducts, 'get_integration_actions')
|
122
|
-
def test_get_data(self, mock_get_integration_actions, mock_get_products):
|
123
|
-
mock_get_integration_actions.return_value = self.sample_products
|
124
|
-
mock_get_products.return_value = [self.sample_products[0]]
|
125
|
-
products = self.get_updated_products.get_data()
|
126
|
-
|
127
|
-
self.assertEqual(len(products), 1)
|
128
|
-
self.assertEqual(products[0].name, 'test')
|
129
|
-
|
130
|
-
@patch('channel_app.core.clients.OmnitronApiClient')
|
131
|
-
@patch.object(BaseClient, 'get_instance')
|
132
|
-
@patch.object(ChannelIntegrationActionEndpoint, '_list')
|
133
|
-
def test_get_integration_actions(
|
134
|
-
self,
|
135
|
-
mock_list,
|
136
|
-
mock_get_instance,
|
137
|
-
mock_omnitron_api_client
|
138
|
-
):
|
139
|
-
example_response = MagicMock()
|
140
|
-
example_response.json.return_value = [
|
141
|
-
{
|
142
|
-
'id': 1,
|
143
|
-
'channel': 1,
|
144
|
-
'content_type': 'product',
|
145
|
-
'remote_id': 1,
|
146
|
-
'object_id': 1,
|
147
|
-
},
|
148
|
-
{
|
149
|
-
'id': 2,
|
150
|
-
'channel': 1,
|
151
|
-
'content_type': 'product',
|
152
|
-
'remote_id': 2,
|
153
|
-
'object_id': 2,
|
154
|
-
}
|
155
|
-
]
|
156
|
-
mock_list.return_value = example_response
|
157
|
-
|
158
|
-
products = self.get_updated_products.get_integration_actions(
|
159
|
-
self.sample_products
|
160
|
-
)
|
161
|
-
|
162
|
-
for product in products:
|
163
|
-
for key, value \
|
164
|
-
in example_response.json.return_value[product.pk - 1].items():
|
165
|
-
self.assertEqual(
|
166
|
-
getattr(product.integration_action, key),
|
167
|
-
value
|
168
|
-
)
|
169
|
-
|
170
|
-
|
171
|
-
def test_get_integration_actions_without_product(self):
|
172
|
-
products = self.get_updated_products.get_integration_actions([])
|
173
|
-
self.assertEqual(products, [])
|
174
|
-
|
175
|
-
|
176
|
-
class TestGetInsertedOrUpdatedProducts(
|
177
|
-
TestGetInsertedProducts,
|
178
|
-
BaseTestCaseMixin
|
179
|
-
):
|
180
|
-
"""
|
181
|
-
Test case for GetInsertedOrUpdatedProducts
|
182
|
-
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetInsertedOrUpdatedProducts
|
183
|
-
"""
|
184
|
-
def setUp(self) -> None:
|
185
|
-
self.get_inserted_products = GetInsertedProducts(
|
186
|
-
integration=self.mock_integration
|
187
|
-
)
|
188
|
-
self.get_inserted_products.path = "inserts_or_updates"
|
189
|
-
return super().setUp()
|
190
|
-
|
191
|
-
|
192
|
-
class TestGetDeletedProducts(BaseTestCaseMixin):
|
193
|
-
"""
|
194
|
-
Test case for GetDeletedProducts
|
195
|
-
run: python -m unittest channel_app.omnitron.commands.tests.test_products.TestGetDeletedProducts
|
196
|
-
"""
|
197
|
-
|
198
|
-
def setUp(self) -> None:
|
199
|
-
self.get_deleted_products = GetDeletedProducts(
|
200
|
-
integration=self.mock_integration
|
201
|
-
)
|
202
|
-
self.products = [
|
203
|
-
{
|
204
|
-
"pk": 23,
|
205
|
-
"channel": 3,
|
206
|
-
"content_type": {
|
207
|
-
"id": 1,
|
208
|
-
"app_label": "products",
|
209
|
-
"model": "product"
|
210
|
-
},
|
211
|
-
"object_id": 1,
|
212
|
-
"remote_id": None,
|
213
|
-
"version_date": "2023-11-07T08:58:16.079727Z",
|
214
|
-
"state": {},
|
215
|
-
"modified_date": "2023-11-08T09:11:56.919937Z",
|
216
|
-
"local_batch_id": "7c43e5fb-32be-4a18-a6fa-539c9d2485ee",
|
217
|
-
"status": "processing",
|
218
|
-
"created_date": "2023-11-08T09:11:56.919929Z"
|
219
|
-
}
|
220
|
-
]
|
221
|
-
|
222
|
-
@patch.object(GetDeletedProducts, 'get_deleted_products_ia')
|
223
|
-
def test_get_data(self, mock_get_deleted_products_ia):
|
224
|
-
mock_get_deleted_products_ia.return_value = self.products
|
225
|
-
products = self.get_deleted_products.get_data()
|
226
|
-
self.assertEqual(len(products), 1)
|
227
|
-
|
228
|
-
product = products[0]
|
229
|
-
self.assertEqual(product.get('pk'), 23)
|
230
|
-
|
231
|
-
@patch('channel_app.core.clients.OmnitronApiClient')
|
232
|
-
@patch.object(BaseClient, 'get_instance')
|
233
|
-
@patch.object(ChannelIntegrationActionEndpoint, '_list')
|
234
|
-
def test_get_deleted_products_ia(
|
235
|
-
self,
|
236
|
-
mock_list,
|
237
|
-
mock_get_instance,
|
238
|
-
mock_omnitron_api_client
|
239
|
-
):
|
240
|
-
example_response = MagicMock()
|
241
|
-
example_response.json.return_value = self.products
|
242
|
-
mock_list.return_value = example_response
|
243
|
-
products_ia = self.get_deleted_products.get_deleted_products_ia()
|
244
|
-
self.assertEqual(len(products_ia), 1)
|
245
|
-
|
246
|
-
product = products_ia[0].get_parameters()
|
247
|
-
self.assertEqual(product.get('pk'), 23)
|
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
|
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
|
File without changes
|
File without changes
|
{channel_app-0.0.134 → channel_app-0.0.135}/channel_app/channel/commands/product_categories.py
RENAMED
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
|
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
|
{channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/integration_actions.py
RENAMED
File without changes
|
{channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/orders/__init__.py
RENAMED
File without changes
|
{channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/orders/addresses.py
RENAMED
File without changes
|
{channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/orders/cargo_companies.py
RENAMED
File without changes
|
{channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/orders/customers.py
RENAMED
File without changes
|
File without changes
|
{channel_app-0.0.134 → channel_app-0.0.135}/channel_app/omnitron/commands/product_categories.py
RENAMED
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
|
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
|
{channel_app-0.0.134 → channel_app-0.0.135}/docs/source/images/batch_request_state_machine.png
RENAMED
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
|