PHP code example of viewtrender / php-youtube-testkit-core

1. Go to this page and download the library: Download viewtrender/php-youtube-testkit-core library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

viewtrender / php-youtube-testkit-core example snippets




namespace Tests\Unit;

use PHPUnit\Framework\TestCase;
use Viewtrender\Youtube\YoutubeDataApi;
use Viewtrender\Youtube\Factories\YoutubeVideo;

class VideoServiceTest extends TestCase
{
    protected function tearDown(): void
    {
        YoutubeDataApi::reset();
        parent::tearDown();
    }

    public function test_it_fetches_video_details(): void
    {
        YoutubeDataApi::fake([
            YoutubeVideo::listWithVideos([
                [
                    'id' => 'dQw4w9WgXcQ',
                    'snippet' => [
                        'title' => 'Never Gonna Give You Up',
                        'channelTitle' => 'Rick Astley',
                    ],
                    'statistics' => [
                        'viewCount' => '1500000000',
                        'likeCount' => '15000000',
                    ],
                ],
            ]),
        ]);

        $youtube = YoutubeDataApi::youtube();
        $response = $youtube->videos->listVideos('snippet,statistics', ['id' => 'dQw4w9WgXcQ']);

        $video = $response->getItems()[0];
        $this->assertSame('Never Gonna Give You Up', $video->getSnippet()->getTitle());
        $this->assertSame('1500000000', $video->getStatistics()->getViewCount());

        YoutubeDataApi::assertListedVideos();
        YoutubeDataApi::assertSentCount(1);
    }
}



namespace Tests\Unit;

use PHPUnit\Framework\TestCase;
use Viewtrender\Youtube\YoutubeAnalyticsApi;
use Viewtrender\Youtube\Factories\AnalyticsQueryResponse;

class ChannelAnalyticsTest extends TestCase
{
    protected function tearDown(): void
    {
        YoutubeAnalyticsApi::reset();
        parent::tearDown();
    }

    public function test_it_fetches_channel_overview_metrics(): void
    {
        YoutubeAnalyticsApi::fake([
            AnalyticsQueryResponse::channelOverview([
                'views' => 500000,
                'estimatedMinutesWatched' => 1500000,
                'subscribersGained' => 1000,
            ]),
        ]);

        $analytics = YoutubeAnalyticsApi::youtubeAnalytics();
        $response = $analytics->reports->query([
            'ids' => 'channel==MINE',
            'startDate' => '2024-01-01',
            'endDate' => '2024-01-31',
            'metrics' => 'views,estimatedMinutesWatched,subscribersGained',
        ]);

        $row = $response->getRows()[0];
        $this->assertSame(500000, $row[0]);
        $this->assertSame(1500000, $row[1]);
        $this->assertSame(1000, $row[2]);

        YoutubeAnalyticsApi::assertSentCount(1);
    }
}



namespace Tests\Unit;

use PHPUnit\Framework\TestCase;
use Viewtrender\Youtube\YoutubeReportingApi;
use Viewtrender\Youtube\Factories\ReportingJob;
use Viewtrender\Youtube\Factories\ReportingReport;
use Viewtrender\Youtube\Factories\ReportingMedia;

class ReportingPipelineTest extends TestCase
{
    protected function tearDown(): void
    {
        YoutubeReportingApi::reset();
        parent::tearDown();
    }

    public function test_it_lists_reporting_jobs(): void
    {
        YoutubeReportingApi::fake([
            ReportingJob::list([
                ['id' => 'job-1', 'reportTypeId' => 'channel_basic_a2', 'name' => 'Daily Stats'],
                ['id' => 'job-2', 'reportTypeId' => 'channel_demographics_a1', 'name' => 'Demographics'],
            ]),
        ]);

        $reporting = YoutubeReportingApi::youtubeReporting();
        $response = $reporting->jobs->listJobs();

        $this->assertCount(2, $response->getJobs());
        $this->assertSame('channel_basic_a2', $response->getJobs()[0]->getReportTypeId());

        YoutubeReportingApi::assertSentCount(1);
    }

    public function test_it_downloads_report_csv(): void
    {
        $csvContent = "date,channel_id,views,watch_time_minutes\n" .
                      "2024-01-01,UC123,1000,5000\n" .
                      "2024-01-02,UC123,1200,6000\n";

        YoutubeReportingApi::fake([
            ReportingMedia::download($csvContent),
        ]);

        $reporting = YoutubeReportingApi::youtubeReporting();
        $response = $reporting->media->download('resource-name');

        $this->assertStringContainsString('views,watch_time_minutes', $response->getBody()->getContents());

        YoutubeReportingApi::assertSentCount(1);
    }
}

use Viewtrender\Youtube\YoutubeDataApi;
use Viewtrender\Youtube\Factories\YoutubeVideo;
use Viewtrender\Youtube\Factories\YoutubeChannel;

YoutubeDataApi::fake([
    YoutubeVideo::list(),      // first request
    YoutubeChannel::list(),    // second request
]);

YoutubeVideo::listWithVideos([
    [
        'id' => 'abc123',
        'snippet' => ['title' => 'My Custom Title'],
        'statistics' => ['viewCount' => '999'],
    ],
]);

YoutubeDataApi::assertListedVideos();
YoutubeDataApi::assertListedChannels();
YoutubeDataApi::assertListedPlaylists();
YoutubeDataApi::assertSearched();
YoutubeDataApi::assertSentCount(2);
YoutubeDataApi::assertNothingSent();

