Http::response(['result' => ['AddResults' => [['Id' => 777]]]], 200), ]); $client = new YandexDirectClient('https://api-sandbox.direct.yandex.com', 'TESTTOKEN'); $id = $client->addCpmBannerCampaign( 'Лидерра медийная #1', '2026-07-26', '2026-08-26', 50_000_000, 1_000_000_000, 3, 7, ); expect($id)->toBe(777); Http::assertSent(function ($req) { $body = $req->data(); $campaign = $body['params']['Campaigns'][0]; $strategy = $campaign['CpmBannerCampaign']['BiddingStrategy']; $cpMax = $strategy['Network']['CpMaximumImpressions']; $freq = $campaign['CpmBannerCampaign']['FrequencyCap']; return $body['method'] === 'add' && $campaign['Name'] === 'Лидерра медийная #1' && $campaign['StartDate'] === '2026-07-26' && $campaign['EndDate'] === '2026-08-26' && $strategy['Search']['BiddingStrategyType'] === 'SERVING_OFF' && $strategy['Network']['BiddingStrategyType'] === 'CP_MAXIMUM_IMPRESSIONS' && $cpMax['AverageCpm'] === 50_000_000 && $cpMax['SpendLimit'] === 1_000_000_000 && $cpMax['StartDate'] === '2026-07-26' && $cpMax['EndDate'] === '2026-08-26' && $cpMax['AutoContinue'] === 'NO' && $freq['Impressions'] === 3 && $freq['PeriodDays'] === 7; }); }); it('sends auto continue yes when requested for the cpm banner campaign', function () { Http::fake([ '*/json/v5/campaigns' => Http::response(['result' => ['AddResults' => [['Id' => 778]]]], 200), ]); $client = new YandexDirectClient('https://api-sandbox.direct.yandex.com', 'TESTTOKEN'); $client->addCpmBannerCampaign( 'Лидерра медийная #2', '2026-07-26', '2026-08-26', 50_000_000, 1_000_000_000, 3, 7, 'YES', ); Http::assertSent(function ($req) { $body = $req->data(); return $body['params']['Campaigns'][0]['CpmBannerCampaign']['BiddingStrategy']['Network']['CpMaximumImpressions']['AutoContinue'] === 'YES'; }); }); it('adds an empty cpm banner ad group with an empty keywords object', function () { Http::fake([ '*/json/v5/adgroups' => Http::response(['result' => ['AddResults' => [['Id' => 555]]]], 200), ]); $client = new YandexDirectClient('https://api-sandbox.direct.yandex.com', 'TESTTOKEN'); $id = $client->addCpmBannerAdGroup(777, 'Группа медийная', [1, 213]); expect($id)->toBe(555); Http::assertSent(function ($req) { $body = $req->data(); $group = $body['params']['AdGroups'][0]; $matches = $body['method'] === 'add' && $group['Name'] === 'Группа медийная' && $group['CampaignId'] === 777 && $group['RegionIds'] === [1, 213]; // Пустой JSON-объект {}, а не массив [] $decoded = json_decode($req->body()); $matches = $matches && $decoded->params->AdGroups[0]->CpmBannerKeywordsAdGroup instanceof stdClass; return $matches && str_contains($req->body(), '"CpmBannerKeywordsAdGroup":{}'); }); }); it('adds a media audience target without a context bid', function () { Http::fake([ '*/json/v5/audiencetargets' => Http::response(['result' => ['AddResults' => [['Id' => 999]]]], 200), ]); $client = new YandexDirectClient('https://api-sandbox.direct.yandex.com', 'TESTTOKEN'); $id = $client->addMediaAudienceTarget(555, 58034825); expect($id)->toBe(999); Http::assertSent(function ($req) { $body = $req->data(); $target = $body['params']['AudienceTargets'][0]; return $body['method'] === 'add' && $target['AdGroupId'] === 555 && $target['RetargetingListId'] === 58034825 && ! array_key_exists('ContextBid', $target); }); }); it('adds a cpm banner ad by creative id', function () { Http::fake([ '*/json/v5/ads' => Http::response(['result' => ['AddResults' => [['Id' => 111]]]], 200), ]); $client = new YandexDirectClient('https://api-sandbox.direct.yandex.com', 'TESTTOKEN'); $id = $client->addCpmBannerAd(555, 4242, 'https://liderra.ru/promo'); expect($id)->toBe(111); Http::assertSent(function ($req) { $body = $req->data(); $ad = $body['params']['Ads'][0]; return $body['method'] === 'add' && $ad['AdGroupId'] === 555 && $ad['CpmBannerAdBuilderAd']['Creative']['CreativeId'] === 4242 && $ad['CpmBannerAdBuilderAd']['Href'] === 'https://liderra.ru/promo'; }); }); it('parses a creative preview into an array with is_adaptive true when YES', function () { Http::fake([ '*/json/v5/creatives' => Http::response(['result' => ['Creatives' => [[ 'Id' => 4242, 'Type' => 'HTML5_CREATIVE', 'PreviewUrl' => 'https://yastatic.net/preview/4242', 'ThumbnailUrl' => 'https://yastatic.net/thumb/4242', 'IsAdaptive' => 'YES', 'Width' => 300, 'Height' => 250, ]]]], 200), ]); $client = new YandexDirectClient('https://api-sandbox.direct.yandex.com', 'TESTTOKEN'); $preview = $client->getCreativePreview(4242); expect($preview)->toBe([ 'id' => 4242, 'type' => 'HTML5_CREATIVE', 'preview_url' => 'https://yastatic.net/preview/4242', 'thumbnail_url' => 'https://yastatic.net/thumb/4242', 'is_adaptive' => true, 'width' => 300, 'height' => 250, ]); Http::assertSent(function ($req) { $body = $req->data(); return $body['method'] === 'get' && $body['params']['SelectionCriteria']['Ids'] === [4242] && $body['params']['FieldNames'] === ['Id', 'Type', 'PreviewUrl', 'ThumbnailUrl', 'IsAdaptive', 'Width', 'Height']; }); }); it('returns null from creative preview when the creative is not found', function () { Http::fake([ '*/json/v5/creatives' => Http::response(['result' => ['Creatives' => []]], 200), ]); $client = new YandexDirectClient('https://api-sandbox.direct.yandex.com', 'TESTTOKEN'); $preview = $client->getCreativePreview(9999); expect($preview)->toBeNull(); });