From a7fe8503fd4b5f53a4c9c37f80942da70d1c0b0d Mon Sep 17 00:00:00 2001 From: ykxiao Date: Thu, 7 Sep 2023 14:18:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=B7=E6=9C=A8=E8=87=AA=E5=8A=A8=E5=8C=96ME?= =?UTF-8?q?S=E7=B3=BB=E7=BB=9FSDK=E5=88=9D=E5=A7=8B=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + .phpunit.result.cache | 1 + README.md | 25 +++++ composer.json | 23 ++++ phpunit.xml | 21 ++++ src/Exceptions/Exception.php | 16 +++ src/Exceptions/HttpException.php | 14 +++ src/Exceptions/InvalidArgumentException.php | 14 +++ src/OrderActions/Order.php | 114 ++++++++++++++++++++ src/OrderActions/Sign.php | 23 ++++ tests/Feature/OrderTest.php | 90 ++++++++++++++++ 11 files changed, 344 insertions(+) create mode 100644 .gitignore create mode 100644 .phpunit.result.cache create mode 100644 README.md create mode 100644 composer.json create mode 100644 phpunit.xml create mode 100644 src/Exceptions/Exception.php create mode 100644 src/Exceptions/HttpException.php create mode 100644 src/Exceptions/InvalidArgumentException.php create mode 100644 src/OrderActions/Order.php create mode 100644 src/OrderActions/Sign.php create mode 100644 tests/Feature/OrderTest.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2130d09 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.idea +/vendor +composer.lock diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 0000000..5b09eef --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +{"version":1,"defects":{"Feature\\OrderTest::testGetProductOrder":5},"times":{"Unit\\OrderTest::testGetWeatherWithInvalidType":0.041,"Feature\\OrderTest::testGetWeatherWithInvalidType":0.026,"Unit\\OrderTest::testGetWeatherWithInvalidFormat":0,"Feature\\OrderTest::testGetWeatherWithInvalidFormat":0,"Feature\\OrderTest::testGetWeatherWithGuzzleRuntimeException":0.074,"Feature\\OrderTest::testGetHttpClient":0.015,"Feature\\OrderTest::testSetGuzzleOptions":0.002,"Unit\\OrderTest::testGetWeatherWithGuzzleRuntimeException":0.101,"Unit\\OrderTest::testGetHttpClient":0.02,"Unit\\OrderTest::testSetGuzzleOptions":0.004,"Feature\\OrderTest::testGetProductOrder":0.202}} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..bafe300 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# 德木自动化项目开放接口SDK + +# 介绍 +用于德木自动化对外开放接口数据交互 + +# 要求 +- php版本:>=7.0 + +# 安装 + +```php +composer require ykxiao/dmmes +``` + +# 使用 + +```php +$secretKey = 'gFBfirGATxafTeq74RAngaL74Ksdxhuy'; + +$w = new Order($secretKey); + +// 获取工单数据 + +$response = $w->getProductOrder('SN5436745676543'); +``` diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..81ecb6e --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "ykxiao/dmmes", + "description": "Automation Project SDK", + "license": "MIT", + "autoload": { + "psr-4": { + "Ykxiao\\Dmmes\\": "src/" + } + }, + "authors": [ + { + "name": "ykxiao" + } + ], + "require": { + "guzzlehttp/guzzle": "^7.8", + "ext-json": "*" + }, + "require-dev": { + "phpunit/phpunit": "^9.6", + "mockery/mockery": "^1.6" + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..83fd8a6 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,21 @@ + + + + + ./tests/Feature + + + + + ./src + + + diff --git a/src/Exceptions/Exception.php b/src/Exceptions/Exception.php new file mode 100644 index 0000000..ca93d90 --- /dev/null +++ b/src/Exceptions/Exception.php @@ -0,0 +1,16 @@ +secretKey = $secretKey; + $this->type = $type; + $this->format = $format; + } + + public function getHttpClient() + { + return new Client($this->guzzleOptions); + } + + public function setGuzzleOptions(array $options) + { + $this->guzzleOptions = $options; + } + + /** + * @param $params + * @return mixed|string + * @throws GuzzleException + * @throws HttpException + * @throws InvalidArgumentException + */ + public function baseFun($params) + { + $url = $this->apiUrl . 'production.status'; + + if (!in_array(strtolower($this->format), ['xml', 'json'])) { + throw new InvalidArgumentException('Invalid response format: ' . $this->format); + } + + if (!in_array(strtolower($this->type), ['base', 'all'])) { + throw new InvalidArgumentException('Invalid type value(base/all): ' . $this->type); + } + + $params['output'] = $this->format; + $params['extensions'] = $this->type; + + $signature = (new Sign())->generateHmacSignature($this->secretKey, $params); + + $params = [ + 'headers' => ['content-type' => 'application/json', 'accept' => 'application/json'], + 'body' => json_encode([ + 'signature' => $signature, + 'data' => $params + ]), + 'http_errors' => false + ]; + + try { + $response = $this->getHttpClient() + ->request('POST', $url, $params) + ->getBody() + ->getContents(); + + return 'json' === $this->format ? json_decode($response, true) : $response; + } catch (\Exception $e) { + throw new HttpException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * 获取工单信息 + * @param $order_sn + * @return mixed|string + * @throws GuzzleException + * @throws HttpException + * @throws InvalidArgumentException + */ + public function getProductOrder($order_sn) + { + $data = [ + 'order_sn' => $order_sn + ]; + return $this->baseFun($data); + } +} diff --git a/src/OrderActions/Sign.php b/src/OrderActions/Sign.php new file mode 100644 index 0000000..aee88e4 --- /dev/null +++ b/src/OrderActions/Sign.php @@ -0,0 +1,23 @@ +expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid type value(base/all): foo'); + + $w->getProductOrder('SN23454324565432'); + + $this->fail('Failed to assert getOrder throw exception with invalid argument.'); + } + + public function testGetWeatherWithInvalidFormat() + { + $w = new Order('mock-key', 'base', 'array'); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid response format: array'); + + $w->getProductOrder('SN23454324565432'); + + $this->fail('Failed to assert getOrder throw exception with invalid argument.'); + } + + public function testGetWeatherWithGuzzleRuntimeException() + { + $client = \Mockery::mock(Client::class); + $client->allows() + ->get(new AnyArgs()) + ->andThrow(new \Exception('request timeout')); + + $w = \Mockery::mock(Order::class, ['mock-key'])->makePartial(); + $w->allows()->getHttpClient()->andReturn($client); + + $this->expectException(HttpException::class); + //$this->expectExceptionMessage('request timeout'); + + $w->getProductOrder('SN23454324565432'); + } + + public function testGetHttpClient() + { + $w = new Order('mock-key'); + + // 断言返回结果为 GuzzleHttp\ClientInterface 实例 + $this->assertInstanceOf(ClientInterface::class, $w->getHttpClient()); + } + + public function testSetGuzzleOptions() + { + $w = new Order('mock-key'); + + // 设置参数前,timeout 为 null + $this->assertNull($w->getHttpClient()->getConfig('timeout')); + + // 设置参数 + $w->setGuzzleOptions(['timeout' => 5000]); + + // 设置参数后,timeout 为 5000 + $this->assertSame(5000, $w->getHttpClient()->getConfig('timeout')); + } + + public function testGetProductOrder() + { + $w = new Order('mock-key'); + + $w->getProductOrder('SN23454324565432'); + $this->assertInstanceOf(ClientInterface::class, $w->getHttpClient()); + } +}