You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

396 lines
11 KiB

  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright 2018, Denis Mosolov <denismosolov@gmail.com>
  5. *
  6. * @author Denis Mosolov <denismosolov@gmail.com>
  7. *
  8. * @license GNU AGPL version 3 or any later version
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Afferoq General Public License as
  12. * published by the Free Software Foundation, either version 3 of the
  13. * License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Affero General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. *
  23. */
  24. namespace OCA\Talk\Tests\php\Command\Turn;
  25. use OCA\Talk\Command\Turn\Add;
  26. use OCP\IConfig;
  27. use PHPUnit\Framework\MockObject\MockObject;
  28. use Symfony\Component\Console\Input\InputInterface;
  29. use Symfony\Component\Console\Output\OutputInterface;
  30. use Test\TestCase;
  31. class AddTest extends TestCase {
  32. protected IConfig&MockObject $config;
  33. protected InputInterface&MockObject $input;
  34. protected OutputInterface&MockObject $output;
  35. protected Add $command;
  36. public function setUp(): void {
  37. parent::setUp();
  38. $this->config = $this->createMock(IConfig::class);
  39. $this->command = new Add($this->config);
  40. $this->input = $this->createMock(InputInterface::class);
  41. $this->output = $this->createMock(OutputInterface::class);
  42. }
  43. public function testServerEmptyString(): void {
  44. $this->input->method('getArgument')
  45. ->willReturnCallback(function ($arg) {
  46. if ($arg === 'schemes') {
  47. return 'turn,turns';
  48. } elseif ($arg === 'server') {
  49. return '';
  50. } elseif ($arg === 'protocols') {
  51. return 'udp,tcp';
  52. }
  53. throw new \Exception();
  54. });
  55. $this->input->method('getOption')
  56. ->willReturnCallback(function ($arg) {
  57. if ($arg === 'secret') {
  58. return 'my-test-secret';
  59. } elseif ($arg === 'generate-secret') {
  60. return false;
  61. }
  62. throw new \Exception();
  63. });
  64. $this->output->expects($this->once())
  65. ->method('writeln')
  66. ->with($this->equalTo('<error>Server cannot be empty.</error>'));
  67. $this->config->expects($this->never())
  68. ->method('setAppValue');
  69. self::invokePrivate($this->command, 'execute', [$this->input, $this->output]);
  70. }
  71. public function testSecretEmpty(): void {
  72. $this->input->method('getArgument')
  73. ->willReturnCallback(function ($arg) {
  74. if ($arg === 'schemes') {
  75. return 'turn,turns';
  76. } elseif ($arg === 'server') {
  77. return 'turn.test.com';
  78. } elseif ($arg === 'protocols') {
  79. return 'udp,tcp';
  80. }
  81. throw new \Exception();
  82. });
  83. $this->input->method('getOption')
  84. ->willReturnCallback(function ($arg) {
  85. if ($arg === 'secret') {
  86. return '';
  87. } elseif ($arg === 'generate-secret') {
  88. return false;
  89. }
  90. throw new \Exception();
  91. });
  92. $this->output->expects($this->once())
  93. ->method('writeln')
  94. ->with($this->equalTo('<error>Secret cannot be empty.</error>'));
  95. $this->config->expects($this->never())
  96. ->method('setAppValue');
  97. self::invokePrivate($this->command, 'execute', [$this->input, $this->output]);
  98. }
  99. public function testGenerateSecret(): void {
  100. $this->input->method('getArgument')
  101. ->willReturnCallback(function ($arg) {
  102. if ($arg === 'schemes') {
  103. return 'turn,turns';
  104. } elseif ($arg === 'server') {
  105. return 'turn.test.com';
  106. } elseif ($arg === 'protocols') {
  107. return 'udp,tcp';
  108. }
  109. throw new \Exception();
  110. });
  111. $this->input->method('getOption')
  112. ->willReturnCallback(function ($arg) {
  113. if ($arg === 'secret') {
  114. return null;
  115. } elseif ($arg === 'generate-secret') {
  116. return true;
  117. }
  118. throw new \Exception();
  119. });
  120. $command = $this->getMockBuilder(Add::class)
  121. ->onlyMethods(['getUniqueSecret'])
  122. ->setConstructorArgs([$this->config])
  123. ->getMock();
  124. $command->expects($this->once())
  125. ->method('getUniqueSecret')
  126. ->willReturn('my-generaeted-test-secret');
  127. $this->config->method('getAppValue')
  128. ->with('spreed', 'turn_servers')
  129. ->willReturn(json_encode([]));
  130. $this->config->expects($this->once())
  131. ->method('setAppValue')
  132. ->with(
  133. $this->equalTo('spreed'),
  134. $this->equalTo('turn_servers'),
  135. $this->equalTo(json_encode([
  136. [
  137. 'schemes' => 'turn,turns',
  138. 'server' => 'turn.test.com',
  139. 'secret' => 'my-generaeted-test-secret',
  140. 'protocols' => 'udp,tcp'
  141. ]
  142. ]))
  143. );
  144. $this->output->expects($this->once())
  145. ->method('writeln')
  146. ->with($this->equalTo('<info>Added turn.test.com.</info>'));
  147. self::invokePrivate($command, 'execute', [$this->input, $this->output]);
  148. }
  149. public function testSecretAndGenerateSecretOptions(): void {
  150. $this->input->method('getArgument')
  151. ->willReturnCallback(function ($arg) {
  152. if ($arg === 'schemes') {
  153. return 'turn,turns';
  154. } elseif ($arg === 'server') {
  155. return 'turn.test.com';
  156. } elseif ($arg === 'protocols') {
  157. return 'udp,tcp';
  158. }
  159. throw new \Exception();
  160. });
  161. $this->input->method('getOption')
  162. ->willReturnCallback(function ($arg) {
  163. if ($arg === 'secret') {
  164. return 'my-test-secret';
  165. } elseif ($arg === 'generate-secret') {
  166. return true;
  167. }
  168. throw new \Exception();
  169. });
  170. $this->output->expects($this->once())
  171. ->method('writeln')
  172. ->with($this->equalTo('<error>You must provide --secret or --generate-secret.</error>'));
  173. $this->config->expects($this->never())
  174. ->method('setAppValue');
  175. self::invokePrivate($this->command, 'execute', [$this->input, $this->output]);
  176. }
  177. public function testInvalidSchemesString(): void {
  178. $this->input->method('getArgument')
  179. ->willReturnCallback(function ($arg) {
  180. if ($arg === 'schemes') {
  181. return 'invalid-scheme';
  182. } elseif ($arg === 'server') {
  183. return 'turn.test.com';
  184. } elseif ($arg === 'protocols') {
  185. return 'udp,tcp';
  186. }
  187. throw new \Exception();
  188. });
  189. $this->input->method('getOption')
  190. ->willReturnCallback(function ($arg) {
  191. if ($arg === 'secret') {
  192. return 'my-test-secret';
  193. } elseif ($arg === 'generate-secret') {
  194. return false;
  195. }
  196. throw new \Exception();
  197. });
  198. $this->output->expects($this->once())
  199. ->method('writeln')
  200. ->with($this->equalTo('<error>Not allowed schemes, must be turn or turns or turn,turns.</error>'));
  201. $this->config->expects($this->never())
  202. ->method('setAppValue');
  203. self::invokePrivate($this->command, 'execute', [$this->input, $this->output]);
  204. }
  205. public function testInvalidProtocolsString(): void {
  206. $this->input->method('getArgument')
  207. ->willReturnCallback(function ($arg) {
  208. if ($arg === 'schemes') {
  209. return 'turn,turns';
  210. } elseif ($arg === 'server') {
  211. return 'turn.test.com';
  212. } elseif ($arg === 'protocols') {
  213. return 'invalid-protocol';
  214. }
  215. throw new \Exception();
  216. });
  217. $this->input->method('getOption')
  218. ->willReturnCallback(function ($arg) {
  219. if ($arg === 'secret') {
  220. return 'my-test-secret';
  221. } elseif ($arg === 'generate-secret') {
  222. return false;
  223. }
  224. throw new \Exception();
  225. });
  226. $this->output->expects($this->once())
  227. ->method('writeln')
  228. ->with($this->equalTo('<error>Not allowed protocols, must be udp or tcp or udp,tcp.</error>'));
  229. $this->config->expects($this->never())
  230. ->method('setAppValue');
  231. self::invokePrivate($this->command, 'execute', [$this->input, $this->output]);
  232. }
  233. public function testAddServerToEmptyList(): void {
  234. $this->input->method('getArgument')
  235. ->willReturnCallback(function ($arg) {
  236. if ($arg === 'schemes') {
  237. return 'turn,turns';
  238. } elseif ($arg === 'server') {
  239. return 'turn.test.com';
  240. } elseif ($arg === 'protocols') {
  241. return 'udp,tcp';
  242. }
  243. throw new \Exception();
  244. });
  245. $this->input->method('getOption')
  246. ->willReturnCallback(function ($arg) {
  247. if ($arg === 'secret') {
  248. return 'my-test-secret';
  249. } elseif ($arg === 'generate-secret') {
  250. return false;
  251. }
  252. throw new \Exception();
  253. });
  254. $this->config->method('getAppValue')
  255. ->with('spreed', 'turn_servers')
  256. ->willReturn(json_encode([]));
  257. $this->config->expects($this->once())
  258. ->method('setAppValue')
  259. ->with(
  260. $this->equalTo('spreed'),
  261. $this->equalTo('turn_servers'),
  262. $this->equalTo(json_encode([
  263. [
  264. 'schemes' => 'turn,turns',
  265. 'server' => 'turn.test.com',
  266. 'secret' => 'my-test-secret',
  267. 'protocols' => 'udp,tcp'
  268. ]
  269. ]))
  270. );
  271. $this->output->expects($this->once())
  272. ->method('writeln')
  273. ->with($this->equalTo('<info>Added turn.test.com.</info>'));
  274. self::invokePrivate($this->command, 'execute', [$this->input, $this->output]);
  275. }
  276. public function testAddServerToNonEmptyList(): void {
  277. $this->input->method('getArgument')
  278. ->willReturnCallback(function ($arg) {
  279. if ($arg === 'schemes') {
  280. return 'turn,turns';
  281. } elseif ($arg === 'server') {
  282. return 'turn2.test.com';
  283. } elseif ($arg === 'protocols') {
  284. return 'udp,tcp';
  285. }
  286. throw new \Exception();
  287. });
  288. $this->input->method('getOption')
  289. ->willReturnCallback(function ($arg) {
  290. if ($arg === 'secret') {
  291. return 'my-test-secret-2';
  292. } elseif ($arg === 'generate-secret') {
  293. return false;
  294. }
  295. throw new \Exception();
  296. });
  297. $this->config->method('getAppValue')
  298. ->with('spreed', 'turn_servers')
  299. ->willReturn(json_encode([
  300. [
  301. 'server' => 'turn1.test.com',
  302. 'secret' => 'my-test-secret-1',
  303. 'protocols' => 'udp,tcp'
  304. ]
  305. ]));
  306. $this->config->expects($this->once())
  307. ->method('setAppValue')
  308. ->with(
  309. $this->equalTo('spreed'),
  310. $this->equalTo('turn_servers'),
  311. $this->equalTo(json_encode([
  312. [
  313. 'server' => 'turn1.test.com',
  314. 'secret' => 'my-test-secret-1',
  315. 'protocols' => 'udp,tcp'
  316. ],
  317. [
  318. 'schemes' => 'turn,turns',
  319. 'server' => 'turn2.test.com',
  320. 'secret' => 'my-test-secret-2',
  321. 'protocols' => 'udp,tcp'
  322. ]
  323. ]))
  324. );
  325. $this->output->expects($this->once())
  326. ->method('writeln')
  327. ->with($this->equalTo('<info>Added turn2.test.com.</info>'));
  328. self::invokePrivate($this->command, 'execute', [$this->input, $this->output]);
  329. }
  330. public function testServerSanitization(): void {
  331. $this->input->method('getArgument')
  332. ->willReturnCallback(function ($arg) {
  333. if ($arg === 'schemes') {
  334. return 'turn,turns';
  335. } elseif ($arg === 'server') {
  336. return 'https://turn.test.com';
  337. } elseif ($arg === 'protocols') {
  338. return 'udp,tcp';
  339. }
  340. throw new \Exception();
  341. });
  342. $this->input->method('getOption')
  343. ->willReturnCallback(function ($arg) {
  344. if ($arg === 'secret') {
  345. return 'my-test-secret';
  346. } elseif ($arg === 'generate-secret') {
  347. return false;
  348. }
  349. throw new \Exception();
  350. });
  351. $this->config->method('getAppValue')
  352. ->with('spreed', 'turn_servers')
  353. ->willReturn(json_encode([]));
  354. $this->config->expects($this->once())
  355. ->method('setAppValue')
  356. ->with(
  357. $this->equalTo('spreed'),
  358. $this->equalTo('turn_servers'),
  359. $this->equalTo(json_encode([
  360. [
  361. 'schemes' => 'turn,turns',
  362. 'server' => 'turn.test.com',
  363. 'secret' => 'my-test-secret',
  364. 'protocols' => 'udp,tcp'
  365. ]
  366. ]))
  367. );
  368. self::invokePrivate($this->command, 'execute', [$this->input, $this->output]);
  369. }
  370. }