1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace Hn \McpServer \Tests \Functional ;
6+
7+ use Hn \McpServer \Service \LanguageService ;
8+ use TYPO3 \CMS \Core \Authentication \BackendUserAuthentication ;
9+ use TYPO3 \CMS \Core \Context \Context ;
10+ use TYPO3 \CMS \Core \Database \ConnectionPool ;
11+ use TYPO3 \CMS \Core \Localization \LanguageServiceFactory ;
12+ use TYPO3 \CMS \Core \Utility \GeneralUtility ;
13+ use TYPO3 \TestingFramework \Core \Functional \FunctionalTestCase ;
14+
15+ /**
16+ * Abstract base test class for functional tests
17+ *
18+ * Provides common setup and utility methods to reduce code duplication
19+ * across test classes.
20+ */
21+ abstract class AbstractFunctionalTest extends FunctionalTestCase
22+ {
23+ protected Context $ context ;
24+ protected ConnectionPool $ connectionPool ;
25+ protected LanguageService $ languageService ;
26+
27+ /**
28+ * Core extensions that most tests need
29+ */
30+ protected array $ coreExtensionsToLoad = [
31+ 'workspaces ' ,
32+ 'frontend ' ,
33+ ];
34+
35+ /**
36+ * Test extensions that most tests need
37+ */
38+ protected array $ testExtensionsToLoad = [
39+ 'mcp_server ' ,
40+ ];
41+
42+ protected function setUp (): void
43+ {
44+ parent ::setUp ();
45+
46+ $ this ->initializeServices ();
47+ $ this ->setupDefaultLanguage ();
48+ $ this ->loadStandardFixtures ();
49+ $ this ->setupDefaultBackendUser ();
50+ }
51+
52+ /**
53+ * Initialize commonly used services
54+ */
55+ protected function initializeServices (): void
56+ {
57+ $ this ->context = GeneralUtility::makeInstance (Context::class);
58+ $ this ->connectionPool = GeneralUtility::makeInstance (ConnectionPool::class);
59+ $ this ->languageService = GeneralUtility::makeInstance (LanguageService::class);
60+ }
61+
62+ /**
63+ * Set up default backend user
64+ *
65+ * @param int $uid Backend user UID
66+ * @return BackendUserAuthentication
67+ */
68+ protected function setupDefaultBackendUser (int $ uid = 1 ): BackendUserAuthentication
69+ {
70+ $ backendUser = $ this ->setUpBackendUser ($ uid );
71+ $ GLOBALS ['BE_USER ' ] = $ backendUser ;
72+ return $ backendUser ;
73+ }
74+
75+ /**
76+ * Set up default language service
77+ *
78+ * @param string $languageKey Language key (default: 'default')
79+ */
80+ protected function setupDefaultLanguage (string $ languageKey = 'default ' ): void
81+ {
82+ $ GLOBALS ['LANG ' ] = GeneralUtility::makeInstance (LanguageServiceFactory::class)->create ($ languageKey );
83+ }
84+
85+ /**
86+ * Load standard test fixtures
87+ *
88+ * Override this method in child classes to customize fixture loading
89+ */
90+ protected function loadStandardFixtures (): void
91+ {
92+ // Load common fixtures used by most tests
93+ $ fixturesPath = __DIR__ . '/Fixtures/ ' ;
94+
95+ if (file_exists ($ fixturesPath . 'be_users.csv ' )) {
96+ $ this ->importCSVDataSet ($ fixturesPath . 'be_users.csv ' );
97+ }
98+
99+ if (file_exists ($ fixturesPath . 'pages.csv ' )) {
100+ $ this ->importCSVDataSet ($ fixturesPath . 'pages.csv ' );
101+ }
102+
103+ if (file_exists ($ fixturesPath . 'tt_content.csv ' )) {
104+ $ this ->importCSVDataSet ($ fixturesPath . 'tt_content.csv ' );
105+ }
106+ }
107+
108+ /**
109+ * Get the root page UID from fixtures
110+ *
111+ * @return int
112+ */
113+ protected function getRootPageUid (): int
114+ {
115+ return 1 ; // Standard fixture root page
116+ }
117+
118+ /**
119+ * Create a workspace and switch to it
120+ *
121+ * @param string $title Workspace title
122+ * @return int Workspace ID
123+ */
124+ protected function createAndSwitchToWorkspace (string $ title = 'Test Workspace ' ): int
125+ {
126+ $ connection = $ this ->connectionPool ->getConnectionForTable ('sys_workspace ' );
127+ $ connection ->insert ('sys_workspace ' , [
128+ 'title ' => $ title ,
129+ 'description ' => 'Workspace for testing ' ,
130+ 'adminusers ' => '1 ' ,
131+ 'members ' => '1 ' ,
132+ 'db_mountpoints ' => '0 ' ,
133+ 'file_mountpoints ' => '' ,
134+ 'publish_time ' => 0 ,
135+ 'unpublish_time ' => 0 ,
136+ 'freeze ' => 0 ,
137+ 'live_edit ' => 0 ,
138+ 'swap_modes ' => 0 ,
139+ 'publish_access ' => 0 ,
140+ 'stagechg_notification ' => 0 ,
141+ 'custom_stages ' => 0 ,
142+ 'uid ' => 0 ,
143+ 'pid ' => 0 ,
144+ ]);
145+
146+ $ workspaceId = (int )$ connection ->lastInsertId ();
147+ $ this ->switchToWorkspace ($ workspaceId );
148+
149+ return $ workspaceId ;
150+ }
151+
152+ /**
153+ * Switch to a specific workspace
154+ *
155+ * @param int $workspaceId
156+ */
157+ protected function switchToWorkspace (int $ workspaceId ): void
158+ {
159+ $ GLOBALS ['BE_USER ' ]->workspace = $ workspaceId ;
160+ $ this ->context ->setAspect ('workspace ' , new \TYPO3 \CMS \Core \Context \WorkspaceAspect ($ workspaceId ));
161+ }
162+
163+ /**
164+ * Get a database connection for a table
165+ *
166+ * @param string $table
167+ * @return \TYPO3\CMS\Core\Database\Connection
168+ */
169+ protected function getConnectionForTable (string $ table ): \TYPO3 \CMS \Core \Database \Connection
170+ {
171+ return $ this ->connectionPool ->getConnectionForTable ($ table );
172+ }
173+ }
0 commit comments