Completed
Branch master (886cf7)
by Jan
07:19
created

AuditLogSearchTest   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 4
lcom 1
cbo 10
dl 0
loc 168
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 37 1
A tearDown() 0 5 1
B testProductRanking() 0 77 1
A getVersionData() 0 18 1
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Administration\Test\Search;
4
5
use Doctrine\DBAL\Connection;
6
use Shopware\Administration\Search\AdministrationSearch;
7
use Shopware\Core\Content\Product\ProductDefinition;
8
use Shopware\Core\Content\Product\ProductStruct;
9
use Shopware\Core\Defaults;
10
use Shopware\Core\Framework\Context;
11
use Shopware\Core\Framework\ORM\RepositoryInterface;
12
use Shopware\Core\Framework\Struct\Uuid;
13
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
14
15
class AuditLogSearchTest extends KernelTestCase
16
{
17
    /**
18
     * @var RepositoryInterface
19
     */
20
    private $productRepository;
21
22
    /**
23
     * @var Connection
24
     */
25
    private $connection;
26
27
    /**
28
     * @var AdministrationSearch
29
     */
30
    private $search;
31
32
    /**
33
     * @var Context
34
     */
35
    private $context;
36
37
    /**
38
     * @var string
39
     */
40
    private $userId;
41
42
    protected function setUp()
43
    {
44
        self::bootKernel();
45
46
        $this->connection = self::$container->get(Connection::class);
47
        $this->connection->beginTransaction();
48
49
        $this->productRepository = self::$container->get('product.repository');
50
        $this->search = self::$container->get(AdministrationSearch::class);
51
        $this->context = $context = Context::createDefaultContext(Defaults::TENANT_ID);
0 ignored issues
show
Documentation Bug introduced by
$context = \Shopware\Cor...re\Defaults::TENANT_ID) is of type object<self>, but the property $context was declared to be of type object<Shopware\Core\Framework\Context>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
52
53
        $this->connection->executeUpdate('
54
            DELETE FROM `version`;
55
            DELETE FROM `version_commit`;
56
            DELETE FROM `version_commit_data`;
57
            DELETE FROM `user`;
58
            DELETE FROM `order`;
59
            DELETE FROM `customer`;
60
            DELETE FROM `product`;
61
        ');
62
63
        $this->userId = Uuid::uuid4()->getHex();
64
65
        $repo = self::$container->get('user.repository');
66
        $repo->upsert([
67
            [
68
                'id' => $this->userId,
69
                'localeId' => '7b52d9dd-2b06-40ec-90be-9f57edf29be7',
70
                'name' => 'test-user',
71
                'username' => 'test-user',
72
                'email' => Uuid::uuid4()->getHex() . '@example.com',
73
                'password' => 'shopware',
74
            ],
75
        ], $context);
76
77
        parent::setUp();
78
    }
79
80
    protected function tearDown()
81
    {
82
        $this->connection->rollBack();
83
        parent::tearDown();
84
    }
85
86
    public function testProductRanking()
87
    {
88
        $context = Context::createDefaultContext(Defaults::TENANT_ID);
89
90
        $p1 = Uuid::uuid4()->getHex();
91
        $productId2 = Uuid::uuid4()->getHex();
92
93
        $this->productRepository->upsert([
94
            ['id' => $p1, 'name' => 'test product 1', 'price' => ['gross' => 10, 'net' => 9], 'tax' => ['name' => 'test', 'rate' => 5], 'manufacturer' => ['name' => 'test']],
95
            ['id' => $productId2, 'name' => 'test product 2', 'price' => ['gross' => 10, 'net' => 9], 'tax' => ['name' => 'test', 'rate' => 5], 'manufacturer' => ['name' => 'test']],
96
            ['id' => Uuid::uuid4()->getHex(), 'name' => 'notmatch', 'price' => ['gross' => 10, 'net' => 9], 'tax' => ['name' => 'test', 'rate' => 5], 'manufacturer' => ['name' => 'test']],
97
            ['id' => Uuid::uuid4()->getHex(), 'name' => 'notmatch', 'price' => ['gross' => 10, 'net' => 9], 'tax' => ['name' => 'test', 'rate' => 5], 'manufacturer' => ['name' => 'test']],
98
        ], $context);
99
100
        $result = $this->search->search('product', 1, 20, $context, $this->userId);
101
102
        //no audit log exists? product 1 was insert first and should match first
103
        self::assertEquals(2, $result['total']);
104
        self::assertCount(2, $result['data']);
105
106
        /** @var ProductStruct $first */
107
        $first = $result['data'][0];
108
        self::assertInstanceOf(ProductStruct::class, $first);
109
110
        /** @var ProductStruct $second */
111
        $second = $result['data'][1];
112
        self::assertInstanceOf(ProductStruct::class, $second);
113
114
        $firstScore = $first->getExtension('search')->get('_score');
115
        $secondScore = $second->getExtension('search')->get('_score');
116
117
        self::assertSame($secondScore, $firstScore);
118
119
        $this->productRepository->update([
120
            ['id' => $productId2, 'price' => ['gross' => 15, 'net' => 1]],
121
            ['id' => $productId2, 'price' => ['gross' => 20, 'net' => 1]],
122
            ['id' => $productId2, 'price' => ['gross' => 25, 'net' => 1]],
123
            ['id' => $productId2, 'price' => ['gross' => 30, 'net' => 1]],
124
        ], Context::createDefaultContext(Defaults::TENANT_ID));
125
126
        $changes = $this->getVersionData(ProductDefinition::getEntityName(), $productId2, Defaults::LIVE_VERSION);
127
        $this->assertNotEmpty($changes);
128
129
        $this->connection->executeUpdate('UPDATE version_commit_data SET user_id = NULL');
130
        $this->connection->executeUpdate(
131
            "UPDATE version_commit_data SET user_id = :user
132
             WHERE entity_name = :entity 
133
             AND JSON_EXTRACT(entity_id, '$.id') = :id",
134
            [
135
                'id' => $productId2,
136
                'entity' => ProductDefinition::getEntityName(),
137
                'user' => Uuid::fromStringToBytes($this->userId),
138
            ]
139
        );
140
141
        $result = $this->search->search('product', 1, 20, $context, $this->userId);
142
143
        self::assertEquals(2, $result['total']);
144
        self::assertCount(2, $result['data']);
145
146
        /** @var ProductStruct $first */
147
        $first = $result['data'][0];
148
        self::assertInstanceOf(ProductStruct::class, $first);
149
150
        /** @var ProductStruct $second */
151
        $second = $result['data'][1];
152
        self::assertInstanceOf(ProductStruct::class, $second);
153
154
        // `product-2` should now be boosted
155
        self::assertSame($first->getId(), $productId2);
156
        self::assertSame($second->getId(), $p1);
157
158
        $firstScore = $first->getExtension('search')->get('_score');
159
        $secondScore = $second->getExtension('search')->get('_score');
160
161
        self::assertTrue($firstScore > $secondScore);
162
    }
163
164
    private function getVersionData(string $entity, string $id, string $versionId): array
165
    {
166
        return $this->connection->fetchAll(
167
            "SELECT d.* 
168
             FROM version_commit_data d
169
             INNER JOIN version_commit c
170
               ON c.id = d.version_commit_id
171
               AND c.version_id = :version
172
             WHERE entity_name = :entity 
173
             AND JSON_EXTRACT(entity_id, '$.id') = :id
174
             ORDER BY ai",
175
            [
176
                'entity' => $entity,
177
                'id' => $id,
178
                'version' => Uuid::fromStringToBytes($versionId),
179
            ]
180
        );
181
    }
182
}
183