OpenApiUtilClientTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. <?php
  2. namespace AlibabaCloud\OpenApiUtil\Tests;
  3. use AlibabaCloud\OpenApiUtil\OpenApiUtilClient;
  4. use AlibabaCloud\OpenApiUtil\Tests\Models\SourceModel;
  5. use AlibabaCloud\OpenApiUtil\Tests\Models\urlListObject;
  6. use AlibabaCloud\OpenApiUtil\Tests\Models\TargetModel;
  7. use AlibabaCloud\Tea\Model;
  8. use AlibabaCloud\Tea\Request;
  9. use AlibabaCloud\Tea\Utils\Utils;
  10. use PHPUnit\Framework\TestCase;
  11. use GuzzleHttp\Psr7\Stream;
  12. /**
  13. * @internal
  14. * @coversNothing
  15. */
  16. class OpenApiUtilClientTest extends TestCase
  17. {
  18. public function testConvert()
  19. {
  20. $model = new MockModel();
  21. $model->a = 'foo';
  22. $output = new MockModel();
  23. OpenApiUtilClient::convert($model, $output);
  24. $this->assertEquals($model->a, $output->a);
  25. if (\function_exists('\GuzzleHttp\Psr7\stream_for')) {
  26. // @deprecated stream_for will be removed in guzzlehttp/psr7:2.0
  27. $stream = \GuzzleHttp\Psr7\stream_for('test');
  28. } else {
  29. $stream = \GuzzleHttp\Psr7\Utils::streamFor('test');
  30. }
  31. $source = new SourceModel();
  32. $source->test = 'test';
  33. $source->bodyObject = $stream;
  34. $source->listObject = [
  35. $stream
  36. ];
  37. $urlListObject = new urlListObject();
  38. $urlListObject->urlObject = $stream;
  39. $source->urlListObject = [
  40. $urlListObject
  41. ];
  42. $target = new TargetModel();
  43. OpenApiUtilClient::convert($source, $target);
  44. $this->assertEquals('test', $target->test);
  45. $this->assertNull($target->empty);
  46. $this->assertNull($target->body);
  47. $this->assertTrue(empty($target->list));
  48. $this->assertNotNull($target->urlList[0]);
  49. $this->assertNull($target->urlList[0]->url);
  50. }
  51. public function testGetStringToSign()
  52. {
  53. $request = new Request();
  54. $request->method = 'GET';
  55. $request->pathname = '/';
  56. $request->headers['accept'] = 'application/json';
  57. $this->assertEquals("GET\napplication/json\n\n\n\n/", OpenApiUtilClient::getStringToSign($request));
  58. $request->headers = [
  59. 'accept' => 'application/json',
  60. 'content-md5' => 'md5',
  61. 'content-type' => 'application/json',
  62. 'date' => 'date',
  63. ];
  64. $this->assertEquals("GET\napplication/json\nmd5\napplication/json\ndate\n/", OpenApiUtilClient::getStringToSign($request));
  65. $request->headers = [
  66. 'accept' => 'application/json',
  67. 'content-md5' => 'md5',
  68. 'content-type' => 'application/json',
  69. 'date' => 'date',
  70. 'x-acs-custom-key' => 'any value',
  71. ];
  72. $this->assertEquals("GET\napplication/json\nmd5\napplication/json\ndate\nx-acs-custom-key:any value\n/", OpenApiUtilClient::getStringToSign($request));
  73. $request->query = [
  74. 'key' => 'val ue with space',
  75. ];
  76. $this->assertEquals("GET\napplication/json\nmd5\napplication/json\ndate\nx-acs-custom-key:any value\n/?key=val ue with space", OpenApiUtilClient::getStringToSign($request));
  77. }
  78. public function testGetROASignature()
  79. {
  80. $this->assertEquals('OmuTAr79tpI6CRoAdmzKRq5lHs0=', OpenApiUtilClient::getROASignature('stringtosign', 'secret'));
  81. }
  82. public function testToForm()
  83. {
  84. $this->assertEquals('bool=true&client=test&strs.1=str1&strs.2=str2&strs.3=false&tag.key=value', OpenApiUtilClient::toForm([
  85. 'client' => 'test',
  86. 'tag' => [
  87. 'key' => 'value',
  88. ],
  89. 'strs' => ['str1', 'str2', false],
  90. 'bool' => true,
  91. 'null' => null,
  92. ]));
  93. }
  94. public function testGetTimestamp()
  95. {
  96. $date = OpenApiUtilClient::getTimestamp();
  97. $this->assertEquals(20, \strlen($date));
  98. }
  99. public function testQuery()
  100. {
  101. $model = new MockModel();
  102. $model->a = 'foo';
  103. $model->c = 'boo';
  104. $model->r = true;
  105. $array = [
  106. 'a' => 'a',
  107. 'b1' => [
  108. 'a' => 'a',
  109. ],
  110. 'b2' => [
  111. 'a' => 'a',
  112. ],
  113. 'c' => ['x', 'y', 'z'],
  114. 'd' => [
  115. $model
  116. ],
  117. 'e' => true,
  118. 'f' => null,
  119. ];
  120. $this->assertEquals([
  121. 'a' => 'a',
  122. 'b1.a' => 'a',
  123. 'b2.a' => 'a',
  124. 'c.1' => 'x',
  125. 'c.2' => 'y',
  126. 'c.3' => 'z',
  127. 'd.1.A' => 'foo',
  128. 'd.1.b' => '',
  129. 'd.1.c' => 'boo',
  130. 'd.1.c' => 'boo',
  131. 'd.1.r' => 'true',
  132. 'e' => 'true',
  133. 'f' => null
  134. ], OpenApiUtilClient::query($array));
  135. }
  136. public function testGetRPCSignature()
  137. {
  138. $request = new Request();
  139. $request->pathname = '';
  140. $request->query = [
  141. 'query' => 'test',
  142. 'body' => 'test',
  143. ];
  144. $this->assertEquals('XlUyV4sXjOuX5FnjUz9IF9tm5rU=', OpenApiUtilClient::getRPCSignature($request->query, $request->method, 'secret'));
  145. }
  146. public function testArrayToStringWithSpecifiedStyle()
  147. {
  148. $data = ['ok', 'test', 2, 3];
  149. $this->assertEquals(
  150. 'instance.1=ok&instance.2=test&instance.3=2&instance.4=3',
  151. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  152. $data,
  153. 'instance',
  154. 'repeatList'
  155. )
  156. );
  157. $this->assertEquals(
  158. '["ok","test",2,3]',
  159. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  160. $data,
  161. 'instance',
  162. 'json'
  163. )
  164. );
  165. $test = new ParseModel([
  166. 'str' => 'A',
  167. 'model' => new ParseModel(['str' => 'sub model']),
  168. 'array' => [1, 2, 3],
  169. ]);
  170. $this->assertEquals(
  171. '{"str":"A","model":{"str":"sub model","model":null,"array":null},"array":[1,2,3]}',
  172. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  173. $test,
  174. 'instance',
  175. 'json'
  176. )
  177. );
  178. // model item in array
  179. $test = [
  180. new ParseModel([
  181. 'str' => 'A',
  182. ]),
  183. ];
  184. $this->assertEquals(
  185. '[{"str":"A","model":null,"array":null}]',
  186. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  187. $test,
  188. 'instance',
  189. 'json'
  190. )
  191. );
  192. // model item in map
  193. $test = [
  194. 'model' => new ParseModel([
  195. 'str' => 'A',
  196. ]),
  197. ];
  198. $this->assertEquals(
  199. '{"model":{"str":"A","model":null,"array":null}}',
  200. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  201. $test,
  202. 'instance',
  203. 'json'
  204. )
  205. );
  206. $this->assertEquals(
  207. 'ok,test,2,3',
  208. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  209. $data,
  210. 'instance',
  211. 'simple'
  212. )
  213. );
  214. $this->assertEquals(
  215. 'ok test 2 3',
  216. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  217. $data,
  218. 'instance',
  219. 'spaceDelimited'
  220. )
  221. );
  222. $this->assertEquals(
  223. 'ok|test|2|3',
  224. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  225. $data,
  226. 'instance',
  227. 'pipeDelimited'
  228. )
  229. );
  230. $this->assertEquals(
  231. '',
  232. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  233. $data,
  234. 'instance',
  235. 'piDelimited'
  236. )
  237. );
  238. $this->assertEquals(
  239. '',
  240. OpenApiUtilClient::arrayToStringWithSpecifiedStyle(
  241. null,
  242. 'instance',
  243. 'pipeDelimited'
  244. )
  245. );
  246. }
  247. public function testParseToArray()
  248. {
  249. $test = $this->parseData();
  250. $data = $test['data'];
  251. $expected = $test['expected'];
  252. foreach ($data as $index => $item) {
  253. $this->assertEquals($expected[$index], OpenApiUtilClient::parseToArray($item));
  254. }
  255. }
  256. public function testParseToMap()
  257. {
  258. $test = $this->parseData();
  259. $data = $test['data'];
  260. $expected = $test['expected'];
  261. foreach ($data as $index => $item) {
  262. $this->assertEquals($expected[$index], OpenApiUtilClient::parseToMap($item));
  263. }
  264. }
  265. public function testGetEndpoint()
  266. {
  267. $endpoint = 'ecs.cn-hangzhou.aliyun.cs.com';
  268. $useAccelerate = false;
  269. $endpointType = 'public';
  270. $this->assertEquals('ecs.cn-hangzhou.aliyun.cs.com', OpenApiUtilClient::getEndpoint($endpoint, $useAccelerate, $endpointType));
  271. $endpointType = 'internal';
  272. $this->assertEquals('ecs-internal.cn-hangzhou.aliyun.cs.com', OpenApiUtilClient::getEndpoint($endpoint, $useAccelerate, $endpointType));
  273. $useAccelerate = true;
  274. $endpointType = 'accelerate';
  275. $this->assertEquals('oss-accelerate.aliyuncs.com', OpenApiUtilClient::getEndpoint($endpoint, $useAccelerate, $endpointType));
  276. }
  277. public function testHexEncode()
  278. {
  279. $data = OpenApiUtilClient::hash(Utils::toBytes('test'), 'ACS3-HMAC-SHA256');
  280. $this->assertEquals(
  281. Utils::toBytes(hex2bin('9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08')),
  282. $data
  283. );
  284. $data = OpenApiUtilClient::hash(Utils::toBytes('test'), 'ACS3-RSA-SHA256');
  285. $this->assertEquals(
  286. Utils::toBytes(hex2bin('9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08')),
  287. $data
  288. );
  289. $data = OpenApiUtilClient::hash(Utils::toBytes('test'), 'ACS3-HMAC-SM3');
  290. $this->assertEquals(
  291. Utils::toBytes(hex2bin('55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a65890c2a19ecf88a307e76a23')),
  292. $data
  293. );
  294. $data = OpenApiUtilClient::hash(Utils::toBytes('test'), 'ACS3-HM-SHA256');
  295. $this->assertEquals('', Utils::toString($data));
  296. }
  297. public function testGetEncodePath()
  298. {
  299. $this->assertEquals(
  300. '/path/%20test',
  301. OpenApiUtilClient::getEncodePath('/path/ test')
  302. );
  303. }
  304. public function testGetEncodeParam()
  305. {
  306. $this->assertEquals(
  307. 'a%2Fb%2Fc%2F%20test',
  308. OpenApiUtilClient::getEncodeParam('a/b/c/ test')
  309. );
  310. }
  311. public function testGetAuthorization()
  312. {
  313. $request = new Request();
  314. $request->method = '';
  315. $request->pathname = '';
  316. $request->query = [
  317. 'test' => 'ok',
  318. 'empty' => '',
  319. ];
  320. $request->headers = [
  321. 'x-acs-test' => 'http',
  322. 'x-acs-TEST' => 'https',
  323. ];
  324. $res = OpenApiUtilClient::getAuthorization($request, 'ACS3-HMAC-SHA256', '55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a65890c2a19ecf88a307e76a23', 'acesskey', 'secret');
  325. $this->assertEquals('ACS3-HMAC-SHA256 Credential=acesskey,SignedHeaders=x-acs-test,Signature=0a0f89a45f1ec3537a2d1a1046c71b95513a8f1f02526056968da19b99a5b914', $res);
  326. $request->query = null;
  327. $res = OpenApiUtilClient::getAuthorization($request, 'ACS3-HMAC-SHA256', '55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a65890c2a19ecf88a307e76a23', 'acesskey', 'secret');
  328. $this->assertEquals('ACS3-HMAC-SHA256 Credential=acesskey,SignedHeaders=x-acs-test,Signature=af6d32deb090ae85a21d7183055cf18dca17751da96979cdf964f8f0853e9dd2', $res);
  329. }
  330. public function testSign()
  331. {
  332. $this->assertEquals(
  333. 'b9ff646822f41ef647c1416fa2b8408923828abc0464af6706e18db3e8553da8',
  334. OpenApiUtilClient::hexEncode(OpenApiUtilClient::sign('secret', 'source', 'ACS3-HMAC-SM3'))
  335. );
  336. $this->assertEquals(
  337. '1d93c62698a1c26427265668e79fac099aa26c1df873669599a2fb2f272e64c9',
  338. OpenApiUtilClient::hexEncode(OpenApiUtilClient::sign('secret', 'source', 'ACS3-HMAC-SHA256'))
  339. );
  340. }
  341. private function parseData()
  342. {
  343. return [
  344. 'data' => [
  345. 'NotArray',
  346. new ParseModel([
  347. 'str' => 'A',
  348. 'model' => new ParseModel(['str' => 'sub model']),
  349. 'array' => [1, 2, 3],
  350. ]),
  351. [ // model item in array
  352. new ParseModel([
  353. 'str' => 'A',
  354. ]),
  355. ],
  356. [ // model item in map
  357. 'model' => new ParseModel([
  358. 'str' => 'A',
  359. ]),
  360. ],
  361. ],
  362. 'expected' => [
  363. ['NotArray'],
  364. [
  365. 'str' => 'A',
  366. 'model' => [
  367. 'str' => 'sub model',
  368. 'model' => null,
  369. 'array' => null,
  370. ],
  371. 'array' => [1, 2, 3],
  372. ],
  373. [
  374. [
  375. 'str' => 'A',
  376. 'model' => null,
  377. 'array' => null,
  378. ],
  379. ],
  380. [
  381. 'model' => [
  382. 'str' => 'A',
  383. 'model' => null,
  384. 'array' => null,
  385. ],
  386. ],
  387. ],
  388. 'expectedJsonStr' => [
  389. '["NotArray"]',
  390. 'NotArray',
  391. 'NotArray',
  392. 'NotArray',
  393. ],
  394. ];
  395. }
  396. }
  397. class MockModel extends Model
  398. {
  399. public $a = 'A';
  400. public $b = '';
  401. public $c = '';
  402. public $r;
  403. public function __construct()
  404. {
  405. $this->_name['a'] = 'A';
  406. $this->_required['c'] = true;
  407. parent::__construct([]);
  408. }
  409. public function toMap()
  410. {
  411. $res = [];
  412. if (null !== $this->a) {
  413. $res['A'] = $this->a;
  414. }
  415. if (null !== $this->b) {
  416. $res['b'] = $this->b;
  417. }
  418. if (null !== $this->c) {
  419. $res['c'] = $this->c;
  420. }
  421. if (null !== $this->r) {
  422. $res['r'] = $this->r;
  423. }
  424. return $res;
  425. }
  426. public static function fromMap($map = [])
  427. {
  428. $model = new self();
  429. if (isset($map['A'])) {
  430. $model->a = $map['A'];
  431. }
  432. if (isset($map['b'])) {
  433. $model->b = $map['b'];
  434. }
  435. if (isset($map['c'])) {
  436. $model->c = $map['c'];
  437. }
  438. if (isset($map['r'])) {
  439. $model->r = $map['r'];
  440. }
  441. return $model;
  442. }
  443. }
  444. class ParseModel extends Model
  445. {
  446. public $str;
  447. public $model;
  448. public $array;
  449. }