use Viewtrender\Youtube\Factories\YoutubePlaylistItems;

// Generate 3 pages with 5 items each
YoutubeDataApi::fake([
    ...YoutubePlaylistItems::paginated(pages: 3, perPage: 5),
]);

// Test pagination logic
$youtube = YoutubeDataApi::youtube();
$pageToken = null;
$allItems = [];

do {
    $response = $youtube->playlistItems->listPlaylistItems(
        'snippet',
        ['playlistId' => 'PLxxx', 'pageToken' => $pageToken]
    );
    $allItems = array_merge($allItems, $response->getItems());
    $pageToken = $response->getNextPageToken();
} while ($pageToken !== null);

$this->assertCount(15, $allItems);

use Viewtrender\Youtube\Factories\YoutubePlaylistItems;

// Using raw arrays (merged with fixture defaults)
YoutubeDataApi::fake([
    ...YoutubePlaylistItems::pages([
        // Page 1 — vid2']]],
        ],
        // Page 2 — last page, no nextPageToken
        [
            ['snippet' => ['title' => 'Third Video', 'resourceId' => ['videoId' => 'vid3']]],
        ],
    ]),
]);

// Using named constructors
YoutubeDataApi::fake([
    ...YoutubeActivities::pages([
        [
            YoutubeActivities::activity([
                'snippet' => ['title' => 'Uploaded: New Video', 'type' => 'upload'],
                'contentDetails' => ['upload' => ['videoId' => 'vid1']],
            ]),
        ],
        [
            YoutubeActivities::activity([
                'snippet' => ['title' => 'Liked: Some Video', 'type' => 'like'],
            ]),
        ],
    ]),
]);

use Viewtrender\Youtube\YoutubeAnalyticsApi;
use Viewtrender\Youtube\Factories\AnalyticsQueryResponse;

YoutubeAnalyticsApi::fake([
    AnalyticsQueryResponse::dailyMetrics([
        ['day' => '2024-01-01', 'views' => 1000],
        ['day' => '2024-01-02', 'views' => 1200],
    ]),
]);

AnalyticsQueryResponse::channelOverview([
    'views' => 500000,
    'estimatedMinutesWatched' => 1500000,
    'averageViewDuration' => 180,
    'subscribersGained' => 1000,
    'subscribersLost' => 50,
]);

AnalyticsQueryResponse::trafficSources([
    ['source' => 'RELATED_VIDEO', 'views' => 500000],
    ['source' => 'YT_SEARCH', 'views' => 300000],
    ['source' => 'EXT_URL', 'views' => 100000],
]);

AnalyticsQueryResponse::demographics([
    ['ageGroup' => 'age18-24', 'gender' => 'male', 'viewerPercentage' => 25.5],
    ['ageGroup' => 'age25-34', 'gender' => 'female', 'viewerPercentage' => 18.2],
]);

AnalyticsQueryResponse::videoTypes([
    ['video' => 'abc123', 'creatorContentType' => 'VIDEO_ON_DEMAND', 'views' => 180000],
    ['video' => 'def456', 'creatorContentType' => 'SHORTS', 'views' => 120000],
    ['video' => 'ghi789', 'creatorContentType' => 'LIVE_STREAM', 'views' => 50000],
]);

use Viewtrender\Youtube\YoutubeReportingApi;
use Viewtrender\Youtube\Factories\ReportingJob;
use Viewtrender\Youtube\Factories\ReportingReport;
use Viewtrender\Youtube\Factories\ReportingReportType;
use Viewtrender\Youtube\Factories\ReportingMedia;

YoutubeReportingApi::fake([
    ReportingJob::create(['id' => 'job-123', 'reportTypeId' => 'channel_basic_a2']),
]);

ReportingJob::create([
    'id' => 'job-123',
    'reportTypeId' => 'channel_basic_a2',
    'name' => 'My Channel Report',
]);

ReportingJob::list([
    ['id' => 'job-1', 'reportTypeId' => 'channel_basic_a2', 'name' => 'Job 1'],
    ['id' => 'job-2', 'reportTypeId' => 'channel_demographics_a1', 'name' => 'Job 2'],
]);

ReportingReport::list([
    [
        'id' => 'report-1',
        'jobId' => 'job-123',
        'startTime' => '2024-01-01T00:00:00Z',
        'endTime' => '2024-01-02T00:00:00Z',
        'downloadUrl' => 'https://youtube.com/reporting/v1/media/report-1',
    ],
]);

$csv = "date,channel_id,views,watch_time_minutes\n" .
       "2024-01-01,UC123,1000,5000\n";

ReportingMedia::download($csv);

use Viewtrender\Youtube\Responses\ErrorResponse;

YoutubeDataApi::fake([
    ErrorResponse::notFound('Video not found.'),
    ErrorResponse::quotaExceeded('Daily quota exhausted.'),
    ErrorResponse::forbidden(),
    ErrorResponse::unauthorized(),
    ErrorResponse::badRequest(),
]);

use Viewtrender\Youtube\Responses\FakeResponse;

FakeResponse::make(['kind' => 'youtube#videoListResponse', 'items' => []]);
FakeResponse::fromFixture('youtube/videos-list.json');
FakeResponse::make(['error' => 'bad'])->status(400);

$fake = YoutubeDataApi::fake([YoutubeVideo::list()]);
$fake->preventStrayRequests();

YoutubeDataApi::registerContainerSwap(function () {
    $container->set(YouTube::class, new YouTube(YoutubeDataApi::client()));
});