diff --git a/README.md b/README.md index b3dc351..0e1330a 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,10 @@ This client is a combination of code generated by [OpenAPI Generator](https://op from the Hangar OpenAPI specification and some wrappers around it to improve the usability. The generated code can be found in `src/Api` and `src/Model`. It is recommended to use the wrappers in -`src/Client` instead. The wrappers provide methods to fetch related data from the API, the data returned -by the API is available through `getData()`. +`src/Client` instead. The wrappers extend the generated models, so the data returned by the API is available +through the getters of the wrapper, e.g. `$project->getName()`. They also provide methods to fetch related data +from the API. These methods start with `fetch`, e.g. `$project->fetchVersions()`, and send a request each time +they are called. Only `fetchProject()` of `Version` and `ProjectPage` keeps the project once it is known. ## Requirements - PHP 8.4 or newer @@ -88,7 +90,7 @@ you can use it like an array. It also has a `getResults()` method which returns $projects = $hangarClient->getProjects(); foreach ($projects as $project) { - echo $project->getData()->getName() . PHP_EOL; + echo $project->getName() . PHP_EOL; } if ($projects->hasNextPage()) { @@ -126,7 +128,7 @@ $projects = $hangarClient->getProjects($options); ```php // get a project by its slug or id $project = $hangarClient->getProject("mclogs"); -echo $project->getData()->getName() . ": " . $project->getData()->getStats()->getDownloads() . " downloads" . PHP_EOL; +echo $project->getName() . ": " . $project->getStats()->getDownloads() . " downloads" . PHP_EOL; // get the project a file belongs to by the SHA-256 hash of the file $project = $hangarClient->getProjectByVersionHash(hash_file("sha256", "/path/to/plugin.jar")); @@ -138,30 +140,30 @@ The `Project` wrapper provides methods to fetch related data: $project = $hangarClient->getProject("mclogs"); // versions of the project (paginated), optionally filtered by channel and platform -$versions = $project->getVersions(); -$versions = $project->getVersions("Release", Platform::PAPER); +$versions = $project->fetchVersions(); +$versions = $project->fetchVersions("Release", Platform::PAPER); // a specific version by its name -$version = $project->getVersion("3.3.4"); +$version = $project->fetchVersion("3.3.4"); // the owner of the project -$owner = $project->getOwner(); +$owner = $project->fetchOwner(); // members, stargazers and watchers of the project (paginated) -$members = $project->getMembers(); -$stargazers = $project->getStarGazers(); -$watchers = $project->getWatchers(); +$members = $project->fetchMembers(); +$stargazers = $project->fetchStarGazers(); +$watchers = $project->fetchWatchers(); // pages of the project -$mainPage = $project->getMainPage(); -$page = $project->getPage("config"); +$mainPage = $project->fetchMainPage(); +$page = $project->fetchPage("config"); ``` The daily stats of a project require an API key of a member of the project: ```php // stats since the project was created, or for a specific period -$stats = $project->getDailyStats(); -$stats = $project->getDailyStats(new DateTime("2026-01-01"), new DateTime("2026-02-01")); +$stats = $project->fetchDailyStats(); +$stats = $project->fetchDailyStats(new DateTime("2026-01-01"), new DateTime("2026-02-01")); foreach ($stats as $date => $dayStats) { echo $date . ": " . $dayStats->getDownloads() . " downloads, " . $dayStats->getViews() . " views" . PHP_EOL; @@ -172,8 +174,8 @@ foreach ($stats as $date => $dayStats) { Some methods, e.g. the projects a user has starred, return `CompactProject` objects. They contain less data, but provide the same methods as `Project`. You can fetch the full project: ```php -foreach ($hangarClient->getUser("Aternos")->getStarredProjects() as $compactProject) { - $project = $compactProject->getProject(); +foreach ($hangarClient->getUser("Aternos")->fetchStarredProjects() as $compactProject) { + $project = $compactProject->fetchProject(); } ``` @@ -198,12 +200,12 @@ $latestRelease = $hangarClient->getLatestReleaseVersion("mclogs"); $latestVersion = $hangarClient->getLatestVersion("mclogs", "Release"); // get the project of a version -$project = $version->getProject(); +$project = $version->fetchProject(); ``` The daily stats of a version require an API key: ```php -$stats = $version->getDailyStats(); +$stats = $version->fetchDailyStats(); foreach ($stats as $date => $dayStats) { echo $date . ": " . $dayStats->getTotalDownloads() . " downloads" . PHP_EOL; @@ -218,7 +220,7 @@ use Aternos\HangarApi\Client\Options\UserSearch\UserSortField; // get a user by name $user = $hangarClient->getUser("Aternos"); -echo $user->getData()->getName() . ": " . $user->getData()->getProjectCount() . " projects" . PHP_EOL; +echo $user->getName() . ": " . $user->getProjectCount() . " projects" . PHP_EOL; // search for users (paginated) $users = $hangarClient->getUsers(new UserSearchOptions()->setQuery("aternos")->setSort(UserSortField::NAME)); @@ -228,14 +230,14 @@ $staff = $hangarClient->getStaff(sort: StaffSortField::ROLES); $authors = $hangarClient->getAuthors("aternos"); // get the projects of a user (paginated) -$projects = $user->getProjects(); +$projects = $user->fetchProjects(); // get the projects a user has starred or is watching (paginated) -$starredProjects = $user->getStarredProjects(); -$watchedProjects = $user->getWatchedProjects(); +$starredProjects = $user->fetchStarredProjects(); +$watchedProjects = $user->fetchWatchedProjects(); // get the projects a user has pinned on their profile -$pinnedProjects = $user->getPinnedProjects(); +$pinnedProjects = $user->fetchPinnedProjects(); ``` ## Project Pages diff --git a/src/Client/CompactProject.php b/src/Client/CompactProject.php index 99be82b..9198678 100644 --- a/src/Client/CompactProject.php +++ b/src/Client/CompactProject.php @@ -18,59 +18,49 @@ * @package Aternos\HangarApi\Client * @description This class wraps a compact project (a project with fewer fields) and allows you to fetch additional data. */ -class CompactProject +class CompactProject extends ProjectCompact { + /** + * @param HangarAPIClient $client + * @param ProjectCompact $data + */ public function __construct( protected HangarAPIClient $client, - protected ProjectCompact $project, + ProjectCompact $data, ) { + parent::__construct($data->container); } /** - * @return ProjectCompact - */ - public function getData(): ProjectCompact - { - return $this->project; - } - - /** - * Get the slug of this project (shorthand for getData()->getNamespace()->getSlug()) + * Get the slug of this project (shorthand for getNamespace()->getSlug()) * @return string */ public function getSlug(): string { - return $this->project->getNamespace()->getSlug(); - } - - /** - * Get the id of this project (shorthand for getData()->getId()) - * @return int - */ - public function getId(): int - { - return $this->project->getId(); + return $this->getNamespace()->getSlug(); } /** - * Get the full project data + * Fetch the full project data + * This sends a request to the Hangar API every time it is called. * @return Project * @throws ApiException */ - public function getProject(): Project + public function fetchProject(): Project { return $this->client->getProject($this->getId()); } /** - * Get all versions of this project (paginated) + * Fetch all versions of this project (paginated) + * This sends a request to the Hangar API every time it is called. * @param string|null $channel * @param Platform|null $platform * @return ProjectVersionList * @throws ApiException */ - public function getVersions(?string $channel = null, ?Platform $platform = null): ProjectVersionList + public function fetchVersions(?string $channel = null, ?Platform $platform = null): ProjectVersionList { $options = new VersionSearchOptions($this->getId()); $options->setChannel($channel); @@ -79,90 +69,98 @@ public function getVersions(?string $channel = null, ?Platform $platform = null) } /** - * get a single version + * Fetch a single version + * This sends a request to the Hangar API every time it is called. * @param string $name * @return Version * @throws ApiException */ - public function getVersion(string $name): Version + public function fetchVersion(string $name): Version { return $this->client->getVersion($this->getId(), $name); } /** - * Get all watchers of this project (paginated) + * Fetch all watchers of this project (paginated) + * This sends a request to the Hangar API every time it is called. * @return UserList * @throws ApiException */ - public function getWatchers(): UserList + public function fetchWatchers(): UserList { return $this->client->getProjectWatchers($this->getId()); } /** - * Get a list of daily project stats + * Fetch a list of daily project stats * Days without downloads/views are not be included + * This sends a request to the Hangar API every time it is called. * @param DateTime|null $from default: project creation date * @param DateTime|null $to default: now * @return array * @throws ApiException */ - public function getDailyStats(?DateTime $from = null, ?DateTime $to = null): array + public function fetchDailyStats(?DateTime $from = null, ?DateTime $to = null): array { return $this->client->getDailyProjectStats( $this->getId(), - $from ?? $this->getData()->getCreatedAt(), + $from ?? $this->getCreatedAt(), $to ); } /** - * Get a list of users who starred this project (paginated) + * Fetch a list of users who starred this project (paginated) + * This sends a request to the Hangar API every time it is called. * @return UserList * @throws ApiException */ - public function getStarGazers(): UserList + public function fetchStarGazers(): UserList { return $this->client->getProjectStarGazers($this->getId()); } /** - * Get a list of users who are members of this project (paginated) + * Fetch a list of users who are members of this project (paginated) + * This sends a request to the Hangar API every time it is called. * @return ProjectMemberList * @throws ApiException */ - public function getMembers(): ProjectMemberList + public function fetchMembers(): ProjectMemberList { return $this->client->getProjectMembers($this->getId()); } /** - * Get the owner of this project + * Fetch the owner of this project + * This sends a request to the Hangar API every time it is called. * @return User * @throws ApiException */ - public function getOwner(): User + public function fetchOwner(): User { - return $this->client->getUser($this->project->getNamespace()->getOwner()); + return $this->client->getUser($this->getNamespace()->getOwner()); } /** - * Get the main page of this project + * Fetch the main page of this project + * This sends a request to the Hangar API every time it is called. * @return ProjectPage * @throws ApiException */ - public function getMainPage(): ProjectPage + public function fetchMainPage(): ProjectPage { return $this->client->getProjectMainPage($this->getId()); } /** - * Get a page of this project + * Fetch a page of this project + * This sends a request to the Hangar API every time it is called. * @param string $path * @return ProjectPage * @throws ApiException */ - public function getPage(string $path): ProjectPage + public function fetchPage(string $path): ProjectPage { return $this->client->getProjectPage($this->getId(), $path); } diff --git a/src/Client/Project.php b/src/Client/Project.php index ac60ea8..bddfca6 100644 --- a/src/Client/Project.php +++ b/src/Client/Project.php @@ -9,6 +9,7 @@ use Aternos\HangarApi\Client\Options\VersionSearch\VersionSearchOptions; use Aternos\HangarApi\Model\DayProjectStats; use Aternos\HangarApi\Model\Platform; +use Aternos\HangarApi\Model\Project as ProjectModel; use DateTime; /** @@ -17,49 +18,38 @@ * @package Aternos\HangarApi\Client * @description This class wraps a full project on hangar and allows you to fetch additional data. */ -class Project +class Project extends ProjectModel { - public function __construct( - protected HangarAPIClient $client, - protected \Aternos\HangarApi\Model\Project $project, - ) - { - } - /** - * @return \Aternos\HangarApi\Model\Project + * @param HangarAPIClient $client + * @param ProjectModel $data */ - public function getData(): \Aternos\HangarApi\Model\Project + public function __construct( + protected HangarAPIClient $client, + ProjectModel $data, + ) { - return $this->project; + parent::__construct($data->container); } /** - * Get the slug of this project (shorthand for getData()->getNamespace()->getSlug()) + * Get the slug of this project (shorthand for getNamespace()->getSlug()) * @return string */ public function getSlug(): string { - return $this->project->getNamespace()->getSlug(); - } - - /** - * Get the id of this project (shorthand for getData()->getId()) - * @return int - */ - public function getId(): int - { - return $this->project->getId(); + return $this->getNamespace()->getSlug(); } /** - * Get all versions of this project (paginated) + * Fetch all versions of this project (paginated) + * This sends a request to the Hangar API every time it is called. * @param string|null $channel * @param Platform|null $platform * @return ProjectVersionList * @throws ApiException */ - public function getVersions(?string $channel = null, ?Platform $platform = null): ProjectVersionList + public function fetchVersions(?string $channel = null, ?Platform $platform = null): ProjectVersionList { $options = new VersionSearchOptions($this->getId()); $options->setProject($this); @@ -69,90 +59,98 @@ public function getVersions(?string $channel = null, ?Platform $platform = null) } /** - * get a single version + * Fetch a single version + * This sends a request to the Hangar API every time it is called. * @param string $name * @return Version * @throws ApiException */ - public function getVersion(string $name): Version + public function fetchVersion(string $name): Version { return $this->client->getVersion($this, $name); } /** - * Get all watchers of this project (paginated) + * Fetch all watchers of this project (paginated) + * This sends a request to the Hangar API every time it is called. * @return UserList * @throws ApiException */ - public function getWatchers(): UserList + public function fetchWatchers(): UserList { return $this->client->getProjectWatchers($this->getId()); } /** - * Get a list of daily project stats + * Fetch a list of daily project stats * Days without downloads/views will not be included + * This sends a request to the Hangar API every time it is called. * @param DateTime|null $from default: project creation date * @param DateTime|null $to default: now * @return array * @throws ApiException */ - public function getDailyStats(?DateTime $from = null, ?DateTime $to = null): array + public function fetchDailyStats(?DateTime $from = null, ?DateTime $to = null): array { return $this->client->getDailyProjectStats( $this->getId(), - $from ?? $this->getData()->getCreatedAt(), + $from ?? $this->getCreatedAt(), $to ); } /** - * Get a list of users who starred this project (paginated) + * Fetch a list of users who starred this project (paginated) + * This sends a request to the Hangar API every time it is called. * @return UserList * @throws ApiException */ - public function getStarGazers(): UserList + public function fetchStarGazers(): UserList { return $this->client->getProjectStarGazers($this->getId()); } /** - * Get a list of users who are members of this project (paginated) + * Fetch a list of users who are members of this project (paginated) + * This sends a request to the Hangar API every time it is called. * @return ProjectMemberList * @throws ApiException */ - public function getMembers(): ProjectMemberList + public function fetchMembers(): ProjectMemberList { return $this->client->getProjectMembers($this->getId()); } /** - * Get the owner of this project + * Fetch the owner of this project + * This sends a request to the Hangar API every time it is called. * @return User * @throws ApiException */ - public function getOwner(): User + public function fetchOwner(): User { - return $this->client->getUser($this->project->getNamespace()->getOwner()); + return $this->client->getUser($this->getNamespace()->getOwner()); } /** - * Get the main page of this project + * Fetch the main page of this project + * This sends a request to the Hangar API every time it is called. * @return ProjectPage * @throws ApiException */ - public function getMainPage(): ProjectPage + public function fetchMainPage(): ProjectPage { return $this->client->getProjectMainPage($this->getId()); } /** - * Get a page of this project + * Fetch a page of this project + * This sends a request to the Hangar API every time it is called. * @param string $path * @return ProjectPage * @throws ApiException */ - public function getPage(string $path): ProjectPage + public function fetchPage(string $path): ProjectPage { return $this->client->getProjectPage($this->getId(), $path); } diff --git a/src/Client/ProjectPage.php b/src/Client/ProjectPage.php index 2cfba16..628a467 100644 --- a/src/Client/ProjectPage.php +++ b/src/Client/ProjectPage.php @@ -38,12 +38,12 @@ public function setContent(string $content): static } /** - * Get the project this page belongs to - * This method will make an API request if the project is not set + * Fetch the project this page belongs to + * This sends a request to the Hangar API only if the project is not known yet. * @return Project * @throws ApiException */ - public function getProject(): Project + public function fetchProject(): Project { return $this->project ??= $this->client->getProject($this->projectSlugOrId); } diff --git a/src/Client/User.php b/src/Client/User.php index 1cd4ca2..30afb8d 100644 --- a/src/Client/User.php +++ b/src/Client/User.php @@ -7,6 +7,7 @@ use Aternos\HangarApi\Client\List\CompactProject\WatchedProjectList; use Aternos\HangarApi\Client\List\ProjectList; use Aternos\HangarApi\Client\Options\ProjectSearch\ProjectSearchOptions; +use Aternos\HangarApi\Model\User as UserModel; /** * Class User @@ -14,64 +15,64 @@ * @package Aternos\HangarApi\Client * @description This class wraps a hangar user and allows you to fetch additional data. */ -class User +class User extends UserModel { + /** + * @param HangarAPIClient $client + * @param UserModel $data + */ public function __construct( protected HangarAPIClient $client, - protected \Aternos\HangarApi\Model\User $user, + UserModel $data, ) { + parent::__construct($data->container); } /** - * Get the user data - * @return \Aternos\HangarApi\Model\User - */ - public function getData(): \Aternos\HangarApi\Model\User - { - return $this->user; - } - - /** - * Get a list of projects this user is watching + * Fetch a list of projects this user is watching + * This sends a request to the Hangar API every time it is called. * @return WatchedProjectList * @throws ApiException */ - public function getWatchedProjects(): WatchedProjectList + public function fetchWatchedProjects(): WatchedProjectList { - return $this->client->getProjectsWatchedByUser($this->user->getId()); + return $this->client->getProjectsWatchedByUser($this->getId()); } /** - * Get a list of projects this user has starred + * Fetch a list of projects this user has starred + * This sends a request to the Hangar API every time it is called. * @return StarredProjectList * @throws ApiException */ - public function getStarredProjects(): StarredProjectList + public function fetchStarredProjects(): StarredProjectList { - return $this->client->getProjectsStarredByUser($this->user->getId()); + return $this->client->getProjectsStarredByUser($this->getId()); } /** - * Get a list of projects this user has pinned + * Fetch a list of projects this user has pinned + * This sends a request to the Hangar API every time it is called. * @return CompactProject[] * @throws ApiException */ - public function getPinnedProjects(): array + public function fetchPinnedProjects(): array { - return $this->client->getProjectsPinnedByUser($this->user->getId()); + return $this->client->getProjectsPinnedByUser($this->getId()); } /** - * Get a list of projects owned by the user + * Fetch a list of projects owned by the user * The projects are searched by the name of the user, see {@see ProjectSearchOptions::setOwner()} + * This sends a request to the Hangar API every time it is called. * @return ProjectList * @throws ApiException */ - public function getProjects(): ProjectList + public function fetchProjects(): ProjectList { $options = new ProjectSearchOptions(); - $options->setOwner($this->user->getName()); + $options->setOwner($this->getName()); return $this->client->getProjects($options); } } diff --git a/src/Client/Version.php b/src/Client/Version.php index 294f62a..e12c5c6 100644 --- a/src/Client/Version.php +++ b/src/Client/Version.php @@ -3,6 +3,7 @@ namespace Aternos\HangarApi\Client; use Aternos\HangarApi\ApiException; +use Aternos\HangarApi\Model\Version as VersionModel; use Aternos\HangarApi\Model\VersionStats; use DateTime; @@ -12,15 +13,22 @@ * @package Aternos\HangarApi\Client * @description This class wraps a version of a project on hangar and allows you to fetch additional data. */ -class Version +class Version extends VersionModel { + /** + * @param HangarAPIClient $client + * @param VersionModel $data + * @param string $projectSlugOrId slug or id of the project this version belongs to + * @param Project|null $project the project this version belongs to, if it is already known + */ public function __construct( - protected HangarAPIClient $client, - protected \Aternos\HangarApi\Model\Version $version, - protected string $projectSlugOrId, - protected ?Project $project = null, + protected HangarAPIClient $client, + VersionModel $data, + protected string $projectSlugOrId, + protected ?Project $project = null, ) { + parent::__construct($data->container); } /** @@ -33,11 +41,12 @@ public function getProjectSlugOrId(): string } /** - * Get the project this version belongs to + * Fetch the project this version belongs to + * This sends a request to the Hangar API only if the project is not known yet. * @return Project * @throws ApiException */ - public function getProject(): Project + public function fetchProject(): Project { if ($this->project) { return $this->project; @@ -47,27 +56,20 @@ public function getProject(): Project return $this->project; } - /** - * @return \Aternos\HangarApi\Model\Version - */ - public function getData(): \Aternos\HangarApi\Model\Version - { - return $this->version; - } - /** * Fetch a daily list of statistics for this version * Days without downloads/views are not be included + * This sends a request to the Hangar API every time it is called. * @param DateTime|null $from default: version creation date * @param DateTime|null $to default: now * @return array * @throws ApiException */ - public function getDailyStats(?DateTime $from = null, ?DateTime $to = null): array + public function fetchDailyStats(?DateTime $from = null, ?DateTime $to = null): array { return $this->client->getDailyVersionStatsById( - $this->getData()->getId(), - $from ?? $this->getData()->getCreatedAt(), + $this->getId(), + $from ?? $this->getCreatedAt(), $to ); } diff --git a/tests/Integration/Client/ClientTest.php b/tests/Integration/Client/ClientTest.php index 38d05b8..6605bfd 100644 --- a/tests/Integration/Client/ClientTest.php +++ b/tests/Integration/Client/ClientTest.php @@ -62,41 +62,39 @@ protected function assertValidNamespace($namespace): void protected function assertValidProject($project): void { $this->assertNotNull($project); - $this->assertNotNull($project->getData()); - $this->assertValidNamespace($project->getData()->getNamespace()); - $this->assertNotNull($project->getData()->getName()); - $this->assertNotNull($project->getData()->getStats()); - $this->assertNotNull($project->getData()->getStats()->getViews()); - $this->assertNotNull($project->getData()->getStats()->getDownloads()); - $this->assertNotNull($project->getData()->getStats()->getRecentViews()); - $this->assertNotNull($project->getData()->getStats()->getRecentDownloads()); - $this->assertNotNull($project->getData()->getStats()->getStars()); - $this->assertNotNull($project->getData()->getStats()->getWatchers()); - $this->assertNotNull($project->getData()->getCategory()); - $this->assertNotSame(Category::UNKNOWN_DEFAULT_OPEN_API, $project->getData()->getCategory()); - $this->assertNotNull($project->getData()->getLastUpdated()); - $this->assertNotNull($project->getData()->getVisibility()); - $this->assertNotNull($project->getData()->getDescription()); - $this->assertNotNull($project->getData()->getSettings()); + $this->assertValidNamespace($project->getNamespace()); + $this->assertNotNull($project->getName()); + $this->assertNotNull($project->getStats()); + $this->assertNotNull($project->getStats()->getViews()); + $this->assertNotNull($project->getStats()->getDownloads()); + $this->assertNotNull($project->getStats()->getRecentViews()); + $this->assertNotNull($project->getStats()->getRecentDownloads()); + $this->assertNotNull($project->getStats()->getStars()); + $this->assertNotNull($project->getStats()->getWatchers()); + $this->assertNotNull($project->getCategory()); + $this->assertNotSame(Category::UNKNOWN_DEFAULT_OPEN_API, $project->getCategory()); + $this->assertNotNull($project->getLastUpdated()); + $this->assertNotNull($project->getVisibility()); + $this->assertNotNull($project->getDescription()); + $this->assertNotNull($project->getSettings()); } protected function assertValidCompactProject($project): void { $this->assertNotNull($project); - $this->assertNotNull($project->getData()); - $this->assertValidNamespace($project->getData()->getNamespace()); - $this->assertNotNull($project->getData()->getName()); - $this->assertNotNull($project->getData()->getStats()); - $this->assertNotNull($project->getData()->getStats()->getViews()); - $this->assertNotNull($project->getData()->getStats()->getDownloads()); - $this->assertNotNull($project->getData()->getStats()->getRecentViews()); - $this->assertNotNull($project->getData()->getStats()->getRecentDownloads()); - $this->assertNotNull($project->getData()->getStats()->getStars()); - $this->assertNotNull($project->getData()->getStats()->getWatchers()); - $this->assertNotNull($project->getData()->getCategory()); - $this->assertNotSame(Category::UNKNOWN_DEFAULT_OPEN_API, $project->getData()->getCategory()); - $this->assertNotNull($project->getData()->getLastUpdated()); - $this->assertNotNull($project->getData()->getVisibility()); + $this->assertValidNamespace($project->getNamespace()); + $this->assertNotNull($project->getName()); + $this->assertNotNull($project->getStats()); + $this->assertNotNull($project->getStats()->getViews()); + $this->assertNotNull($project->getStats()->getDownloads()); + $this->assertNotNull($project->getStats()->getRecentViews()); + $this->assertNotNull($project->getStats()->getRecentDownloads()); + $this->assertNotNull($project->getStats()->getStars()); + $this->assertNotNull($project->getStats()->getWatchers()); + $this->assertNotNull($project->getCategory()); + $this->assertNotSame(Category::UNKNOWN_DEFAULT_OPEN_API, $project->getCategory()); + $this->assertNotNull($project->getLastUpdated()); + $this->assertNotNull($project->getVisibility()); } protected function assertValidResultList($list): void @@ -110,19 +108,19 @@ protected function assertValidResultList($list): void protected function isSameProject($a, $b): bool { - if (!$a?->getData()?->getNamespace()?->getOwner() || !$b?->getData()?->getNamespace()?->getOwner()) { + if (!$a?->getNamespace()?->getOwner() || !$b?->getNamespace()?->getOwner()) { return false; } - if (!$a?->getData()?->getNamespace()?->getSlug() || !$b?->getData()?->getNamespace()?->getSlug()) { + if (!$a?->getNamespace()?->getSlug() || !$b?->getNamespace()?->getSlug()) { return false; } - if ($a->getData()->getNamespace()->getOwner() !== $b->getData()->getNamespace()->getOwner()) { + if ($a->getNamespace()->getOwner() !== $b->getNamespace()->getOwner()) { return false; } - if ($a->getData()->getNamespace()->getSlug() !== $b->getData()->getNamespace()->getSlug()) { + if ($a->getNamespace()->getSlug() !== $b->getNamespace()->getSlug()) { return false; } @@ -186,7 +184,7 @@ public function testGetProjectsInCategory(): void foreach ($projectList as $project) { $this->assertValidProject($project); - $this->assertSame(Category::ADMIN_TOOLS, $project->getData()->getCategory()); + $this->assertSame(Category::ADMIN_TOOLS, $project->getCategory()); } $this->assertTrue($projectList->hasNextPage()); @@ -202,7 +200,7 @@ public function testGetProjectsInCategory(): void foreach ($projectList as $project) { $this->assertValidProject($project); - $this->assertSame(Category::ADMIN_TOOLS, $project->getData()->getCategory()); + $this->assertSame(Category::ADMIN_TOOLS, $project->getCategory()); } $this->assertTrue($projectList->hasNextPage()); } @@ -223,7 +221,7 @@ public function testGetProjectsByOwner(): void foreach ($projectList as $project) { $this->assertValidProject($project); - $this->assertEquals("Aternos", $project->getData()->getNamespace()->getOwner()); + $this->assertEquals("Aternos", $project->getNamespace()->getOwner()); } $this->assertEquals(2, $projectList->getPagination()->getCount()); @@ -248,7 +246,7 @@ public function testGetRecentlyUpdatedProjects(): void $lastUpdated = time(); foreach ($projectList as $project) { $this->assertValidProject($project); - $updated = $project->getData()->getLastUpdated()->getTimestamp(); + $updated = $project->getLastUpdated()->getTimestamp(); $this->assertLessThanOrEqual($lastUpdated, $updated); $lastUpdated = $updated; } @@ -270,7 +268,7 @@ public function testGetNotRecentlyUpdatedProjects(): void $lastUpdated = 0; foreach ($projectList as $project) { $this->assertValidProject($project); - $updated = $project->getData()->getLastUpdated()->getTimestamp(); + $updated = $project->getLastUpdated()->getTimestamp(); $this->assertGreaterThanOrEqual($lastUpdated, $updated); $lastUpdated = $updated; } @@ -339,15 +337,15 @@ public function testGetProject(): void $project = $this->apiClient->getProject("mclogs"); $this->assertNotNull($project); $this->assertValidProject($project); - $this->assertEquals("Aternos", $project->getData()->getNamespace()->getOwner()); + $this->assertEquals("Aternos", $project->getNamespace()->getOwner()); - $versions = $project->getVersions(); + $versions = $project->fetchVersions(); $this->assertNotNull($versions); $this->assertNotEmpty($versions); foreach ($versions as $version) { - $this->assertEquals($project, $version->getProject()); - $fetched = $project->getVersion($version->getData()->getName()); - $this->assertEquals($version->getData()->getName(), $fetched->getData()->getName()); + $this->assertEquals($project, $version->fetchProject()); + $fetched = $project->fetchVersion($version->getName()); + $this->assertEquals($version->getName(), $fetched->getName()); } } @@ -360,9 +358,9 @@ public function testGetProjectMembers(): void $project = $this->apiClient->getProject("motdgg"); $this->assertNotNull($project); $this->assertValidProject($project); - $this->assertEquals("Aternos", $project->getData()->getNamespace()->getOwner()); + $this->assertEquals("Aternos", $project->getNamespace()->getOwner()); - $members = $project->getMembers(); + $members = $project->fetchMembers(); $this->assertValidResultList($members); $this->assertNotEmpty(array_filter($members->getResults(), function ($member) { return $member->getUser() === "Aternos"; @@ -378,16 +376,16 @@ public function testGetProjectWatchers(): void $project = $this->apiClient->getProject("motdgg"); $this->assertNotNull($project); $this->assertValidProject($project); - $this->assertEquals("Aternos", $project->getData()->getNamespace()->getOwner()); + $this->assertEquals("Aternos", $project->getNamespace()->getOwner()); - $watchers = $project->getWatchers(); + $watchers = $project->fetchWatchers(); $this->assertValidResultList($watchers); $this->assertNotEmpty(array_filter($watchers->getResults(), function ($watcher) { - return $watcher->getData()->getName() === "Julian"; + return $watcher->getName() === "Julian"; })); foreach ($watchers as $watcher) { - $projects = $watcher->getWatchedProjects(); + $projects = $watcher->fetchWatchedProjects(); $this->assertValidResultList($projects); if ($projects->hasNextPage()) { @@ -417,7 +415,7 @@ public function testGetDailyProjectStats(): void $this->assertNotNull($project); $this->assertValidProject($project); - $stats = $project->getDailyStats(); + $stats = $project->fetchDailyStats(); $this->assertNotNull($stats); $this->assertNotEmpty($stats); @@ -444,12 +442,12 @@ public function testGetDailyProjectVersionStats(): void $this->assertNotNull($project); $this->assertValidProject($project); - $versions = $project->getVersions(); + $versions = $project->fetchVersions(); $this->assertValidResultList($versions); foreach ($versions as $version) { - foreach ($version->getData()->getStats()->getPlatformDownloads() as $downloads) { + foreach ($version->getStats()->getPlatformDownloads() as $downloads) { if ($downloads > 0) { - $stats = $version->getDailyStats(); + $stats = $version->fetchDailyStats(); $this->assertNotNull($stats); $this->assertNotEmpty($stats); @@ -481,8 +479,7 @@ public function testGetUsers(): void foreach ($users as $user) { $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertNotNull($user->getData()->getName()); + $this->assertNotNull($user->getName()); } $this->assertTrue($users->hasNextPage()); @@ -494,12 +491,11 @@ public function testGetUsers(): void $users = $users->getPreviousPage(); $this->assertValidResultList($users); - $this->assertEquals($firstUserOfPage[$i]->getData()->getName(), $users[0]->getData()->getName()); + $this->assertEquals($firstUserOfPage[$i]->getName(), $users[0]->getName()); foreach ($users as $user) { $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertNotNull($user->getData()->getName()); + $this->assertNotNull($user->getName()); } $this->assertTrue($users->hasNextPage()); } @@ -514,8 +510,7 @@ public function testGetUser(): void { $user = $this->apiClient->getUser("Aternos"); $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertEquals("Aternos", $user->getData()->getName()); + $this->assertEquals("Aternos", $user->getName()); } /** @@ -526,10 +521,9 @@ public function testGetProjectsWatchedByUser(): void { $user = $this->apiClient->getUser("Julian"); $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertEquals("Julian", $user->getData()->getName()); + $this->assertEquals("Julian", $user->getName()); - $watched = $user->getWatchedProjects(); + $watched = $user->fetchWatchedProjects(); $this->assertValidResultList($watched); foreach ($watched as $project) { @@ -545,10 +539,9 @@ public function testGetProjectsStarredByUser(): void { $user = $this->apiClient->getUser("Julian"); $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertEquals("Julian", $user->getData()->getName()); + $this->assertEquals("Julian", $user->getName()); - $starred = $user->getStarredProjects(); + $starred = $user->fetchStarredProjects(); $this->assertValidResultList($starred); foreach ($starred as $project) { @@ -568,7 +561,7 @@ public function testGetProjectsStarredByUserSortedByStarsKeepsSortOnNextPage(): $this->assertValidResultList($starred); foreach ($starred as $project) { $this->assertValidCompactProject($project); - $stars[] = $project->getData()->getStats()->getStars(); + $stars[] = $project->getStats()->getStars(); } $starred = $starred->getNextPage(); } @@ -616,15 +609,14 @@ public function testGetProjectsOfUser(): void { $user = $this->apiClient->getUser("Aternos"); $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertEquals("Aternos", $user->getData()->getName()); + $this->assertEquals("Aternos", $user->getName()); - $projects = $user->getProjects(); + $projects = $user->fetchProjects(); $this->assertValidResultList($projects); foreach ($projects as $project) { $this->assertValidProject($project); - $this->assertEquals("Aternos", $project->getData()->getNamespace()->getOwner()); + $this->assertEquals("Aternos", $project->getNamespace()->getOwner()); } $this->assertGreaterThanOrEqual(2, $projects->getPagination()->getCount()); @@ -646,8 +638,7 @@ public function testGetStaff(): void foreach ($users as $user) { $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertNotNull($user->getData()->getName()); + $this->assertNotNull($user->getName()); } $this->assertTrue($users->hasNextPage()); @@ -659,12 +650,11 @@ public function testGetStaff(): void $users = $users->getPreviousPage(); $this->assertValidResultList($users); - $this->assertEquals($firstUserOfPage[$i]->getData()->getName(), $users[0]->getData()->getName()); + $this->assertEquals($firstUserOfPage[$i]->getName(), $users[0]->getName()); foreach ($users as $user) { $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertNotNull($user->getData()->getName()); + $this->assertNotNull($user->getName()); } $this->assertTrue($users->hasNextPage()); } @@ -687,8 +677,7 @@ public function testGetAuthors(): void foreach ($users as $user) { $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertNotNull($user->getData()->getName()); + $this->assertNotNull($user->getName()); } $this->assertTrue($users->hasNextPage()); @@ -700,12 +689,11 @@ public function testGetAuthors(): void $users = $users->getPreviousPage(); $this->assertValidResultList($users); - $this->assertEquals($firstUserOfPage[$i]->getData()->getName(), $users[0]->getData()->getName()); + $this->assertEquals($firstUserOfPage[$i]->getName(), $users[0]->getName()); foreach ($users as $user) { $this->assertNotNull($user); - $this->assertNotNull($user->getData()); - $this->assertNotNull($user->getData()->getName()); + $this->assertNotNull($user->getName()); } $this->assertTrue($users->hasNextPage()); } @@ -771,7 +759,7 @@ public function testGetAuthorsSortedByNameKeepsSortOnNextPage(): void for ($i = 0; $i < 2; $i++) { $this->assertValidResultList($users); foreach ($users as $user) { - $names[] = $user->getData()->getName(); + $names[] = $user->getName(); } $users = $users->getNextPage(); } @@ -792,16 +780,16 @@ public function testGetProjectPage(): void $this->assertNotNull($page->getContent()); $this->assertNotEmpty($page->getContent()); $this->assertNotNull($page->getPath()); - $project = $page->getProject(); - $this->assertEquals($page->getContent(), $project->getMainPage()->getContent()); + $project = $page->fetchProject(); + $this->assertEquals($page->getContent(), $project->fetchMainPage()->getContent()); - $configPage = $project->getPage("Config"); + $configPage = $project->fetchPage("Config"); $this->assertNotNull($configPage); $this->assertNotNull($configPage->getContent()); $this->assertNotEmpty($configPage->getContent()); $this->assertNotNull($configPage->getPath()); - $this->assertEquals($configPage->getContent(), $project->getPage("Config")->getContent()); - $this->assertEquals($configPage->getContent(), $project->getPage("/Config")->getContent()); - $this->assertEquals($configPage->getContent(), $project->getPage("/Config/")->getContent()); + $this->assertEquals($configPage->getContent(), $project->fetchPage("Config")->getContent()); + $this->assertEquals($configPage->getContent(), $project->fetchPage("/Config")->getContent()); + $this->assertEquals($configPage->getContent(), $project->fetchPage("/Config/")->getContent()); } } diff --git a/tests/Unit/Client/CompactProjectTest.php b/tests/Unit/Client/CompactProjectTest.php index 0b45c0a..052f328 100644 --- a/tests/Unit/Client/CompactProjectTest.php +++ b/tests/Unit/Client/CompactProjectTest.php @@ -11,7 +11,7 @@ class CompactProjectTest extends ClientTestCase /** * @throws ApiException */ - public function testGetProject(): void + public function testFetchProject(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showStarred.json")), @@ -19,14 +19,14 @@ public function testGetProject(): void ]); $compactProject = $client->getProjectsStarredByUser("Aternos")[0]; - $this->assertInstanceOf(Project::class, $compactProject->getProject()); + $this->assertInstanceOf(Project::class, $compactProject->fetchProject()); $this->assertGetRequest("/projects/246", index: 1); } /** * @throws ApiException */ - public function testGetVersions(): void + public function testFetchVersions(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showStarred.json")), @@ -34,7 +34,7 @@ public function testGetVersions(): void ]); $project = $client->getProjectsStarredByUser("Aternos")[0]; - $versions = $project->getVersions("Release"); + $versions = $project->fetchVersions("Release"); $this->assertGetRequest("/projects/246/versions", ["channel" => "Release"], 1); $this->assertSame("246", $versions[0]->getProjectSlugOrId()); @@ -43,7 +43,7 @@ public function testGetVersions(): void /** * @throws ApiException */ - public function testGetVersion(): void + public function testFetchVersion(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showStarred.json")), @@ -51,7 +51,7 @@ public function testGetVersion(): void ]); $project = $client->getProjectsStarredByUser("Aternos")[0]; - $project->getVersion("3.3.4"); + $project->fetchVersion("3.3.4"); $this->assertGetRequest("/projects/246/versions/3.3.4", index: 1); } @@ -59,7 +59,7 @@ public function testGetVersion(): void /** * @throws ApiException */ - public function testGetWatchers(): void + public function testFetchWatchers(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showStarred.json")), @@ -67,14 +67,14 @@ public function testGetWatchers(): void ]); $project = $client->getProjectsStarredByUser("Aternos")[0]; - $this->assertCount(2, $project->getWatchers()); + $this->assertCount(2, $project->fetchWatchers()); $this->assertGetRequest("/projects/246/watchers", index: 1); } /** * @throws ApiException */ - public function testGetStarGazers(): void + public function testFetchStarGazers(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showStarred.json")), @@ -82,14 +82,14 @@ public function testGetStarGazers(): void ]); $project = $client->getProjectsStarredByUser("Aternos")[0]; - $this->assertCount(2, $project->getStarGazers()); + $this->assertCount(2, $project->fetchStarGazers()); $this->assertGetRequest("/projects/246/stargazers", index: 1); } /** * @throws ApiException */ - public function testGetMembers(): void + public function testFetchMembers(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showStarred.json")), @@ -97,14 +97,14 @@ public function testGetMembers(): void ]); $project = $client->getProjectsStarredByUser("Aternos")[0]; - $this->assertCount(1, $project->getMembers()); + $this->assertCount(1, $project->fetchMembers()); $this->assertGetRequest("/projects/246/members", index: 1); } /** * @throws ApiException */ - public function testGetOwner(): void + public function testFetchOwner(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showStarred.json")), @@ -112,7 +112,7 @@ public function testGetOwner(): void ]); $project = $client->getProjectsStarredByUser("Aternos")[0]; - $project->getOwner(); + $project->fetchOwner(); $this->assertGetRequest("/users/Aternos", index: 1); } @@ -120,7 +120,31 @@ public function testGetOwner(): void /** * @throws ApiException */ - public function testGetMainPage(): void + public function testFetchDailyStats(): void + { + $client = $this->createClient([ + new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getUserPinnedProjects.json")), + new Response(200, [], json_encode(["token" => "test-jwt", "expiresIn" => 3600])), + new Response(200, [], json_encode(["result" => true])), + new Response(200, [], json_encode(["2026-01-01" => ["downloads" => 3, "views" => 5]])), + ]); + $project = $client->getProjectsPinnedByUser("Aternos")[0]; + $client->setApiKey("test-api-key"); + + $stats = $project->fetchDailyStats(); + + $this->assertEquals("/api/v1/authenticate", $this->getRequest(1)->getUri()->getPath()); + $this->assertGetRequest("/permissions/hasAll", ["permissions" => "is_subject_member", "project" => "246"], 2); + $this->assertEquals("/api/v1/projects/246/stats", $this->getRequest(3)->getUri()->getPath()); + $this->assertSame("2023-04-05T09:53:36+00:00", $this->getQuery(3)["fromDate"]); + $this->assertArrayHasKey("toDate", $this->getQuery(3)); + $this->assertSame(3, $stats["2026-01-01"]->getDownloads()); + } + + /** + * @throws ApiException + */ + public function testFetchMainPage(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showStarred.json")), @@ -128,14 +152,14 @@ public function testGetMainPage(): void ]); $project = $client->getProjectsStarredByUser("Aternos")[0]; - $this->assertSame("# Main page", $project->getMainPage()->getContent()); + $this->assertSame("# Main page", $project->fetchMainPage()->getContent()); $this->assertGetRequest("/pages/main/246", index: 1); } /** * @throws ApiException */ - public function testGetPage(): void + public function testFetchPage(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showStarred.json")), @@ -143,7 +167,7 @@ public function testGetPage(): void ]); $project = $client->getProjectsStarredByUser("Aternos")[0]; - $this->assertSame("# Config", $project->getPage("config")->getContent()); + $this->assertSame("# Config", $project->fetchPage("config")->getContent()); $this->assertGetRequest("/pages/page/246", ["path" => "config"], 1); } } diff --git a/tests/Unit/Client/HangarAPIClientTest.php b/tests/Unit/Client/HangarAPIClientTest.php index 8c51a0c..035fca1 100644 --- a/tests/Unit/Client/HangarAPIClientTest.php +++ b/tests/Unit/Client/HangarAPIClientTest.php @@ -297,7 +297,7 @@ public function testGetVersion(): void $version = $client->getVersion("mclogs", "3.3.4"); $this->assertGetRequest("/projects/mclogs/versions/3.3.4"); - $this->assertSame(30673, $version->getData()->getId()); + $this->assertSame(30673, $version->getId()); $this->assertSame("mclogs", $version->getProjectSlugOrId()); } @@ -315,7 +315,7 @@ public function testGetVersionOfProjectUsesProjectId(): void $version = $client->getVersion($project, "3.3.4"); $this->assertGetRequest("/projects/246/versions/3.3.4", index: 1); - $this->assertSame($project, $version->getProject()); + $this->assertSame($project, $version->fetchProject()); $this->assertRequestCount(2); } @@ -329,7 +329,7 @@ public function testGetVersionById(): void $version = $client->getVersionById(30673); $this->assertGetRequest("/versions/30673"); - $this->assertSame("3.3.4", $version->getData()->getName()); + $this->assertSame("3.3.4", $version->getName()); } /** @@ -374,8 +374,8 @@ public function testGetUser(): void $user = $client->getUser("Aternos"); $this->assertGetRequest("/users/Aternos"); - $this->assertSame(196, $user->getData()->getId()); - $this->assertSame("Aternos", $user->getData()->getName()); + $this->assertSame(196, $user->getId()); + $this->assertSame("Aternos", $user->getName()); } /** diff --git a/tests/Unit/Client/ProjectPageTest.php b/tests/Unit/Client/ProjectPageTest.php new file mode 100644 index 0000000..8a970b5 --- /dev/null +++ b/tests/Unit/Client/ProjectPageTest.php @@ -0,0 +1,28 @@ +createClient([ + new Response(200, ["Content-Type" => "text/plain"], "# Main page"), + new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), + ]); + $page = $client->getProjectMainPage("mclogs"); + + $project = $page->fetchProject(); + + $this->assertGetRequest("/projects/mclogs", index: 1); + $this->assertSame("mclogs", $project->getSlug()); + $this->assertSame($project, $page->fetchProject()); + $this->assertCount(2, $this->requests); + } +} diff --git a/tests/Unit/Client/ProjectTest.php b/tests/Unit/Client/ProjectTest.php index 8bc5060..e3aa802 100644 --- a/tests/Unit/Client/ProjectTest.php +++ b/tests/Unit/Client/ProjectTest.php @@ -11,7 +11,7 @@ class ProjectTest extends ClientTestCase /** * @throws ApiException */ - public function testGetVersions(): void + public function testFetchVersions(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), @@ -19,16 +19,16 @@ public function testGetVersions(): void ]); $project = $client->getProject("mclogs"); - $versions = $project->getVersions("Release", Platform::PAPER); + $versions = $project->fetchVersions("Release", Platform::PAPER); $this->assertGetRequest("/projects/246/versions", ["channel" => "Release", "platform" => "PAPER"], 1); - $this->assertSame($project, $versions[0]->getProject()); + $this->assertSame($project, $versions[0]->fetchProject()); } /** * @throws ApiException */ - public function testGetVersion(): void + public function testFetchVersion(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), @@ -36,16 +36,16 @@ public function testGetVersion(): void ]); $project = $client->getProject("mclogs"); - $version = $project->getVersion("3.3.4"); + $version = $project->fetchVersion("3.3.4"); $this->assertGetRequest("/projects/246/versions/3.3.4", index: 1); - $this->assertSame("3.3.4", $version->getData()->getName()); + $this->assertSame("3.3.4", $version->getName()); } /** * @throws ApiException */ - public function testGetWatchers(): void + public function testFetchWatchers(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), @@ -53,14 +53,14 @@ public function testGetWatchers(): void ]); $project = $client->getProject("mclogs"); - $this->assertCount(2, $project->getWatchers()); + $this->assertCount(2, $project->fetchWatchers()); $this->assertGetRequest("/projects/246/watchers", index: 1); } /** * @throws ApiException */ - public function testGetStarGazers(): void + public function testFetchStarGazers(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), @@ -68,14 +68,14 @@ public function testGetStarGazers(): void ]); $project = $client->getProject("mclogs"); - $this->assertCount(2, $project->getStarGazers()); + $this->assertCount(2, $project->fetchStarGazers()); $this->assertGetRequest("/projects/246/stargazers", index: 1); } /** * @throws ApiException */ - public function testGetMembers(): void + public function testFetchMembers(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), @@ -83,14 +83,14 @@ public function testGetMembers(): void ]); $project = $client->getProject("mclogs"); - $this->assertCount(1, $project->getMembers()); + $this->assertCount(1, $project->fetchMembers()); $this->assertGetRequest("/projects/246/members", index: 1); } /** * @throws ApiException */ - public function testGetOwner(): void + public function testFetchOwner(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), @@ -98,14 +98,39 @@ public function testGetOwner(): void ]); $project = $client->getProject("mclogs"); - $this->assertSame("Aternos", $project->getOwner()->getData()->getName()); + $this->assertSame("Aternos", $project->fetchOwner()->getName()); $this->assertGetRequest("/users/Aternos", index: 1); } /** * @throws ApiException */ - public function testGetMainPage(): void + public function testFetchDailyStats(): void + { + $client = $this->createClient([ + new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), + new Response(200, [], json_encode(["token" => "test-jwt", "expiresIn" => 3600])), + new Response(200, [], json_encode(["result" => true])), + new Response(200, [], json_encode(["2026-01-01" => ["downloads" => 3, "views" => 5]])), + ]); + $project = $client->getProject("mclogs"); + $client->setApiKey("test-api-key"); + + $stats = $project->fetchDailyStats(); + + $this->assertEquals("/api/v1/authenticate", $this->getRequest(1)->getUri()->getPath()); + $this->assertGetRequest("/permissions/hasAll", ["permissions" => "is_subject_member", "project" => "246"], 2); + $this->assertEquals("/api/v1/projects/246/stats", $this->getRequest(3)->getUri()->getPath()); + $this->assertSame("2023-04-05T09:53:36+00:00", $this->getQuery(3)["fromDate"]); + $this->assertArrayHasKey("toDate", $this->getQuery(3)); + $this->assertSame(3, $stats["2026-01-01"]->getDownloads()); + $this->assertSame(5, $stats["2026-01-01"]->getViews()); + } + + /** + * @throws ApiException + */ + public function testFetchMainPage(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), @@ -113,14 +138,14 @@ public function testGetMainPage(): void ]); $project = $client->getProject("mclogs"); - $this->assertSame("# Main page", $project->getMainPage()->getContent()); + $this->assertSame("# Main page", $project->fetchMainPage()->getContent()); $this->assertGetRequest("/pages/main/246", index: 1); } /** * @throws ApiException */ - public function testGetPage(): void + public function testFetchPage(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), @@ -128,7 +153,7 @@ public function testGetPage(): void ]); $project = $client->getProject("mclogs"); - $this->assertSame("# Config", $project->getPage("config")->getContent()); + $this->assertSame("# Config", $project->fetchPage("config")->getContent()); $this->assertGetRequest("/pages/page/246", ["path" => "config"], 1); } } diff --git a/tests/Unit/Client/UserTest.php b/tests/Unit/Client/UserTest.php index 818b889..572390a 100644 --- a/tests/Unit/Client/UserTest.php +++ b/tests/Unit/Client/UserTest.php @@ -12,7 +12,7 @@ class UserTest extends ClientTestCase /** * @throws ApiException */ - public function testGetWatchedProjects(): void + public function testFetchWatchedProjects(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getUser.json")), @@ -20,7 +20,7 @@ public function testGetWatchedProjects(): void ]); $user = $client->getUser("Aternos"); - $projects = $user->getWatchedProjects(); + $projects = $user->fetchWatchedProjects(); $this->assertGetRequest("/users/196/watching", index: 1); $this->assertContainsOnlyInstancesOf(CompactProject::class, $projects->getResults()); @@ -29,7 +29,7 @@ public function testGetWatchedProjects(): void /** * @throws ApiException */ - public function testGetStarredProjects(): void + public function testFetchStarredProjects(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getUser.json")), @@ -37,7 +37,7 @@ public function testGetStarredProjects(): void ]); $user = $client->getUser("Aternos"); - $projects = $user->getStarredProjects(); + $projects = $user->fetchStarredProjects(); $this->assertGetRequest("/users/196/starred", index: 1); $this->assertContainsOnlyInstancesOf(CompactProject::class, $projects->getResults()); @@ -46,7 +46,7 @@ public function testGetStarredProjects(): void /** * @throws ApiException */ - public function testGetPinnedProjects(): void + public function testFetchPinnedProjects(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getUser.json")), @@ -54,7 +54,7 @@ public function testGetPinnedProjects(): void ]); $user = $client->getUser("Aternos"); - $projects = $user->getPinnedProjects(); + $projects = $user->fetchPinnedProjects(); $this->assertGetRequest("/users/196/pinned", index: 1); $this->assertContainsOnlyInstancesOf(CompactProject::class, $projects); @@ -63,7 +63,7 @@ public function testGetPinnedProjects(): void /** * @throws ApiException */ - public function testGetProjects(): void + public function testFetchProjects(): void { $client = $this->createClient([ new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getUser.json")), @@ -71,7 +71,7 @@ public function testGetProjects(): void ]); $user = $client->getUser("Aternos"); - $projects = $user->getProjects(); + $projects = $user->fetchProjects(); $this->assertGetRequest("/projects", ["owner" => "Aternos"], 1); $this->assertContainsOnlyInstancesOf(Project::class, $projects->getResults()); diff --git a/tests/Unit/Client/VersionTest.php b/tests/Unit/Client/VersionTest.php new file mode 100644 index 0000000..1965b8d --- /dev/null +++ b/tests/Unit/Client/VersionTest.php @@ -0,0 +1,47 @@ +createClient([ + new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showVersion.json")), + new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/getProject.json")), + ]); + $version = $client->getVersion("mclogs", "3.3.4"); + + $project = $version->fetchProject(); + + $this->assertGetRequest("/projects/mclogs", index: 1); + $this->assertSame("mclogs", $project->getSlug()); + $this->assertSame($project, $version->fetchProject()); + $this->assertCount(2, $this->requests); + } + + /** + * @throws ApiException + */ + public function testFetchDailyStats(): void + { + $client = $this->createClient([ + new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/showVersion.json")), + new Response(200, [], json_encode(["2026-01-01" => ["platformDownloads" => ["PAPER" => 2], "totalDownloads" => 2]])), + ]); + $version = $client->getVersion("mclogs", "3.3.4"); + + $stats = $version->fetchDailyStats(); + + $this->assertEquals("/api/v1/versions/30673/stats", $this->getRequest(1)->getUri()->getPath()); + $this->assertSame("2026-09-22T09:44:44+00:00", $this->getQuery(1)["fromDate"]); + $this->assertArrayHasKey("toDate", $this->getQuery(1)); + $this->assertSame(2, $stats["2026-01-01"]->getTotalDownloads()); + } +} diff --git a/tests/Unit/Client/WrapperTest.php b/tests/Unit/Client/WrapperTest.php new file mode 100644 index 0000000..648d00f --- /dev/null +++ b/tests/Unit/Client/WrapperTest.php @@ -0,0 +1,102 @@ + + */ + public static function wrapperProvider(): array + { + return [ + "Project" => [ + Project::class, + ProjectModel::class, + "getProject.json", + fn(HangarAPIClient $client) => $client->getProject("mclogs"), + ], + "CompactProject" => [ + CompactProject::class, + ProjectCompact::class, + "getUserPinnedProjects.json", + fn(HangarAPIClient $client) => $client->getProjectsPinnedByUser("Aternos")[0], + ], + "User" => [ + User::class, + UserModel::class, + "getUser.json", + fn(HangarAPIClient $client) => $client->getUser("Aternos"), + ], + "Version" => [ + Version::class, + VersionModel::class, + "showVersion.json", + fn(HangarAPIClient $client) => $client->getVersion("mclogs", "3.3.4"), + ], + ]; + } + + /** + * Create the generated model from the first entry of a fixture, the way the generated API does + * @param string $fixture + * @param class-string $modelClass + * @return object + */ + protected function createModel(string $fixture, string $modelClass): object + { + $data = json_decode(file_get_contents(__DIR__ . "/Fixtures/" . $fixture)); + return ObjectSerializer::deserialize(is_array($data) ? $data[0] : $data, $modelClass); + } + + /** + * @throws ApiException + */ + #[DataProvider("wrapperProvider")] + public function testWrapperExtendsModel(string $wrapperClass, string $modelClass, string $fixture, callable $fetch): void + { + $client = $this->createClient([new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/" . $fixture))]); + + $wrapper = $fetch($client); + + $this->assertInstanceOf($wrapperClass, $wrapper); + $this->assertInstanceOf($modelClass, $wrapper); + $this->assertFalse(method_exists($wrapper, "getData")); + $this->assertEquals($this->createModel($fixture, $modelClass)->getId(), $wrapper->getId()); + } + + /** + * @throws ApiException + */ + #[DataProvider("wrapperProvider")] + public function testWrapperIsSerializedLikeModel(string $wrapperClass, string $modelClass, string $fixture, callable $fetch): void + { + $client = $this->createClient([new Response(200, [], file_get_contents(__DIR__ . "/Fixtures/" . $fixture))]); + + $wrapper = $fetch($client); + + $this->assertJsonStringEqualsJsonString( + json_encode($this->createModel($fixture, $modelClass)), + json_encode($wrapper), + ); + $this->assertStringNotContainsString("client", json_encode($wrapper)); + } +}