diff --git a/lib/Controller/IonosAccountsController.php b/lib/Controller/IonosAccountsController.php
index de8e448704..9a1a5b700d 100644
--- a/lib/Controller/IonosAccountsController.php
+++ b/lib/Controller/IonosAccountsController.php
@@ -38,13 +38,10 @@ public function __construct(
}
// Helper: input validation
- private function validateInput(string $accountName, string $emailAddress): ?JSONResponse {
- if ($accountName === '' || $emailAddress === '') {
+ private function validateInput(string $accountName, string $emailUser): ?JSONResponse {
+ if ($accountName === '' || $emailUser === '') {
return new JSONResponse(['success' => false, 'message' => self::ERR_ALL_FIELDS_REQUIRED, 'error' => self::ERR_IONOS_API_ERROR], 400);
}
- if (!filter_var($emailAddress, FILTER_VALIDATE_EMAIL)) {
- return new JSONResponse(['success' => false, 'message' => 'Invalid email address format', 'error' => self::ERR_IONOS_API_ERROR], 400);
- }
return null;
}
@@ -52,20 +49,19 @@ private function validateInput(string $accountName, string $emailAddress): ?JSON
* @NoAdminRequired
*/
#[TrapError]
- public function create(string $accountName, string $emailAddress): JSONResponse {
- if ($error = $this->validateInput($accountName, $emailAddress)) {
+ public function create(string $accountName, string $emailUser): JSONResponse {
+ if ($error = $this->validateInput($accountName, $emailUser)) {
return $error;
}
try {
- $this->logger->info('Starting IONOS email account creation', [ 'emailAddress' => $emailAddress, 'accountName' => $accountName ]);
- $ionosResponse = $this->ionosMailService->createEmailAccount($emailAddress);
+ $this->logger->info('Starting IONOS email account creation', [ 'emailAddress' => $emailUser, 'accountName' => $accountName ]);
+ $ionosResponse = $this->ionosMailService->createEmailAccount($emailUser);
- $this->logger->info('IONOS email account created successfully', [ 'emailAddress' => $emailAddress ]);
- return $this->createNextcloudMailAccount($accountName, $emailAddress, $ionosResponse);
+ $this->logger->info('IONOS email account created successfully', [ 'emailAddress' => $ionosResponse->getEmail() ]);
+ return $this->createNextcloudMailAccount($accountName, $ionosResponse);
} catch (ServiceException $e) {
$data = [
- 'emailAddress' => $emailAddress,
'error' => self::ERR_IONOS_API_ERROR,
'statusCode' => $e->getCode(),
];
@@ -77,13 +73,13 @@ public function create(string $accountName, string $emailAddress): JSONResponse
}
}
- private function createNextcloudMailAccount(string $accountName, string $emailAddress, MailAccountConfig $mailConfig): JSONResponse {
+ private function createNextcloudMailAccount(string $accountName, MailAccountConfig $mailConfig): JSONResponse {
$imap = $mailConfig->getImap();
$smtp = $mailConfig->getSmtp();
return $this->accountsController->create(
$accountName,
- $emailAddress,
+ $mailConfig->getEmail(),
$imap->getHost(),
$imap->getPort(),
$imap->getSecurity(),
diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php
index df82aafb34..2ea0f62352 100644
--- a/lib/Controller/PageController.php
+++ b/lib/Controller/PageController.php
@@ -21,6 +21,7 @@
use OCA\Mail\Service\AliasesService;
use OCA\Mail\Service\Classification\ClassificationSettingsService;
use OCA\Mail\Service\InternalAddressService;
+use OCA\Mail\Service\IONOS\IonosConfigService;
use OCA\Mail\Service\OutboxService;
use OCA\Mail\Service\QuickActionsService;
use OCA\Mail\Service\SmimeService;
@@ -74,7 +75,8 @@ class PageController extends Controller {
private InternalAddressService $internalAddressService;
private QuickActionsService $quickActionsService;
- public function __construct(string $appName,
+ public function __construct(
+ string $appName,
IRequest $request,
IURLGenerator $urlGenerator,
IConfig $config,
@@ -97,6 +99,7 @@ public function __construct(string $appName,
InternalAddressService $internalAddressService,
IAvailabilityCoordinator $availabilityCoordinator,
QuickActionsService $quickActionsService,
+ private IonosConfigService $ionosConfigService,
) {
parent::__construct($appName, $request);
@@ -208,9 +211,12 @@ public function index(): TemplateResponse {
$user = $this->userSession->getUser();
$response = new TemplateResponse($this->appName, 'index');
+
+
$this->initialStateService->provideInitialState('preferences', [
'attachment-size-limit' => $this->config->getSystemValue('app.mail.attachment-size-limit', 0),
'ionos-mailconfig-enabled' => $this->config->getAppValue('mail', 'ionos-mailconfig-enabled', 'no') === 'yes',
+ 'ionos-mailconfig-domain' => $this->ionosConfigService->getMailDomain(),
'app-version' => $this->config->getAppValue('mail', 'installed_version'),
'external-avatars' => $this->preferences->getPreference($this->currentUserId, 'external-avatars', 'true'),
'layout-mode' => $this->preferences->getPreference($this->currentUserId, 'layout-mode', 'vertical-split'),
diff --git a/lib/Service/IONOS/IonosConfigService.php b/lib/Service/IONOS/IonosConfigService.php
index a429972324..6606c510bb 100644
--- a/lib/Service/IONOS/IonosConfigService.php
+++ b/lib/Service/IONOS/IonosConfigService.php
@@ -13,7 +13,10 @@
use OCP\Exceptions\AppConfigException;
use OCP\IAppConfig;
use OCP\IConfig;
+use Pdp\Domain;
+use Pdp\Rules;
use Psr\Log\LoggerInterface;
+use Throwable;
/**
* Service for managing IONOS API configuration
@@ -125,4 +128,49 @@ public function getApiConfig(): array {
'basicAuthPass' => $this->getBasicAuthPassword(),
];
}
+
+ /**
+ * Get the mail domain from customer domain
+ *
+ * Extracts the registrable domain (mail domain) from the customer domain
+ * configured in system settings.
+ */
+ public function getMailDomain(): string {
+ $customerDomain = $this->config->getSystemValue('ncw.customerDomain', '');
+ return $this->extractMailDomain($customerDomain);
+ }
+
+ /**
+ * Extract the registrable domain (mail domain) from a customer domain.
+ *
+ * Uses the Public Suffix List via Pdp library to properly extract the
+ * registrable domain, handling multi-level TLDs like .co.uk correctly.
+ *
+ * Examples:
+ * - foo.bar.lol -> bar.lol
+ * - mail.test.co.uk -> test.co.uk
+ * - sub.domain.example.com -> example.com
+ *
+ * @param string $customerDomain The full customer domain
+ * @return string The extracted mail domain, or empty string if input is empty
+ */
+ private function extractMailDomain(string $customerDomain): string {
+ if (empty($customerDomain)) {
+ return '';
+ }
+
+ try {
+ $publicSuffixList = Rules::fromPath(__DIR__ . '/../../../resources/public_suffix_list.dat');
+ $domain = Domain::fromIDNA2008($customerDomain);
+ $result = $publicSuffixList->resolve($domain);
+ return $result->registrableDomain()->toString();
+ } catch (Throwable $e) {
+ // Fallback to simple extraction if Pdp fails
+ $parts = explode('.', $customerDomain);
+ if (count($parts) >= 2) {
+ return $parts[count($parts) - 2] . '.' . $parts[count($parts) - 1];
+ }
+ return $customerDomain;
+ }
+ }
}
diff --git a/lib/Service/IONOS/IonosMailService.php b/lib/Service/IONOS/IonosMailService.php
index e7218de40b..4e9e802a79 100644
--- a/lib/Service/IONOS/IonosMailService.php
+++ b/lib/Service/IONOS/IonosMailService.php
@@ -41,24 +41,23 @@ public function __construct(
* @throws ServiceException
* @throws AppConfigException
*/
- public function createEmailAccount(string $emailAddress): MailAccountConfig {
- $config = $this->configService->getApiConfig();
+ public function createEmailAccount(string $userName): MailAccountConfig {
$userId = $this->getCurrentUserId();
- $userName = $this->extractUsername($emailAddress);
- $domain = $this->extractDomain($emailAddress);
+ $domain = $this->configService->getMailDomain();
$this->logger->debug('Sending request to mailconfig service', [
- 'extRef' => $config['extRef'],
- 'emailAddress' => $emailAddress,
- 'apiBaseUrl' => $config['apiBaseUrl']
+ 'extRef' => $this->configService->getExternalReference(),
+ 'userName' => $userName,
+ 'domain' => $domain,
+ 'apiBaseUrl' => $this->configService->getApiBaseUrl()
]);
$client = $this->apiClientService->newClient([
- 'auth' => [$config['basicAuthUser'], $config['basicAuthPass']],
- 'verify' => !$config['allowInsecure'],
+ 'auth' => [$this->configService->getBasicAuthUser(), $this->configService->getBasicAuthPassword()],
+ 'verify' => !$this->configService->getAllowInsecure(),
]);
- $apiInstance = $this->apiClientService->newEventAPIApi($client, $config['apiBaseUrl']);
+ $apiInstance = $this->apiClientService->newEventAPIApi($client, $this->configService->getApiBaseUrl());
$mailCreateData = new MailCreateData();
$mailCreateData->setNextcloudUserId($userId);
@@ -72,14 +71,14 @@ public function createEmailAccount(string $emailAddress): MailAccountConfig {
try {
$this->logger->debug('Send message to mailconfig service', ['data' => $mailCreateData]);
- $result = $apiInstance->createMailbox(self::BRAND, $config['extRef'], $mailCreateData);
+ $result = $apiInstance->createMailbox(self::BRAND, $this->configService->getExternalReference(), $mailCreateData);
if ($result instanceof ErrorMessage) {
$this->logger->error('Failed to create ionos mail', ['status code' => $result->getStatus(), 'message' => $result->getMessage()]);
throw new ServiceException('Failed to create ionos mail', $result->getStatus());
}
if ($result instanceof MailAccountResponse) {
- return $this->buildSuccessResponse($emailAddress, $result);
+ return $this->buildSuccessResponse($result);
}
$this->logger->debug('Failed to create ionos mail: Unknown response type', ['data' => $result ]);
@@ -98,40 +97,6 @@ public function createEmailAccount(string $emailAddress): MailAccountConfig {
}
}
- /**
- * Extract domain from email address
- *
- * @throws ServiceException
- */
- public function extractDomain(string $emailAddress): string {
- $atPosition = strrchr($emailAddress, '@');
- if ($atPosition === false) {
- throw new ServiceException('Invalid email address: unable to extract domain');
- }
- $domain = substr($atPosition, 1);
- if ($domain === '') {
- throw new ServiceException('Invalid email address: unable to extract domain');
- }
- return $domain;
- }
-
- /**
- * Extract username from email address
- *
- * @throws ServiceException
- */
- public function extractUsername(string $emailAddress): string {
- $atPosition = strrpos($emailAddress, '@');
- if ($atPosition === false) {
- throw new ServiceException('Invalid email address: unable to extract username');
- }
- $userName = substr($emailAddress, 0, $atPosition);
- if ($userName === '') {
- throw new ServiceException('Invalid email address: unable to extract username');
- }
- return $userName;
- }
-
/**
* Get the current user ID
*
@@ -170,11 +135,10 @@ private function normalizeSslMode(string $apiSslMode): string {
/**
* Build success response with mail configuration
*
- * @param string $emailAddress
* @param MailAccountResponse $response
* @return MailAccountConfig
*/
- private function buildSuccessResponse(string $emailAddress, MailAccountResponse $response): MailAccountConfig {
+ private function buildSuccessResponse(MailAccountResponse $response): MailAccountConfig {
$smtpServer = $response->getServer()->getSmtp();
$imapServer = $response->getServer()->getImap();
@@ -195,7 +159,7 @@ private function buildSuccessResponse(string $emailAddress, MailAccountResponse
);
return new MailAccountConfig(
- email: $emailAddress,
+ email: $response->getEmail(),
imap: $imapConfig,
smtp: $smtpConfig,
);
diff --git a/src/components/ionos/NewEmailAddressTab.vue b/src/components/ionos/NewEmailAddressTab.vue
index d0b99e8a85..cb4c290f49 100644
--- a/src/components/ionos/NewEmailAddressTab.vue
+++ b/src/components/ionos/NewEmailAddressTab.vue
@@ -13,17 +13,17 @@
@change="clearAllFeedback"
autofocus />
-
- {{ t('mail', 'Please enter an email of the format name@example.com') }}
+
+ {{ t('mail', 'Please enter a valid email user name') }}
- @myworkspace.com
+ @{{ emailDomain }}
{},
},
},
data() {
return {
accountName: '',
- emailAddress: '',
+ emailUser: '',
localLoading: false,
feedback: null,
}
},
computed: {
...mapStores(useMainStore),
+ fullEmailAddress() {
+ return this.emailUser ? `${this.emailUser}@${this.emailDomain}` : ''
+ },
+
isFormValid() {
return this.accountName
- && this.isValidEmail(this.emailAddress)
+ && this.emailUser
+ && this.isValidEmail(this.fullEmailAddress)
},
buttonText() {
@@ -95,6 +100,10 @@ export default {
? t('mail', 'Creating account...')
: t('mail', 'Create & Connect')
},
+
+ emailDomain() {
+ return this.mainStore.getPreference('ionos-mailconfig-domain', 'myworkspace.com')
+ },
},
methods: {
async submitForm() {
@@ -104,7 +113,7 @@ export default {
try {
const account = await this.callIonosAPI({
accountName: this.accountName,
- emailAddress: this.emailAddress,
+ emailUser: this.emailUser,
})
logger.debug(`account ${account.id} created`, { account })
@@ -147,11 +156,11 @@ export default {
}
},
- async callIonosAPI({ accountName, emailAddress }) {
+ async callIonosAPI({ accountName, emailUser }) {
const url = generateUrl('/apps/mail/api/ionos/accounts')
return axios
- .post(url, { accountName, emailAddress })
+ .post(url, { accountName, emailUser })
.then((resp) => resp.data.data)
.then(fixAccountId)
.catch((e) => {
diff --git a/src/init.js b/src/init.js
index d055872bc9..bc9529ad6a 100644
--- a/src/init.js
+++ b/src/init.js
@@ -41,6 +41,10 @@ export default function initAfterAppCreation() {
key: 'ionos-mailconfig-enabled',
value: preferences['ionos-mailconfig-enabled'],
})
+ mainStore.savePreferenceMutation({
+ key: 'ionos-mailconfig-domain',
+ value: preferences['ionos-mailconfig-domain'],
+ })
mainStore.savePreferenceMutation({
key: 'external-avatars',
value: preferences['external-avatars'],
diff --git a/tests/Unit/Controller/IonosAccountsControllerTest.php b/tests/Unit/Controller/IonosAccountsControllerTest.php
index 1e8c6f61d2..ad43b0085d 100644
--- a/tests/Unit/Controller/IonosAccountsControllerTest.php
+++ b/tests/Unit/Controller/IonosAccountsControllerTest.php
@@ -55,14 +55,14 @@ protected function setUp(): void {
public function testCreateWithMissingFields(): void {
// Test with empty account name
- $response = $this->controller->create('', 'test@example.com');
+ $response = $this->controller->create('', 'testuser');
$this->assertEquals(400, $response->getStatus());
$data = $response->getData();
$this->assertFalse($data['success']);
$this->assertEquals('All fields are required', $data['message']);
$this->assertEquals('IONOS_API_ERROR', $data['error']);
- // Test with empty email address
+ // Test with empty email user
$response = $this->controller->create('Test Account', '');
$this->assertEquals(400, $response->getStatus());
$data = $response->getData();
@@ -71,17 +71,9 @@ public function testCreateWithMissingFields(): void {
$this->assertEquals('IONOS_API_ERROR', $data['error']);
}
- public function testCreateWithInvalidEmailFormat(): void {
- $response = $this->controller->create('Test Account', 'invalid-email');
- $this->assertEquals(400, $response->getStatus());
- $data = $response->getData();
- $this->assertFalse($data['success']);
- $this->assertEquals('Invalid email address format', $data['message']);
- $this->assertEquals('IONOS_API_ERROR', $data['error']);
- }
-
public function testCreateSuccess(): void {
$accountName = 'Test Account';
+ $emailUser = 'test';
$emailAddress = 'test@example.com';
// Create MailAccountConfig DTO
@@ -109,7 +101,7 @@ public function testCreateSuccess(): void {
// Mock successful IONOS mail service response
$this->ionosMailService->method('createEmailAccount')
- ->with($emailAddress)
+ ->with($emailUser)
->willReturn($mailAccountConfig);
// Mock account creation response
@@ -135,7 +127,7 @@ public function testCreateSuccess(): void {
)
->willReturn($accountResponse);
- $response = $this->controller->create($accountName, $emailAddress);
+ $response = $this->controller->create($accountName, $emailUser);
// The controller now directly returns the AccountsController response
$this->assertSame($accountResponse, $response);
@@ -143,11 +135,11 @@ public function testCreateSuccess(): void {
public function testCreateWithServiceException(): void {
$accountName = 'Test Account';
- $emailAddress = 'test@example.com';
+ $emailUser = 'test';
// Mock IONOS mail service to throw ServiceException
$this->ionosMailService->method('createEmailAccount')
- ->with($emailAddress)
+ ->with($emailUser)
->willThrowException(new ServiceException('Failed to create email account'));
$this->logger
@@ -156,29 +148,27 @@ public function testCreateWithServiceException(): void {
->with(
'IONOS service error: Failed to create email account',
[
- 'emailAddress' => $emailAddress,
'error' => 'IONOS_API_ERROR',
'statusCode' => 0,
]
);
$expectedResponse = \OCA\Mail\Http\JsonResponse::fail([
- 'emailAddress' => 'test@example.com',
'error' => 'IONOS_API_ERROR',
'statusCode' => 0,
]);
- $response = $this->controller->create($accountName, $emailAddress);
+ $response = $this->controller->create($accountName, $emailUser);
self::assertEquals($expectedResponse, $response);
}
public function testCreateWithServiceExceptionWithStatusCode(): void {
$accountName = 'Test Account';
- $emailAddress = 'test@example.com';
+ $emailUser = 'test';
// Mock IONOS mail service to throw ServiceException with HTTP 409 (Duplicate)
$this->ionosMailService->method('createEmailAccount')
- ->with($emailAddress)
+ ->with($emailUser)
->willThrowException(new ServiceException('Duplicate email account', 409));
$this->logger
@@ -187,29 +177,27 @@ public function testCreateWithServiceExceptionWithStatusCode(): void {
->with(
'IONOS service error: Duplicate email account',
[
- 'emailAddress' => $emailAddress,
'error' => 'IONOS_API_ERROR',
'statusCode' => 409,
]
);
$expectedResponse = \OCA\Mail\Http\JsonResponse::fail([
- 'emailAddress' => 'test@example.com',
'error' => 'IONOS_API_ERROR',
'statusCode' => 409,
]);
- $response = $this->controller->create($accountName, $emailAddress);
+ $response = $this->controller->create($accountName, $emailUser);
self::assertEquals($expectedResponse, $response);
}
public function testCreateWithGenericException(): void {
$accountName = 'Test Account';
- $emailAddress = 'test@example.com';
+ $emailUser = 'test';
// Mock IONOS mail service to throw a generic exception
$this->ionosMailService->method('createEmailAccount')
- ->with($emailAddress)
+ ->with($emailUser)
->willThrowException(new \Exception('Generic error'));
$expectedResponse = \OCA\Mail\Http\JsonResponse::error('Could not create account',
@@ -217,7 +205,7 @@ public function testCreateWithGenericException(): void {
[],
0
);
- $response = $this->controller->create($accountName, $emailAddress);
+ $response = $this->controller->create($accountName, $emailUser);
self::assertEquals($expectedResponse, $response);
}
@@ -274,7 +262,7 @@ public function testCreateNextcloudMailAccount(): void {
$method = $reflection->getMethod('createNextcloudMailAccount');
$method->setAccessible(true);
- $result = $method->invoke($this->controller, $accountName, $emailAddress, $mailConfig);
+ $result = $method->invoke($this->controller, $accountName, $mailConfig);
$this->assertSame($expectedResponse, $result);
}
diff --git a/tests/Unit/Controller/PageControllerTest.php b/tests/Unit/Controller/PageControllerTest.php
index fd7bc37923..21f75432ee 100644
--- a/tests/Unit/Controller/PageControllerTest.php
+++ b/tests/Unit/Controller/PageControllerTest.php
@@ -21,6 +21,7 @@
use OCA\Mail\Service\AliasesService;
use OCA\Mail\Service\Classification\ClassificationSettingsService;
use OCA\Mail\Service\InternalAddressService;
+use OCA\Mail\Service\IONOS\IonosConfigService;
use OCA\Mail\Service\MailManager;
use OCA\Mail\Service\OutboxService;
use OCA\Mail\Service\QuickActionsService;
@@ -113,6 +114,8 @@ class PageControllerTest extends TestCase {
private IAvailabilityCoordinator&MockObject $availabilityCoordinator;
+ private IonosConfigService&MockObject $ionosConfigService;
+
protected function setUp(): void {
parent::setUp();
@@ -139,6 +142,7 @@ protected function setUp(): void {
$this->internalAddressService = $this->createMock(InternalAddressService::class);
$this->availabilityCoordinator = $this->createMock(IAvailabilityCoordinator::class);
$this->quickActionsService = $this->createMock(QuickActionsService::class);
+ $this->ionosConfigService = $this->createMock(IonosConfigService::class);
$this->controller = new PageController(
$this->appName,
@@ -164,6 +168,7 @@ protected function setUp(): void {
$this->internalAddressService,
$this->availabilityCoordinator,
$this->quickActionsService,
+ $this->ionosConfigService,
);
}
@@ -282,8 +287,10 @@ public function testIndex(): void {
$this->returnValue(''),
$this->returnValue('cron'),
$this->returnValue('yes'),
- $this->returnValue('no')
);
+ $this->ionosConfigService->expects($this->once())
+ ->method('getMailDomain')
+ ->willReturn('example.tld');
$this->aiIntegrationsService->expects(self::exactly(4))
->method('isLlmProcessingEnabled')
->willReturn(false);
@@ -335,6 +342,7 @@ public function testIndex(): void {
'reply-mode' => 'bottom',
'app-version' => '1.2.3',
'ionos-mailconfig-enabled' => false,
+ 'ionos-mailconfig-domain' => 'example.tld',
'collect-data' => 'true',
'start-mailbox-id' => '123',
'tag-classified-messages' => 'false',
diff --git a/tests/Unit/Service/IONOS/IonosConfigServiceTest.php b/tests/Unit/Service/IONOS/IonosConfigServiceTest.php
index cf27ab3911..b4391f3e53 100644
--- a/tests/Unit/Service/IONOS/IonosConfigServiceTest.php
+++ b/tests/Unit/Service/IONOS/IonosConfigServiceTest.php
@@ -172,4 +172,49 @@ public function testGetApiConfigSuccess(): void {
'basicAuthPass' => 'testpass',
], $result);
}
+
+ public function testGetMailDomainWithValidDomain(): void {
+ $this->config->method('getSystemValue')
+ ->with('ncw.customerDomain', '')
+ ->willReturn('mail.example.com');
+
+ $result = $this->service->getMailDomain();
+ $this->assertEquals('example.com', $result);
+ }
+
+ public function testGetMailDomainWithEmptyDomain(): void {
+ $this->config->method('getSystemValue')
+ ->with('ncw.customerDomain', '')
+ ->willReturn('');
+
+ $result = $this->service->getMailDomain();
+ $this->assertEquals('', $result);
+ }
+
+ public function testGetMailDomainWithMultiLevelTld(): void {
+ $this->config->method('getSystemValue')
+ ->with('ncw.customerDomain', '')
+ ->willReturn('mail.test.co.uk');
+
+ $result = $this->service->getMailDomain();
+ $this->assertEquals('test.co.uk', $result);
+ }
+
+ public function testGetMailDomainWithSubdomain(): void {
+ $this->config->method('getSystemValue')
+ ->with('ncw.customerDomain', '')
+ ->willReturn('foo.bar.lol');
+
+ $result = $this->service->getMailDomain();
+ $this->assertEquals('bar.lol', $result);
+ }
+
+ public function testGetMailDomainWithSimpleDomain(): void {
+ $this->config->method('getSystemValue')
+ ->with('ncw.customerDomain', '')
+ ->willReturn('example.com');
+
+ $result = $this->service->getMailDomain();
+ $this->assertEquals('example.com', $result);
+ }
}
diff --git a/tests/Unit/Service/IONOS/IonosMailServiceTest.php b/tests/Unit/Service/IONOS/IonosMailServiceTest.php
index a038319efc..94842f920b 100644
--- a/tests/Unit/Service/IONOS/IonosMailServiceTest.php
+++ b/tests/Unit/Service/IONOS/IonosMailServiceTest.php
@@ -51,17 +51,17 @@ protected function setUp(): void {
}
public function testCreateEmailAccountSuccess(): void {
- $emailAddress = 'test@example.com';
+ $userName = 'test';
+ $domain = 'example.com';
+ $emailAddress = $userName . '@' . $domain;
// Mock config
- $this->configService->method('getApiConfig')
- ->willReturn([
- 'extRef' => 'test-ext-ref',
- 'apiBaseUrl' => 'https://api.example.com',
- 'allowInsecure' => false,
- 'basicAuthUser' => 'testuser',
- 'basicAuthPass' => 'testpass',
- ]);
+ $this->configService->method('getExternalReference')->willReturn('test-ext-ref');
+ $this->configService->method('getApiBaseUrl')->willReturn('https://api.example.com');
+ $this->configService->method('getAllowInsecure')->willReturn(false);
+ $this->configService->method('getBasicAuthUser')->willReturn('testuser');
+ $this->configService->method('getBasicAuthPassword')->willReturn('testpass');
+ $this->configService->method('getMailDomain')->willReturn($domain);
// Mock user session
$user = $this->createMock(IUser::class);
@@ -116,7 +116,7 @@ public function testCreateEmailAccountSuccess(): void {
$apiInstance->method('createMailbox')->willReturn($mailAccountResponse);
- $result = $this->service->createEmailAccount($emailAddress);
+ $result = $this->service->createEmailAccount($userName);
$this->assertInstanceOf(MailAccountConfig::class, $result);
$this->assertEquals($emailAddress, $result->getEmail());
@@ -133,17 +133,16 @@ public function testCreateEmailAccountSuccess(): void {
}
public function testCreateEmailAccountWithApiException(): void {
- $emailAddress = 'test@example.com';
+ $userName = 'test';
+ $domain = 'example.com';
// Mock config
- $this->configService->method('getApiConfig')
- ->willReturn([
- 'extRef' => 'test-ext-ref',
- 'apiBaseUrl' => 'https://api.example.com',
- 'allowInsecure' => false,
- 'basicAuthUser' => 'testuser',
- 'basicAuthPass' => 'testpass',
- ]);
+ $this->configService->method('getExternalReference')->willReturn('test-ext-ref');
+ $this->configService->method('getApiBaseUrl')->willReturn('https://api.example.com');
+ $this->configService->method('getAllowInsecure')->willReturn(false);
+ $this->configService->method('getBasicAuthUser')->willReturn('testuser');
+ $this->configService->method('getBasicAuthPassword')->willReturn('testpass');
+ $this->configService->method('getMailDomain')->willReturn($domain);
// Mock user session
$user = $this->createMock(IUser::class);
@@ -168,21 +167,20 @@ public function testCreateEmailAccountWithApiException(): void {
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Failed to create ionos mail');
- $this->service->createEmailAccount($emailAddress);
+ $this->service->createEmailAccount($userName);
}
public function testCreateEmailAccountWithErrorMessageResponse(): void {
- $emailAddress = 'test@example.com';
+ $userName = 'test';
+ $domain = 'example.com';
// Mock config
- $this->configService->method('getApiConfig')
- ->willReturn([
- 'extRef' => 'test-ext-ref',
- 'apiBaseUrl' => 'https://api.example.com',
- 'allowInsecure' => false,
- 'basicAuthUser' => 'testuser',
- 'basicAuthPass' => 'testpass',
- ]);
+ $this->configService->method('getExternalReference')->willReturn('test-ext-ref');
+ $this->configService->method('getApiBaseUrl')->willReturn('https://api.example.com');
+ $this->configService->method('getAllowInsecure')->willReturn(false);
+ $this->configService->method('getBasicAuthUser')->willReturn('testuser');
+ $this->configService->method('getBasicAuthPassword')->willReturn('testpass');
+ $this->configService->method('getMailDomain')->willReturn($domain);
// Mock user session
$user = $this->createMock(IUser::class);
@@ -209,21 +207,20 @@ public function testCreateEmailAccountWithErrorMessageResponse(): void {
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Failed to create ionos mail');
- $this->service->createEmailAccount($emailAddress);
+ $this->service->createEmailAccount($userName);
}
public function testCreateEmailAccountWithUnknownResponseType(): void {
- $emailAddress = 'test@example.com';
+ $userName = 'test';
+ $domain = 'example.com';
// Mock config
- $this->configService->method('getApiConfig')
- ->willReturn([
- 'extRef' => 'test-ext-ref',
- 'apiBaseUrl' => 'https://api.example.com',
- 'allowInsecure' => false,
- 'basicAuthUser' => 'testuser',
- 'basicAuthPass' => 'testpass',
- ]);
+ $this->configService->method('getExternalReference')->willReturn('test-ext-ref');
+ $this->configService->method('getApiBaseUrl')->willReturn('https://api.example.com');
+ $this->configService->method('getAllowInsecure')->willReturn(false);
+ $this->configService->method('getBasicAuthUser')->willReturn('testuser');
+ $this->configService->method('getBasicAuthPassword')->willReturn('testpass');
+ $this->configService->method('getMailDomain')->willReturn($domain);
// Mock user session
$user = $this->createMock(IUser::class);
@@ -245,21 +242,18 @@ public function testCreateEmailAccountWithUnknownResponseType(): void {
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Failed to create ionos mail');
- $this->service->createEmailAccount($emailAddress);
+ $this->service->createEmailAccount($userName);
}
public function testCreateEmailAccountWithNoUserSession(): void {
- $emailAddress = 'test@example.com';
+ $userName = 'test';
// Mock config
- $this->configService->method('getApiConfig')
- ->willReturn([
- 'extRef' => 'test-ext-ref',
- 'apiBaseUrl' => 'https://api.example.com',
- 'allowInsecure' => false,
- 'basicAuthUser' => 'testuser',
- 'basicAuthPass' => 'testpass',
- ]);
+ $this->configService->method('getExternalReference')->willReturn('test-ext-ref');
+ $this->configService->method('getApiBaseUrl')->willReturn('https://api.example.com');
+ $this->configService->method('getAllowInsecure')->willReturn(false);
+ $this->configService->method('getBasicAuthUser')->willReturn('testuser');
+ $this->configService->method('getBasicAuthPassword')->willReturn('testpass');
// Mock no user session
$this->userSession->method('getUser')->willReturn(null);
@@ -267,51 +261,7 @@ public function testCreateEmailAccountWithNoUserSession(): void {
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('No user session found');
- $this->service->createEmailAccount($emailAddress);
- }
-
- public function testExtractDomainSuccess(): void {
- $result = $this->service->extractDomain('user@example.com');
- $this->assertEquals('example.com', $result);
-
- $result = $this->service->extractDomain('test.user@subdomain.example.com');
- $this->assertEquals('subdomain.example.com', $result);
- }
-
- public function testExtractDomainWithNoAtSign(): void {
- $this->expectException(ServiceException::class);
- $this->expectExceptionMessage('Invalid email address: unable to extract domain');
-
- $this->service->extractDomain('invalid-email');
- }
-
- public function testExtractDomainWithEmptyDomain(): void {
- $this->expectException(ServiceException::class);
- $this->expectExceptionMessage('Invalid email address: unable to extract domain');
-
- $this->service->extractDomain('user@');
- }
-
- public function testExtractUsernameSuccess(): void {
- $result = $this->service->extractUsername('user@example.com');
- $this->assertEquals('user', $result);
-
- $result = $this->service->extractUsername('test.user@subdomain.example.com');
- $this->assertEquals('test.user', $result);
- }
-
- public function testExtractUsernameWithNoAtSign(): void {
- $this->expectException(ServiceException::class);
- $this->expectExceptionMessage('Invalid email address: unable to extract username');
-
- $this->service->extractUsername('invalid-email');
- }
-
- public function testExtractUsernameWithEmptyUsername(): void {
- $this->expectException(ServiceException::class);
- $this->expectExceptionMessage('Invalid email address: unable to extract username');
-
- $this->service->extractUsername('@example.com');
+ $this->service->createEmailAccount($userName);
}
/**
@@ -320,17 +270,17 @@ public function testExtractUsernameWithEmptyUsername(): void {
* @dataProvider sslModeNormalizationProvider
*/
public function testSslModeNormalization(string $apiSslMode, string $expectedSecurity): void {
- $emailAddress = 'test@example.com';
+ $userName = 'test';
+ $domain = 'example.com';
+ $emailAddress = $userName . '@' . $domain;
// Mock config
- $this->configService->method('getApiConfig')
- ->willReturn([
- 'extRef' => 'test-ext-ref',
- 'apiBaseUrl' => 'https://api.example.com',
- 'allowInsecure' => false,
- 'basicAuthUser' => 'testuser',
- 'basicAuthPass' => 'testpass',
- ]);
+ $this->configService->method('getExternalReference')->willReturn('test-ext-ref');
+ $this->configService->method('getApiBaseUrl')->willReturn('https://api.example.com');
+ $this->configService->method('getAllowInsecure')->willReturn(false);
+ $this->configService->method('getBasicAuthUser')->willReturn('testuser');
+ $this->configService->method('getBasicAuthPassword')->willReturn('testpass');
+ $this->configService->method('getMailDomain')->willReturn($domain);
// Mock user session
$user = $this->createMock(IUser::class);
@@ -378,7 +328,7 @@ public function testSslModeNormalization(string $apiSslMode, string $expectedSec
$apiInstance->method('createMailbox')->willReturn($mailAccountResponse);
- $result = $this->service->createEmailAccount($emailAddress);
+ $result = $this->service->createEmailAccount($userName);
$this->assertEquals($expectedSecurity, $result->getImap()->getSecurity());
$this->assertEquals($expectedSecurity, $result->getSmtp()->getSecurity());