From 818f95cfe02f13f91a1e6f76c975bba87ea69f48 Mon Sep 17 00:00:00 2001 From: Michelangelo van Dam Date: Sun, 26 Apr 2020 00:01:51 +0200 Subject: [PATCH] Issue 64: Added VIES test service I have taken a look at this request to access the integration test service of VIES which were made in issue #64 and issue #83. I can conclude that yes, it is possible to access this test service of VIES for integration tests (issue #64), but I was not able to verify if a backend service of VIES was not accessible. In my test case I used Germany as it was supposed to be "DE-Germany Unavailable daily from 11:00 PM to 01:30 AM" as was stated on https://ec.europa.eu/taxation_customs/vies/help.html. But on https://ec.europa.eu/taxation_customs/vies/monitoring.html it shows green. Not sure if the information in the help page is still accurate since my normal and test SOAP calls all succeeded. --- src/Vies/Vies.php | 33 +++++ tests/Vies/ViesTest.php | 56 +++++++ tests/Vies/_files/checkVatTestService.wsdl | 164 +++++++++++++++++++++ 3 files changed, 253 insertions(+) create mode 100644 tests/Vies/_files/checkVatTestService.wsdl diff --git a/src/Vies/Vies.php b/src/Vies/Vies.php index 4a19f6e..b54587e 100644 --- a/src/Vies/Vies.php +++ b/src/Vies/Vies.php @@ -49,7 +49,9 @@ class Vies const VIES_PROTO = 'http'; const VIES_DOMAIN = 'ec.europa.eu'; const VIES_WSDL = '/taxation_customs/vies/checkVatService.wsdl'; + const VIES_TEST_WSDL = '/taxation_customs/vies/checkVatTestService.wsdl'; const VIES_EU_COUNTRY_TOTAL = 28; + const VIES_TEST_VAT_NRS = [100, 200]; protected const VIES_EU_COUNTRY_LIST = [ 'AT' => ['name' => 'Austria', 'validator' => Validator\ValidatorAT::class], @@ -248,6 +250,11 @@ public function validateVat( if (! isset(self::VIES_EU_COUNTRY_LIST[$countryCode])) { throw new ViesException(sprintf('Invalid country code "%s" provided', $countryCode)); } + + if (in_array((int) $vatNumber, self::VIES_TEST_VAT_NRS, true)) { + return $this->validateTestVat($countryCode, $vatNumber); + } + $vatNumber = self::filterVat($vatNumber); if (! $this->validateVatSum($countryCode, $vatNumber)) { @@ -405,4 +412,30 @@ private function validateArgument(string $argumentValue): bool } return true; } + + private function validateTestVat($countryCode, $testVatNumber): CheckVatResponse + { + $wsdl = sprintf('%s://%s%s', self::VIES_PROTO, self::VIES_DOMAIN, self::VIES_TEST_WSDL); + $this->setWsdl($wsdl); + $requestParams = [ + 'countryCode' => $countryCode, + 'vatNumber' => $testVatNumber, + ]; + try { + return new CheckVatResponse( + $this->getSoapClient()->__soapCall('checkVat', [$requestParams]) + ); + } catch (SoapFault $e) { + $message = sprintf( + 'Back-end VIES service cannot validate the VAT number "%s%s" at this moment. ' + . 'The service responded with the critical error "%s". This is probably a temporary ' + . 'problem. Please try again later.', + $countryCode, + $testVatNumber, + $e->getMessage() + ); + + throw new ViesServiceException($message, 0, $e); + } + } } diff --git a/tests/Vies/ViesTest.php b/tests/Vies/ViesTest.php index 6ae7f75..bb7dabf 100644 --- a/tests/Vies/ViesTest.php +++ b/tests/Vies/ViesTest.php @@ -644,4 +644,60 @@ public function testSoapVersionsAreDefined(int $soapVersion, string $expectedVal $this->assertInstanceOf(SoapClient::class, $vies->getSoapClient()); } + + public function vatTestNumberProvider(): array + { + return [ + 'Belgian VAT ID that tests valid' => ['BE', '100', true], + 'Irish VAT ID that tests invalid' => ['IE', '200', false], + 'German VAT ID that tests valid' => ['DE', '100', true], + ]; + } + + /** + * Testing the test VAT SOAP service + * + * @param string $countryCode + * @param string $vatNumber + * @param bool $expectation + * @throws ViesException + * @throws ViesServiceException + * + * @covers ::validateTestVat + * @covers ::validateVat + * @covers ::setWsdl + * + * @dataProvider vatTestNumberProvider + */ + public function testViesTestService(string $countryCode, string $vatNumber, bool $expectation) + { + $result = (new Vies())->validateVat($countryCode, $vatNumber); + $this->assertSame($expectation, $result->isValid()); + } + + /** + * Testing if we can catch soap exceptions when trying + * to make VIES test calls + * + * @throws ViesException + * @throws ViesServiceException + * @throws \ReflectionException + * + * @covers ::validateVat + * @covers ::validateTestVat + */ + public function testExceptionIsRaisedWhenSoapCallFailsForTestService() + { + $this->expectException(ViesServiceException::class); + $stub = $this->getMockFromWsdl(dirname(__FILE__) . '/_files/checkVatTestService.wsdl'); + $stub->expects($this->any()) + ->method('__soapCall') + ->will($this->throwException(new SoapFault("test", "myMessage"))); + + (new Vies()) + ->setSoapClient($stub) + ->validateVat('BE', '100') + ; + $this->fail('Expected exception was not raised'); + } } diff --git a/tests/Vies/_files/checkVatTestService.wsdl b/tests/Vies/_files/checkVatTestService.wsdl new file mode 100644 index 0000000..5442f32 --- /dev/null +++ b/tests/Vies/_files/checkVatTestService.wsdl @@ -0,0 +1,164 @@ + + + + Specific disclaimer for this service ----------------------------------------- + Here is the list of VAT Number to use to receive each kind of answer : + 100 = Valid request with Valid VAT Number + 200 = Valid request with an Invalid VAT Number + 201 = Error : INVALID_INPUT + 202 = Error : INVALID_REQUESTER_INFO + 300 = Error : SERVICE_UNAVAILABLE + 301 = Error : MS_UNAVAILABLE + 302 = Error : TIMEOUT + 400 = Error : VAT_BLOCKED + 401 = Error : IP_BLOCKED + 500 = Error : GLOBAL_MAX_CONCURRENT_REQ + 501 = Error : GLOBAL_MAX_CONCURRENT_REQ_TIME + 600 = Error : MS_MAX_CONCURRENT_REQ + 601 = Error : MS_MAX_CONCURRENT_REQ_TIME + + For all the other cases, The web service will responds with a "SERVICE_UNAVAILABLE" error. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VALID + + + + + INVALID + + + + + NOT_PROCESSED + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +