diff --git a/src/Attribute.php b/src/AttributeData.php similarity index 51% rename from src/Attribute.php rename to src/AttributeData.php index 9a343f2..277f3e1 100644 --- a/src/Attribute.php +++ b/src/AttributeData.php @@ -4,14 +4,14 @@ use function SnowIO\FredhopperDataModel\Internal\sanitizeId; use function SnowIO\FredhopperDataModel\Internal\validateId; -class Attribute extends Entity +final class AttributeData { - public static function of(string $id, string $type, array $names): self + public static function of(string $id, string $type, InternationalizedString $names): self { - validateId($id); + self::validateId($id); AttributeType::validate($type); - foreach ($names as $locale => $name) { - Locale::validate($locale); + if ($names->isEmpty()) { + throw new FredhopperDataException('A name must be provided for at least one locale.'); } $attribute = new self; $attribute->id = $id; @@ -20,6 +20,11 @@ public static function of(string $id, string $type, array $names): self return $attribute; } + public static function validateId(string $id): void + { + validateId($id); + } + public static function sanitizeId(string $id): string { return sanitizeId($id); @@ -35,27 +40,36 @@ public function getType(): string return $this->type; } - public function getNames(): array + public function getNames(): InternationalizedString { return $this->names; } public function getName(string $locale): ?string { - return $this->names[$locale] ?? null; + return $this->names->getValue($locale); + } + + public function equals($other): bool + { + return $other instanceof AttributeData + && $this->id === $other->id + && $this->type === $other->type + && $this->names->equals($other->names); } public function toJson(): array { - $json = parent::toJson(); - $json['attribute_id'] = $this->id; - $json['type'] = $this->type; - $json['names'] = $this->names; - return $json; + return [ + 'attribute_id' => $this->id, + 'type' => $this->type, + 'names' => $this->names->toJson(), + ]; } private $id; private $type; + /** @var InternationalizedString */ private $names; private function __construct() diff --git a/src/AttributeOption.php b/src/AttributeOption.php index ae3ed8a..eb58939 100644 --- a/src/AttributeOption.php +++ b/src/AttributeOption.php @@ -1,20 +1,32 @@ attributeId = $attributeId; $attributeOption->valueId = $valueId; + $attributeOption->displayValues = InternationalizedString::create(); return $attributeOption; } + public static function validateValueId(string $valueId): void + { + validateId($valueId); + } + + public static function sanitizeValueId(string $valueId): string + { + return sanitizeId($valueId); + } + public function getAttributeId(): string { return $this->attributeId; @@ -25,47 +37,51 @@ public function getValueId(): string return $this->valueId; } - public function withDisplayValues(array $displayValues): self + public function withDisplayValues(InternationalizedString $displayValues): self { - foreach ($displayValues as $locale => $displayValue) { - Locale::validate($locale); - } $attributeOption = clone $this; $attributeOption->displayValues = $displayValues; return $attributeOption; } - public function withDisplayValue(string $displayValue, string $locale): self + public function withDisplayValue(LocalizedString $displayValue): self { - Locale::validate($locale); $attributeOption = clone $this; - $attributeOption->displayValues[$locale] = $displayValue; + $attributeOption->displayValues = $this->displayValues->with($displayValue); return $attributeOption; } - public function getDisplayValues(): array + public function getDisplayValues(): InternationalizedString { - return $this->displayValues ?? []; + return $this->displayValues; } public function getDisplayValue(string $locale): ?string { - Locale::validate($locale); - return $this->displayValues[$locale] ?? null; + return $this->displayValues->getValue($locale); + } + + public function equals($other): bool + { + return $other instanceof AttributeOption + && $other->valueId === $this->valueId + && $other->attributeId === $this->attributeId + && $other->displayValues->equals($this->displayValues); } public function toJson(): array { - $json = parent::toJson(); - $json['value_id'] = $this->valueId; - $json['attribute_id'] = $this->attributeId; - $json['display_values'] = $this->displayValues; - return $json; + return [ + 'value_id' => $this->valueId, + 'attribute_id' => $this->attributeId, + 'display_values' => $this->displayValues->toJson(), + ]; } private $valueId; private $attributeId; - private $displayValues = []; + /** @var InternationalizedString */ + private $displayValues; private function __construct() { diff --git a/src/AttributeType.php b/src/AttributeType.php index ff9565e..243fc04 100644 --- a/src/AttributeType.php +++ b/src/AttributeType.php @@ -27,7 +27,7 @@ public static function isValid(string $type): bool public static function validate(string $type): void { if (!\in_array($type, self::ALL)) { - throw new \Exception('Invalid Type'); + throw new FredhopperDataException('Invalid Type'); } } diff --git a/src/AttributeValue.php b/src/AttributeValue.php index 3dc0f28..254aaa4 100644 --- a/src/AttributeValue.php +++ b/src/AttributeValue.php @@ -4,7 +4,7 @@ use function SnowIO\FredhopperDataModel\Internal\sanitizeId; use function SnowIO\FredhopperDataModel\Internal\validateId; -class AttributeValue +final class AttributeValue { public static function of(string $attributeId, $value): self { @@ -51,13 +51,6 @@ public function equals($object): bool && $object->locale === $this->locale; } - public function toJson(): array - { - return [ - $this->attributeId => $this->value, - ]; - } - private $attributeId; private $value; private $locale; diff --git a/src/AttributeValueSet.php b/src/AttributeValueSet.php index d821312..e95594c 100644 --- a/src/AttributeValueSet.php +++ b/src/AttributeValueSet.php @@ -1,82 +1,27 @@ attributeValues[$key] = $attributeValue; + $result->items[$key] = $attributeValue; return $result; } - public function add(self $otherSet): self - { - if ($otherSet->overlaps($this)) { - throw new \Error; - } - $mergedValues = \array_merge($this->attributeValues, $otherSet->attributeValues); - return new self($mergedValues); - } - - public function overlaps(AttributeValueSet $otherSet): bool - { - return !empty(\array_intersect_key($this->attributeValues, $otherSet->attributeValues)) - || !empty(\array_intersect_key($otherSet->attributeValues, $this->attributeValues)); - } - - public function equals($object): bool - { - if (!$object instanceof self || \count($object->attributeValues) != \count($this->attributeValues)) { - return false; - } - - foreach ($this->attributeValues as $attributeValueId => $attributeValue) { - $otherAttributeValue = $object->attributeValues[$attributeValueId] ?? null; - if (!$attributeValue->equals($otherAttributeValue)) { - return false; - } - } - - return true; - } - - public function toArray(): array - { - return \array_values($this->attributeValues); - } - - public function getIterator(): \Iterator - { - foreach ($this->attributeValues as $attributeValue) { - yield $attributeValue; - } - } - - /** @var AttributeValue[] */ - private $attributeValues; - - private function __construct(array $attributeValues) + private static function getKey(AttributeValue $attributeValue): string { - $this->attributeValues = $attributeValues; + return "{$attributeValue->getAttributeId()}-{$attributeValue->getLocale()}"; } - private static function getKey(AttributeValue $attributeValue): string + private static function itemsAreEqual(AttributeValue $item1, AttributeValue $item2): bool { - return "{$attributeValue->getAttributeId()}-{$attributeValue->getLocale()}"; + return $item1->equals($item2); } } diff --git a/src/Category.php b/src/CategoryData.php similarity index 58% rename from src/Category.php rename to src/CategoryData.php index 1fb656e..dc3430f 100644 --- a/src/Category.php +++ b/src/CategoryData.php @@ -1,13 +1,13 @@ $name) { - Locale::validate($locale); + if ($names->isEmpty()) { + throw new FredhopperDataException('A name must be provided for at least one locale.'); } $category = new self; $category->id = $id; @@ -25,7 +25,7 @@ public static function sanitizeId(string $id): string public static function validateId(string $id): void { if (!\preg_match('{^[a-z][a-z0-9_]+$}', $id)) { - throw new \Exception('Invalid Id'); + throw new FredhopperDataException('Invalid Id'); } } @@ -34,15 +34,14 @@ public function getId(): string return $this->id; } - public function getNames(): array + public function getNames(): InternationalizedString { return $this->names; } public function getName(string $locale): ?string { - Locale::validate($locale); - return $this->names[$locale] ?? null; + return $this->names->getValue($locale); } public function getParentId(): ?string @@ -58,17 +57,26 @@ public function withParent(string $parentId): self return $category; } + public function equals($other): bool + { + return $other instanceof CategoryData + && $this->id === $other->id + && $this->parentId === $other->parentId + && $this->names->equals($other->names); + } + public function toJson(): array { - $json = parent::toJson(); - $json['category_id'] = $this->id; - $json['names'] = $this->names; - $json['parent_id'] = $this->parentId; - return $json; + return [ + 'category_id' => $this->id, + 'parent_id' => $this->parentId, + 'names' => $this->names->toJson(), + ]; } private $id; private $parentId; + /** @var InternationalizedString */ private $names; private function __construct() diff --git a/src/CategoryIdSet.php b/src/CategoryIdSet.php new file mode 100644 index 0000000..ab9b868 --- /dev/null +++ b/src/CategoryIdSet.php @@ -0,0 +1,37 @@ +items[$categoryId] = $categoryId; + return $result; + } + + public function add(self $otherSet): self + { + $result = new self; + $result->items = \array_merge($this->items, $otherSet->items); + return $result; + } + + public function toJson(): array + { + return \array_values($this->items); + } + + private static function getKey(string $categoryId): string + { + return $categoryId; + } +} diff --git a/src/Entity.php b/src/Command/Command.php similarity index 53% rename from src/Entity.php rename to src/Command/Command.php index 6bb2c41..4d3daec 100644 --- a/src/Entity.php +++ b/src/Command/Command.php @@ -1,9 +1,9 @@ timestamp; } @@ -21,10 +21,13 @@ public function withTimestamp(int $timestamp) public function toJson(): array { - return [ - '@timestamp' => $this->timestamp, - ]; + if (isset($this->timestamp)) { + return [ + '@timestamp' => $this->timestamp, + ]; + } + return []; } - private $timestamp = 0; + private $timestamp; } diff --git a/src/Command/DeleteAttributeCommand.php b/src/Command/DeleteAttributeCommand.php new file mode 100644 index 0000000..9a86640 --- /dev/null +++ b/src/Command/DeleteAttributeCommand.php @@ -0,0 +1,32 @@ +attributeId = $attributeId; + return $command; + } + + public function getAttributeId(): string + { + return $this->attributeId; + } + + public function toJson(): array + { + return parent::toJson() + ['attribute_id' => $this->attributeId]; + } + + private $attributeId; + + private function __construct() + { + + } +} diff --git a/src/Command/DeleteAttributeOptionCommand.php b/src/Command/DeleteAttributeOptionCommand.php new file mode 100644 index 0000000..c3e7554 --- /dev/null +++ b/src/Command/DeleteAttributeOptionCommand.php @@ -0,0 +1,44 @@ +attributeId = $attributeId; + $command->valueId = $valueId; + return $command; + } + + public function getAttributeId(): string + { + return $this->attributeId; + } + + public function getValueId(): string + { + return $this->valueId; + } + + public function toJson(): array + { + return parent::toJson() + [ + 'attribute_id' => $this->attributeId, + 'value_id' => $this->valueId, + ]; + } + + private $attributeId; + private $valueId; + + private function __construct() + { + + } +} diff --git a/src/Command/DeleteCategoryCommand.php b/src/Command/DeleteCategoryCommand.php new file mode 100644 index 0000000..7558885 --- /dev/null +++ b/src/Command/DeleteCategoryCommand.php @@ -0,0 +1,32 @@ +categoryId = $categoryId; + return $command; + } + + public function getCategoryId(): string + { + return $this->categoryId; + } + + public function toJson(): array + { + return parent::toJson() + ['category_id' => $this->categoryId]; + } + + private $categoryId; + + private function __construct() + { + + } +} diff --git a/src/Command/DeleteProductCommand.php b/src/Command/DeleteProductCommand.php new file mode 100644 index 0000000..da6026b --- /dev/null +++ b/src/Command/DeleteProductCommand.php @@ -0,0 +1,32 @@ +productId = $productId; + return $command; + } + + public function getProductId(): string + { + return $this->productId; + } + + public function toJson(): array + { + return parent::toJson() + ['product_id' => $this->productId]; + } + + private $productId; + + private function __construct() + { + + } +} diff --git a/src/Command/DeleteVariantCommand.php b/src/Command/DeleteVariantCommand.php new file mode 100644 index 0000000..a0d9df7 --- /dev/null +++ b/src/Command/DeleteVariantCommand.php @@ -0,0 +1,32 @@ +variantId = $variantId; + return $command; + } + + public function getVariantId(): string + { + return $this->variantId; + } + + public function toJson(): array + { + return parent::toJson() + ['variant_id' => $this->variantId]; + } + + private $variantId; + + private function __construct() + { + + } +} diff --git a/src/Command/SaveAttributeCommand.php b/src/Command/SaveAttributeCommand.php new file mode 100644 index 0000000..0af4507 --- /dev/null +++ b/src/Command/SaveAttributeCommand.php @@ -0,0 +1,32 @@ +attributeData = $attributeData; + return $command; + } + + public function getAttributeData(): AttributeData + { + return $this->attributeData; + } + + public function toJson(): array + { + return parent::toJson() + $this->attributeData->toJson(); + } + + /** @var AttributeData */ + private $attributeData; + + private function __construct() + { + + } +} diff --git a/src/Command/SaveAttributeOptionCommand.php b/src/Command/SaveAttributeOptionCommand.php new file mode 100644 index 0000000..6962f29 --- /dev/null +++ b/src/Command/SaveAttributeOptionCommand.php @@ -0,0 +1,32 @@ +attributeOption = $attributeOption; + return $command; + } + + public function getAttributeOption(): AttributeOption + { + return $this->attributeOption; + } + + public function toJson(): array + { + return parent::toJson() + $this->attributeOption->toJson(); + } + + /** @var AttributeOption */ + private $attributeOption; + + private function __construct() + { + + } +} diff --git a/src/Command/SaveCategoryCommand.php b/src/Command/SaveCategoryCommand.php new file mode 100644 index 0000000..4c8de81 --- /dev/null +++ b/src/Command/SaveCategoryCommand.php @@ -0,0 +1,32 @@ +categoryData = $categoryData; + return $command; + } + + public function getCategoryData(): CategoryData + { + return $this->categoryData; + } + + public function toJson(): array + { + return parent::toJson() + $this->categoryData->toJson(); + } + + /** @var CategoryData */ + private $categoryData; + + private function __construct() + { + + } +} diff --git a/src/Command/SaveProductCommand.php b/src/Command/SaveProductCommand.php new file mode 100644 index 0000000..20138eb --- /dev/null +++ b/src/Command/SaveProductCommand.php @@ -0,0 +1,32 @@ +productData = $productData; + return $command; + } + + public function getProductData(): ProductData + { + return $this->productData; + } + + public function toJson(): array + { + return parent::toJson() + $this->productData->toJson(); + } + + /** @var ProductData */ + private $productData; + + private function __construct() + { + + } +} diff --git a/src/Command/SaveVariantCommand.php b/src/Command/SaveVariantCommand.php new file mode 100644 index 0000000..9df0a71 --- /dev/null +++ b/src/Command/SaveVariantCommand.php @@ -0,0 +1,32 @@ +variantData = $variantData; + return $command; + } + + public function getVariantData(): VariantData + { + return $this->variantData; + } + + public function toJson(): array + { + return parent::toJson() + $this->variantData->toJson(); + } + + /** @var VariantData */ + private $variantData; + + private function __construct() + { + + } +} diff --git a/src/FredhopperDataException.php b/src/FredhopperDataException.php new file mode 100644 index 0000000..14edf7d --- /dev/null +++ b/src/FredhopperDataException.php @@ -0,0 +1,7 @@ +items[$key])) { + throw new FredhopperDataException; + } + $set->items[$key] = $item; + } + return $set; + } + + public static function create(): self + { + return new self; + } + + public function add(self $otherSet): self + { + if ($otherSet->overlaps($this)) { + throw new FredhopperDataException; + } + $result = new self; + $result->items = \array_merge($this->items, $otherSet->items); + return $result; + } + + public function overlaps(self $otherSet): bool + { + foreach ($this->items as $key => $item) { + if (isset($otherSet->items[$key])) { + return true; + } + } + foreach ($otherSet->items as $key => $item) { + if (isset($this->items[$key])) { + return true; + } + } + return false; + } + + public function count(): int + { + return \count($this->items); + } + + public function isEmpty(): bool + { + return empty($this->items); + } + + public function equals($object): bool + { + if (!$object instanceof self) { + return false; + } + + if (\count($this->items) != \count($object->items)) { + return false; + } + + foreach ($this->items as $key => $item) { + $otherItem = $object->items[$key]; + if (!self::itemsAreEqual($item, $otherItem)) { + return false; + } + } + + return true; + } + + public function getIterator(): \Iterator + { + foreach ($this->items as $item) { + yield $item; + } + } + + private $items = []; + + private function __construct() + { + + } + + private static function itemsAreEqual($item1, $item2): bool + { + return $item1 === $item2; + } +} diff --git a/src/Internal/functions.php b/src/Internal/functions.php index a28f5c9..269cfc8 100644 --- a/src/Internal/functions.php +++ b/src/Internal/functions.php @@ -1,10 +1,12 @@ items[$locale])) { + Locale::validate($locale); + return null; + } + return $this->items[$locale]; + } + + public function with(LocalizedString $localizedString): self + { + $set = clone $this; + $set->items[$localizedString->getLocale()] = $localizedString; + return $set; + } + + public function getValue(string $locale): ?string + { + if (!isset($this->items[$locale])) { + Locale::validate($locale); + return null; + } + return $this->items[$locale]->getValue(); + } + + public function withValue(string $value, string $locale): self + { + return $this->with(LocalizedString::of($value, $locale)); + } + + public function getLocales(): array + { + return \array_keys($this->items); + } + + public function toJson(): array + { + return \array_map( + function (LocalizedString $localizedString) { + return $localizedString->getValue(); + }, + $this->items + ); + } + + /** @var LocalizedString[] */ + private $items = []; + + private function getKey(LocalizedString $localizedString): string + { + return $localizedString->getLocale(); + } + + private static function itemsAreEqual(LocalizedString $item1, LocalizedString $item2): bool + { + return $item1->equals($item2); + } +} diff --git a/src/Item.php b/src/ItemData.php similarity index 56% rename from src/Item.php rename to src/ItemData.php index 1babc74..b5303a7 100644 --- a/src/Item.php +++ b/src/ItemData.php @@ -4,7 +4,7 @@ use function SnowIO\FredhopperDataModel\Internal\sanitizeId; use function SnowIO\FredhopperDataModel\Internal\validateId; -abstract class Item extends Entity +abstract class ItemData { public static function sanitizeId(string $id): string { @@ -26,6 +26,9 @@ public function getAttributeValues(): AttributeValueSet return $this->attributeValues; } + /** + * @return static + */ public function withAttributeValues(AttributeValueSet $attributeValues): self { $item = clone $this; @@ -33,15 +36,36 @@ public function withAttributeValues(AttributeValueSet $attributeValues): self return $item; } + /** + * @return static + */ + public function withAttributeValue(AttributeValue $attributeValue): self + { + $item = clone $this; + $item->attributeValues = $this->attributeValues->with($attributeValue); + return $item; + } + + public function equals($other): bool + { + return $other instanceof ItemData + && $this->id === $other->id + && $this->attributeValues->equals($other->attributeValues); + } + public function toJson(): array { - $json = parent::toJson(); - $attributeValues = []; + $json = []; /** @var AttributeValue $attributeValue */ foreach ($this->attributeValues as $attributeValue) { - $attributeValues += $attributeValue->toJson(); + $attributeId = $attributeValue->getAttributeId(); + $locale = $attributeValue->getLocale(); + if (isset($locale)) { + $json['localizations'][$locale][$attributeId] = $attributeValue->getValue(); + } else { + $json['attribute_values'][$attributeId] = $attributeValue->getValue(); + } } - $json['attribute_values'] = $attributeValues; return $json; } diff --git a/src/Locale.php b/src/Locale.php index 030832c..032f9bf 100644 --- a/src/Locale.php +++ b/src/Locale.php @@ -125,7 +125,7 @@ public static function isValid(string $locale): bool public static function validate(string $locale): void { if (!\in_array($locale, self::ALL)) { - throw new \Exception('Invalid Locale'); + throw new FredhopperDataException('Invalid Locale'); } } diff --git a/src/LocalizedString.php b/src/LocalizedString.php new file mode 100644 index 0000000..9433a16 --- /dev/null +++ b/src/LocalizedString.php @@ -0,0 +1,39 @@ +value = $value; + $localizedString->locale = $locale; + return $localizedString; + } + + public function getValue(): string + { + return $this->value; + } + + public function getLocale(): string + { + return $this->locale; + } + + public function equals($object): bool + { + return $object instanceof LocalizedString + && $this->value === $object->value + && $this->locale === $object->locale; + } + + private $value; + private $locale; + + private function __construct() + { + + } +} diff --git a/src/Product.php b/src/Product.php deleted file mode 100644 index cb8dfe5..0000000 --- a/src/Product.php +++ /dev/null @@ -1,30 +0,0 @@ -categoryIds = $categoryIds; - return $product; - } - - public function getCategoryIds(): array - { - return $this->categoryIds; - } - - public function toJson(): array - { - $json = parent::toJson(); - $json['product_id'] = $this->getId(); - $json['category_ids'] = $this->categoryIds; - return $json; - } - - private $categoryIds; -} diff --git a/src/ProductData.php b/src/ProductData.php new file mode 100644 index 0000000..7f00c49 --- /dev/null +++ b/src/ProductData.php @@ -0,0 +1,48 @@ +categoryIds = CategoryIdSet::create(); + return $product; + } + + public function getCategoryIds(): CategoryIdSet + { + return $this->categoryIds; + } + + public function withCategoryIds(CategoryIdSet $categoryIds): ProductData + { + $result = clone $this; + $result->categoryIds = $categoryIds; + return $result; + } + + public function withCategoryId(string $categoryId): ProductData + { + $result = clone $this; + $result->categoryIds = $this->categoryIds->with($categoryId); + return $result; + } + + public function equals($other): bool + { + return $other instanceof ProductData + && parent::equals($other) + && $this->categoryIds->equals($other->categoryIds); + } + + public function toJson(): array + { + $json = parent::toJson(); + $json['product_id'] = $this->getId(); + $json['category_ids'] = $this->categoryIds->toJson(); + return $json; + } + + private $categoryIds; +} diff --git a/src/Variant.php b/src/VariantData.php similarity index 70% rename from src/Variant.php rename to src/VariantData.php index 13cfdd6..c5f2e90 100644 --- a/src/Variant.php +++ b/src/VariantData.php @@ -1,12 +1,15 @@ productId = $productId; return $variant; } diff --git a/test/unit/AttributeOptionTest.php b/test/unit/AttributeOptionTest.php index 9539fe3..9a409b5 100644 --- a/test/unit/AttributeOptionTest.php +++ b/test/unit/AttributeOptionTest.php @@ -4,31 +4,27 @@ use Exception; use PHPUnit\Framework\TestCase; use SnowIO\FredhopperDataModel\AttributeOption; +use SnowIO\FredhopperDataModel\LocalizedString; +use SnowIO\FredhopperDataModel\InternationalizedString; class AttributeOptionTest extends TestCase { public function testObjectInitialisation() { - $attributeOption = AttributeOption::of('color', 'red') - ->withDisplayValues([ - 'en_GB' => 'Red', - 'de_DE' => 'Rot', - 'es_ES' => 'Rojo', - 'fr_FR' => 'Rouge', - ])->withDisplayValue('Rougee', 'fr_FR') - ->withTimestamp(1506951117); + $displayValues = InternationalizedString::create() + ->withValue('Red', 'en_GB') + ->withValue('Rot', 'de_DE') + ->withValue('Rojo', 'es_ES') + ->withValue('Rouge', 'fr_FR'); + $option = AttributeOption::of('color', 'red') + ->withDisplayValues($displayValues) + ->withDisplayValue(LocalizedString::of('Rougee', 'fr_FR')); - self::assertEquals(1506951117, $attributeOption->getTimestamp()); - self::assertEquals('red', $attributeOption->getValueId()); - self::assertEquals('color', $attributeOption->getAttributeId()); - self::assertEquals('Red', $attributeOption->getDisplayValue('en_GB')); - self::assertEquals([ - 'en_GB' => 'Red', - 'de_DE' => 'Rot', - 'es_ES' => 'Rojo', - 'fr_FR' => 'Rougee', - ], $attributeOption->getDisplayValues()); - self::assertEquals(null, $attributeOption->getDisplayValue('es_US')); + self::assertSame('red', $option->getValueId()); + self::assertSame('color', $option->getAttributeId()); + self::assertSame('Red', $option->getDisplayValue('en_GB')); + self::assertTrue($option->getDisplayValues()->equals($displayValues->withValue('Rougee', 'fr_FR'))); + self::assertSame(null, $option->getDisplayValue('es_US')); } /** @@ -42,17 +38,15 @@ public function testInvalidAttributeId() public function testToJson() { + $displayValues = InternationalizedString::create() + ->withValue('Red', 'en_GB') + ->withValue('Rot', 'de_DE') + ->withValue('Rojo', 'es_ES') + ->withValue('Rouge', 'fr_FR'); $attributeOption = AttributeOption::of('color', 'red') - ->withDisplayValues([ - 'en_GB' => 'Red', - 'de_DE' => 'Rot', - 'es_ES' => 'Rojo', - 'fr_FR' => 'Rouge', - ]) - ->withTimestamp(1506951117); + ->withDisplayValues($displayValues); self::assertEquals([ - '@timestamp' => 1506951117, 'value_id' => 'red', 'attribute_id' => 'color', 'display_values' => [ @@ -67,8 +61,8 @@ public function testToJson() public function testChangeDisplayValue() { $option = AttributeOption::of('color', 'red') - ->withDisplayValue('Red', 'en_GB') - ->withDisplayValue('Red!', 'en_GB'); + ->withDisplayValue(LocalizedString::of('Red', 'en_GB')) + ->withDisplayValue(LocalizedString::of('Red!', 'en_GB')); self::assertSame('Red!', $option->getDisplayValue('en_GB')); } diff --git a/test/unit/AttributeTest.php b/test/unit/AttributeTest.php index 4ecd769..34f61e3 100644 --- a/test/unit/AttributeTest.php +++ b/test/unit/AttributeTest.php @@ -2,30 +2,27 @@ namespace SnowIO\FredhopperDataModel\Test; use Exception; -use SnowIO\FredhopperDataModel\Attribute; +use SnowIO\FredhopperDataModel\AttributeData; +use SnowIO\FredhopperDataModel\InternationalizedString; class AttributeTest extends \PHPUnit\Framework\TestCase { public function testObjectInitialisation() { - $attribute = Attribute::of( + $attributeNames = InternationalizedString::create() + ->withValue('Color', 'en_GB') + ->withValue('Coleur', 'fr_FR'); + $attribute = AttributeData::of( 'colour', 'list', - [ - 'en_GB' => 'Color', - 'fr_FR' => 'Couleur', - ] - )->withTimestamp(1506951117); + $attributeNames + ); - self::assertEquals('colour', $attribute->getId()); - self::assertEquals('list', $attribute->getType()); - self::assertEquals(1506951117, $attribute->getTimestamp()); - self::assertEquals([ - 'en_GB' => 'Color', - 'fr_FR' => 'Couleur', - ], $attribute->getNames()); - self::assertEquals(null, $attribute->getName('en_DE')); + self::assertSame('colour', $attribute->getId()); + self::assertSame('list', $attribute->getType()); + self::assertSame($attributeNames, $attribute->getNames()); + self::assertEquals(null, $attribute->getName('de_DE')); } /** @@ -34,13 +31,12 @@ public function testObjectInitialisation() */ public function testInvalidAttributeId() { - Attribute::of( + AttributeData::of( '$colour', 'list', - [ - 'en_GB' => 'Color', - 'fr_FR' => 'Couleur', - ] + InternationalizedString::create() + ->withValue('Color', 'en_GB') + ->withValue('Coleur', 'fr_FR') ); } @@ -50,58 +46,38 @@ public function testInvalidAttributeId() */ public function testInvalidAttributeType() { - Attribute::of( + AttributeData::of( 'colour', 'object', - [ - 'en_GB' => 'Color', - 'fr_FR' => 'Couleur', - ] - ); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage Invalid Locale - */ - public function testInvalidAttributeLocale() - { - Attribute::of( - 'colour', - 'list', - [ - 'en_GB' => 'Color', - 'fr_Fr' => 'Couleur', - ] + InternationalizedString::create() + ->withValue('Color', 'en_GB') + ->withValue('Coleur', 'fr_FR') ); } public function testToJson() { - $attribute = Attribute::of( + $attribute = AttributeData::of( 'colour', 'list', - [ - 'en_GB' => 'Color', - 'fr_FR' => 'Couleur', - ] + InternationalizedString::create() + ->withValue('Color', 'en_GB') + ->withValue('Coleur', 'fr_FR') ); - $attribute = $attribute->withTimestamp(1506948035); self::assertEquals([ - '@timestamp' => 1506948035, 'attribute_id' => 'colour', 'type' => 'list', 'names' => [ 'en_GB' => 'Color', - 'fr_FR' => 'Couleur', + 'fr_FR' => 'Coleur', ] ], $attribute->toJson()); } public function testSanitisation() { - $attributeId = Attribute::sanitizeId('tile-color'); + $attributeId = AttributeData::sanitizeId('tile-color'); self::assertEquals('tile_color', $attributeId); } } diff --git a/test/unit/AttributeValueSetTest.php b/test/unit/AttributeValueSetTest.php index b8e7faf..88d0bdf 100644 --- a/test/unit/AttributeValueSetTest.php +++ b/test/unit/AttributeValueSetTest.php @@ -11,11 +11,11 @@ public function testDuplicateAttributeIdWithDifferentLocaleSupported() $red = AttributeValue::of('color', 'red')->withLocale('en_GB'); $blue = AttributeValue::of('color', 'rot')->withLocale('de_DE'); $set = AttributeValueSet::of([$red, $blue]); - self::assertCount(2, $set->toArray()); + self::assertSame(2, $set->count()); } /** - * @expectedException \Error + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException */ public function testDuplicateAttributeIdThrows() { @@ -25,7 +25,7 @@ public function testDuplicateAttributeIdThrows() } /** - * @expectedException \Error + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException */ public function testDuplicateAttributeIdLocaleCombinationThrows() { @@ -34,6 +34,14 @@ public function testDuplicateAttributeIdLocaleCombinationThrows() AttributeValueSet::of([$red, $blue]); } + /** + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException + */ + public function testPassingNonAttributeValueToConstructorThrows() + { + AttributeValueSet::of(['hello dave!']); + } + public function testAddingAnAttributeSet() { $colorUk = AttributeValue::of('color', 'red')->withLocale('en_GB'); @@ -50,7 +58,7 @@ public function testAddingAnAttributeSet() } /** - * @expectedException \Error + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException */ public function testAddingOverlappingAttributeSetsThrows() { @@ -62,4 +70,18 @@ public function testAddingOverlappingAttributeSetsThrows() $otherAttributes = AttributeValueSet::of([$blue]); $attributes->add($otherAttributes); } + + public function testEquals() + { + $colour1 = AttributeValue::of('color', 'red'); + $colour2 = AttributeValue::of('color', 'red'); + $size1 = AttributeValue::of('size', 'large'); + $size2 = AttributeValue::of('size', 'large'); + $length = AttributeValue::of('length', 'long'); + $set1 = AttributeValueSet::of([$colour1, $size1]); + $set2 = AttributeValueSet::of([$size2, $colour2]); + self::assertTrue($set1->equals($set2)); + $set3 = $set2->with($length); + self::assertFalse($set1->equals($set3)); + } } diff --git a/test/unit/AttributeValueTest.php b/test/unit/AttributeValueTest.php index 554c7e4..50c6331 100644 --- a/test/unit/AttributeValueTest.php +++ b/test/unit/AttributeValueTest.php @@ -23,14 +23,6 @@ public function testInvalidAttributeId() AttributeValue::of('c%o*lour', 'Rose'); } - public function testToJson() - { - $attributeValue = AttributeValue::of('colour', 'Rot')->withLocale('de_DE'); - self::assertEquals([ - 'colour' => 'Rot' - ], $attributeValue->toJson()); - } - public function testSanitization() { $sanitizedValueId = AttributeValue::sanitizeId('red$'); diff --git a/test/unit/CategoryTest.php b/test/unit/CategoryTest.php index dd9a9c5..aed4309 100644 --- a/test/unit/CategoryTest.php +++ b/test/unit/CategoryTest.php @@ -1,63 +1,58 @@ 'Category 01', - 'fr_FR' => 'Catégorie 01', - ])->withTimestamp(1506951117); + $categoryNames = InternationalizedString::create() + ->withValue('Category 01', 'en_GB') + ->withValue('Catégorie 01', 'fr_FR'); + $category = CategoryData::of('category01', $categoryNames); - self::assertEquals('category01', $category->getId()); - self::assertEquals(null, $category->getName('de_DE')); - self::assertEquals(null, $category->getParentId()); - self::assertEquals(1506951117, $category->getTimestamp()); - self::assertEquals([ - 'en_GB' => 'Category 01', - 'fr_FR' => 'Catégorie 01', - ], $category->getNames()); + self::assertSame('category01', $category->getId()); + self::assertSame(null, $category->getName('de_DE')); + self::assertSame(null, $category->getParentId()); + self::assertSame($categoryNames, $category->getNames()); } /** - * @expectedException \Exception + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException * @expectedExceptionMessage Invalid Id */ public function testInvalidCategoryId() { - Category::of('01cat', [ - 'en_GB' => 'Category 01', - 'fr_FR' => 'Catégorie 01', - ]); + $categoryNames = InternationalizedString::create() + ->withValue('Category 01', 'en_GB') + ->withValue('Catégorie 01', 'fr_FR'); + CategoryData::of('01cat', $categoryNames); } /** - * @expectedException \Exception + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException * @expectedExceptionMessage Invalid Id */ public function testInvalidParentId() { - $category = Category::of('category01', [ - 'en_GB' => 'Category 01', - 'fr_FR' => 'Catégorie 01', - ]); + $categoryNames = InternationalizedString::create() + ->withValue('Category 01', 'en_GB') + ->withValue('Catégorie 01', 'fr_FR'); + $category = CategoryData::of('category01', $categoryNames); $category->withParent('02cat'); } public function testToJson() { - $category = Category::of('category01', [ - 'en_GB' => 'Category 01', - 'fr_FR' => 'Catégorie 01', - ]); + $categoryNames = InternationalizedString::create() + ->withValue('Category 01', 'en_GB') + ->withValue('Catégorie 01', 'fr_FR'); + $category = CategoryData::of('category01', $categoryNames); $category = $category->withParent('category02'); - $category = $category->withTimestamp(1506951117); self::assertEquals([ - '@timestamp' => 1506951117, 'category_id' => 'category01', 'parent_id' => 'category02', 'names'=> [ @@ -69,7 +64,7 @@ public function testToJson() public function testSanitisation() { - $attributeId = Category::sanitizeId('category_01'); + $attributeId = CategoryData::sanitizeId('category_01'); self::assertEquals('category01', $attributeId); } } diff --git a/test/unit/LocalizedStringSetTest.php b/test/unit/LocalizedStringSetTest.php new file mode 100644 index 0000000..27fb76d --- /dev/null +++ b/test/unit/LocalizedStringSetTest.php @@ -0,0 +1,56 @@ +count()); + self::assertSame(true, $emptySet->isEmpty()); + foreach ($emptySet as $item) { + self::fail(); + } + self::assertTrue($emptySet->equals(InternationalizedString::create())); + self::assertNull($emptySet->get('en_GB')); + self::assertNull($emptySet->getValue('en_GB')); + self::assertSame([], $emptySet->getLocales()); + } + + public function testGetExistentValue() + { + $set = InternationalizedString::create()->withValue('Red', 'en_GB'); + self::assertSame('Red', $set->getValue('en_GB')); + self::assertTrue($set->get('en_GB')->equals(LocalizedString::of('Red', 'en_GB'))); + + $set = InternationalizedString::create()->with(LocalizedString::of('Red', 'en_GB')); + self::assertSame('Red', $set->getValue('en_GB')); + self::assertTrue($set->get('en_GB')->equals(LocalizedString::of('Red', 'en_GB'))); + } + + public function testGetNonExistentValue() + { + $set = InternationalizedString::create()->withValue('Red', 'en_GB'); + self::assertNull($set->getValue('de_DE')); + self::assertNull($set->get('de_DE')); + } + + public function testReplaceValue() + { + $set = InternationalizedString::create() + ->withValue('Red', 'en_GB') + ->withValue('Red!', 'en_GB'); + self::assertSame('Red!', $set->getValue('en_GB')); + self::assertTrue($set->get('en_GB')->equals(LocalizedString::of('Red!', 'en_GB'))); + + $set = InternationalizedString::create() + ->withValue('Red', 'en_GB') + ->with(LocalizedString::of('Red!', 'en_GB')); + self::assertSame('Red!', $set->getValue('en_GB')); + self::assertTrue($set->get('en_GB')->equals(LocalizedString::of('Red!', 'en_GB'))); + } +} diff --git a/test/unit/LocalizedStringTest.php b/test/unit/LocalizedStringTest.php new file mode 100644 index 0000000..458ed8f --- /dev/null +++ b/test/unit/LocalizedStringTest.php @@ -0,0 +1,34 @@ +getValue()); + self::assertSame('en_GB', $localizedString->getLocale()); + } + + /** + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException + */ + public function testInvalidLocaleThrows() + { + LocalizedString::of('Foo', 'en_FR'); + } + + public function testEquals() + { + $localizedString1 = LocalizedString::of('Hello!', 'en_GB'); + $localizedString2 = LocalizedString::of('Hello!', 'en_GB'); + $localizedString3 = LocalizedString::of('Hello!', 'de_DE'); + $localizedString4 = LocalizedString::of('Hello', 'en_GB'); + self::assertTrue($localizedString1->equals($localizedString2)); + self::assertFalse($localizedString1->equals($localizedString3)); + self::assertFalse($localizedString1->equals($localizedString4)); + } +} diff --git a/test/unit/ProductTest.php b/test/unit/ProductTest.php index de6d06a..73dd3fb 100644 --- a/test/unit/ProductTest.php +++ b/test/unit/ProductTest.php @@ -5,21 +5,21 @@ use PHPUnit\Framework\TestCase; use SnowIO\FredhopperDataModel\AttributeValue; use SnowIO\FredhopperDataModel\AttributeValueSet; -use SnowIO\FredhopperDataModel\Product; +use SnowIO\FredhopperDataModel\CategoryIdSet; +use SnowIO\FredhopperDataModel\ProductData; class ProductTest extends TestCase { public function testObjectInitialisation() { - $attributeValue = AttributeValue::of('no_of_pages', 33); - $attributeValueSet = AttributeValueSet::of([$attributeValue]); - $product = Product::of('an_v2783', ['books', 'fiction', 'sci_fi',]) - ->withAttributeValues($attributeValueSet) - ->withTimestamp(1506951117); - self::assertEquals('an_v2783', $product->getId()); - self::assertEquals(['books', 'fiction', 'sci_fi',], $product->getCategoryIds()); - self::assertEquals(1506951117, $product->getTimestamp()); - self::assertEquals([$attributeValue], iterator_to_array($product->getAttributeValues())); + $categoryIds = CategoryIdSet::of(['books', 'fiction', 'sci_fi']); + $attributeValueSet = AttributeValueSet::create()->with(AttributeValue::of('no_of_pages', 33)); + $product = ProductData::of('an_v2783') + ->withCategoryIds($categoryIds) + ->withAttributeValues($attributeValueSet); + self::assertSame('an_v2783', $product->getId()); + self::assertSame($categoryIds, $product->getCategoryIds()); + self::assertSame($attributeValueSet, $product->getAttributeValues()); } /** @@ -28,18 +28,17 @@ public function testObjectInitialisation() */ public function testInvalidProductId() { - Product::of('$0i0ifjgo', ['books', 'fiction', 'sci_fi',]); + ProductData::of('$0i0ifjgo', CategoryIdSet::of(['books', 'fiction', 'sci_fi'])); } public function testToJson() { - $attributeValue = AttributeValue::of('no_of_pages', 33); - $attributeValueSet = AttributeValueSet::of([$attributeValue]); - $product = Product::of('an_v2783', ['books', 'fiction', 'sci_fi',]) - ->withTimestamp(1506951117) + $categoryIds = CategoryIdSet::of(['books', 'fiction', 'sci_fi']); + $attributeValueSet = AttributeValueSet::create()->with(AttributeValue::of('no_of_pages', 33)); + $product = ProductData::of('an_v2783') + ->withCategoryIds($categoryIds) ->withAttributeValues($attributeValueSet); self::assertEquals([ - '@timestamp' => 1506951117, 'product_id' => 'an_v2783', 'category_ids' => [ 'books', 'fiction', 'sci_fi', @@ -52,7 +51,18 @@ public function testToJson() public function testSanitization() { - $attributeId = Product::sanitizeId('product#01-38927'); + $attributeId = ProductData::sanitizeId('product#01-38927'); self::assertEquals('product_01_38927', $attributeId); } + + public function testEquals() + { + $product1 = ProductData::of('foo', CategoryIdSet::of(['bar', 'baz'])) + ->withAttributeValue(AttributeValue::of('colour', 'red')); + $product2 = ProductData::of('foo', CategoryIdSet::of(['bar', 'baz'])) + ->withAttributeValue(AttributeValue::of('colour', 'red')); + self::assertTrue($product1->equals($product2)); + $product3 = $product1->withCategoryId('wibble'); + self::assertFalse($product1->equals($product3)); + } } diff --git a/test/unit/VariantTest.php b/test/unit/VariantTest.php index a532f9c..3494308 100644 --- a/test/unit/VariantTest.php +++ b/test/unit/VariantTest.php @@ -4,7 +4,7 @@ use PHPUnit\Framework\TestCase; use SnowIO\FredhopperDataModel\AttributeValue; use SnowIO\FredhopperDataModel\AttributeValueSet; -use SnowIO\FredhopperDataModel\Variant; +use SnowIO\FredhopperDataModel\VariantData; class VariantTest extends TestCase { @@ -12,43 +12,39 @@ public function testObjectInitialisation() { $attributeValue = AttributeValue::of('no_of_pairs', 2); $attributeValueSet = AttributeValueSet::of([$attributeValue]); - $variant = Variant::of('acme_red_wool_socks', 'acme_wool_socks') - ->withTimestamp(1506951117) + $variant = VariantData::of('acme_red_wool_socks', 'acme_wool_socks') ->withAttributeValues($attributeValueSet); self::assertEquals('acme_red_wool_socks', $variant->getId()); self::assertEquals('acme_wool_socks', $variant->getProductId()); self::assertEquals([$attributeValue], iterator_to_array($variant->getAttributeValues())); - self::assertEquals(1506951117, $variant->getTimestamp()); } /** - * @expectedException \Exception + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException * @expectedExceptionMessage Invalid Id */ public function testInvalidVariantId() { - Variant::of('$acme$wool$socks', 'acme_wool_socks'); + VariantData::of('$acme$wool$socks', 'acme_wool_socks'); } /** - * @expectedException \Exception + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException * @expectedExceptionMessage Invalid Id */ public function testInvalidProductId() { - Variant::of('acme_wool_socks', 'acme$wool$socks'); + VariantData::of('acme_wool_socks', 'acme$wool$socks'); } public function testToJson() { $attributeValue = AttributeValue::of('no_of_pairs', 2); $attributeValueSet = AttributeValueSet::of([$attributeValue]); - $variant = Variant::of('acme_red_wool_socks', 'acme_wool_socks') - ->withAttributeValues($attributeValueSet) - ->withTimestamp(1506951117); + $variant = VariantData::of('acme_red_wool_socks', 'acme_wool_socks') + ->withAttributeValues($attributeValueSet); self::assertEquals([ - '@timestamp' => 1506951117, 'variant_id' => 'acme_red_wool_socks', 'product_id' => 'acme_wool_socks', 'attribute_values' => [ @@ -59,7 +55,15 @@ public function testToJson() public function testSanitization() { - $attributeId = Variant::sanitizeId('variant#01-38927'); + $attributeId = VariantData::sanitizeId('variant#01-38927'); self::assertEquals('variant_01_38927', $attributeId); } + + /** + * @expectedException \SnowIO\FredhopperDataModel\FredhopperDataException + */ + public function testVariantIdSameAsProductIdThrows() + { + VariantData::of('foo', 'foo'); + } }