CrudTest::setUp()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SergeyNezbritskiy\NovaPoshta\Tests\Integration\Models\ContactPerson;
6
7
use Exception;
8
use PHPUnit\Framework\TestCase;
9
use SergeyNezbritskiy\NovaPoshta\Models\ContactPerson;
10
use SergeyNezbritskiy\NovaPoshta\Models\Counterparty;
11
use SergeyNezbritskiy\NovaPoshta\NovaPoshtaApiException;
12
use SergeyNezbritskiy\NovaPoshta\Tests\UsesConnectionTrait;
13
14
use function count;
15
16
class CrudTest extends TestCase
17
{
18
    use UsesConnectionTrait;
19
20
    private ContactPerson $model;
21
    private Counterparty $counterpartyModel;
22
23
    protected function setUp(): void
24
    {
25
        $connection = $this->getConnection();
26
        $this->model = new ContactPerson($connection);
27
        $this->counterpartyModel = new Counterparty($connection);
28
    }
29
30
    /**
31
     * @return void
32
     * @throws NovaPoshtaApiException
33
     * @throws Exception
34
     */
35
    public function testContactPersonCrud(): void
36
    {
37
        $sfx = $this->randomString(5);
38
        $counterparty = $this->counterpartyModel->savePrivatePerson([
39
            'FirstName' => 'Іван' . $sfx,
40
            'MiddleName' => 'Іванович' . $sfx,
41
            'LastName' => 'Іванов' . $sfx,
42
            'Email' => 'ivan.ivanov.' . substr(uniqid(), 0, 5) . '@nova.poshta.test',
43
            'Phone' => rand(380000000000, 380000999999),
44
            'CounterpartyProperty' => 'Recipient',
45
        ]);
46
        if (filter_var(getenv('CLEAR_CONTACT_PERSONS'), FILTER_VALIDATE_BOOL)) {
47
            $this->clearContactPersons($counterparty);
48
        }
49
50
        //create counterparty
51
        $contactPersonData = [
52
            'FirstName' => 'Петро' . $sfx,
53
            'MiddleName' => 'Петрович' . $sfx,
54
            'LastName' => 'Петров' . $sfx,
55
            'Email' => 'petro.petrov.' . substr(uniqid(), 0, 5) . '@nova.poshta.test',
56
            'Phone' => rand(380000000000, 380000999999),
57
        ];
58
        $contactPerson = $this->model->save($counterparty['Ref'], $contactPersonData);
59
        $this->assertContactPerson($counterparty, $contactPerson, ['Email', 'MiddleName']);
60
61
62
        //update contact person
63
        $contactPersonData['Ref'] = $contactPerson['Ref'];
64
        $contactPersonData['MiddleName'] = 'Сидорович' . $sfx;
65
        $contactPersonUpdated = $this->model->update($counterparty['Ref'], $contactPersonData);
66
        $this->assertContactPerson($counterparty, $contactPersonUpdated, ['Ref', 'MiddleName', 'Email']);
67
68
        //delete contact person
69
        $this->model->delete($contactPerson['Ref']);
70
        $this->assertContactPersonMissing($counterparty['Ref']);
71
72
        //delete counterparty contact person
73
        $this->model->delete($contactPerson['Ref']);
74
    }
75
76
    /**
77
     * @param array $counterparty
78
     * @param array $expectedResult
79
     * @param array $compareAttributes
80
     * @return void
81
     * @throws NovaPoshtaApiException
82
     */
83
    private function assertContactPerson(array $counterparty, array $expectedResult, array $compareAttributes): void
84
    {
85
        $page = 1;
86
        do {
87
            $contactPersons = $this->counterpartyModel->getCounterpartyContactPersons($counterparty['Ref'], $page++);
88
            foreach ($contactPersons as $contactPerson) {
89
                if ($this->ensureContactPerson($contactPerson, $expectedResult, $compareAttributes)) {
90
                    $this->assertTrue(true, 'Imitate that we did an assertion');
91
                    return;
92
                }
93
            }
94
        } while (count($contactPersons) > 0);
95
        $this->fail('Contact person not found');
96
    }
97
98
    /**
99
     * @param string $ref
100
     * @return void
101
     * @throws NovaPoshtaApiException
102
     */
103
    private function assertContactPersonMissing(string $ref): void
104
    {
105
        $page = 1;
106
        do {
107
            $result = $this->counterpartyModel->getCounterpartyContactPersons($ref, $page++);
108
            foreach ($result as $contactPerson) {
109
                if ($this->ensureContactPerson($contactPerson, ['Ref' => $ref], ['Ref'])) {
110
                    $this->fail('Assert failed that counterparty `' . $ref . '` has been deleted');
111
                }
112
            }
113
        } while (count($result) > 0);
114
        $this->assertTrue(true, 'Imitate that we did an assertion');
115
    }
116
117
    /**
118
     * @param array $contactPerson
119
     * @param array $expectedResult
120
     * @param array $compareAttributes
121
     * @return bool
122
     */
123
    private function ensureContactPerson(array $contactPerson, array $expectedResult, array $compareAttributes): bool
124
    {
125
        foreach ($compareAttributes as $attribute) {
126
            if ($contactPerson[$attribute] !== $expectedResult[$attribute]) {
127
                return false;
128
            }
129
        }
130
        return true;
131
    }
132
133
    /**
134
     * @throws Exception
135
     */
136
    private function randomString(int $length = 10): string
137
    {
138
        $characters = 'абвгґдеєжзиіїйклмнопрстуфхцчшщьюяАБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ';
139
        $charactersLength = mb_strlen($characters);
140
        $randomString = '';
141
        for ($i = 0; $i < $length; $i++) {
142
            $symbolPosition = random_int(0, $charactersLength - 1);
143
            $randomString .= mb_substr($characters, $symbolPosition, 1);
144
        }
145
        return $randomString;
146
    }
147
148
    /**
149
     * @param array $counterparty
150
     * @return void
151
     * @throws NovaPoshtaApiException
152
     */
153
    private function clearContactPersons(array $counterparty): void
154
    {
155
        do {
156
            $result = $this->counterpartyModel->getCounterpartyContactPersons($counterparty['Ref']);
157
            foreach ($result as $contactPerson) {
158
                $this->model->delete($contactPerson['Ref']);
159
                $template = 'Contact person %s %s has been deleted' . PHP_EOL;
160
                echo sprintf($template, $contactPerson['FirstName'], $contactPerson['LastName']);
161
            }
162
        } while (count($result) > 0);
163
    }
164
}
165