PluginProbe ʕ •ᴥ•ʔ
Event Tickets with Ticket Scanner / 2.9.4
Event Tickets with Ticket Scanner v2.9.4
3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.4 trunk 2.6.0 2.7.0 2.7.1 2.7.10 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.10 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.0 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 3.0.0 3.0.1 3.0.2 3.0.3
event-tickets-with-ticket-scanner / tests / SeatingExportTest.php
event-tickets-with-ticket-scanner / tests Last commit date
bin 3 months ago fixtures 3 months ago AdminCodeCleanupAndPDFTest.php 3 months ago AdminCodesByProductTest.php 3 months ago AdminCustomerNameTest.php 3 months ago AdminErrorLogTest.php 3 months ago AdminFormatWarningTest.php 3 months ago AdminListAndCodeOpsTest.php 3 months ago AdminListQueryTest.php 3 months ago AdminMetaAndErrorTest.php 3 months ago AdminOptionsAndMigrationTest.php 3 months ago AdminOrderInfoTest.php 3 months ago AdminRedeemAmountTest.php 3 months ago AdminRestrictionAndRstrTest.php 3 months ago AdminSettingsAndDatepickerTest.php 3 months ago AdminSettingsCodeTest.php 3 months ago AdminTicketInfoTest.php 3 months ago AdminTimezoneAndMiscTest.php 3 months ago AdminWCCodeOpsTest.php 3 months ago AuthtokenAccessTest.php 3 months ago AuthtokenCRUDTest.php 3 months ago AuthtokenEditAndRemoveTest.php 3 months ago AuthtokenTest.php 3 months ago BaseLimitsTest.php 3 months ago CartCodeRestrictionAndAssignTest.php 3 months ago CartMetaAndBeforeCartTest.php 3 months ago CartValidationTest.php 3 months ago ContextWizardTest.php 3 months ago CoreAlignAndSearchTest.php 3 months ago CoreCodeOpsAndDBLogTest.php 3 months ago CoreDecodeAndReplaceTest.php 3 months ago CoreEncodeMetaTest.php 3 months ago CoreExpiredAndRegisteredTest.php 3 months ago CoreMetaAndUrlTest.php 3 months ago CoreMetaObjectStructureTest.php 3 months ago CoreMetaTest.php 3 months ago CoreMethodsTest.php 3 months ago CoreOrderAndIPTest.php 3 months ago CoreParserAndQueryTest.php 3 months ago CoreParserURLAndMergePDFTest.php 3 months ago CoreReplaceAndExpireTest.php 3 months ago CoreTicketIdAndExpirationTest.php 3 months ago CoreTicketIdAndUrlTest.php 3 months ago CoreTicketURLComponentsTest.php 3 months ago CountRedeemsTodayTest.php 3 months ago CronjobTest.php 3 months ago DBOperationsTest.php 3 months ago DBSanitizeAndQueryTest.php 3 months ago DBSanitizeTest.php 3 months ago DBTablesAndUpdateTest.php 3 months ago DatabaseTest.php 3 months ago DateCalcAndCorrectProductTest.php 3 months ago DaychooserTest.php 3 months ago EmailHandlerTest.php 3 months ago EmailOrderMetaAndAttachmentsTest.php 3 months ago ErrorLogAndSanitizeTest.php 3 months ago EventTimeWindowTest.php 3 months ago FrontendCheckCodeTest.php 3 months ago FrontendCountConfirmedTest.php 3 months ago FrontendExecuteJSONAndCheckCodeTest.php 3 months ago FrontendIsUsedAndOptionsTest.php 3 months ago FrontendMarkUsedTest.php 3 months ago FrontendValidationTest.php 3 months ago FullTicketFlowTest.php 3 months ago HelpersTest.php 3 months ago ListManagementTest.php 3 months ago MaxRedeemPerDayTest.php 3 months ago MessengerAndRESTEndpointsTest.php 3 months ago MessengerTypeCheckTest.php 3 months ago OldPremiumGuardTest.php 3 months ago OneTimeUseTest.php 3 months ago OptionsChangeAndLoadTest.php 3 months ago OptionsDeleteAndResetTest.php 3 months ago OptionsExportImportTest.php 3 months ago OptionsFormatsTest.php 3 months ago OptionsHistoryTest.php 3 months ago OptionsMigrationTest.php 3 months ago OptionsResetAndFormatTest.php 3 months ago OptionsTest.php 3 months ago OrderDeleteAndRefundDeleteTest.php 3 months ago OrderMetaKeyValueDisplayTest.php 3 months ago OrderStatusHandlerTest.php 3 months ago OrderTicketGenerationTest.php 3 months ago OrderTicketQueryTest.php 3 months ago PDFAndQRConfigTest.php 3 months ago PDFMergeAndPWAServiceWorkerTest.php 3 months ago PDFSettersTest.php 3 months ago PDFSettingsTest.php 3 months ago PDFUtilsTest.php 3 months ago PWAManifestAndSessionTest.php 3 months ago PartialRefundAndCodeCleanupTest.php 3 months ago PluginInitAndShortcodeTest.php 3 months ago ProductSettingsTest.php 3 months ago QRCodeAndDesignerTest.php 3 months ago QRPDFAndBadgePDFTest.php 3 months ago RESTRoutesAndPingTest.php 3 months ago RefundTest.php 3 months ago RestApiTest.php 3 months ago RestApiTicketTest.php 3 months ago ScannerBoilerplateAndFormatWarningsTest.php 3 months ago SeatingBlockTest.php 3 months ago SeatingCoordinatorTest.php 3 months ago SeatingExportTest.php 3 months ago SeatingMetaTest.php 3 months ago SeatingPlanCRUDTest.php 3 months ago SeatingPlanTest.php 3 months ago SeatingSeatCRUDTest.php 3 months ago SetupWizardTest.php 3 months ago ShortcodeAndCartCheckTest.php 3 months ago ShortcodeAndCodesDisplayTest.php 3 months ago ShortcodesAndCodeListTest.php 3 months ago StaticDateAndTimeTest.php 3 months ago StaticHelpersAndMessengerTest.php 3 months ago StaticUtilMethodsTest.php 3 months ago TicketBadgeTemplateTest.php 3 months ago TicketCalcDateTest.php 3 months ago TicketDesignerAndBadgeTest.php 3 months ago TicketDesignerTemplateTest.php 3 months ago TicketDesignerTest.php 3 months ago TicketDisplayTest.php 3 months ago TicketExpirationAndICSTest.php 3 months ago TicketLabelAndDisplayTest.php 3 months ago TicketLabelsAndStaticsTest.php 3 months ago TicketQRSettersTest.php 3 months ago TicketRedeemTest.php 3 months ago TicketRoutingTest.php 3 months ago TicketScannerMethodsTest.php 3 months ago TicketSettersAndOrderTest.php 3 months ago TicketUtilAndICSTest.php 3 months ago TicketUtilMethodsTest.php 3 months ago TicketWPMLAndSubscriptionTest.php 3 months ago TimezoneRedeemBlockingTest.php 3 months ago UrlParsingTest.php 3 months ago VariationTicketTest.php 3 months ago WCBaseMetaConstantsTest.php 3 months ago WCCheckoutCartFlowTest.php 3 months ago WCEmailAttachmentTest.php 3 months ago WCFrontendAjaxAndDatepickerTest.php 3 months ago WCFrontendCartHandlerTest.php 3 months ago WCFrontendCartHandlersTest.php 3 months ago WCFrontendCartTest.php 3 months ago WCFrontendCartValidationTest.php 3 months ago WCFrontendHandlersTest.php 3 months ago WCFrontendLabelsTest.php 3 months ago WCFrontendMethodsTest.php 3 months ago WCOrderDeleteTest.php 3 months ago WCOrderDisplayMetaTest.php 3 months ago WCOrderHasTicketsTest.php 3 months ago WCOrderHooksTest.php 3 months ago WCOrderItemMetaDisplayTest.php 3 months ago WCOrderItemOpsTest.php 3 months ago WCOrderLifecycleTest.php 3 months ago WCOrderMethodsTest.php 3 months ago WCOrderTicketDetectionTest.php 3 months ago WCOrderTicketNumberTest.php 3 months ago WCProductAndVariationTest.php 3 months ago WCProductColumnsTest.php 3 months ago WCProductConfigAndColumnsTest.php 3 months ago WCProductIsTicketAndListsTest.php 3 months ago WCProductMetaSaveTest.php 3 months ago WCProductMethodsTest.php 3 months ago WCProductTabsAndSideBoxTest.php 3 months ago WCProductTicketTest.php 3 months ago WebhooksAndMigrationTest.php 3 months ago bootstrap.php 3 months ago composer.json 3 months ago phpunit.xml 3 months ago test-premium-compat.sh 3 months ago
SeatingExportTest.php
384 lines
1 <?php
2 /**
3 * Tests for seating plan CSV export (#209).
4 */
5
6 class SeatingExportTest extends WP_UnitTestCase {
7
8 private sasoEventtickets $main;
9 private sasoEventtickets_Seating $seating;
10 private int $userId;
11 private int $planId = 0;
12
13 public function set_up(): void {
14 parent::set_up();
15 $this->userId = self::factory()->user->create(['role' => 'administrator']);
16 wp_set_current_user($this->userId);
17
18 $this->main = sasoEventtickets::Instance();
19 $this->seating = $this->main->getSeating();
20 }
21
22 public function tear_down(): void {
23 // Clean up created seats and plan
24 if ($this->planId > 0) {
25 global $wpdb;
26 $seatsTable = $this->main->getDB()->getTabelle('seats');
27 $plansTable = $this->main->getDB()->getTabelle('seatingplans');
28 $wpdb->delete($seatsTable, ['seatingplan_id' => $this->planId]);
29 $wpdb->delete($plansTable, ['id' => $this->planId]);
30 }
31 parent::tear_down();
32 }
33
34 private function createTestPlan(string $name = 'Test Plan'): int {
35 global $wpdb;
36 $table = $this->main->getDB()->getTabelle('seatingplans');
37 $wpdb->insert($table, [
38 'name' => $name,
39 'aktiv' => 1,
40 'time' => wp_date('Y-m-d H:i:s'),
41 'timezone' => wp_timezone_string(),
42 'layout_type' => 'simple',
43 'meta' => '{}',
44 'meta_draft' => '{}',
45 'meta_published' => '{}',
46 'created_at' => wp_date('Y-m-d H:i:s'),
47 'updated_at' => wp_date('Y-m-d H:i:s'),
48 'created_by' => $this->userId,
49 'updated_by' => $this->userId,
50 ]);
51 $this->planId = (int) $wpdb->insert_id;
52 return $this->planId;
53 }
54
55 private function createTestSeat(int $planId, string $identifier, array $metaOverrides = []): int {
56 global $wpdb;
57 $table = $this->main->getDB()->getTabelle('seats');
58 $meta = array_merge([
59 'seat_label' => '',
60 'seat_category' => '',
61 'description' => '',
62 'capacity' => 1,
63 'price_modifier' => 0,
64 ], $metaOverrides);
65 $wpdb->insert($table, [
66 'seatingplan_id' => $planId,
67 'seat_identifier' => $identifier,
68 'aktiv' => 1,
69 'sort_order' => 0,
70 'time' => wp_date('Y-m-d H:i:s'),
71 'timezone' => wp_timezone_string(),
72 'meta' => wp_json_encode($meta),
73 'is_deleted' => 0,
74 'created_at' => wp_date('Y-m-d H:i:s'),
75 'updated_at' => wp_date('Y-m-d H:i:s'),
76 'created_by' => $this->userId,
77 'updated_by' => $this->userId,
78 ]);
79 return (int) $wpdb->insert_id;
80 }
81
82 // ── prepareSeatsForExport ──────────────────────────────
83
84 public function test_prepareSeatsForExport_returns_correct_columns(): void {
85 $planId = $this->createTestPlan();
86 $this->createTestSeat($planId, 'A-1');
87
88 $result = $this->seating->prepareSeatsForExport($planId);
89
90 $this->assertCount(1, $result);
91 $row = $result[0];
92 $this->assertArrayHasKey('identifier', $row);
93 $this->assertArrayHasKey('label', $row);
94 $this->assertArrayHasKey('category', $row);
95 $this->assertArrayHasKey('active', $row);
96 $this->assertArrayHasKey('sort_order', $row);
97 $this->assertArrayHasKey('description', $row);
98 $this->assertArrayHasKey('capacity', $row);
99 $this->assertArrayHasKey('price_modifier', $row);
100 }
101
102 public function test_prepareSeatsForExport_includes_meta_fields(): void {
103 $planId = $this->createTestPlan();
104 $this->createTestSeat($planId, 'VIP-3', [
105 'seat_label' => 'VIP Seat 3',
106 'seat_category' => 'VIP',
107 'description' => 'Front row center',
108 'capacity' => 2,
109 'price_modifier' => 25.50,
110 ]);
111
112 $result = $this->seating->prepareSeatsForExport($planId);
113
114 $this->assertCount(1, $result);
115 $row = $result[0];
116 $this->assertEquals('VIP-3', $row['identifier']);
117 $this->assertEquals('VIP Seat 3', $row['label']);
118 $this->assertEquals('VIP', $row['category']);
119 $this->assertEquals('Front row center', $row['description']);
120 $this->assertEquals(2, $row['capacity']);
121 $this->assertEquals(25.50, $row['price_modifier']);
122 }
123
124 public function test_prepareSeatsForExport_handles_empty_plan(): void {
125 $planId = $this->createTestPlan();
126
127 $result = $this->seating->prepareSeatsForExport($planId);
128
129 $this->assertIsArray($result);
130 $this->assertEmpty($result);
131 }
132
133 public function test_prepareSeatsForExport_requires_valid_plan(): void {
134 $this->expectException(\Exception::class);
135 $this->seating->prepareSeatsForExport(999999);
136 }
137
138 public function test_prepareSeatsForExport_formats_active_flag(): void {
139 $planId = $this->createTestPlan();
140 $this->createTestSeat($planId, 'A-1');
141
142 // Create an inactive seat directly
143 global $wpdb;
144 $table = $this->main->getDB()->getTabelle('seats');
145 $wpdb->insert($table, [
146 'seatingplan_id' => $planId,
147 'seat_identifier' => 'A-2',
148 'aktiv' => 0,
149 'sort_order' => 1,
150 'time' => wp_date('Y-m-d H:i:s'),
151 'timezone' => wp_timezone_string(),
152 'meta' => '{}',
153 'is_deleted' => 0,
154 'created_at' => wp_date('Y-m-d H:i:s'),
155 'updated_at' => wp_date('Y-m-d H:i:s'),
156 'created_by' => $this->userId,
157 'updated_by' => $this->userId,
158 ]);
159
160 $result = $this->seating->prepareSeatsForExport($planId);
161
162 $activeStates = array_column($result, 'active', 'identifier');
163 $this->assertEquals('yes', $activeStates['A-1']);
164 $this->assertEquals('no', $activeStates['A-2']);
165 }
166
167 public function test_prepareSeatsForExport_handles_multiple_seats(): void {
168 $planId = $this->createTestPlan();
169 $this->createTestSeat($planId, 'A-1', ['seat_category' => 'Standard']);
170 $this->createTestSeat($planId, 'A-2', ['seat_category' => 'Standard']);
171 $this->createTestSeat($planId, 'B-1', ['seat_category' => 'VIP']);
172
173 $result = $this->seating->prepareSeatsForExport($planId);
174
175 $this->assertCount(3, $result);
176 $identifiers = array_column($result, 'identifier');
177 $this->assertContains('A-1', $identifiers);
178 $this->assertContains('A-2', $identifiers);
179 $this->assertContains('B-1', $identifiers);
180 }
181
182 // ── importSeatsCSV ─────────────────────────────────────
183
184 public function test_importSeatsCSV_creates_new_seats(): void {
185 $planId = $this->createTestPlan();
186
187 $result = $this->seating->importSeatsCSV([
188 'plan_id' => $planId,
189 'rows' => [
190 ['identifier' => 'A-1', 'label' => 'Seat A1', 'category' => 'Standard'],
191 ['identifier' => 'A-2', 'label' => 'Seat A2', 'category' => 'VIP'],
192 ],
193 ]);
194
195 $this->assertEquals(2, $result['created']);
196 $this->assertEquals(0, $result['updated']);
197 $this->assertEquals(0, $result['skipped']);
198 }
199
200 public function test_importSeatsCSV_updates_existing_seats(): void {
201 $planId = $this->createTestPlan();
202 $this->createTestSeat($planId, 'A-1', ['seat_category' => 'Standard']);
203
204 $result = $this->seating->importSeatsCSV([
205 'plan_id' => $planId,
206 'rows' => [
207 ['identifier' => 'A-1', 'label' => 'Updated Label', 'category' => 'VIP'],
208 ],
209 ]);
210
211 $this->assertEquals(0, $result['created']);
212 $this->assertEquals(1, $result['updated']);
213
214 // Verify the update took effect
215 $seat = $this->seating->getSeatManager()->getByIdentifier($planId, 'A-1');
216 $this->assertEquals('VIP', $seat['meta']['seat_category']);
217 $this->assertEquals('Updated Label', $seat['meta']['seat_label']);
218 }
219
220 public function test_importSeatsCSV_mixed_create_and_update(): void {
221 $planId = $this->createTestPlan();
222 $this->createTestSeat($planId, 'A-1', ['seat_category' => 'Standard']);
223
224 $result = $this->seating->importSeatsCSV([
225 'plan_id' => $planId,
226 'rows' => [
227 ['identifier' => 'A-1', 'label' => 'Updated', 'category' => 'VIP'],
228 ['identifier' => 'B-1', 'label' => 'New Seat', 'category' => 'Standard'],
229 ],
230 ]);
231
232 $this->assertEquals(1, $result['created']);
233 $this->assertEquals(1, $result['updated']);
234 }
235
236 public function test_importSeatsCSV_skips_empty_identifiers(): void {
237 $planId = $this->createTestPlan();
238
239 $result = $this->seating->importSeatsCSV([
240 'plan_id' => $planId,
241 'rows' => [
242 ['identifier' => 'A-1', 'label' => 'Good'],
243 ['identifier' => '', 'label' => 'No ID'],
244 ['identifier' => ' ', 'label' => 'Whitespace'],
245 ],
246 ]);
247
248 $this->assertEquals(1, $result['created']);
249 $this->assertEquals(2, $result['skipped']);
250 }
251
252 public function test_importSeatsCSV_requires_valid_plan(): void {
253 $this->expectException(\Exception::class);
254 $this->seating->importSeatsCSV([
255 'plan_id' => 999999,
256 'rows' => [['identifier' => 'A-1']],
257 ]);
258 }
259
260 public function test_importSeatsCSV_requires_rows(): void {
261 $planId = $this->createTestPlan();
262 $this->expectException(\Exception::class);
263 $this->seating->importSeatsCSV([
264 'plan_id' => $planId,
265 'rows' => [],
266 ]);
267 }
268
269 public function test_importSeatsCSV_roundtrip_export_import(): void {
270 $planId = $this->createTestPlan();
271 $this->createTestSeat($planId, 'A-1', [
272 'seat_label' => 'Seat A1',
273 'seat_category' => 'VIP',
274 'description' => 'Front row',
275 'capacity' => 2,
276 'price_modifier' => 15.00,
277 ]);
278 $this->createTestSeat($planId, 'A-2', [
279 'seat_label' => 'Seat A2',
280 'seat_category' => 'Standard',
281 ]);
282
283 // Export
284 $exported = $this->seating->prepareSeatsForExport($planId);
285 $this->assertCount(2, $exported);
286
287 // Create a new plan and import into it
288 $newPlanId = $this->createTestPlan('Import Target');
289
290 $result = $this->seating->importSeatsCSV([
291 'plan_id' => $newPlanId,
292 'rows' => $exported,
293 ]);
294
295 $this->assertEquals(2, $result['created']);
296
297 // Verify imported data matches
298 $importedSeats = $this->seating->prepareSeatsForExport($newPlanId);
299 $this->assertCount(2, $importedSeats);
300
301 $importedMap = array_column($importedSeats, null, 'identifier');
302 $this->assertEquals('Seat A1', $importedMap['A-1']['label']);
303 $this->assertEquals('VIP', $importedMap['A-1']['category']);
304 $this->assertEquals('Front row', $importedMap['A-1']['description']);
305 $this->assertEquals(2, $importedMap['A-1']['capacity']);
306 $this->assertEquals(15.00, $importedMap['A-1']['price_modifier']);
307 }
308
309 // ── Forward/Backward Compatibility ────────────────────
310
311 public function test_importSeatsCSV_reports_unknown_columns(): void {
312 $planId = $this->createTestPlan();
313
314 $result = $this->seating->importSeatsCSV([
315 'plan_id' => $planId,
316 'rows' => [
317 ['identifier' => 'A-1', 'label' => 'Seat A1', 'future_field' => 'value', 'another_new' => '42'],
318 ],
319 ]);
320
321 $this->assertEquals(1, $result['created']);
322 $this->assertArrayHasKey('ignored_columns', $result);
323 $this->assertContains('future_field', $result['ignored_columns']);
324 $this->assertContains('another_new', $result['ignored_columns']);
325 }
326
327 public function test_importSeatsCSV_partial_update_preserves_existing_meta(): void {
328 $planId = $this->createTestPlan();
329 $this->createTestSeat($planId, 'A-1', [
330 'seat_label' => 'Original Label',
331 'seat_category' => 'VIP',
332 'description' => 'Front row center',
333 'capacity' => 3,
334 'price_modifier' => 20.00,
335 ]);
336
337 // Import with only identifier and category — other fields should be preserved
338 $result = $this->seating->importSeatsCSV([
339 'plan_id' => $planId,
340 'rows' => [
341 ['identifier' => 'A-1', 'category' => 'Standard'],
342 ],
343 ]);
344
345 $this->assertEquals(0, $result['created']);
346 $this->assertEquals(1, $result['updated']);
347
348 $seat = $this->seating->getSeatManager()->getByIdentifier($planId, 'A-1');
349 $meta = is_string($seat['meta']) ? json_decode($seat['meta'], true) : $seat['meta'];
350
351 // Updated field
352 $this->assertEquals('Standard', $meta['seat_category']);
353 // Preserved fields
354 $this->assertEquals('Original Label', $meta['seat_label']);
355 $this->assertEquals('Front row center', $meta['description']);
356 $this->assertEquals(3, $meta['capacity']);
357 $this->assertEquals(20.00, $meta['price_modifier']);
358 }
359
360 public function test_importSeatsCSV_old_csv_without_new_fields_keeps_defaults(): void {
361 $planId = $this->createTestPlan();
362
363 // Minimal CSV — only identifier, simulating an old export format
364 $result = $this->seating->importSeatsCSV([
365 'plan_id' => $planId,
366 'rows' => [
367 ['identifier' => 'B-1'],
368 ],
369 ]);
370
371 $this->assertEquals(1, $result['created']);
372
373 $seat = $this->seating->getSeatManager()->getByIdentifier($planId, 'B-1');
374 $meta = is_string($seat['meta']) ? json_decode($seat['meta'], true) : $seat['meta'];
375
376 // Defaults applied for missing fields
377 // seat_label defaults to identifier when empty (SeatManager::create behavior)
378 $this->assertEquals('B-1', $meta['seat_label']);
379 $this->assertEquals('', $meta['seat_category']);
380 $this->assertEquals(1, $meta['capacity']);
381 $this->assertEquals(0, $meta['price_modifier']);
382 }
383 }
384