function it_normalizes_groups($normalizer, $structureVersionProvider, $versionManager, $versionNormalizer, $localizedConverter, GroupInterface $tshirt, GroupTypeInterface $groupType, Version $oldestLog, Version $newestLog, ArrayCollection $products, ProductInterface $product, \ArrayIterator $productsIterator) { $options = ['decimal_separator' => ',', 'date_format' => 'dd/MM/yyyy']; $tshirt->getType()->willReturn($groupType); $groupType->isVariant()->willReturn(true); $variantNormalized = ['code' => 'my_variant', 'axis' => ['color', 'size'], 'type' => 'variant', 'values' => ['number' => ['data' => 12.5, 'locale' => null, 'scope' => null], 'metric' => ['data' => 12.5, 'locale' => null, 'scope' => null], 'prices' => ['data' => 12.5, 'locale' => null, 'scope' => null], 'date' => ['data' => '2015-01-31', 'locale' => null, 'scope' => null]]]; $valuesLocalized = ['number' => ['data' => '12,5000', 'locale' => null, 'scope' => null], 'metric' => ['data' => '12,5000', 'locale' => null, 'scope' => null], 'prices' => ['data' => '12,50', 'locale' => null, 'scope' => null], 'date' => ['data' => '31/01/2015', 'locale' => null, 'scope' => null]]; $normalizer->normalize($tshirt, 'json', $options)->willReturn($variantNormalized); $localizedConverter->convertToLocalizedFormats($variantNormalized['values'], $options)->willReturn($valuesLocalized); $structureVersionProvider->getStructureVersion()->willReturn(1); $versionManager->getOldestLogEntry($tshirt)->willReturn($oldestLog); $versionManager->getNewestLogEntry($tshirt)->willReturn($newestLog); $versionNormalizer->normalize($oldestLog, 'internal_api')->willReturn('normalized_oldest_log'); $versionNormalizer->normalize($newestLog, 'internal_api')->willReturn('normalized_newest_log'); $products->getIterator()->willReturn($productsIterator); $productsIterator->rewind()->shouldBeCalled(); $productsCount = 1; $productsIterator->valid()->will(function () use(&$productsCount) { return $productsCount-- > 0; }); $productsIterator->next()->shouldBeCalled(); $productsIterator->current()->will(new ReturnPromise([$product])); $product->getId()->willReturn(42); $tshirt->getId()->willReturn(12); $tshirt->getProducts()->willReturn($products); $this->normalize($tshirt, 'internal_api', $options)->shouldReturn(['code' => 'my_variant', 'axis' => ['color', 'size'], 'type' => 'variant', 'values' => $valuesLocalized, 'products' => [42], 'meta' => ['id' => 12, 'form' => 'pim-variant-group-edit-form', 'structure_version' => 1, 'model_type' => 'variant_group', 'created' => 'normalized_oldest_log', 'updated' => 'normalized_newest_log']]); }
function it_fails_if_the_group_code_is_not_found($groupRepository, ProductInterface $product, GroupInterface $pack, GroupTypeInterface $nonVariantType) { $groupRepository->findOneByIdentifier('not valid code')->willReturn(null); $pack->getType()->willReturn($nonVariantType); $nonVariantType->isVariant()->willReturn(false); $this->shouldThrow(InvalidArgumentException::expected('variant_group', 'existing variant group code', 'setter', 'variant_group', 'not valid code'))->during('setFieldData', [$product, 'variant_group', 'not valid code']); }
function it_validates_products_with_one_variant_group($context, $onlyOneVariantGroup, ProductInterface $mug, GroupInterface $mugVariantGroup, GroupInterface $otherGroup, GroupTypeInterface $variantType, GroupTypeInterface $groupType) { $mug->getGroups()->willReturn([$mugVariantGroup, $otherGroup]); $mugVariantGroup->getType()->willReturn($variantType); $otherGroup->getType()->willReturn($groupType); $variantType->isVariant()->willReturn(true); $groupType->isVariant()->willReturn(false); $context->buildViolation(Argument::any())->shouldNotBeCalled(); $this->validate($mug, $onlyOneVariantGroup); }
/** * Call when form is valid * * @param GroupInterface $group */ protected function onSuccess(GroupInterface $group) { $appendProducts = $this->form->get('appendProducts')->getData(); $removeProducts = $this->form->get('removeProducts')->getData(); $options = ['add_products' => $appendProducts, 'remove_products' => $removeProducts]; if ($group->getType()->isVariant()) { $options['copy_values_to_products'] = true; $this->convertLocalizedValues($group); } $this->groupSaver->save($group, $options); }
function it_supports_standard_normalization(GroupInterface $variantGroup, GroupTypeInterface $variantGroupType) { $variantGroup->getType()->willReturn($variantGroupType); $variantGroupType->isVariant()->willReturn(false); $this->supportsNormalization($variantGroup, 'standard')->shouldReturn(false); $variantGroupType->isVariant()->willReturn(true); $this->supportsNormalization($variantGroup, 'standard')->shouldReturn(true); $this->supportsNormalization(new \stdClass(), 'standard')->shouldReturn(false); $this->supportsNormalization($variantGroup, 'xml')->shouldReturn(false); $this->supportsNormalization($variantGroup, 'json')->shouldReturn(false); }
function it_adds_a_violation_if_axis_attributes_are_invalid($context, GroupInterface $variantGroup, GroupType $type, VariantGroupAxis $constraint, ConstraintViolationBuilderInterface $violation, AttributeInterface $invalidAxis) { $variantGroup->getId()->willReturn(12); $variantGroup->getType()->willReturn($type); $variantGroup->getCode()->willReturn('tshirt'); $type->isVariant()->willReturn(true); $variantGroup->getAxisAttributes()->willReturn([$invalidAxis]); $invalidAxis->getAttributeType()->willReturn(AttributeTypes::TEXT); $invalidAxis->getCode()->willReturn('name'); $violationData = ['%group%' => 'tshirt', '%attribute%' => 'name']; $context->buildViolation($constraint->invalidAxisMessage, $violationData)->shouldBeCalled()->willReturn($violation); $this->validate($variantGroup, $constraint); }
/** * {@inheritdoc} */ protected function normalizeVariantGroupValues(GroupInterface $group, $format, array $context) { if (!$group->getType()->isVariant() || null === $group->getProductTemplate()) { return []; } $valuesData = $group->getProductTemplate()->getValuesData(); $values = $this->valuesDenormalizer->denormalize($valuesData, 'ProductValue[]', 'json'); $normalizedValues = []; foreach ($values as $value) { $normalizedValues = array_replace($normalizedValues, $this->serializer->normalize($value, $format, ['entity' => 'product'] + $context)); } ksort($normalizedValues); return $normalizedValues; }
function it_sets_groups_field($groupRepository, ProductInterface $product, GroupInterface $pack, GroupInterface $cross, GroupInterface $up, GroupTypeInterface $nonVariantType) { $groupRepository->findOneByIdentifier('pack')->willReturn($pack); $groupRepository->findOneByIdentifier('cross')->willReturn($cross); $product->getGroups()->willReturn([$up]); $up->getType()->willReturn($nonVariantType); $nonVariantType->isVariant()->willReturn(false); $product->removeGroup($up)->shouldBeCalled(); $pack->getType()->willReturn($nonVariantType); $nonVariantType->isVariant()->willReturn(false); $cross->getType()->willReturn($nonVariantType); $nonVariantType->isVariant()->willReturn(false); $product->addGroup($pack)->shouldBeCalled(); $product->addGroup($cross)->shouldBeCalled(); $this->setFieldData($product, 'groups', ['pack', 'cross']); }
function it_saves_a_variant_group_and_copies_values_to_products($optionsResolver, $objectManager, $templateApplier, $eventDispatcher, GroupInterface $group, GroupType $type, ProductInterface $product, ProductTemplateInterface $template, ArrayCollection $products) { $optionsResolver->resolveSaveOptions(['copy_values_to_products' => true])->willReturn(['flush' => true, 'copy_values_to_products' => true, 'add_products' => [], 'remove_products' => []]); $group->getType()->willReturn($type); $group->getCode()->willReturn('my_code'); $objectManager->persist($group)->shouldBeCalled(); $objectManager->flush()->shouldBeCalled(); $type->isVariant()->willReturn(true); $group->getProductTemplate()->willReturn($template); $group->getProducts()->willReturn($products); $products->toArray()->willReturn([$product]); $templateApplier->apply($template, [$product])->shouldBeCalled(); $eventDispatcher->dispatch(StorageEvents::PRE_SAVE, Argument::cetera())->shouldBeCalled(); $eventDispatcher->dispatch(StorageEvents::POST_SAVE, Argument::cetera())->shouldBeCalled(); $this->save($group, ['copy_values_to_products' => true]); }
function it_adds_a_violation_if_variant_group_template_contains_a_unique_attribute(GroupInterface $variantGroup, GroupType $type, ProductTemplateInterface $template, VariantGroupValues $constraint, $attributeRepository, $context, ConstraintViolationBuilderInterface $violation) { $variantGroup->getType()->willReturn($type); $variantGroup->getCode()->willReturn('tshirt'); $type->isVariant()->willReturn(true); $variantGroup->getProductTemplate()->willReturn($template); $variantGroup->getAxisAttributes()->willReturn([]); $attributeRepository->findUniqueAttributeCodes()->willReturn(['sku', 'barcode']); $template->getValuesData()->willReturn(['sku' => 'SKU-001']); $violationData = ['%group%' => 'tshirt', '%attributes%' => '"sku"']; $context->buildViolation($constraint->message, $violationData)->shouldBeCalled()->willReturn($violation); $this->validate($variantGroup, $constraint); $template->getValuesData()->willReturn(['sku' => 'SKU-001', 'barcode' => 01122334455]); $violationData = ['%group%' => 'tshirt', '%attributes%' => '"sku", "barcode"']; $context->buildViolation($constraint->message, $violationData)->shouldBeCalled()->willReturn($violation); $this->validate($variantGroup, $constraint); }
function it_normalizes_a_variant_group_with_its_values($transNormalizer, $valuesDenormalizer, $valuesNormalizer, GroupInterface $group, GroupTypeInterface $groupType, AttributeInterface $attr, ProductTemplateInterface $productTemplate) { $groupType->getCode()->willReturn('VARIANT'); $groupType->isVariant()->willReturn(true); $group->getCode()->willReturn('laser_sabers'); $valuesData = ['name' => 'Light saber model', 'size' => '120']; $context = ['with_variant_group_values' => true]; $format = 'csv'; $productTemplate->getValuesData()->willReturn($valuesData); $valuesDenormalizer->denormalize($valuesData, Argument::any(), Argument::any())->willReturn('denormalized_values'); $valuesNormalizer->normalize('denormalized_values', Argument::any(), Argument::any())->willReturn('normalized_values'); $group->getProductTemplate()->willReturn($productTemplate); $group->getType()->willReturn($groupType); $attr->getCode()->willReturn('light_color'); $group->getAxisAttributes()->willReturn([$attr]); $transNormalizer->normalize($group, $format, $context)->willReturn([]); $this->normalize($group, $format, $context)->shouldReturn(['code' => 'laser_sabers', 'type' => 'VARIANT', 'axis' => ['light_color'], 'values' => 'normalized_values']); }
function it_is_not_attribute_removable_with_group_containing_attribute(AttributeInterface $attribute, GroupInterface $group, GroupTypeInterface $groupType, ArrayCollection $groupAttributes) { $groupType->isVariant()->willReturn(true); $groupAttributes->contains($attribute)->willReturn(true); $group->getType()->willReturn($groupType); $group->getAxisAttributes()->willReturn($groupAttributes); $group->addProduct($this)->willReturn($this); $this->addGroup($group); $this->isAttributeRemovable($attribute)->shouldReturn(false); }
function it_does_not_add_violation_when_validating_product_in_groups_with_unique_combination_of_axis_attributes($context, $productRepository, GroupInterface $tShirtVariantGroup, GroupTypeInterface $tShirtGroupType, ProductInterface $redTShirtProduct, AttributeInterface $sizeAttribute, AttributeInterface $colorAttribute, ProductValueInterface $sizeProductValue, ProductValueInterface $redColorProductValue, UniqueVariantAxis $uniqueVariantAxisConstraint) { $tShirtVariantGroup->getId()->willReturn(1); $tShirtVariantGroup->getLabel()->willReturn('TShirts'); $tShirtVariantGroup->getType()->willReturn($tShirtGroupType); $tShirtGroupType->isVariant()->willReturn(true); $tShirtVariantGroup->getAxisAttributes()->willReturn([$sizeAttribute, $colorAttribute]); $sizeAttribute->getCode()->willReturn('size'); $sizeAttribute->isBackendTypeReferenceData()->willReturn(false); $colorAttribute->getCode()->willReturn('color'); $colorAttribute->isBackendTypeReferenceData()->willReturn(false); $redTShirtProduct->getVariantGroup()->willReturn($tShirtVariantGroup); $redTShirtProduct->getId()->willReturn(1); $redTShirtProduct->getValue('size')->willReturn($sizeProductValue); $redTShirtProduct->getValue('color')->willReturn($redColorProductValue); $sizeProductValue->getOption()->willReturn('XL'); $redColorProductValue->getOption()->willReturn('Red'); $criteria = [['attribute' => $sizeAttribute, 'option' => 'XL'], ['attribute' => $colorAttribute, 'option' => 'Red']]; $productRepository->findAllForVariantGroup($tShirtVariantGroup, $criteria)->willReturn([]); $context->buildViolation()->shouldNotBeCalled(Argument::cetera()); $this->validate($redTShirtProduct, $uniqueVariantAxisConstraint); }
/** * Normalize the variant group values * * @param GroupInterface $group * @param string $format * @param array $context * * @return array */ protected function normalizeVariantGroupValues(GroupInterface $group, $format, array $context) { if (!$group->getType()->isVariant() || null === $group->getProductTemplate()) { return []; } $context["entity"] = "variant-group"; // As variant group > product template > values data are not type hinted we cannot normalize them directly // so we first denormalize them into product values using the common format then normalize them // this allow to transform localization based values for example return $this->valuesNormalizer->normalize($this->valuesDenormalizer->denormalize($group->getProductTemplate()->getValuesData(), $format, $context), $format, $context); }
function it_normalizes_a_variant_group_with_its_values_on_versioning_context($transNormalizer, $valuesDenormalizer, GroupInterface $group, CustomSerializer $serializer, GroupTypeInterface $groupType, AttributeInterface $attr, ProductTemplateInterface $productTemplate, ProductValueInterface $productValue1) { $groupType->getCode()->willReturn('VARIANT'); $groupType->isVariant()->willReturn(true); $group->getCode()->willReturn('lego'); $valuesData = ['name' => 'Light saber model', 'size' => '120']; $context = ['versioning' => true]; $format = 'csv'; $productTemplate->getValuesData()->willReturn($valuesData); $valuesDenormalizer->denormalize($valuesData, 'ProductValue[]', 'json')->willReturn([$productValue1]); $newContext = array_merge($context, ['with_variant_group_values' => true]); $serializer->normalize($productValue1, $format, ['entity' => 'product'] + $newContext)->willReturn(['age' => '6+']); $group->getProductTemplate()->willReturn($productTemplate); $group->getType()->willReturn($groupType); $attr->getCode()->willReturn('model'); $group->getAxisAttributes()->willReturn([$attr]); $transNormalizer->normalize($group, $format, $context)->willReturn([]); $this->setSerializer($serializer); $this->normalize($group, $format, $context)->shouldReturn(['code' => 'lego', 'type' => 'VARIANT', 'axis' => 'model', 'age' => '6+']); }
/** * Normalize the variant group values * * @param GroupInterface $group * @param string $format * @param array $context * * @return array */ protected function normalizeVariantGroupValues(GroupInterface $group, $format, array $context) { $valuesData = []; if ($group->getType()->isVariant() && null !== $group->getProductTemplate()) { $template = $group->getProductTemplate(); $valuesData = $template->getValuesData(); } return $valuesData; }