mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Move to transformation adapter
This commit is contained in:
@@ -9,11 +9,12 @@ use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\MethodType;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Transformation\Transformation;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Installations;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Vcs\Comment;
|
||||
use Appwrite\Vcs\Domain;
|
||||
use Appwrite\Transformation\Adapter\BranchDomain;
|
||||
use Swoole\Coroutine\WaitGroup;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Adapters\Dotenv as ConfigDotenv;
|
||||
@@ -370,7 +371,15 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
|
||||
// VCS branch preview
|
||||
if (!empty($providerBranch)) {
|
||||
$domain = Domain::generateBranchDomain($providerBranch, $resource->getId(), $project->getId(), $sitesDomain);
|
||||
$transformation = new Transformation([new BranchDomain()]);
|
||||
$transformation->setInput([
|
||||
'branch' => $providerBranch,
|
||||
'resourceId' => $resource->getId(),
|
||||
'projectId' => $project->getId(),
|
||||
'sitesDomain' => $sitesDomain,
|
||||
]);
|
||||
$transformation->transform();
|
||||
$domain = $transformation->getOutput();
|
||||
$ruleId = md5($domain);
|
||||
try {
|
||||
$authorization->skip(
|
||||
|
||||
@@ -6,7 +6,8 @@ use Appwrite\Event\Build;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Action;
|
||||
use Appwrite\Platform\Modules\Compute\Validator\Specification as SpecificationValidator;
|
||||
use Appwrite\Vcs\Domain;
|
||||
use Appwrite\Transformation\Adapter\BranchDomain;
|
||||
use Appwrite\Transformation\Transformation;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -297,7 +298,15 @@ class Base extends Action
|
||||
|
||||
// VCS branch preview
|
||||
if (!empty($providerBranch)) {
|
||||
$domain = Domain::generateBranchDomain($providerBranch, $site->getId(), $project->getId(), $sitesDomain);
|
||||
$transformation = new Transformation([new BranchDomain()]);
|
||||
$transformation->setInput([
|
||||
'branch' => $providerBranch,
|
||||
'resourceId' => $site->getId(),
|
||||
'projectId' => $project->getId(),
|
||||
'sitesDomain' => $sitesDomain,
|
||||
]);
|
||||
$transformation->transform();
|
||||
$domain = $transformation->getOutput();
|
||||
$ruleId = md5($domain);
|
||||
try {
|
||||
$authorization->skip(
|
||||
|
||||
@@ -9,9 +9,10 @@ use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Screenshot;
|
||||
use Appwrite\Event\StatsUsage;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Transformation\Transformation;
|
||||
use Appwrite\Utopia\Response\Model\Deployment;
|
||||
use Appwrite\Vcs\Comment;
|
||||
use Appwrite\Vcs\Domain;
|
||||
use Appwrite\Transformation\Adapter\BranchDomain;
|
||||
use Exception;
|
||||
use Executor\Executor;
|
||||
use Swoole\Coroutine as Co;
|
||||
@@ -1038,8 +1039,15 @@ class Builds extends Action
|
||||
// VCS branch
|
||||
$branchName = $deployment->getAttribute('providerBranch');
|
||||
if (!empty($branchName)) {
|
||||
$sitesDomain = $platform['sitesDomain'];
|
||||
$domain = Domain::generateBranchDomain($branchName, $resource->getId(), $project->getId(), $sitesDomain);
|
||||
$transformation = new Transformation([new BranchDomain()]);
|
||||
$transformation->setInput([
|
||||
'branch' => $branchName,
|
||||
'resourceId' => $resource->getId(),
|
||||
'projectId' => $project->getId(),
|
||||
'sitesDomain' => $platform['sitesDomain'],
|
||||
]);
|
||||
$transformation->transform();
|
||||
$domain = $transformation->getOutput();
|
||||
$ruleId = md5($domain);
|
||||
|
||||
try {
|
||||
|
||||
+55
-44
@@ -1,10 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Vcs;
|
||||
namespace Appwrite\Transformation\Adapter;
|
||||
|
||||
use Appwrite\Transformation\Adapter;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Domain
|
||||
class BranchDomain extends Adapter
|
||||
{
|
||||
/**
|
||||
* Maximum length for branch prefix in domain name
|
||||
@@ -16,6 +17,56 @@ class Domain
|
||||
*/
|
||||
public const HASH_SUFFIX_LENGTH = 7;
|
||||
|
||||
/**
|
||||
* @param array<mixed> $traits
|
||||
*/
|
||||
public function isValid(array $traits): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform branch name into a valid domain name.
|
||||
*
|
||||
* Input should be an array with:
|
||||
* - 'branch' (string): The branch name
|
||||
* - 'resourceId' (string): The resource ID (site or function)
|
||||
* - 'projectId' (string): The project ID
|
||||
* - 'sitesDomain' (string): The base sites domain
|
||||
*/
|
||||
public function transform(): void
|
||||
{
|
||||
$branch = $this->input['branch'] ?? '';
|
||||
$resourceId = $this->input['resourceId'] ?? '';
|
||||
$projectId = $this->input['projectId'] ?? '';
|
||||
$sitesDomain = $this->input['sitesDomain'] ?? '';
|
||||
|
||||
$branchPrefix = $this->generateBranchPrefix($branch);
|
||||
$resourceProjectHash = substr(hash('sha256', $resourceId . $projectId), 0, self::HASH_SUFFIX_LENGTH);
|
||||
$this->output = "branch-{$branchPrefix}-{$resourceProjectHash}.{$sitesDomain}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a branch prefix for domain name from a branch name.
|
||||
* Takes up to 16 characters, sanitizes them for domain use,
|
||||
* and appends a hash suffix if the branch name is longer than 16 characters.
|
||||
*
|
||||
* @param string $branch The branch name
|
||||
* @return string The branch prefix for domain name
|
||||
*/
|
||||
private function generateBranchPrefix(string $branch): string
|
||||
{
|
||||
$branchPrefix = substr($branch, 0, self::BRANCH_PREFIX_MAX_LENGTH);
|
||||
$branchPrefix = $this->sanitizeBranchName($branchPrefix);
|
||||
|
||||
if (strlen($branch) > self::BRANCH_PREFIX_MAX_LENGTH) {
|
||||
$remainingChars = substr($branch, self::BRANCH_PREFIX_MAX_LENGTH);
|
||||
$branchPrefix .= '-' . substr(hash('sha256', $remainingChars), 0, self::HASH_SUFFIX_LENGTH);
|
||||
}
|
||||
|
||||
return $branchPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize a branch name for use in a domain name.
|
||||
* Replaces any characters that are not alphanumeric or hyphens with hyphens,
|
||||
@@ -24,16 +75,15 @@ class Domain
|
||||
* @param string $branch The branch name to sanitize
|
||||
* @return string The sanitized branch name
|
||||
*/
|
||||
public static function sanitizeBranchName(string $branch): string
|
||||
private function sanitizeBranchName(string $branch): string
|
||||
{
|
||||
// Replace any sequence of invalid characters with a single hyphen
|
||||
$allowedChars = array_merge(
|
||||
Text::NUMBERS,
|
||||
Text::ALPHABET_UPPER,
|
||||
Text::ALPHABET_LOWER,
|
||||
['-']
|
||||
);
|
||||
$allowedCharsFlip = array_flip($allowedChars); // Flip solves issues with named numeric indexes
|
||||
$allowedCharsFlip = array_flip($allowedChars);
|
||||
|
||||
$sanitized = '';
|
||||
for ($i = 0; $i < \strlen($branch); $i++) {
|
||||
@@ -49,45 +99,6 @@ class Domain
|
||||
}
|
||||
}
|
||||
|
||||
// Remove leading and trailing hyphens
|
||||
return trim($sanitized, '-');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a branch prefix for domain name from a branch name.
|
||||
* Takes up to 16 characters, sanitizes them for domain use,
|
||||
* and appends a hash suffix if the branch name is longer than 16 characters.
|
||||
*
|
||||
* @param string $branch The branch name
|
||||
* @return string The branch prefix for domain name
|
||||
*/
|
||||
public static function generateBranchPrefix(string $branch): string
|
||||
{
|
||||
$branchPrefix = substr($branch, 0, self::BRANCH_PREFIX_MAX_LENGTH);
|
||||
$branchPrefix = self::sanitizeBranchName($branchPrefix);
|
||||
|
||||
if (strlen($branch) > self::BRANCH_PREFIX_MAX_LENGTH) {
|
||||
$remainingChars = substr($branch, self::BRANCH_PREFIX_MAX_LENGTH);
|
||||
$branchPrefix .= '-' . substr(hash('sha256', $remainingChars), 0, self::HASH_SUFFIX_LENGTH);
|
||||
}
|
||||
|
||||
return $branchPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a full branch preview domain name.
|
||||
*
|
||||
* @param string $branch The branch name
|
||||
* @param string $resourceId The resource ID (site or function)
|
||||
* @param string $projectId The project ID
|
||||
* @param string $sitesDomain The base sites domain
|
||||
* @return string The full domain name
|
||||
*/
|
||||
public static function generateBranchDomain(string $branch, string $resourceId, string $projectId, string $sitesDomain): string
|
||||
{
|
||||
$branchPrefix = self::generateBranchPrefix($branch);
|
||||
$resourceProjectHash = substr(hash('sha256', $resourceId . $projectId), 0, self::HASH_SUFFIX_LENGTH);
|
||||
|
||||
return "branch-{$branchPrefix}-{$resourceProjectHash}.{$sitesDomain}";
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests\Unit\Transformation;
|
||||
|
||||
use Appwrite\Transformation\Adapter\BranchDomain;
|
||||
use Appwrite\Transformation\Adapter\Mock;
|
||||
use Appwrite\Transformation\Adapter\Preview;
|
||||
use Appwrite\Transformation\Transformation;
|
||||
@@ -40,4 +41,122 @@ class TransformationTest extends TestCase
|
||||
$this->assertStringContainsString("Preview by", $transformer->getOutput());
|
||||
$this->assertStringContainsString("Mock:", $transformer->getOutput());
|
||||
}
|
||||
|
||||
public function testBranchDomain(): void
|
||||
{
|
||||
$transformer = new Transformation([new BranchDomain()]);
|
||||
|
||||
// Branch name with slash
|
||||
$transformer->setInput([
|
||||
'branch' => 'feature/test',
|
||||
'resourceId' => 'site123',
|
||||
'projectId' => 'proj456',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain = $transformer->getOutput();
|
||||
$this->assertStringNotContainsString('/', $domain);
|
||||
$this->assertStringStartsWith('branch-feature-test-', $domain);
|
||||
$this->assertStringEndsWith('.appwrite.network', $domain);
|
||||
|
||||
// Branch domain consistency
|
||||
$transformer->setInput([
|
||||
'branch' => 'feature/test',
|
||||
'resourceId' => 'site123',
|
||||
'projectId' => 'proj456',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain2 = $transformer->getOutput();
|
||||
$this->assertEquals($domain, $domain2);
|
||||
|
||||
// Different resources should produce different domains
|
||||
$transformer->setInput([
|
||||
'branch' => 'feature/test',
|
||||
'resourceId' => 'site789',
|
||||
'projectId' => 'proj456',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain2 = $transformer->getOutput();
|
||||
$this->assertNotEquals($domain, $domain2);
|
||||
|
||||
// Different projects should produce different domains
|
||||
$transformer->setInput([
|
||||
'branch' => 'feature/test',
|
||||
'resourceId' => 'site123',
|
||||
'projectId' => 'proj789',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain2 = $transformer->getOutput();
|
||||
$this->assertNotEquals($domain, $domain2);
|
||||
|
||||
// Some real-world branch names
|
||||
$transformer->setInput([
|
||||
'branch' => 'feature/SER-1234',
|
||||
'resourceId' => 'site123',
|
||||
'projectId' => 'proj456',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain = $transformer->getOutput();
|
||||
$this->assertStringStartsWith('branch-feature-ser-1234-', $domain);
|
||||
$this->assertStringEndsWith('.appwrite.network', $domain);
|
||||
|
||||
$transformer->setInput([
|
||||
'branch' => 'bugfix/fix-login',
|
||||
'resourceId' => 'site123',
|
||||
'projectId' => 'proj456',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain = $transformer->getOutput();
|
||||
$this->assertStringStartsWith('branch-bugfix-fix-login-', $domain);
|
||||
$this->assertStringEndsWith('.appwrite.network', $domain);
|
||||
|
||||
$transformer->setInput([
|
||||
'branch' => 'hotfix/v1.2.3',
|
||||
'resourceId' => 'site123',
|
||||
'projectId' => 'proj456',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain = $transformer->getOutput();
|
||||
$this->assertStringStartsWith('branch-hotfix-v1-2-3-', $domain);
|
||||
$this->assertStringEndsWith('.appwrite.network', $domain);
|
||||
|
||||
$transformer->setInput([
|
||||
'branch' => 'release/2024.01',
|
||||
'resourceId' => 'site123',
|
||||
'projectId' => 'proj456',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain = $transformer->getOutput();
|
||||
$this->assertStringStartsWith('branch-release-2024-01-', $domain);
|
||||
$this->assertStringEndsWith('.appwrite.network', $domain);
|
||||
|
||||
$transformer->setInput([
|
||||
'branch' => 'user/john/experiment',
|
||||
'resourceId' => 'site123',
|
||||
'projectId' => 'proj456',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain = $transformer->getOutput();
|
||||
$this->assertStringStartsWith('branch-user-john-experiment-', $domain);
|
||||
$this->assertStringEndsWith('.appwrite.network', $domain);
|
||||
|
||||
$transformer->setInput([
|
||||
'branch' => 'dependabot/npm_and_yarn/lodash-4.17.21',
|
||||
'resourceId' => 'site123',
|
||||
'projectId' => 'proj456',
|
||||
'sitesDomain' => 'appwrite.network'
|
||||
]);
|
||||
$transformer->transform();
|
||||
$domain = $transformer->getOutput();
|
||||
$this->assertStringStartsWith('branch-dependabot-npm-and-yarn-lodash-4-17-21-', $domain);
|
||||
$this->assertStringEndsWith('.appwrite.network', $domain);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,207 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Vcs;
|
||||
|
||||
use Appwrite\Vcs\Domain;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DomainTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* Test sanitizing branch names with various invalid characters
|
||||
*/
|
||||
public function testSanitizeBranchNameWithSlash(): void
|
||||
{
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature/test'));
|
||||
$this->assertEquals('user-john-fix', Domain::sanitizeBranchName('user/john/fix'));
|
||||
$this->assertEquals('abc-test-235', Domain::sanitizeBranchName('abc/test-235'));
|
||||
}
|
||||
|
||||
public function testSanitizeBranchNameWithUnderscore(): void
|
||||
{
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature_test'));
|
||||
$this->assertEquals('my-branch-name', Domain::sanitizeBranchName('my_branch_name'));
|
||||
}
|
||||
|
||||
public function testSanitizeBranchNameWithMultipleInvalidChars(): void
|
||||
{
|
||||
// Multiple consecutive invalid characters should become a single hyphen
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature//test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature__test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature/_test'));
|
||||
}
|
||||
|
||||
public function testSanitizeBranchNameWithSpecialChars(): void
|
||||
{
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature@test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature#test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature$test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature%test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature&test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature*test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature+test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature=test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature!test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature~test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature`test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature^test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature:test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature;test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature,test'));
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature.test'));
|
||||
}
|
||||
|
||||
public function testSanitizeBranchNameWithSpaces(): void
|
||||
{
|
||||
$this->assertEquals('feature-test', Domain::sanitizeBranchName('feature test'));
|
||||
$this->assertEquals('my-branch-name', Domain::sanitizeBranchName('my branch name'));
|
||||
}
|
||||
|
||||
public function testSanitizeBranchNameTrimsHyphens(): void
|
||||
{
|
||||
// Leading and trailing invalid chars should be removed
|
||||
$this->assertEquals('feature', Domain::sanitizeBranchName('/feature'));
|
||||
$this->assertEquals('feature', Domain::sanitizeBranchName('feature/'));
|
||||
$this->assertEquals('feature', Domain::sanitizeBranchName('/feature/'));
|
||||
$this->assertEquals('feature', Domain::sanitizeBranchName('//feature//'));
|
||||
}
|
||||
|
||||
public function testSanitizeBranchNamePreservesValidChars(): void
|
||||
{
|
||||
// Valid branch names should remain unchanged
|
||||
$this->assertEquals('main', Domain::sanitizeBranchName('main'));
|
||||
$this->assertEquals('develop', Domain::sanitizeBranchName('develop'));
|
||||
$this->assertEquals('feature-123', Domain::sanitizeBranchName('feature-123'));
|
||||
$this->assertEquals('v1-2-3', Domain::sanitizeBranchName('v1-2-3'));
|
||||
$this->assertEquals('UPPERCASE', Domain::sanitizeBranchName('UPPERCASE'));
|
||||
$this->assertEquals('MixedCase123', Domain::sanitizeBranchName('MixedCase123'));
|
||||
}
|
||||
|
||||
public function testSanitizeBranchNameWithEmptyString(): void
|
||||
{
|
||||
$this->assertEquals('', Domain::sanitizeBranchName(''));
|
||||
}
|
||||
|
||||
public function testSanitizeBranchNameWithOnlyInvalidChars(): void
|
||||
{
|
||||
$this->assertEquals('', Domain::sanitizeBranchName('///'));
|
||||
$this->assertEquals('', Domain::sanitizeBranchName('___'));
|
||||
$this->assertEquals('', Domain::sanitizeBranchName('@#$'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test generating branch prefix for domain names
|
||||
*/
|
||||
public function testGenerateBranchPrefixShortBranch(): void
|
||||
{
|
||||
// Branch names <= 16 characters should not have hash suffix
|
||||
$prefix = Domain::generateBranchPrefix('main');
|
||||
$this->assertEquals('main', $prefix);
|
||||
|
||||
$prefix = Domain::generateBranchPrefix('feature-test');
|
||||
$this->assertEquals('feature-test', $prefix);
|
||||
|
||||
$prefix = Domain::generateBranchPrefix('exactly16chars12');
|
||||
$this->assertEquals('exactly16chars12', $prefix);
|
||||
}
|
||||
|
||||
public function testGenerateBranchPrefixLongBranch(): void
|
||||
{
|
||||
// Branch names > 16 characters should have hash suffix
|
||||
$prefix = Domain::generateBranchPrefix('this-is-a-very-long-branch-name');
|
||||
// First 16 chars: "this-is-a-very-l" + hash of remaining chars
|
||||
$this->assertStringStartsWith('this-is-a-very-l-', $prefix);
|
||||
$this->assertEquals(24, strlen($prefix)); // 16 + 1 (hyphen) + 7 (hash)
|
||||
}
|
||||
|
||||
public function testGenerateBranchPrefixWithInvalidChars(): void
|
||||
{
|
||||
// Branch with slash should be sanitized
|
||||
$prefix = Domain::generateBranchPrefix('feature/test');
|
||||
$this->assertEquals('feature-test', $prefix);
|
||||
|
||||
// Long branch with slash
|
||||
$prefix = Domain::generateBranchPrefix('feature/very/long/branch/name');
|
||||
$this->assertStringStartsWith('feature-very-lon-', $prefix);
|
||||
$this->assertEquals(24, strlen($prefix));
|
||||
}
|
||||
|
||||
public function testGenerateBranchPrefixConsistency(): void
|
||||
{
|
||||
// Same input should produce same output
|
||||
$prefix1 = Domain::generateBranchPrefix('feature/my-long-branch-name');
|
||||
$prefix2 = Domain::generateBranchPrefix('feature/my-long-branch-name');
|
||||
$this->assertEquals($prefix1, $prefix2);
|
||||
}
|
||||
|
||||
public function testGenerateBranchPrefixDifferentHashes(): void
|
||||
{
|
||||
// Different branch names with same first 16 chars should have different hashes
|
||||
$prefix1 = Domain::generateBranchPrefix('feature-branch-01234567890');
|
||||
$prefix2 = Domain::generateBranchPrefix('feature-branch-0abcdefghij');
|
||||
|
||||
// Both start with sanitized first 16 chars
|
||||
$this->assertStringStartsWith('feature-branch-0-', $prefix1);
|
||||
$this->assertStringStartsWith('feature-branch-0-', $prefix2);
|
||||
|
||||
// But have different hash suffixes
|
||||
$this->assertNotEquals($prefix1, $prefix2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test generating full branch domain names
|
||||
*/
|
||||
public function testGenerateBranchDomain(): void
|
||||
{
|
||||
$domain = Domain::generateBranchDomain('main', 'site123', 'proj456', 'appwrite.network');
|
||||
$this->assertStringStartsWith('branch-main-', $domain);
|
||||
$this->assertStringEndsWith('.appwrite.network', $domain);
|
||||
}
|
||||
|
||||
public function testGenerateBranchDomainWithSlash(): void
|
||||
{
|
||||
$domain = Domain::generateBranchDomain('feature/test', 'site123', 'proj456', 'appwrite.network');
|
||||
// Should NOT contain slash
|
||||
$this->assertStringNotContainsString('/', $domain);
|
||||
$this->assertStringStartsWith('branch-feature-test-', $domain);
|
||||
$this->assertStringEndsWith('.appwrite.network', $domain);
|
||||
}
|
||||
|
||||
public function testGenerateBranchDomainConsistency(): void
|
||||
{
|
||||
// Same inputs should produce same domain
|
||||
$domain1 = Domain::generateBranchDomain('feature/test', 'site123', 'proj456', 'appwrite.network');
|
||||
$domain2 = Domain::generateBranchDomain('feature/test', 'site123', 'proj456', 'appwrite.network');
|
||||
$this->assertEquals($domain1, $domain2);
|
||||
}
|
||||
|
||||
public function testGenerateBranchDomainDifferentResources(): void
|
||||
{
|
||||
// Different resources should produce different domains
|
||||
$domain1 = Domain::generateBranchDomain('main', 'site123', 'proj456', 'appwrite.network');
|
||||
$domain2 = Domain::generateBranchDomain('main', 'site789', 'proj456', 'appwrite.network');
|
||||
$this->assertNotEquals($domain1, $domain2);
|
||||
}
|
||||
|
||||
public function testGenerateBranchDomainDifferentProjects(): void
|
||||
{
|
||||
// Different projects should produce different domains
|
||||
$domain1 = Domain::generateBranchDomain('main', 'site123', 'proj456', 'appwrite.network');
|
||||
$domain2 = Domain::generateBranchDomain('main', 'site123', 'proj789', 'appwrite.network');
|
||||
$this->assertNotEquals($domain1, $domain2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test real-world branch name scenarios
|
||||
*/
|
||||
public function testRealWorldBranchNames(): void
|
||||
{
|
||||
// Common Git branch naming conventions
|
||||
$this->assertEquals('feature-SER-1234', Domain::sanitizeBranchName('feature/SER-1234'));
|
||||
$this->assertEquals('bugfix-fix-login', Domain::sanitizeBranchName('bugfix/fix-login'));
|
||||
$this->assertEquals('hotfix-v1-2-3', Domain::sanitizeBranchName('hotfix/v1.2.3'));
|
||||
$this->assertEquals('release-2024-01', Domain::sanitizeBranchName('release/2024.01'));
|
||||
$this->assertEquals('user-john-experiment', Domain::sanitizeBranchName('user/john/experiment'));
|
||||
$this->assertEquals('dependabot-npm-and-yarn-lodash-4-17-21', Domain::sanitizeBranchName('dependabot/npm_and_yarn/lodash-4.17.21'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user