KeywordsTest.php 8.24 KB
<?php

namespace Tests\Unit;

use App\Jobs\ProcessCallLimitedAPI;
use App\Models\Account;
use App\Models\AdGroup;
use App\Models\Campaigns;
use App\Models\Dictionary;
use App\Models\Keyword;
use App\Models\Pivots\GoalKeyword;
use App\Models\Tokens;
use App\Models\User;
use App\Service\Contract\API;
use App\Service\Requests\APIRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class KeywordsTest extends TestCase
{
    use RefreshDatabase;

    private $request;
    private $user;
    private $token_main;
    private $token;
    private $campaign;
    private $groups;
    private $dictionary;
    private $dicCampaign;

    protected function setUp(): void
    {
        parent::setUp();

        $account = Account::create(['name' => 'Acme Corporation']);

        $this->user = factory(User::class)->create([
            'account_id' => $account->id,
            'first_name' => 'John',
            'last_name' => 'Doe',
            'email' => 'johndoe@example.com',
            'owner' => true,
        ]);

        $this->token = factory(Tokens::class)->create([
            'created_by' => $this->user->getKey()
        ]);

        $this->token_main = factory(Tokens::class)->create([
            'type' => Tokens::MAIN,
            'created_by' => $this->user->id,
        ]);

        $this->campaign = factory(Campaigns::class)->create([
            'external_id' => 1,
            'manage' => true,
            'token' => $this->token_main->getKey(),
        ]);

        $this->dictionary = factory(Dictionary::class)->create([
            'region_id' => 1,
            'type' => Dictionary::CITY,
        ]);

        $this->actingAs($this->user)
            ->post(route('token.city.store', [
                $this->token->id,
                $this->dictionary->getKey(),
            ]))
            ->assertStatus(302);

        $this->dicCampaign = $this->campaign->dictionaryCampaigns()->first();
        $this->dicCampaign->external_id = 12;
        $this->dicCampaign->save();

        //группы
        $this->groups = factory(AdGroup::class)->create([
            'external_id' => 1,
            'campaign_id' => $this->campaign->getKey(),
            'campaign_external_id' => $this->campaign->external_id,
        ]);

        $connection = config('database.default');
        $now = $connection=='sqlite'? DB::raw("strftime('%Y-%m-%d %H:%M:%S', datetime('now'))") : DB::raw('now()');
        AdGroup::where('external_id', 1)->update(['keywords_loaded_at'   =>  $now]);

        //целевые группы
        $this->goalGroups = $this->groups->goalGroups()->create([
            'external_id' => 2,
            'dictionary_campaign_external_id' => $this->dicCampaign->external_id,
            'ad_group_id' => $this->groups->id,
            'dictionary_campaign_id' => $this->dicCampaign->id,
            'name' => $this->groups->name,
            'negative_keywords' => $this->groups->negative_keywords
        ]);

        //ключи
        for($i=1; $i<11; $i++){
            $this->groups->keywords()->create(
                factory(Keyword::class)->make([
                    'campaign_id' => $this->campaign->getKey(),
                    'external_id' => $i,
                    'campaign_external_id' => $this->campaign->external_id,
                    'ad_group_external_id' => $this->groups->external_id,
                ])->toArray()
            );
        }

        //целевые ключи
        foreach ($this->groups->keywords as $keyword){
            $keyword->goalKeywords()->create([
                'external_id'   =>  "101" . $keyword->external_id,
                'dictionary_campaign_external_id'   =>  $this->dicCampaign->external_id,
                'goal_ad_group_external_id'   =>  $this->goalGroups->external_id,
                'dictionary_campaign_id'   =>  $this->dicCampaign->id,
                'goal_ad_group_id'   =>  $this->goalGroups->id,
                'keyword_id'   =>  $keyword->id,
            ]);
        }
    }

    public function testCallApi()
    {
        Queue::fake();

        $request = APIRequest::getInstance(API::YANDEX)
            ->setToken($this->token_main)
            ->getRequest('Keywords', 'get');

        Queue::assertNothingPushed();
        $ids_limit = [1,2,3];
        $request->call(['AdGroupIds' => $ids_limit]);
        Queue::assertPushed(ProcessCallLimitedAPI::class);
    }

    public function testHandleApi()
    {
        Queue::fake();
        $request = APIRequest::getInstance(API::YANDEX)
            ->setToken($this->token_main)
            ->getRequest('Keywords', 'get');

        $ids_limit = [1];
        $request->call(['AdGroupIds' => $ids_limit]);
        Queue::assertPushed(ProcessCallLimitedAPI::class);

        sleep(2);
        //генерим новые 10 - слов
        $keywords = factory(Keyword::class, 10)->make([
            'campaign_id' => $this->campaign->getKey(),
            'campaign_external_id' => $this->campaign->external_id,
            'ad_group_external_id' => $this->groups->external_id,
        ]);

        $data = [
            'result' => [
                'Keywords' => [
                ]
            ]
        ];

        //добавляем новые слова
        foreach ($keywords as $k=>$keyword){
            $data['result']['Keywords'][] = [
                'Id'    =>  $k+100,
                'AdGroupId' =>  $keyword->ad_group_external_id,
                'Keyword' =>  $keyword->keyword,
                'UserParam1' =>  null,
                'UserParam2' =>  null,
                'Bid' =>  $keyword->bid,
                'ContextBid' =>  $keyword->context_bid,
                'StrategyPriority' =>  $keyword->strategy_priority,
                'State' =>  $keyword->state,
                'Status' => $keyword->status,
                'ServingStatus' =>  $keyword->serving_status,
            ];
        }

        //добавляем существующие. Из них 3 оставим как есть, 3 изменим, а 4 удалим
        foreach ($this->groups->keywords as $k=>$keyword){
            if ($k<4){
                continue;//удаляем
            }
            if ($k<7){//оставляем как есть
                $data['result']['Keywords'][] = [
                    'Id'    =>  $keyword->external_id,
                    'AdGroupId' =>  $keyword->ad_group_external_id,
                    'Keyword' =>  $keyword->keyword,
                    'UserParam1' =>  null,
                    'UserParam2' =>  null,
                    'Bid' =>  $keyword->bid,
                    'ContextBid' =>  $keyword->context_bid,
                    'StrategyPriority' =>  $keyword->strategy_priority,
                    'State' =>  $keyword->state,
                    'Status' => $keyword->status,
                    'ServingStatus' =>  $keyword->serving_status,
                ];
                continue;
            }
            //остальные меняем
            $data['result']['Keywords'][] = [
                'Id'    =>  $keyword->external_id,
                'AdGroupId' =>  $keyword->ad_group_external_id,
                'Keyword' =>  $keyword->keyword . ' change',
                'UserParam1' =>  null,
                'UserParam2' =>  null,
                'Bid' =>  $keyword->bid,
                'ContextBid' =>  $keyword->context_bid,
                'StrategyPriority' =>  $keyword->strategy_priority,
                'State' =>  $keyword->state,
                'Status' => $keyword->status,
                'ServingStatus' =>  $keyword->serving_status,
            ];
        }

        $request->handle($data);

        $this->groups->refresh();
        $this->goalGroups->refresh();
        //в результате у нас должно стать 20 фраз
        //из них 10 новых
        $this->assertCount( 20, $this->groups->keywords()->withTrashed()->get());
        //3 помечены на изменение
        $this->assertCount( 3, $this->goalGroups->goalKeywords()->whereNotNull('updated_need')->get());
        //20 - 4 на удаление = 16
        $this->assertCount( 16, $this->groups->keywords);

        $goalKeywords = GoalKeyword::getForUpdate($this->token);
        $this->assertCount( 3, $goalKeywords);
    }
}