Skip to content

Commit

Permalink
Merge pull request #18 from iranl/extend-all-testing
Browse files Browse the repository at this point in the history
Extend all testing
  • Loading branch information
iranl authored Jul 10, 2019
2 parents 03ac86d + 2c80142 commit b6dcb7f
Show file tree
Hide file tree
Showing 10 changed files with 480 additions and 33 deletions.
2 changes: 1 addition & 1 deletion breaking262.md → breaking270.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Breaking changes since 2.6.2
# Breaking changes since 2.7.0
Release ... added multiple new resources, but also broke several existing ones.

Breaking changes are present in:
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ composer require 'league/oauth2-client'
## Usage

See [Usage](usage.md).
For breaking changes since 2.6.2 see [Breaking Changes since 2.6.2](breaking262.md).
For breaking changes since 2.7.0 see [Breaking Changes since 2.7.0](breaking270.md).

### Supported resources
Not all resources from the Twinfield API are currently implemented. Feel free to create a pull request when you need
Expand Down
101 changes: 101 additions & 0 deletions src/ApiConnectors/ApiOptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

namespace PhpTwinfield\ApiConnectors;

final class ApiOptions
{
private $retriableExceptionMessages = [
"SSL: Connection reset by peer",
"Your logon credentials are not valid anymore. Try to log on again."
];

private $maxRetries = 3;

/**
* @throws \InvalidArgumentException
*/
public function __construct(?array $messages = null, ?int $maxRetries = null)
{
if ($messages !== null) {
$this->validateMessages($messages);
$this->retriableExceptionMessages = $messages;
}
if ($maxRetries !== null) {
$this->validateMaxRetries($maxRetries);
$this->maxRetries = $maxRetries;
}
}

/**
* @throws \InvalidArgumentException
*/
private function validateMaxRetries(int $maxRetries): void
{
if ($maxRetries < 0) {
throw new \InvalidArgumentException('The max retries should be a positive integer.');
}
}

/**
* @throws \InvalidArgumentException
*/
private function validateMessages(array $messages): void
{
foreach ($messages as $key => $message) {
if (trim($message) === '') {
throw new \InvalidArgumentException(
sprintf('The exception message should not be empty. Key: [%s]', $key)
);
}
}
}

/**
* @return array
*/
public function getRetriableExceptionMessages(): array
{
return $this->retriableExceptionMessages;
}

/**
* @throws \InvalidArgumentException
*/
public function setRetriableExceptionMessages(array $retriableExceptionMessages): ApiOptions
{
return new self(
$retriableExceptionMessages,
$this->maxRetries
);
}

/**
* @throws \InvalidArgumentException
*/
public function addMessages(array $messages): ApiOptions
{
return new self(
array_merge($messages, $this->retriableExceptionMessages),
$this->maxRetries
);
}

/**
* @return int
*/
public function getMaxRetries(): int
{
return $this->maxRetries;
}

/**
* @throws \InvalidArgumentException
*/
public function setMaxRetries(int $maxRetries): ApiOptions
{
return new self(
$this->retriableExceptionMessages,
$maxRetries
);
}
}
38 changes: 21 additions & 17 deletions src/ApiConnectors/BaseApiConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,32 @@ abstract class BaseApiConnector implements LoggerAwareInterface
use LoggerAwareTrait;

/**
* Make sure to only add error messages for failure cases that caused the server not to accept / receive the
* request. Else the automatic retry will cause the request to be understood by the server twice.
*
* @var string[]
* @var AuthenticatedConnection
*/
private const RETRY_REQUEST_EXCEPTION_MESSAGES = [
"SSL: Connection reset by peer",
"Your logon credentials are not valid anymore. Try to log on again."
];
private $connection;

/**
* @var int
*/
private const MAX_RETRIES = 3;
private $numRetries = 0;

/**
* @var AuthenticatedConnection
* @var ApiOptions
*/
private $connection;
private $options;

/**
* @var int
* @throws \InvalidArgumentException
*/
private $numRetries = 0;

public function __construct(AuthenticatedConnection $connection)
public function __construct(AuthenticatedConnection $connection, ?ApiOptions $options = null)
{
$this->connection = $connection;

if ($options === null) {
$this->options = new ApiOptions();
} else {
$this->options = $options;
}
}

/**
Expand All @@ -60,6 +58,11 @@ public function getConnection(): AuthenticatedConnection
return $this->connection;
}

public function getOptions(): ApiOptions
{
return $this->options;
}

/**
* @see sendXmlDocument()
* @throws Exception
Expand All @@ -77,6 +80,7 @@ protected function getProcessXmlService(): ProcessXmlService
* @param \DOMDocument $document
* @return \PhpTwinfield\Response\Response
* @throws Exception
* @throws \RuntimeException
*/
public function sendXmlDocument(\DOMDocument $document) {
$this->logSendingDocument($document);
Expand All @@ -96,13 +100,13 @@ public function sendXmlDocument(\DOMDocument $document) {
$this->connection->resetClient(Services::PROCESSXML());

/* For a given set of exception messages, always retry the request. */
foreach (self::RETRY_REQUEST_EXCEPTION_MESSAGES as $message) {
foreach ($this->getOptions()->getRetriableExceptionMessages() as $message) {
if (stripos($exception->getMessage(), $message) === false) {
continue;
}
$this->numRetries++;

if ($this->numRetries > self::MAX_RETRIES) {
if ($this->numRetries > $this->getOptions()->getMaxRetries()) {
break;
}

Expand Down
1 change: 1 addition & 0 deletions src/CustomerCreditManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class CustomerCreditManagement extends BaseObject

public function __construct()
{
$this->setBlocked(false);
$this->setSendReminder(\PhpTwinfield\Enums\SendReminder::TRUE());
}
}
7 changes: 6 additions & 1 deletion src/DomDocuments/CustomersDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,12 @@ public function addCustomer(Customer $customer)
$creditManagementElement = $this->createElement('creditmanagement');
$customerElement->appendChild($creditManagementElement);

$creditManagementElement->appendChild($this->createNodeWithTextContent('basecreditlimit', Util::formatMoney($creditManagement->getBaseCreditLimit())));
if ($creditManagement->getBaseCreditLimit() !== null) {
$creditManagementElement->appendChild($this->createNodeWithTextContent('basecreditlimit', Util::formatMoney($creditManagement->getBaseCreditLimit())));
} else {
$creditManagementElement->appendChild($this->createNodeWithTextContent('basecreditlimit', 0));
}

$creditManagementElement->appendChild($this->createNodeWithTextContent('blocked', Util::formatBoolean($creditManagement->getBlocked())));
$creditManagementElement->appendChild($this->createNodeWithTextContent('comment', $creditManagement->getComment()));
$creditManagementElement->appendChild($this->createNodeWithTextContent('freetext1', Util::formatBoolean($creditManagement->getFreeText1())));
Expand Down
4 changes: 2 additions & 2 deletions tests/IntegrationTests/resources/customerSendRequest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
</collectmandate>
</financials>
<creditmanagement>
<basecreditlimit/>
<blocked/>
<basecreditlimit>0</basecreditlimit>
<blocked>false</blocked>
<comment/>
<freetext1/>
<freetext2/>
Expand Down
Loading

0 comments on commit b6dcb7f

Please sign in to comment.