PluginProbe ʕ •ᴥ•ʔ
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More / 2.7.0
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More v2.7.0
2.11.0 2.10.0 2.9.0 2.8.0 2.7.0 2.6.7 2.6.8 2.6.5 2.6.4 2.6.3 2.6.2 2.6.0 2.5.5 2.5.4 2.5.3 2.5.2 trunk 1.0 1.0.1 1.0.2 1.0.3 1.1 1.1.1 1.1.2 1.2.0 2.0 2.1.0 2.1.1 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5.0 2.5.1
reviews-feed / tests / Unit / Providers / DuplicatePreventionTest.php
reviews-feed / tests / Unit / Providers Last commit date
DuplicatePreventionTest.php 1 month ago EddItemTemplateBcTest.php 1 month ago EddProviderGateTest.php 1 month ago EddTitleRenderingBcTest.php 1 month ago Smash782BookingUrlHotelIdTest.php 1 month ago
DuplicatePreventionTest.php
226 lines
1 <?php
2
3 namespace SmashBalloon\Reviews\Tests\Unit\Providers;
4
5 use PHPUnit\Framework\TestCase;
6
7 /**
8 * Unit tests for duplicate review prevention.
9 *
10 * Tests the unique constraint logic that prevents duplicate reviews
11 * from being inserted due to race conditions.
12 */
13 class DuplicatePreventionTest extends TestCase
14 {
15 /*
16 |--------------------------------------------------------------------------
17 | Unique Key Generation Tests
18 |--------------------------------------------------------------------------
19 */
20
21 /**
22 * Test that unique key is built from post_id, provider_id, and lang.
23 */
24 public function test_unique_key_components(): void
25 {
26 $review1 = [
27 'post_id' => '5034',
28 'provider_id' => 'wc_multi_abc123',
29 'lang' => '',
30 ];
31
32 $review2 = [
33 'post_id' => '5034',
34 'provider_id' => 'wc_multi_abc123',
35 'lang' => '',
36 ];
37
38 // Same key = duplicate
39 $key1 = $this->buildUniqueKey($review1);
40 $key2 = $this->buildUniqueKey($review2);
41
42 $this->assertEquals($key1, $key2);
43 }
44
45 /**
46 * Test that different provider_ids produce different keys.
47 */
48 public function test_different_provider_ids_are_unique(): void
49 {
50 $review1 = [
51 'post_id' => '5034',
52 'provider_id' => 'wc_multi_abc123',
53 'lang' => '',
54 ];
55
56 $review2 = [
57 'post_id' => '5034',
58 'provider_id' => 'wc_multi_xyz789',
59 'lang' => '',
60 ];
61
62 $key1 = $this->buildUniqueKey($review1);
63 $key2 = $this->buildUniqueKey($review2);
64
65 $this->assertNotEquals($key1, $key2);
66 }
67
68 /**
69 * Test that same review with different languages are unique.
70 */
71 public function test_different_languages_are_unique(): void
72 {
73 $review1 = [
74 'post_id' => '5034',
75 'provider_id' => 'ChIJabc123',
76 'lang' => 'en',
77 ];
78
79 $review2 = [
80 'post_id' => '5034',
81 'provider_id' => 'ChIJabc123',
82 'lang' => 'de',
83 ];
84
85 $key1 = $this->buildUniqueKey($review1);
86 $key2 = $this->buildUniqueKey($review2);
87
88 $this->assertNotEquals($key1, $key2);
89 }
90
91 /*
92 |--------------------------------------------------------------------------
93 | WooCommerce Specific Tests
94 |--------------------------------------------------------------------------
95 */
96
97 /**
98 * Test that WooCommerce comment IDs are used as post_id.
99 */
100 public function test_woocommerce_uses_comment_id_as_post_id(): void
101 {
102 $commentId = 5034;
103 $normalizedReview = $this->normalizeWooCommerceReview($commentId, 'Test Review');
104
105 $this->assertEquals((string) $commentId, $normalizedReview['review_id']);
106 }
107
108 /**
109 * Test that multi-product source ID is preserved.
110 */
111 public function test_multi_product_source_id_format(): void
112 {
113 $productIds = [1, 2, 3];
114 $sourceId = $this->generateMultiProductSourceId($productIds);
115
116 $this->assertStringStartsWith('wc_multi_', $sourceId);
117 $this->assertEquals(41, strlen($sourceId)); // wc_multi_ (8) + md5 hash (32) + time suffix
118 }
119
120 /*
121 |--------------------------------------------------------------------------
122 | Migration Routine Tests
123 |--------------------------------------------------------------------------
124 */
125
126 /**
127 * Test that duplicate removal identifies correct duplicates.
128 */
129 public function test_duplicate_identification(): void
130 {
131 $posts = [
132 ['id' => 1, 'post_id' => '5034', 'provider_id' => 'wc_multi_abc', 'lang' => ''],
133 ['id' => 2, 'post_id' => '5034', 'provider_id' => 'wc_multi_abc', 'lang' => ''], // Duplicate
134 ['id' => 3, 'post_id' => '5035', 'provider_id' => 'wc_multi_abc', 'lang' => ''], // Different post_id
135 ['id' => 4, 'post_id' => '5034', 'provider_id' => 'wc_multi_xyz', 'lang' => ''], // Different provider_id
136 ];
137
138 $duplicateIds = $this->findDuplicateIds($posts);
139
140 $this->assertCount(1, $duplicateIds);
141 $this->assertContains(2, $duplicateIds); // Only id=2 is a duplicate
142 }
143
144 /**
145 * Test that first occurrence is kept, duplicates are removed.
146 */
147 public function test_keeps_first_occurrence(): void
148 {
149 $posts = [
150 ['id' => 10, 'post_id' => '5034', 'provider_id' => 'wc_multi_abc', 'lang' => ''],
151 ['id' => 20, 'post_id' => '5034', 'provider_id' => 'wc_multi_abc', 'lang' => ''],
152 ['id' => 30, 'post_id' => '5034', 'provider_id' => 'wc_multi_abc', 'lang' => ''],
153 ];
154
155 $duplicateIds = $this->findDuplicateIds($posts);
156
157 // Should identify 2 duplicates (id 20 and 30), keeping id 10
158 $this->assertCount(2, $duplicateIds);
159 $this->assertNotContains(10, $duplicateIds);
160 $this->assertContains(20, $duplicateIds);
161 $this->assertContains(30, $duplicateIds);
162 }
163
164 /*
165 |--------------------------------------------------------------------------
166 | Helper Methods
167 |--------------------------------------------------------------------------
168 */
169
170 /**
171 * Build unique key from review data.
172 */
173 private function buildUniqueKey(array $review): string
174 {
175 return $review['post_id'] . '|' . $review['provider_id'] . '|' . $review['lang'];
176 }
177
178 /**
179 * Simulate WooCommerce review normalization.
180 */
181 private function normalizeWooCommerceReview(int $commentId, string $content): array
182 {
183 return [
184 'review_id' => (string) $commentId,
185 'text' => $content,
186 'rating' => 5,
187 'time' => time(),
188 'reviewer' => [
189 'name' => 'Test User',
190 ],
191 'provider' => [
192 'name' => 'woocommerce',
193 ],
194 ];
195 }
196
197 /**
198 * Generate multi-product source ID.
199 */
200 private function generateMultiProductSourceId(array $productIds): string
201 {
202 return 'wc_multi_' . md5(implode('_', $productIds) . '_' . time());
203 }
204
205 /**
206 * Find duplicate IDs in posts array.
207 */
208 private function findDuplicateIds(array $posts): array
209 {
210 $seen = [];
211 $duplicates = [];
212
213 foreach ($posts as $post) {
214 $key = $this->buildUniqueKey($post);
215
216 if (isset($seen[$key])) {
217 $duplicates[] = $post['id'];
218 } else {
219 $seen[$key] = $post['id'];
220 }
221 }
222
223 return $duplicates;
224 }
225 }
226