LimitsTest.php 9.41 KB
<?php

namespace Tests\Unit;

use App\Models\Account;
use App\Models\Tokens;
use App\Models\User;
use App\Service\Contract\API;
use App\Service\HeaderLimits;
use App\Service\Limits;
use App\Service\Requests\DirectRequest;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Date;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class LimitsTest extends TestCase
{
    use RefreshDatabase;

    private $token;
    private $limitService;

    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->id
        ]);
        $this->limitService = Limits::getInstance($this->token);
    }

    public function testCurrentLimit()
    {
        $this->assertEquals($this->token->limit, $this->limitService->current());
    }

    public function testDayLimitException(){
        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 1
        ]));
        $this->expectException(ModelNotFoundException::class);
        $this->limitService->dayLimit();
    }

    public function testCurrentDayLimit()
    {
        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 0
        ]));
        $this->assertEquals($limit->day, $this->limitService->dayLimit());
        sleep(1);
        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 0
        ]));
        $this->assertEquals($limit->day, $this->limitService->dayLimit());
    }

    public function testRefreshCurrentLimit(){
        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 0,
            'updated_at' => Date::now()->subHours(24),
            'current' => 2,
            'day'   =>  48
        ]));

        $this->limitService->refreshCurrentLimit();
        $this->assertEquals($this->token->limit, 48);

        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 0,
            'updated_at' => Date::now()->subHours(3),
            'current' => 2,
            'day'   =>  48
        ]));

        $this->limitService->refreshCurrentLimit();
        $this->assertEquals($this->token->limit, 8);

        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 0,
            'updated_at' => Date::now()->subHours(1),
            'current' => 2,
            'day'   =>  48
        ]));

        $this->limitService->refreshCurrentLimit();
        $this->assertEquals($this->token->limit, 4);

        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 0,
            'current' => 0,
            'day'   =>  24
        ]));

        $this->limitService->refreshCurrentLimit();
        $this->assertEquals($this->token->limit, 1);

        //этот лимит не будет учтен, т.к. предыдущий позже
        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 0,
            'updated_at' => Date::now()->subHours(1),
            'current' => 2,
            'day'   =>  48
        ]));

        $this->limitService->refreshCurrentLimit();
        $this->assertEquals($this->token->limit, 1);
    }

    public function testCountObjectsLimit()
    {
        $request = \App\Service\Requests\APIRequest::getInstance(API::YANDEX)
        ->setToken($this->token);

        $request->setService('AdExtensions');
        $request->setMethod('add');

        $this->token->limit = 6;
        $objects = $this->limitService->countObjectsLimit($request);
//        Todo метод не описан, и нет максимального колл-во для загрузки, сейчас -1 без максимума
//        $this->assertEquals($objects, 1);
        $this->assertEquals($objects, -1);

        $this->token->limit = 12;
        $objects = $this->limitService->countObjectsLimit($request);
//        Todo метод не описан, и нет максимального колл-во для загрузки, сейчас -1 без максимума
//        $this->assertEquals($objects, 7);
        $this->assertEquals($objects, -1);


        $request->setService('Bids');
        $request->setMethod('get');

        $this->token->limit = 18;
        $objects = $this->limitService->countObjectsLimit($request);
//        Todo метод не описан, и нет максимального колл-во для загрузки, сейчас -1 без максимума
//        $this->assertEquals($objects, 2000);
        $this->assertEquals($objects, -1);

        $this->token->limit = 21;
        $objects = $this->limitService->countObjectsLimit($request);
//        Todo метод не описан, и нет максимального колл-во для загрузки, сейчас -1 без максимума
//        $this->assertEquals($objects, 4000);
        $this->assertEquals($objects, -1);


        Queue::fake();
        $requestCmpgn = $request->getRequest('Campaigns', 'get');
        $this->token->limit = 191;
        $this->token->save();

        $requestCmpgn->call();
        $objects = $this->limitService->countObjectsLimit($requestCmpgn);

        $this->limitService->doRezerv($requestCmpgn, $objects);

        $this->token->refresh();

        $this->assertEquals($this->token->limit, 181);


        $requestCmpgn = $request->getRequest('Campaigns', 'update');
        $this->token->limit = 191;
        $requestCmpgn->call([
            'dictionaryCampaigns'   =>  $this->token->dictionaryCampaignsEnabledForExternalUpdatedNeedUpdatedForNotReserveUpdate
        ]);
        $objects = $this->limitService->countObjectsLimit($requestCmpgn);
        $this->assertEquals($objects, 0);

        $requestCmpgn->setParams([
            'Campaigns'   =>  [1,2,3]
        ]);
        $objects = $this->limitService->countObjectsLimit($requestCmpgn);
        $this->assertEquals($objects, 3);
    }

    public function testDoRezervNoLimit()
    {
        $request = \App\Service\Requests\APIRequest::getInstance(API::YANDEX);
        $request->setService('AdExtensions');
        $request->setMethod('add');

        $rezerv = new \App\Models\Limits();
        $rezerv->token = $this->token->id;
        $rezerv->service = 'dsd';
        $rezerv->method = 'asdas';
        $rezerv->spent = 1;
        $rezerv->day = 0;
        $rezerv->current = $this->token->limit;
        $rezerv->reserved = 1;
        $rezerv->save();
        $this->token->refresh();
        //т.к. для первого вызова не будет происходить проверки баллов

        $this->expectException(\Exception::class);
        $this->limitService->doRezerv($request, $this->token->limit);
    }

    public function testDoRezerv()
    {
        $request = \App\Service\Requests\APIRequest::getInstance(API::YANDEX);
        $request->setService('AdExtensions');
        $request->setMethod('add');

        $this->token->limit = 10;
        $objects = $this->token->limit-5;
        $last = $this->token->limit;
        $id = $this->limitService->doRezerv($request, $objects);
        $this->assertEquals($this->token->limit, 0);

        $limit = \App\Models\Limits::find($id);
        $this->assertEquals($limit->spent, $last);
        $this->assertEquals(1, $limit->reserved);
        $this->assertEquals($last, $limit->current);
    }

    public function testRemoveRezerv()
    {
        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 1,
            'spent' =>  10
        ]));
        $spent = $this->token->limit;
        $this->limitService->removeRezerv($limit->id);
        $this->assertEquals($this->token->limit, $spent+10);
        $this->expectException(ModelNotFoundException::class);
        $this->limitService->dayLimit();
    }

    public function testAcceptRezerv(){
        $limit = $this->token->limits()->save(factory(\App\Models\Limits::class)->make([
            'reserved' => 1,
            'spent' =>  10
        ]));
        $this->limitService->acceptRezerv(
            $limit->id,
            new HeaderLimits(['Units' => ["1/2/3"]])
        );

        $this->assertEquals($this->token->limit, 2);
        $limit = \App\Models\Limits::find($limit->id);
        $this->assertEquals($limit->spent, 1);
        $this->assertEquals($limit->current, 2);
        $this->assertEquals($limit->day, 3);
        $this->assertEquals($limit->reserved, 0);
    }

    public function testUpdateLimits(){
        $this->limitService->updateLimits(
            new HeaderLimits(['Units' => ["1/2/3"]])
        );

        $this->assertEquals($this->token->limit, 2);
        $limit = $this->token->limits()->complited()->firstOrFail();
        $this->assertEquals($limit->spent, 1);
        $this->assertEquals($limit->current, 2);
        $this->assertEquals($limit->day, 3);
        $this->assertEquals($limit->reserved, 0);
    }
}