appwrite/tests/e2e/Services/Project/SMTPBase.php

848 lines
26 KiB
PHP
Raw Normal View History

2026-04-14 14:55:39 +00:00
<?php
namespace Tests\E2E\Services\Project;
use Tests\E2E\Client;
2026-04-14 15:09:37 +00:00
use Utopia\Database\Helpers\ID;
2026-04-14 14:55:39 +00:00
trait SMTPBase
{
// Update SMTP status tests
public function testUpdateSMTPStatusEnable(): void
{
$response = $this->updateSMTPStatus(true);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertSame(true, $response['body']['smtpEnabled']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPStatusDisable(): void
{
$this->updateSMTPStatus(true);
$response = $this->updateSMTPStatus(false);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertSame(false, $response['body']['smtpEnabled']);
}
public function testUpdateSMTPStatusEnableIdempotent(): void
{
$first = $this->updateSMTPStatus(true);
$this->assertSame(200, $first['headers']['status-code']);
$this->assertSame(true, $first['body']['smtpEnabled']);
$second = $this->updateSMTPStatus(true);
$this->assertSame(200, $second['headers']['status-code']);
$this->assertSame(true, $second['body']['smtpEnabled']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPStatusDisableIdempotent(): void
{
$first = $this->updateSMTPStatus(false);
$this->assertSame(200, $first['headers']['status-code']);
$this->assertSame(false, $first['body']['smtpEnabled']);
$second = $this->updateSMTPStatus(false);
$this->assertSame(200, $second['headers']['status-code']);
$this->assertSame(false, $second['body']['smtpEnabled']);
}
public function testUpdateSMTPStatusResponseModel(): void
{
$response = $this->updateSMTPStatus(true);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertArrayHasKey('$id', $response['body']);
$this->assertArrayHasKey('name', $response['body']);
$this->assertArrayHasKey('smtpEnabled', $response['body']);
$this->assertArrayHasKey('smtpSenderName', $response['body']);
$this->assertArrayHasKey('smtpSenderEmail', $response['body']);
2026-04-20 09:47:06 +00:00
$this->assertArrayHasKey('smtpReplyToEmail', $response['body']);
$this->assertArrayHasKey('smtpReplyToName', $response['body']);
2026-04-14 14:55:39 +00:00
$this->assertArrayHasKey('smtpHost', $response['body']);
$this->assertArrayHasKey('smtpPort', $response['body']);
$this->assertArrayHasKey('smtpUsername', $response['body']);
$this->assertArrayHasKey('smtpPassword', $response['body']);
$this->assertArrayHasKey('smtpSecure', $response['body']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPStatusWithoutAuthentication(): void
{
$response = $this->updateSMTPStatus(true, false);
$this->assertSame(401, $response['headers']['status-code']);
}
// Update SMTP tests
2026-04-16 08:23:31 +00:00
public function testUpdateSMTPCredentials(): void
2026-04-14 14:55:39 +00:00
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertSame(true, $response['body']['smtpEnabled']);
$this->assertSame('Test Sender', $response['body']['smtpSenderName']);
$this->assertSame('sender@example.com', $response['body']['smtpSenderEmail']);
$this->assertSame('maildev', $response['body']['smtpHost']);
$this->assertSame(1025, $response['body']['smtpPort']);
// Cleanup
$this->updateSMTPStatus(false);
}
2026-04-14 15:06:57 +00:00
public function testUpdateSMTPWithOptionalReplyTo(): void
2026-04-14 14:55:39 +00:00
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Full Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
2026-04-20 09:47:06 +00:00
replyToEmail: 'reply@example.com',
replyToName: 'Full Reply',
2026-04-14 14:55:39 +00:00
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame(true, $response['body']['smtpEnabled']);
$this->assertSame('Full Sender', $response['body']['smtpSenderName']);
$this->assertSame('sender@example.com', $response['body']['smtpSenderEmail']);
2026-04-20 09:47:06 +00:00
$this->assertSame('reply@example.com', $response['body']['smtpReplyToEmail']);
$this->assertSame('Full Reply', $response['body']['smtpReplyToName']);
2026-04-14 14:55:39 +00:00
$this->assertSame('maildev', $response['body']['smtpHost']);
$this->assertSame(1025, $response['body']['smtpPort']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPOverwritesPreviousSettings(): void
{
2026-04-16 08:23:31 +00:00
$this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'First Sender',
senderEmail: 'first@example.com',
host: 'maildev',
port: 1025,
);
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Second Sender',
senderEmail: 'second@example.com',
host: 'maildev',
port: 1025,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame('Second Sender', $response['body']['smtpSenderName']);
$this->assertSame('second@example.com', $response['body']['smtpSenderEmail']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPEnablesSMTP(): void
{
// Ensure SMTP is disabled
$this->updateSMTPStatus(false);
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame(true, $response['body']['smtpEnabled']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPResponseModel(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertArrayHasKey('$id', $response['body']);
$this->assertArrayHasKey('name', $response['body']);
$this->assertArrayHasKey('smtpEnabled', $response['body']);
$this->assertArrayHasKey('smtpSenderName', $response['body']);
$this->assertArrayHasKey('smtpSenderEmail', $response['body']);
2026-04-20 09:47:06 +00:00
$this->assertArrayHasKey('smtpReplyToEmail', $response['body']);
$this->assertArrayHasKey('smtpReplyToName', $response['body']);
2026-04-14 14:55:39 +00:00
$this->assertArrayHasKey('smtpHost', $response['body']);
$this->assertArrayHasKey('smtpPort', $response['body']);
$this->assertArrayHasKey('smtpUsername', $response['body']);
$this->assertArrayHasKey('smtpPassword', $response['body']);
$this->assertArrayHasKey('smtpSecure', $response['body']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPWithoutAuthentication(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
authenticated: false,
);
$this->assertSame(401, $response['headers']['status-code']);
}
public function testUpdateSMTPInvalidSenderEmail(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test',
senderEmail: 'not-an-email',
host: 'maildev',
port: 1025,
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPEmptySenderName(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: '',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPEmptySenderEmail(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test',
senderEmail: '',
host: 'maildev',
port: 1025,
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPEmptyHost(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: '',
port: 1025,
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPInvalidHost(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'not a valid host!@#',
port: 1025,
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPInvalidReplyToEmail(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
2026-04-20 09:47:06 +00:00
replyToEmail: 'not-an-email',
2026-04-14 14:55:39 +00:00
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPInvalidSecure(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
secure: 'invalid',
);
$this->assertSame(400, $response['headers']['status-code']);
}
2026-04-14 15:06:57 +00:00
public function testUpdateSMTPSenderNameMinLength(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: 'A',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame('A', $response['body']['smtpSenderName']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPSenderNameMaxLength(): void
{
$name = str_repeat('a', 256);
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: $name,
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame($name, $response['body']['smtpSenderName']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPSenderNameTooLong(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: str_repeat('a', 257),
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPUsernameMinLength(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
username: 'u',
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame('u', $response['body']['smtpUsername']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPUsernameMaxLength(): void
{
$username = str_repeat('a', 256);
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
username: $username,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame($username, $response['body']['smtpUsername']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPUsernameTooLong(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
username: str_repeat('a', 257),
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPUsernameEmpty(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
username: '',
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPPasswordMinLength(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
password: 'p',
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame('p', $response['body']['smtpPassword']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPPasswordMaxLength(): void
{
$password = str_repeat('a', 256);
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
password: $password,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame($password, $response['body']['smtpPassword']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPPasswordTooLong(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
password: str_repeat('a', 257),
);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testUpdateSMTPPasswordEmpty(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:06:57 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
password: '',
);
$this->assertSame(400, $response['headers']['status-code']);
}
2026-04-14 15:01:56 +00:00
public function testUpdateSMTPWithoutSecure(): void
2026-04-14 14:55:39 +00:00
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame('', $response['body']['smtpSecure']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testUpdateSMTPInvalidConnectionRefused(): void
{
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'localhost',
port: 12345,
);
$this->assertSame(400, $response['headers']['status-code']);
$this->assertSame('project_smtp_config_invalid', $response['body']['type']);
}
public function testUpdateSMTPBackwardsCompatibilityDisable(): void
{
// First enable SMTP
$this->updateSMTPStatus(true);
// Use the deprecated enabled=false parameter to disable
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
enabled: false,
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame(false, $response['body']['smtpEnabled']);
}
// Create SMTP test tests
public function testCreateSMTPTest(): void
{
// First configure SMTP
2026-04-16 08:23:31 +00:00
$this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$response = $this->createSMTPTest(['recipient@example.com']);
$this->assertSame(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testCreateSMTPTestMultipleRecipients(): void
{
// First configure SMTP
2026-04-16 08:23:31 +00:00
$this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$response = $this->createSMTPTest([
'recipient1@example.com',
'recipient2@example.com',
'recipient3@example.com',
]);
$this->assertSame(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testCreateSMTPTestWhenSMTPDisabled(): void
{
// Ensure SMTP is disabled
$this->updateSMTPStatus(false);
$response = $this->createSMTPTest(['recipient@example.com']);
$this->assertSame(400, $response['headers']['status-code']);
}
public function testCreateSMTPTestWithoutAuthentication(): void
{
$response = $this->createSMTPTest(['recipient@example.com'], false);
$this->assertSame(401, $response['headers']['status-code']);
}
public function testCreateSMTPTestEmptyEmails(): void
{
// First configure SMTP
2026-04-16 08:23:31 +00:00
$this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$response = $this->createSMTPTest([]);
2026-04-14 15:06:57 +00:00
$this->assertSame(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
2026-04-14 14:55:39 +00:00
// Cleanup
$this->updateSMTPStatus(false);
}
public function testCreateSMTPTestInvalidEmail(): void
{
// First configure SMTP
2026-04-16 08:23:31 +00:00
$this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$response = $this->createSMTPTest(['not-an-email']);
$this->assertSame(400, $response['headers']['status-code']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testCreateSMTPTestExceedsMaxEmails(): void
{
// First configure SMTP
2026-04-16 08:23:31 +00:00
$this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$emails = [];
for ($i = 1; $i <= 11; $i++) {
$emails[] = "recipient{$i}@example.com";
}
$response = $this->createSMTPTest($emails);
$this->assertSame(400, $response['headers']['status-code']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testCreateSMTPTestMaxEmails(): void
{
// First configure SMTP
2026-04-16 08:23:31 +00:00
$this->updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
senderName: 'Test Sender',
senderEmail: 'sender@example.com',
host: 'maildev',
port: 1025,
);
$emails = [];
for ($i = 1; $i <= 10; $i++) {
$emails[] = "recipient{$i}@example.com";
}
$response = $this->createSMTPTest($emails);
$this->assertSame(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
// Cleanup
$this->updateSMTPStatus(false);
}
2026-04-14 15:09:37 +00:00
// Integration tests
public function testCreateSMTPTestEmailDelivery(): void
{
$senderName = 'SMTP Test Sender';
$senderEmail = 'smtptest@appwrite.io';
$replyToEmail = 'smtpreply@appwrite.io';
2026-04-20 09:47:06 +00:00
$replyToName = 'SMTP Reply Team';
2026-04-14 15:09:37 +00:00
$recipientEmail = 'smtpdelivery-' . \uniqid() . '@appwrite.io';
2026-04-20 09:47:06 +00:00
// Configure SMTP with reply-to and auth credentials
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:09:37 +00:00
senderName: $senderName,
senderEmail: $senderEmail,
host: 'maildev',
port: 1025,
2026-04-20 09:47:06 +00:00
replyToEmail: $replyToEmail,
replyToName: $replyToName,
2026-04-14 15:20:03 +00:00
username: 'user',
password: 'password',
2026-04-14 15:09:37 +00:00
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame(true, $response['body']['smtpEnabled']);
// Trigger test email
$response = $this->createSMTPTest([$recipientEmail]);
$this->assertSame(204, $response['headers']['status-code']);
// Verify email arrived via maildev
$email = $this->getLastEmailByAddress($recipientEmail, function ($email) {
$this->assertSame('Custom SMTP email sample', $email['subject']);
});
$this->assertSame($senderEmail, $email['from'][0]['address']);
$this->assertSame($senderName, $email['from'][0]['name']);
$this->assertSame($replyToEmail, $email['replyTo'][0]['address']);
2026-04-20 09:47:06 +00:00
$this->assertSame($replyToName, $email['replyTo'][0]['name']);
2026-04-14 15:09:37 +00:00
$this->assertSame('Custom SMTP email sample', $email['subject']);
$this->assertStringContainsStringIgnoringCase('working correctly', $email['text']);
$this->assertStringContainsStringIgnoringCase('working correctly', $email['html']);
// Cleanup
$this->updateSMTPStatus(false);
}
public function testMagicURLLoginUsesCustomSMTP(): void
{
$senderName = 'Custom Auth Mailer';
$senderEmail = 'authmailer@appwrite.io';
$recipientEmail = 'magicurl-' . \uniqid() . '@appwrite.io';
2026-04-14 15:20:03 +00:00
// Configure custom SMTP with auth credentials
2026-04-16 08:23:31 +00:00
$response = $this->updateSMTPCredentials(
2026-04-14 15:09:37 +00:00
senderName: $senderName,
senderEmail: $senderEmail,
2026-04-14 15:20:22 +00:00
host: 'maildev',
port: 1025,
username: 'user',
password: 'password',
2026-04-14 15:09:37 +00:00
);
$this->assertSame(200, $response['headers']['status-code']);
$this->assertSame(true, $response['body']['smtpEnabled']);
// Trigger MagicURL login as a client (no auth headers needed)
$response = $this->client->call(Client::METHOD_POST, '/account/tokens/magic-url', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], [
'userId' => ID::unique(),
'email' => $recipientEmail,
]);
$this->assertSame(201, $response['headers']['status-code']);
// Verify the email arrived with custom SMTP sender details
$email = $this->getLastEmailByAddress($recipientEmail, function ($email) {
$this->assertStringContainsString('Login', $email['subject']);
});
$this->assertSame($senderEmail, $email['from'][0]['address']);
$this->assertSame($senderName, $email['from'][0]['name']);
$this->assertSame($this->getProject()['name'] . ' Login', $email['subject']);
// Cleanup
$this->updateSMTPStatus(false);
}
2026-04-14 14:55:39 +00:00
// Helpers
protected function updateSMTPStatus(bool $enabled, bool $authenticated = true): mixed
{
$headers = [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
];
if ($authenticated) {
$headers = array_merge($headers, $this->getHeaders());
}
return $this->client->call(Client::METHOD_PATCH, '/project/smtp/status', $headers, [
'enabled' => $enabled,
]);
}
2026-04-16 08:23:31 +00:00
protected function updateSMTPCredentials(
2026-04-14 14:55:39 +00:00
string $senderName = '',
string $senderEmail = '',
string $host = '',
int $port = 587,
2026-04-20 09:47:06 +00:00
?string $replyToEmail = null,
?string $replyToName = null,
2026-04-14 15:01:56 +00:00
?string $username = null,
?string $password = null,
?string $secure = null,
2026-04-14 14:55:39 +00:00
?bool $enabled = null,
bool $authenticated = true,
): mixed {
$headers = [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
];
if ($authenticated) {
$headers = array_merge($headers, $this->getHeaders());
}
$params = [
'senderName' => $senderName,
'senderEmail' => $senderEmail,
'host' => $host,
'port' => $port,
];
2026-04-20 09:47:06 +00:00
if (!\is_null($replyToEmail)) {
$params['replyToEmail'] = $replyToEmail;
}
if (!\is_null($replyToName)) {
$params['replyToName'] = $replyToName;
2026-04-14 15:01:56 +00:00
}
if (!\is_null($username)) {
$params['username'] = $username;
}
if (!\is_null($password)) {
$params['password'] = $password;
}
if (!\is_null($secure)) {
$params['secure'] = $secure;
}
2026-04-14 14:55:39 +00:00
if (!\is_null($enabled)) {
$params['enabled'] = $enabled;
}
2026-04-16 08:23:31 +00:00
return $this->client->call(Client::METHOD_PATCH, '/project/smtp/credentials', $headers, $params);
2026-04-14 14:55:39 +00:00
}
/**
* @param array<string> $emails
*/
protected function createSMTPTest(array $emails, bool $authenticated = true): mixed
{
$headers = [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
];
if ($authenticated) {
$headers = array_merge($headers, $this->getHeaders());
}
return $this->client->call(Client::METHOD_POST, '/project/smtp/tests', $headers, [
'emails' => $emails,
]);
}
}