1<?php
2
3declare(strict_types=1);
4
5namespace ZnoteX\Tests\Security;
6
7use PHPUnit\Framework\TestCase;
8
9require_once dirname(__DIR__, 2) . '/engine/adapter/ServerAdapterInterface.php';
10require_once dirname(__DIR__, 2) . '/engine/adapter/TFSAdapter.php';
11require_once dirname(__DIR__, 2) . '/engine/adapter/CanaryAdapter.php';
12require_once dirname(__DIR__, 2) . '/engine/adapter/OtHireAdapter.php';
13require_once dirname(__DIR__, 2) . '/engine/adapter/BlackTekAdapter.php';
14require_once dirname(__DIR__, 2) . '/engine/adapter/factory.php';
15
16final class ServerAdapterTest extends TestCase
17{
18 protected function setUp(): void
19 {
20 $GLOBALS['config'] = [
21 'ServerEngine' => 'TFS_10',
22 'ServerEngineReal' => 'TFS_10',
23 ];
24 }
25
26 /** @dataProvider engineProvider */
27 public function testFactoryPicksTheRightAdapterClass(string $engine, string $expectedClass): void
28 {
29 $adapter = \znote_server_adapter($engine);
30 $this->assertInstanceOf($expectedClass, $adapter);
31 $this->assertSame($engine, $adapter->key());
32 }
33
34 public static function engineProvider(): array
35 {
36 return [
37 'TFS_02' => ['TFS_02', \TFSAdapter::class],
38 'TFS_03' => ['TFS_03', \TFSAdapter::class],
39 'TFS_10' => ['TFS_10', \TFSAdapter::class],
40 'TFS_16' => ['TFS_16', \TFSAdapter::class],
41 'OTHIRE' => ['OTHIRE', \OtHireAdapter::class],
42 'CANARY' => ['CANARY', \CanaryAdapter::class],
43 'BLACKTEK' => ['BLACKTEK', \BlackTekAdapter::class],
44 ];
45 }
46
47 public function testFactoryFallsBackToGlobalConfigWhenNoEngineIsGiven(): void
48 {
49 $GLOBALS['config']['ServerEngineReal'] = 'OTHIRE';
50 $adapter = \znote_server_adapter();
51 $this->assertInstanceOf(\OtHireAdapter::class, $adapter);
52 }
53
54 public function testFactoryCachesOneInstancePerEngine(): void
55 {
56 $first = \znote_server_adapter('TFS_10');
57 $second = \znote_server_adapter('TFS_10');
58 $this->assertSame($first, $second);
59 }
60
61 public function testLegacyTwoFactorSupportMatchesWhichEnginesHaveAccountsSecret(): void
62 {
63 // TFS_10, TFS_16 (normalised to TFS_10) and BlackTek all ship an
64 // accounts.secret column; TFS_02, TFS_03, Canary and otHire do not.
65 $this->assertTrue((new \TFSAdapter('TFS_10'))->supportsLegacyTwoFactor());
66 $this->assertFalse((new \TFSAdapter('TFS_02'))->supportsLegacyTwoFactor());
67 $this->assertFalse((new \TFSAdapter('TFS_03'))->supportsLegacyTwoFactor());
68 $this->assertFalse((new \TFSAdapter('TFS_16'))->supportsLegacyTwoFactor());
69 $this->assertFalse((new \CanaryAdapter())->supportsLegacyTwoFactor());
70 $this->assertFalse((new \OtHireAdapter())->supportsLegacyTwoFactor());
71 $this->assertTrue((new \BlackTekAdapter())->supportsLegacyTwoFactor());
72 }
73
74 public function testOthireIdentifiesAccountsByIdNotName(): void
75 {
76 $adapter = new \OtHireAdapter();
77 $this->assertSame('id', $adapter->accountIdentityColumn());
78 $this->assertSame('`a`.`id`', $adapter->accountDisplayColumn());
79 }
80
81 /** @dataProvider normalizedEngineProvider */
82 public function testNormalizedEngineMatchesTheSchemaAnAdapterActuallyRuns(string $realEngine, string $expected): void
83 {
84 $this->assertSame($expected, \znote_server_adapter($realEngine)->normalizedEngine());
85 }
86
87 public static function normalizedEngineProvider(): array
88 {
89 return [
90 'TFS_02 stays TFS_02' => ['TFS_02', 'TFS_02'],
91 'TFS_03 stays TFS_03' => ['TFS_03', 'TFS_03'],
92 'TFS_10 stays TFS_10' => ['TFS_10', 'TFS_10'],
93 'TFS_16 normalises to TFS_10' => ['TFS_16', 'TFS_10'],
94 'Canary normalises to TFS_10' => ['CANARY', 'TFS_10'],
95 'BlackTek normalises to TFS_10' => ['BLACKTEK', 'TFS_10'],
96 'otHire stays OTHIRE' => ['OTHIRE', 'OTHIRE'],
97 ];
98 }
99
100 public function testEveryOtherAdapterIdentifiesAccountsByName(): void
101 {
102 foreach ([new \TFSAdapter('TFS_10'), new \CanaryAdapter(), new \BlackTekAdapter()] as $adapter) {
103 $this->assertSame('name', $adapter->accountIdentityColumn());
104 $this->assertSame('`a`.`name`', $adapter->accountDisplayColumn());
105 }
106 }
107}
108