From 55099d724b220683048f5972c22f465b07fe6fd7 Mon Sep 17 00:00:00 2001 From: Andy Stafford Date: Wed, 3 Feb 2021 15:22:25 +0000 Subject: [PATCH] online-from and online-to cannot be empty (#82) * online-from/to * Remove unnecessary test and amend other fixtures * Add nilEmptyWriter and amend product tests/fixtures * Add test and remove an unnecessary method * Categories test and tidy up * Update CategoriesTest.php * Amend and fix tests * Swap params over - maybe I had gone mad yesterday * Add more tests * Amend test Co-authored-by: maxakropolis --- src/Writer/EntityWriter/CategoryXmlWriter.php | 4 +- src/Writer/EntityWriter/ProductXmlWriter.php | 4 +- src/Writer/Xml/NilEmptyWriter.php | 46 +++++++++++++++++++ src/Writer/Xml/XmlWriter.php | 10 ++++ tests/Writer/CategoriesTest.php | 40 ++++++++++++---- tests/Writer/Xml/XmlWriterTest.php | 45 ++++++++++++++---- tests/fixtures/categories.xml | 4 +- tests/fixtures/products.xml | 4 +- 8 files changed, 133 insertions(+), 24 deletions(-) create mode 100644 src/Writer/Xml/NilEmptyWriter.php diff --git a/src/Writer/EntityWriter/CategoryXmlWriter.php b/src/Writer/EntityWriter/CategoryXmlWriter.php index d093490..12a1ad6 100644 --- a/src/Writer/EntityWriter/CategoryXmlWriter.php +++ b/src/Writer/EntityWriter/CategoryXmlWriter.php @@ -21,8 +21,8 @@ public function write(): void $this->writer->ifNotEmpty()->writeAttribute('category-id', $this->category->id); $this->writer->ifNotEmpty()->writeElementWithAttributes('display-name', $this->category->displayName, ['xml:lang' => 'x-default']); $this->writer->ifNotEmpty()->writeElement('online-flag', XmlFormatter::fromBoolean($this->category->onlineFlag)); - $this->writer->ifNotEmpty()->writeElement('online-from', XmlFormatter::fromDateTime($this->category->onlineFrom)); - $this->writer->ifNotEmpty()->writeElement('online-to', XmlFormatter::fromDateTime($this->category->onlineTo)); + $this->writer->nilIfEmpty()->writeElement('online-from', XmlFormatter::fromDateTime($this->category->onlineFrom)); + $this->writer->nilIfEmpty()->writeElement('online-to', XmlFormatter::fromDateTime($this->category->onlineTo)); $this->writer->ifNotEmpty()->writeElement('parent', $this->category->parentId); $this->writeTemplate(); $this->writer->ifNotEmpty()->writeElement('sitemap-included-flag', XmlFormatter::fromBoolean($this->category->sitemapIncludedFlag)); diff --git a/src/Writer/EntityWriter/ProductXmlWriter.php b/src/Writer/EntityWriter/ProductXmlWriter.php index dc88c95..a08812e 100644 --- a/src/Writer/EntityWriter/ProductXmlWriter.php +++ b/src/Writer/EntityWriter/ProductXmlWriter.php @@ -25,8 +25,8 @@ public function write(): void $this->writer->ifNotEmpty()->writeElementWithAttributes('display-name', $this->product->displayName, ['xml:lang' => 'x-default']); $this->writer->ifNotEmpty()->writeElementWithAttributes('long-description', XmlFormatter::sanitise($this->product->longDescription), ['xml:lang' => 'x-default']); $this->writer->ifNotEmpty()->writeElement('online-flag', XmlFormatter::fromBoolean($this->product->onlineFlag)); - $this->writer->writeElement('online-from', XmlFormatter::fromDateTime($this->product->onlineFrom)); - $this->writer->writeElement('online-to', XmlFormatter::fromDateTime($this->product->onlineTo)); + $this->writer->nilIfEmpty()->writeElement('online-from', XmlFormatter::fromDateTime($this->product->onlineFrom)); + $this->writer->nilIfEmpty()->writeElement('online-to', XmlFormatter::fromDateTime($this->product->onlineTo)); $this->writer->ifNotEmpty()->writeElement('available-flag', XmlFormatter::fromBoolean($this->product->availableFlag)); $this->writer->ifNotEmpty()->writeElement('searchable-flag', XmlFormatter::fromBoolean($this->product->searchableFlag)); $this->writer->ifNotEmpty()->writeElement('searchable-if-unavailable-flag', XmlFormatter::fromBoolean($this->product->searchableIfUnavailableFlag)); diff --git a/src/Writer/Xml/NilEmptyWriter.php b/src/Writer/Xml/NilEmptyWriter.php new file mode 100644 index 0000000..59c8f95 --- /dev/null +++ b/src/Writer/Xml/NilEmptyWriter.php @@ -0,0 +1,46 @@ +writer = $writer; + } + + public function writeElement($name, $content = null): bool + { + if (XmlFormatter::isEmptyValue($content)) { + return $this->writeElementWithAttributes($name); + } + + return $this->writer->writeElement($name, $content); + } + + public function writeAttribute($name, $value): bool + { + return $this->writer->writeAttribute($name, $value); + } + + public function writeElementWithAttributes($name, $content = null, array $attributes = []): bool + { + $this->writer->startElement($name); + + foreach ($attributes as $attrName => $attrContent) { + $this->writeAttribute($attrName, $attrContent); + } + + if (XmlFormatter::isEmptyValue($content)) { + $this->writeAttribute('xsi:nil', 'true'); + $this->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + } else { + $this->writer->text($content); + } + + $this->writer->endElement(); + + return true; + } +} diff --git a/src/Writer/Xml/XmlWriter.php b/src/Writer/Xml/XmlWriter.php index 0ad4fa4..b211f6b 100644 --- a/src/Writer/Xml/XmlWriter.php +++ b/src/Writer/Xml/XmlWriter.php @@ -12,6 +12,7 @@ class XmlWriter extends PhpXmlWriter public const INDENT_SPACE = ' '; private $notEmptyWriter; + private $nilEmptyWriter; private $bufferLimit = 100; private $entityCount = 0; @@ -75,6 +76,15 @@ public function ifNotEmpty(): NotEmptyWriter return $this->notEmptyWriter; } + public function nilIfEmpty(): NilEmptyWriter + { + if (! $this->nilEmptyWriter) { + $this->nilEmptyWriter = new NilEmptyWriter($this); + } + + return $this->nilEmptyWriter; + } + public function writeElementWithAttributes($name, $content = null, array $attributes = []): bool { $this->startElement($name); diff --git a/tests/Writer/CategoriesTest.php b/tests/Writer/CategoriesTest.php index 5ad292e..4ac6009 100644 --- a/tests/Writer/CategoriesTest.php +++ b/tests/Writer/CategoriesTest.php @@ -3,7 +3,7 @@ use DateTimeImmutable; use DemandwareXml\Test\FixtureHelper; -use DemandwareXml\Writer\Entity\{Assignment, Category, CustomAttribute, DeletedAssignment, DeletedCategory}; +use DemandwareXml\Writer\Entity\{Assignment, Category, DeletedAssignment, DeletedCategory}; use DemandwareXml\Writer\Xml\XmlWriter; use PHPUnit\Framework\TestCase; @@ -19,22 +19,46 @@ public function test_categories_xml(): void $xml->startDocument(); $xml->startCatalog('TestCatalog'); - foreach (['Socks', 'Death Stars', 'Donuts'] as $index => $example) { - $element = new Category('CAT' . $index); - $element->setDisplayName($example); + $categories = [ + 'Socks' => [ + 'index' => 0, + 'dates' => [ + 'from' => new DateTimeImmutable('2018-01-01 01:01:01'), + 'to' => new DateTimeImmutable('2018-02-02 02:02:02'), + ], + ], + 'Death Stars' => [ + 'index' => 1, + 'dates' => [ + 'from' => null, + 'to' => new DateTimeImmutable('2018-02-02 02:02:02'), + ], + ], + 'Donuts' => [ + 'index' => 2, + 'dates' => [ + 'from' => new DateTimeImmutable('2018-01-01 01:01:01'), + 'to' => null, + ], + ], + ]; + + foreach ($categories as $title => $data) { + $element = new Category('CAT' . $data['index']); + $element->setDisplayName($title); $element->setParent('CAT0'); $element->setTemplate('cat-listings.html'); $element->setOnlineFlag(true); $element->setSitemap(0.2); - $element->setPageAttributes($example, 'Buy ' . $example, mb_strtolower($example), '/' . $example); + $element->setPageAttributes($title, 'Buy ' . $title, mb_strtolower($title), '/' . $title); $element->setOnlineFromTo( - new DateTimeImmutable('2018-01-01 01:01:01'), - new DateTimeImmutable('2018-02-02 02:02:02') + $data['dates']['from'], + $data['dates']['to'] ); $element->addCustomAttributes([ 'itemsPerPage' => 30, - 'promoMast' => 'cat' . $index . '-banner.png', + 'promoMast' => 'cat' . $data['index'] . '-banner.png', 'hasOffers' => true, ]); diff --git a/tests/Writer/Xml/XmlWriterTest.php b/tests/Writer/Xml/XmlWriterTest.php index 8ab17fa..4486944 100644 --- a/tests/Writer/Xml/XmlWriterTest.php +++ b/tests/Writer/Xml/XmlWriterTest.php @@ -83,6 +83,34 @@ public function test_write_empty_element_with_attributes(): void $this->assertXmlStringEqualsXmlString('', $xml->outputMemory(true)); } + public function test_write_nil_element(): void + { + $xml = $this->getMemoryXmlWriter(); + $xml->nilIfEmpty()->writeElement('test'); + $this->assertXmlStringEqualsXmlString('', $xml->outputMemory(true)); + } + + public function test_write_nil_element_with_empty_string(): void + { + $xml = $this->getMemoryXmlWriter(); + $xml->nilIfEmpty()->writeElement('test', ''); + $this->assertXmlStringEqualsXmlString('', $xml->outputMemory(true)); + } + + public function test_write_nil_element_with_string(): void + { + $xml = $this->getMemoryXmlWriter(); + $xml->nilIfEmpty()->writeElement('test', 'content'); + $this->assertXmlStringEqualsXmlString('content', $xml->outputMemory(true)); + } + + public function test_write_nil_element_with_attributes(): void + { + $xml = $this->getMemoryXmlWriter(); + $xml->nilIfEmpty()->writeElementWithAttributes('test', null, ['other' => 'value']); + $this->assertXmlStringEqualsXmlString('', $xml->outputMemory(true)); + } + public function test_write_flushable_entity(): void { $output = TEST_OUTPUT_DIR . '/catalog_auto_flush.xml'; @@ -92,15 +120,16 @@ public function test_write_flushable_entity(): void $xml->writeFlushableEntity(new Product('PRD000001')); $xml->writeFlushableEntity(new Product('PRD000002')); + $this->assertStringContainsString( <<<'XML' - - + + - - + + XML, trim(file_get_contents($output)) @@ -111,12 +140,12 @@ public function test_write_flushable_entity(): void $this->assertStringContainsString( <<<'XML' - - + + - - + + XML, trim(file_get_contents($output)) diff --git a/tests/fixtures/categories.xml b/tests/fixtures/categories.xml index 616dde3..5483bf8 100644 --- a/tests/fixtures/categories.xml +++ b/tests/fixtures/categories.xml @@ -25,7 +25,7 @@ Death Stars true - 2018-01-01T01:01:01 + 2018-02-02T02:02:02 CAT0 @@ -48,7 +48,7 @@ Donuts true 2018-01-01T01:01:01 - 2018-02-02T02:02:02 + CAT0 true diff --git a/tests/fixtures/products.xml b/tests/fixtures/products.xml index 6598c9a..648b4f7 100644 --- a/tests/fixtures/products.xml +++ b/tests/fixtures/products.xml @@ -61,8 +61,8 @@ Minimal Product This minimal product tests how empty fields are output - - + + 500000000001