Skip to content

Commit 47a5c28

Browse files
committed
refactor: enhance functional testing and streamline workspace initialization
- Adjust workspace creation logic in `WorkspaceContextService` to only include necessary fields. - Enable previously disabled plugin hint tests in `GetPageTreeToolPluginHintsTest`. - Extend depth limitation tests in `GetPageTreeToolTest` with comprehensive page structure and validation logic. - Introduce helper methods for test data creation and tree structure verification. - Refactor test cases in `ReadTableToolTest`, `SearchToolTest`, and `WriteTableToolTest` for improved readability and assertion handling.
1 parent 91f1f1a commit 47a5c28

24 files changed

+6005
-149
lines changed

Classes/Service/WorkspaceContextService.php

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -169,28 +169,20 @@ protected function createMcpWorkspace(BackendUserAuthentication $beUser): int
169169
$workspaceDescription = 'Automatically created workspace for Model Context Protocol operations';
170170

171171
// Create workspace record data
172+
// Only use fields that are guaranteed to exist in TYPO3 core
172173
$workspaceData = [
173174
'pid' => 0, // Workspaces are created at root level
174175
'title' => $workspaceTitle,
175176
'description' => $workspaceDescription,
176177
'adminusers' => $beUser->user['uid'] ?? 0,
177178
'members' => '',
178-
'reviewers' => '',
179-
'publish_access' => 1, // Allow publishing
180-
'stagechg_notification' => 0, // No email notifications by default
181-
'edit_notification_defaults' => '',
182-
'edit_allow_notificaton_settings' => 0,
183-
'publish_notification_defaults' => '',
184-
'publish_allow_notificaton_settings' => 0,
185179
'db_mountpoints' => '', // Inherit from user
186180
'file_mountpoints' => '', // Inherit from user
181+
'publish_access' => 1, // Allow publishing
182+
'stagechg_notification' => 0, // No email notifications by default
187183
'freeze' => 0, // Not frozen
188184
'live_edit' => 0, // No live edit
189-
'vtypes' => 0, // Version types
190-
'disable_autocreate' => 0, // Allow auto-creation of versions
191-
'swap_modes' => 1, // Allow swapping
192185
'publish_time' => 0, // No scheduled publishing
193-
'unpublish_time' => 0, // No scheduled unpublishing
194186
];
195187

196188
// Use DataHandler to create the workspace
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
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

Comments
 (0)