FetcherBase.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
  4. *
  5. * @license GNU AGPL version 3 or any later version
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Affero General Public License as
  9. * published by the Free Software Foundation, either version 3 of the
  10. * License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Affero General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. namespace Test\App\AppStore\Fetcher;
  22. use OC\App\AppStore\Fetcher\Fetcher;
  23. use OC\Files\AppData\AppData;
  24. use OC\Files\AppData\Factory;
  25. use OCP\AppFramework\Utility\ITimeFactory;
  26. use OCP\Files\IAppData;
  27. use OCP\Files\NotFoundException;
  28. use OCP\Files\SimpleFS\ISimpleFile;
  29. use OCP\Files\SimpleFS\ISimpleFolder;
  30. use OCP\Http\Client\IClient;
  31. use OCP\Http\Client\IClientService;
  32. use OCP\Http\Client\IResponse;
  33. use OCP\IConfig;
  34. use OCP\ILogger;
  35. use Test\TestCase;
  36. abstract class FetcherBase extends TestCase {
  37. /** @var Factory|\PHPUnit_Framework_MockObject_MockObject */
  38. protected $appDataFactory;
  39. /** @var IAppData|\PHPUnit_Framework_MockObject_MockObject */
  40. protected $appData;
  41. /** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */
  42. protected $clientService;
  43. /** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */
  44. protected $timeFactory;
  45. /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
  46. protected $config;
  47. /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
  48. protected $logger;
  49. /** @var Fetcher */
  50. protected $fetcher;
  51. /** @var string */
  52. protected $fileName;
  53. /** @var string */
  54. protected $endpoint;
  55. public function setUp() {
  56. parent::setUp();
  57. $this->appDataFactory = $this->createMock(Factory::class);
  58. $this->appData = $this->createMock(AppData::class);
  59. $this->appDataFactory->expects($this->once())
  60. ->method('get')
  61. ->with('appstore')
  62. ->willReturn($this->appData);
  63. $this->clientService = $this->createMock(IClientService::class);
  64. $this->timeFactory = $this->createMock(ITimeFactory::class);
  65. $this->config = $this->createMock(IConfig::class);
  66. $this->logger = $this->createMock(ILogger::class);
  67. }
  68. public function testGetWithAlreadyExistingFileAndUpToDateTimestampAndVersion() {
  69. $this->config
  70. ->expects($this->at(0))
  71. ->method('getSystemValue')
  72. ->with('appstoreenabled', true)
  73. ->willReturn(true);
  74. $this->config
  75. ->expects($this->at(1))
  76. ->method('getSystemValue')
  77. ->with('has_internet_connection', true)
  78. ->willReturn(true);
  79. $this->config
  80. ->expects($this->at(2))
  81. ->method('getSystemValue')
  82. ->with(
  83. $this->equalTo('version'),
  84. $this->anything()
  85. )->willReturn('11.0.0.2');
  86. $folder = $this->createMock(ISimpleFolder::class);
  87. $file = $this->createMock(ISimpleFile::class);
  88. $this->appData
  89. ->expects($this->once())
  90. ->method('getFolder')
  91. ->with('/')
  92. ->willReturn($folder);
  93. $folder
  94. ->expects($this->once())
  95. ->method('getFile')
  96. ->with($this->fileName)
  97. ->willReturn($file);
  98. $file
  99. ->expects($this->once())
  100. ->method('getContent')
  101. ->willReturn('{"timestamp":1200,"data":[{"id":"MyApp"}],"ncversion":"11.0.0.2"}');
  102. $this->timeFactory
  103. ->expects($this->once())
  104. ->method('getTime')
  105. ->willReturn(1499);
  106. $expected = [
  107. [
  108. 'id' => 'MyApp',
  109. ],
  110. ];
  111. $this->assertSame($expected, $this->fetcher->get());
  112. }
  113. public function testGetWithNotExistingFileAndUpToDateTimestampAndVersion() {
  114. $this->config
  115. ->expects($this->at(0))
  116. ->method('getSystemValue')
  117. ->with('appstoreenabled', true)
  118. ->willReturn(true);
  119. $this->config
  120. ->expects($this->at(1))
  121. ->method('getSystemValue')
  122. ->with('has_internet_connection', true)
  123. ->willReturn(true);
  124. $this->config
  125. ->expects($this->at(2))
  126. ->method('getSystemValue')
  127. ->with('appstoreenabled', true)
  128. ->willReturn(true);
  129. $this->config
  130. ->expects($this->at(3))
  131. ->method('getSystemValue')
  132. ->with(
  133. $this->equalTo('version'),
  134. $this->anything()
  135. )->willReturn('11.0.0.2');
  136. $folder = $this->createMock(ISimpleFolder::class);
  137. $file = $this->createMock(ISimpleFile::class);
  138. $this->appData
  139. ->expects($this->once())
  140. ->method('getFolder')
  141. ->with('/')
  142. ->willReturn($folder);
  143. $folder
  144. ->expects($this->at(0))
  145. ->method('getFile')
  146. ->with($this->fileName)
  147. ->willThrowException(new NotFoundException());
  148. $folder
  149. ->expects($this->at(1))
  150. ->method('newFile')
  151. ->with($this->fileName)
  152. ->willReturn($file);
  153. $client = $this->createMock(IClient::class);
  154. $this->clientService
  155. ->expects($this->once())
  156. ->method('newClient')
  157. ->willReturn($client);
  158. $response = $this->createMock(IResponse::class);
  159. $client
  160. ->expects($this->once())
  161. ->method('get')
  162. ->with($this->endpoint)
  163. ->willReturn($response);
  164. $response
  165. ->expects($this->once())
  166. ->method('getBody')
  167. ->willReturn('[{"id":"MyNewApp", "foo": "foo"}, {"id":"bar"}]');
  168. $response->method('getHeader')
  169. ->with($this->equalTo('ETag'))
  170. ->willReturn('"myETag"');
  171. $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1502,"ncversion":"11.0.0.2","ETag":"\"myETag\""}';
  172. $file
  173. ->expects($this->at(0))
  174. ->method('putContent')
  175. ->with($fileData);
  176. $file
  177. ->expects($this->at(1))
  178. ->method('getContent')
  179. ->willReturn($fileData);
  180. $this->timeFactory
  181. ->expects($this->at(0))
  182. ->method('getTime')
  183. ->willReturn(1502);
  184. $expected = [
  185. [
  186. 'id' => 'MyNewApp',
  187. 'foo' => 'foo',
  188. ],
  189. [
  190. 'id' => 'bar',
  191. ],
  192. ];
  193. $this->assertSame($expected, $this->fetcher->get());
  194. }
  195. public function testGetWithAlreadyExistingFileAndOutdatedTimestamp() {
  196. $this->config->method('getSystemValue')
  197. ->willReturnCallback(function($key, $default) {
  198. if ($key === 'appstoreenabled') {
  199. return true;
  200. } else if ($key === 'version') {
  201. return '11.0.0.2';
  202. } else {
  203. return $default;
  204. }
  205. });
  206. $folder = $this->createMock(ISimpleFolder::class);
  207. $file = $this->createMock(ISimpleFile::class);
  208. $this->appData
  209. ->expects($this->once())
  210. ->method('getFolder')
  211. ->with('/')
  212. ->willReturn($folder);
  213. $folder
  214. ->expects($this->once())
  215. ->method('getFile')
  216. ->with($this->fileName)
  217. ->willReturn($file);
  218. $file
  219. ->expects($this->at(0))
  220. ->method('getContent')
  221. ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}},"ncversion":"11.0.0.2"}');
  222. $this->timeFactory
  223. ->expects($this->at(0))
  224. ->method('getTime')
  225. ->willReturn(1501);
  226. $client = $this->createMock(IClient::class);
  227. $this->clientService
  228. ->expects($this->once())
  229. ->method('newClient')
  230. ->willReturn($client);
  231. $response = $this->createMock(IResponse::class);
  232. $client
  233. ->expects($this->once())
  234. ->method('get')
  235. ->with($this->endpoint)
  236. ->willReturn($response);
  237. $response
  238. ->expects($this->once())
  239. ->method('getBody')
  240. ->willReturn('[{"id":"MyNewApp", "foo": "foo"}, {"id":"bar"}]');
  241. $response->method('getHeader')
  242. ->with($this->equalTo('ETag'))
  243. ->willReturn('"myETag"');
  244. $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1502,"ncversion":"11.0.0.2","ETag":"\"myETag\""}';
  245. $file
  246. ->expects($this->at(1))
  247. ->method('putContent')
  248. ->with($fileData);
  249. $file
  250. ->expects($this->at(2))
  251. ->method('getContent')
  252. ->willReturn($fileData);
  253. $this->timeFactory
  254. ->expects($this->at(1))
  255. ->method('getTime')
  256. ->willReturn(1502);
  257. $expected = [
  258. [
  259. 'id' => 'MyNewApp',
  260. 'foo' => 'foo',
  261. ],
  262. [
  263. 'id' => 'bar',
  264. ],
  265. ];
  266. $this->assertSame($expected, $this->fetcher->get());
  267. }
  268. public function testGetWithAlreadyExistingFileAndNoVersion() {
  269. $this->config
  270. ->expects($this->at(0))
  271. ->method('getSystemValue')
  272. ->with('appstoreenabled', true)
  273. ->willReturn(true);
  274. $this->config
  275. ->expects($this->at(1))
  276. ->method('getSystemValue')
  277. ->with('has_internet_connection', true)
  278. ->willReturn(true);
  279. $this->config
  280. ->expects($this->at(2))
  281. ->method('getSystemValue')
  282. ->with('appstoreenabled', true)
  283. ->willReturn(true);
  284. $this->config
  285. ->expects($this->at(3))
  286. ->method('getSystemValue')
  287. ->with(
  288. $this->equalTo('version'),
  289. $this->anything()
  290. )->willReturn('11.0.0.2');
  291. $folder = $this->createMock(ISimpleFolder::class);
  292. $file = $this->createMock(ISimpleFile::class);
  293. $this->appData
  294. ->expects($this->once())
  295. ->method('getFolder')
  296. ->with('/')
  297. ->willReturn($folder);
  298. $folder
  299. ->expects($this->once())
  300. ->method('getFile')
  301. ->with($this->fileName)
  302. ->willReturn($file);
  303. $file
  304. ->expects($this->at(0))
  305. ->method('getContent')
  306. ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}}');
  307. $this->timeFactory
  308. ->expects($this->at(0))
  309. ->method('getTime')
  310. ->willReturn(1201);
  311. $client = $this->createMock(IClient::class);
  312. $this->clientService
  313. ->expects($this->once())
  314. ->method('newClient')
  315. ->willReturn($client);
  316. $response = $this->createMock(IResponse::class);
  317. $client
  318. ->expects($this->once())
  319. ->method('get')
  320. ->with($this->endpoint)
  321. ->willReturn($response);
  322. $response
  323. ->expects($this->once())
  324. ->method('getBody')
  325. ->willReturn('[{"id":"MyNewApp", "foo": "foo"}, {"id":"bar"}]');
  326. $response->method('getHeader')
  327. ->with($this->equalTo('ETag'))
  328. ->willReturn('"myETag"');
  329. $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1201,"ncversion":"11.0.0.2","ETag":"\"myETag\""}';
  330. $file
  331. ->expects($this->at(1))
  332. ->method('putContent')
  333. ->with($fileData);
  334. $file
  335. ->expects($this->at(2))
  336. ->method('getContent')
  337. ->willReturn($fileData);
  338. $expected = [
  339. [
  340. 'id' => 'MyNewApp',
  341. 'foo' => 'foo',
  342. ],
  343. [
  344. 'id' => 'bar',
  345. ],
  346. ];
  347. $this->assertSame($expected, $this->fetcher->get());
  348. }
  349. public function testGetWithAlreadyExistingFileAndOutdatedVersion() {
  350. $this->config
  351. ->expects($this->at(0))
  352. ->method('getSystemValue')
  353. ->with('appstoreenabled', true)
  354. ->willReturn(true);
  355. $this->config
  356. ->expects($this->at(1))
  357. ->method('getSystemValue')
  358. ->with('has_internet_connection', true)
  359. ->willReturn(true);
  360. $this->config
  361. ->expects($this->at(2))
  362. ->method('getSystemValue')
  363. ->with('appstoreenabled', true)
  364. ->willReturn(true);
  365. $this->config
  366. ->expects($this->at(3))
  367. ->method('getSystemValue')
  368. ->with(
  369. $this->equalTo('version'),
  370. $this->anything()
  371. )->willReturn('11.0.0.2');
  372. $folder = $this->createMock(ISimpleFolder::class);
  373. $file = $this->createMock(ISimpleFile::class);
  374. $this->appData
  375. ->expects($this->once())
  376. ->method('getFolder')
  377. ->with('/')
  378. ->willReturn($folder);
  379. $folder
  380. ->expects($this->once())
  381. ->method('getFile')
  382. ->with($this->fileName)
  383. ->willReturn($file);
  384. $file
  385. ->expects($this->at(0))
  386. ->method('getContent')
  387. ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}},"ncversion":"11.0.0.1"');
  388. $this->timeFactory
  389. ->method('getTime')
  390. ->willReturn(1201);
  391. $client = $this->createMock(IClient::class);
  392. $this->clientService
  393. ->expects($this->once())
  394. ->method('newClient')
  395. ->willReturn($client);
  396. $response = $this->createMock(IResponse::class);
  397. $client
  398. ->expects($this->once())
  399. ->method('get')
  400. ->with($this->endpoint)
  401. ->willReturn($response);
  402. $response
  403. ->expects($this->once())
  404. ->method('getBody')
  405. ->willReturn('[{"id":"MyNewApp", "foo": "foo"}, {"id":"bar"}]');
  406. $response->method('getHeader')
  407. ->with($this->equalTo('ETag'))
  408. ->willReturn('"myETag"');
  409. $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1201,"ncversion":"11.0.0.2","ETag":"\"myETag\""}';
  410. $file
  411. ->expects($this->at(1))
  412. ->method('putContent')
  413. ->with($fileData);
  414. $file
  415. ->expects($this->at(2))
  416. ->method('getContent')
  417. ->willReturn($fileData);
  418. $expected = [
  419. [
  420. 'id' => 'MyNewApp',
  421. 'foo' => 'foo',
  422. ],
  423. [
  424. 'id' => 'bar',
  425. ],
  426. ];
  427. $this->assertSame($expected, $this->fetcher->get());
  428. }
  429. public function testGetWithExceptionInClient() {
  430. $this->config->method('getSystemValue')
  431. ->willReturnCallback(function($key, $default) {
  432. if ($key === 'appstoreenabled') {
  433. return true;
  434. } else {
  435. return $default;
  436. }
  437. });
  438. $folder = $this->createMock(ISimpleFolder::class);
  439. $file = $this->createMock(ISimpleFile::class);
  440. $this->appData
  441. ->expects($this->once())
  442. ->method('getFolder')
  443. ->with('/')
  444. ->willReturn($folder);
  445. $folder
  446. ->expects($this->once())
  447. ->method('getFile')
  448. ->with($this->fileName)
  449. ->willReturn($file);
  450. $file
  451. ->expects($this->at(0))
  452. ->method('getContent')
  453. ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}}}');
  454. $client = $this->createMock(IClient::class);
  455. $this->clientService
  456. ->expects($this->once())
  457. ->method('newClient')
  458. ->willReturn($client);
  459. $client
  460. ->expects($this->once())
  461. ->method('get')
  462. ->with($this->endpoint)
  463. ->willThrowException(new \Exception());
  464. $this->assertSame([], $this->fetcher->get());
  465. }
  466. public function testGetMatchingETag() {
  467. $this->config->method('getSystemValue')
  468. ->willReturnCallback(function($key, $default) {
  469. if ($key === 'appstoreenabled') {
  470. return true;
  471. } else if ($key === 'version') {
  472. return '11.0.0.2';
  473. } else {
  474. return $default;
  475. }
  476. });
  477. $folder = $this->createMock(ISimpleFolder::class);
  478. $file = $this->createMock(ISimpleFile::class);
  479. $this->appData
  480. ->expects($this->once())
  481. ->method('getFolder')
  482. ->with('/')
  483. ->willReturn($folder);
  484. $folder
  485. ->expects($this->once())
  486. ->method('getFile')
  487. ->with($this->fileName)
  488. ->willReturn($file);
  489. $origData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1200,"ncversion":"11.0.0.2","ETag":"\"myETag\""}';
  490. $file
  491. ->expects($this->at(0))
  492. ->method('getContent')
  493. ->willReturn($origData);
  494. $this->timeFactory
  495. ->expects($this->at(0))
  496. ->method('getTime')
  497. ->willReturn(1501);
  498. $this->timeFactory
  499. ->expects($this->at(1))
  500. ->method('getTime')
  501. ->willReturn(1502);
  502. $client = $this->createMock(IClient::class);
  503. $this->clientService
  504. ->expects($this->once())
  505. ->method('newClient')
  506. ->willReturn($client);
  507. $response = $this->createMock(IResponse::class);
  508. $client
  509. ->expects($this->once())
  510. ->method('get')
  511. ->with(
  512. $this->equalTo($this->endpoint),
  513. $this->equalTo([
  514. 'timeout' => 10,
  515. 'headers' => [
  516. 'If-None-Match' => '"myETag"'
  517. ]
  518. ])
  519. )->willReturn($response);
  520. $response->method('getStatusCode')
  521. ->willReturn(304);
  522. $newData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1502,"ncversion":"11.0.0.2","ETag":"\"myETag\""}';
  523. $file
  524. ->expects($this->at(1))
  525. ->method('putContent')
  526. ->with($newData);
  527. $file
  528. ->expects($this->at(2))
  529. ->method('getContent')
  530. ->willReturn($newData);
  531. $expected = [
  532. [
  533. 'id' => 'MyNewApp',
  534. 'foo' => 'foo',
  535. ],
  536. [
  537. 'id' => 'bar',
  538. ],
  539. ];
  540. $this->assertSame($expected, $this->fetcher->get());
  541. }
  542. public function testGetNoMatchingETag() {
  543. $this->config->method('getSystemValue')
  544. ->willReturnCallback(function($key, $default) {
  545. if ($key === 'appstoreenabled') {
  546. return true;
  547. } else if ($key === 'version') {
  548. return '11.0.0.2';
  549. } else {
  550. return $default;
  551. }
  552. });
  553. $folder = $this->createMock(ISimpleFolder::class);
  554. $file = $this->createMock(ISimpleFile::class);
  555. $this->appData
  556. ->expects($this->once())
  557. ->method('getFolder')
  558. ->with('/')
  559. ->willReturn($folder);
  560. $folder
  561. ->expects($this->at(0))
  562. ->method('getFile')
  563. ->with($this->fileName)
  564. ->willReturn($file);
  565. $file
  566. ->expects($this->at(0))
  567. ->method('getContent')
  568. ->willReturn('{"data":[{"id":"MyOldApp","abc":"def"}],"timestamp":1200,"ncversion":"11.0.0.2","ETag":"\"myETag\""}');
  569. $client = $this->createMock(IClient::class);
  570. $this->clientService
  571. ->expects($this->once())
  572. ->method('newClient')
  573. ->willReturn($client);
  574. $response = $this->createMock(IResponse::class);
  575. $client
  576. ->expects($this->once())
  577. ->method('get')
  578. ->with(
  579. $this->equalTo($this->endpoint),
  580. $this->equalTo([
  581. 'timeout' => 10,
  582. 'headers' => [
  583. 'If-None-Match' => '"myETag"',
  584. ]
  585. ])
  586. )
  587. ->willReturn($response);
  588. $response->method('getStatusCode')
  589. ->willReturn(200);
  590. $response
  591. ->expects($this->once())
  592. ->method('getBody')
  593. ->willReturn('[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}]');
  594. $response->method('getHeader')
  595. ->with($this->equalTo('ETag'))
  596. ->willReturn('"newETag"');
  597. $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1502,"ncversion":"11.0.0.2","ETag":"\"newETag\""}';
  598. $file
  599. ->expects($this->at(1))
  600. ->method('putContent')
  601. ->with($fileData);
  602. $file
  603. ->expects($this->at(2))
  604. ->method('getContent')
  605. ->willReturn($fileData);
  606. $this->timeFactory
  607. ->expects($this->at(0))
  608. ->method('getTime')
  609. ->willReturn(1501);
  610. $this->timeFactory
  611. ->expects($this->at(1))
  612. ->method('getTime')
  613. ->willReturn(1502);
  614. $expected = [
  615. [
  616. 'id' => 'MyNewApp',
  617. 'foo' => 'foo',
  618. ],
  619. [
  620. 'id' => 'bar',
  621. ],
  622. ];
  623. $this->assertSame($expected, $this->fetcher->get());
  624. }
  625. public function testFetchAfterUpgradeNoETag() {
  626. $this->config->method('getSystemValue')
  627. ->willReturnCallback(function($key, $default) {
  628. if ($key === 'appstoreenabled') {
  629. return true;
  630. } else if ($key === 'version') {
  631. return '11.0.0.3';
  632. } else {
  633. return $default;
  634. }
  635. });
  636. $folder = $this->createMock(ISimpleFolder::class);
  637. $file = $this->createMock(ISimpleFile::class);
  638. $this->appData
  639. ->expects($this->once())
  640. ->method('getFolder')
  641. ->with('/')
  642. ->willReturn($folder);
  643. $folder
  644. ->expects($this->at(0))
  645. ->method('getFile')
  646. ->with($this->fileName)
  647. ->willReturn($file);
  648. $file
  649. ->expects($this->at(0))
  650. ->method('getContent')
  651. ->willReturn('{"data":[{"id":"MyOldApp","abc":"def"}],"timestamp":1200,"ncversion":"11.0.0.2","ETag":"\"myETag\""}');
  652. $client = $this->createMock(IClient::class);
  653. $this->clientService
  654. ->expects($this->once())
  655. ->method('newClient')
  656. ->willReturn($client);
  657. $response = $this->createMock(IResponse::class);
  658. $client
  659. ->expects($this->once())
  660. ->method('get')
  661. ->with(
  662. $this->equalTo($this->endpoint),
  663. $this->equalTo([
  664. 'timeout' => 10,
  665. ])
  666. )
  667. ->willReturn($response);
  668. $response->method('getStatusCode')
  669. ->willReturn(200);
  670. $response
  671. ->expects($this->once())
  672. ->method('getBody')
  673. ->willReturn('[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}]');
  674. $response->method('getHeader')
  675. ->with($this->equalTo('ETag'))
  676. ->willReturn('"newETag"');
  677. $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1501,"ncversion":"11.0.0.3","ETag":"\"newETag\""}';
  678. $file
  679. ->expects($this->at(1))
  680. ->method('putContent')
  681. ->with($fileData);
  682. $file
  683. ->expects($this->at(2))
  684. ->method('getContent')
  685. ->willReturn($fileData);
  686. $this->timeFactory
  687. ->expects($this->once())
  688. ->method('getTime')
  689. ->willReturn(1501);
  690. $expected = [
  691. [
  692. 'id' => 'MyNewApp',
  693. 'foo' => 'foo',
  694. ],
  695. [
  696. 'id' => 'bar',
  697. ],
  698. ];
  699. $this->assertSame($expected, $this->fetcher->get());
  700. }
  701. }