Skip to content

Commit 9c53533

Browse files
authored
Add setAttribute and addVariant product actions (#83)
* Add setAttribute and addVariant product actions * Return deep-copy for object on products action
1 parent 2146f30 commit 9c53533

File tree

1 file changed

+83
-20
lines changed

1 file changed

+83
-20
lines changed

src/commercetools/testing/products.py

Lines changed: 83 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,84 @@ def _create_price_from_draft(
149149
)
150150

151151

152+
def _get_target_obj(obj: dict, action: types.ProductUpdateAction):
153+
staged = getattr(action, "staged", False)
154+
if not staged and obj["masterData"]["current"]:
155+
return obj["masterData"]["current"]
156+
return obj["masterData"]["staged"]
157+
158+
159+
def _update_productdata_attr(dst: str, src: str):
160+
def updater(self, obj: dict, action: types.ProductUpdateAction):
161+
value = getattr(action, src)
162+
target_obj = _get_target_obj(obj, action)
163+
164+
if target_obj[dst] != value:
165+
new = copy.deepcopy(obj)
166+
new[dst] = value
167+
return new
168+
return obj
169+
170+
return updater
171+
172+
173+
def _set_attribute_action():
174+
def updater(self, obj: dict, action: types.ProductSetAttributeAction):
175+
staged = getattr(action, "staged", False)
176+
new = copy.deepcopy(obj)
177+
178+
target_obj = _get_target_obj(new, action)
179+
180+
variants = [target_obj["masterVariant"]]
181+
if target_obj["variants"]:
182+
variants += target_obj["variants"]
183+
184+
for variant in variants:
185+
if action.variant_id != variant["id"]:
186+
continue
187+
188+
for attr in variant["attributes"]:
189+
if attr["name"] == action.name:
190+
attr["value"] = action.value
191+
return new
192+
193+
# Attribute not found, will add it
194+
attr_schema = schemas.AttributeSchema()
195+
variant["attributes"].append(
196+
attr_schema.dump(types.Attribute(name=action.name, value=action.value))
197+
)
198+
break
199+
200+
return new
201+
202+
return updater
203+
204+
205+
def _add_variant_action():
206+
def updater(self, obj: dict, action: types.ProductAddVariantAction):
207+
variant = self.model._create_variant_from_draft(
208+
types.ProductVariantDraft(
209+
sku=action.sku,
210+
key=action.key,
211+
prices=action.prices,
212+
attributes=action.attributes,
213+
images=action.images,
214+
assets=action.assets,
215+
)
216+
)
217+
schema = schemas.ProductVariantSchema()
218+
219+
new = copy.deepcopy(obj)
220+
target_obj = _get_target_obj(new, action)
221+
if not target_obj["variants"]:
222+
target_obj["variants"] = []
223+
target_obj["variants"].append(schema.dump(variant))
224+
225+
return new
226+
227+
return updater
228+
229+
152230
class ProductsBackend(ServiceBackend):
153231
service_path = "products"
154232
model_class = ProductsModel
@@ -168,24 +246,9 @@ def urls(self):
168246
("^key=(?P<key>[^/]+)$", "DELETE", self.delete_by_key),
169247
]
170248

171-
def _update_productdata_attr(dst: str, src: str):
172-
def updater(self, obj: dict, action: types.ProductUpdateAction):
173-
value = getattr(action, src)
174-
staged = getattr(action, "staged", False) or True
175-
176-
# Action.staged default is True
177-
if staged:
178-
target_obj = obj["masterData"]["staged"]
179-
else:
180-
target_obj = obj["masterData"]["current"]
181-
182-
if target_obj[dst] != value:
183-
new = copy.deepcopy(obj)
184-
new[dst] = value
185-
return new
186-
return obj
187-
188-
return updater
189-
190249
# Fixme: use decorator for this
191-
_actions = {"changeSlug": _update_productdata_attr("slug", "slug")}
250+
_actions = {
251+
"changeSlug": _update_productdata_attr("slug", "slug"),
252+
"setAttribute": _set_attribute_action(),
253+
"addVariant": _add_variant_action(),
254+
}

0 commit comments

Comments
 (0)