PluginProbe
ووسلام – همگام سازی ووکامرس و باسلام / 1.10.27
ووسلام – همگام سازی ووکامرس و باسلام v1.10.27
1.1.26 1.10.27 1.10.24 1.10.25 1.10.23 1.10.22 1.10.21 1.10.19 1.10.20 1.10.18 1.10.17 1.10.15 1.10.14 1.10.13 1.10.12 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 All 60 releases
sync-basalam / tests / integration / product-attribute-suffix.php

product-attribute-suffix.php in ووسلام – همگام سازی ووکامرس و باسلام 1.10.27, at tests/integration/product-attribute-suffix.php

204 lines 9.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Run inside a local WordPress installation:
4 // docker exec -w /var/www/html/wp-content/plugins/sync-basalam \
5 // basalam-wordpress-local-wordpress-1 php tests/integration/product-attribute-suffix.php
6 require getenv('WORDPRESS_BOOTSTRAP') ?: dirname(__DIR__, 5) . '/wp-load.php';
7
8 use SyncBasalam\Admin\Components\SettingPageComponents;
9 use SyncBasalam\Admin\Product\ProductDataFactory;
10 use SyncBasalam\Admin\Settings\SettingsConfig;
11 use SyncBasalam\Admin\Settings\SettingsContainer;
12 use SyncBasalam\Admin\Settings\SettingsPageHandler;
13
14 if (wp_get_environment_type() !== 'local') {
15 throw new RuntimeException('Run these integration tests only in a local WordPress environment.');
16 }
17
18 $originalSettings = get_option('sync_basalam_settings');
19 $originalPost = $_POST;
20 $products = [];
21 $globalAttributes = [];
22 $taxonomyAttributes = [];
23 $assertions = 0;
24 $scenarios = [];
25 $assertSame = static function ($expected, $actual, string $scenario) use (&$assertions) {
26 if ($expected !== $actual) {
27 throw new RuntimeException($scenario . ': expected ' . var_export($expected, true) . ', got ' . var_export($actual, true));
28 }
29 $assertions++;
30 };
31 $refreshSettings = static function () {
32 // Each scenario represents a new request; clear the request's settings cache.
33 $property = new ReflectionProperty(SettingsContainer::class, 'settings');
34 $property->setAccessible(true);
35 $property->setValue(syncBasalamSettings(), null);
36 };
37 $configure = static function ($names, string $enabled = 'yes', string $prefix = '', string $suffix = '') use ($originalSettings, $refreshSettings) {
38 update_option('sync_basalam_settings', array_merge(SettingsConfig::getDefaultSettings(), (array) $originalSettings, [
39 SettingsConfig::PRODUCT_ATTRIBUTE_SUFFIX_ENABLED => $enabled,
40 SettingsConfig::PRODUCT_ATTRIBUTE_SUFFIX_PRIORITY => $names,
41 SettingsConfig::PRODUCT_PREFIX_TITLE => $prefix,
42 SettingsConfig::PRODUCT_SUFFIX_TITLE => $suffix,
43 ]));
44 $refreshSettings();
45 };
46 $customAttributes = static function (array $values): array {
47 $attributes = [];
48 foreach ($values as $name => $options) {
49 $attribute = new WC_Product_Attribute();
50 $attribute->set_name((string) $name);
51 $attribute->set_options($options);
52 $attributes[] = $attribute;
53 }
54 return $attributes;
55 };
56 $nameFor = static function (WC_Product $product): string {
57 return (new ProductDataFactory())->createHandler($product)->getName($product);
58 };
59
60 try {
61 // Fixture saves must not schedule remote product synchronization.
62 remove_all_actions('save_post');
63 remove_all_actions('woocommerce_new_product');
64 remove_all_actions('woocommerce_update_product');
65
66 $book = ['ناشر' => ['نشر چش�
67 ه'], 'نویسنده' => ['صادق هدایت']];
68 $cases = [
69 ['English comma', 'ناشر, نویسنده', $book, 'کتاب (نشر چش�
70 ه, صادق هدایت)'],
71 ['Persian comma', 'ناشر، نویسنده', $book, 'کتاب (نشر چش�
72 ه, صادق هدایت)'],
73 ['configured order', 'نویسنده, ناشر', $book, 'کتاب (صادق هدایت, نشر چش�
74 ه)'],
75 ['single-attribute compatibility', 'ناشر', $book, 'کتاب (نشر چش�
76 ه)'],
77 ['whitespace', " \tناشر , نویسنده ", ['ناشر' => [' نشر چش�
78 ه '], 'نویسنده' => [' صادق هدایت ']], 'کتاب (نشر چش�
79 ه, صادق هدایت)'],
80 ['duplicates and empty entries', ', ناشر، ناشر, نویسنده,', $book, 'کتاب (نشر چش�
81 ه, صادق هدایت)'],
82 ['missing first attribute', '�
83 ترج�
84 , ناشر', $book, 'کتاب (نشر چش�
85 ه)'],
86 ['missing second attribute', 'ناشر, �
87 ترج�
88 ', $book, 'کتاب (نشر چش�
89 ه)'],
90 ['no matching attributes', '�
91 ترج�
92 , زبان', $book, 'کتاب'],
93 ['empty attribute', 'ناشر, نویسنده', ['ناشر' => [], 'نویسنده' => ['صادق هدایت']], 'کتاب (صادق هدایت)'],
94 ['blank value', 'ناشر, نویسنده', ['ناشر' => [' '], 'نویسنده' => ['صادق هدایت']], 'کتاب (صادق هدایت)'],
95 ['multiple values', 'ناشر, نویسنده', ['ناشر' => ['نشر چش�
96 ه'], 'نویسنده' => ['صادق هدایت', 'بزرگ علوی']], 'کتاب (نشر چش�
97 ه, صادق هدایت, بزرگ علوی)'],
98 ['zero value', 'ش�
99 اره', ['ش�
100 اره' => ['0']], 'کتاب (0)'],
101 ['empty setting', '', $book, 'کتاب'],
102 ['unset setting', null, $book, 'کتاب'],
103 ['only separators', ', ، ,', $book, 'کتاب'],
104 ['no product attributes', 'ناشر, نویسنده', [], 'کتاب'],
105 ];
106
107 foreach ($cases as [$scenario, $names, $attributes, $expected]) {
108 $configure($names);
109 foreach ([WC_Product_Simple::class, WC_Product_Variable::class] as $type) {
110 $product = new $type();
111 $product->set_name('کتاب');
112 $product->set_attributes($customAttributes($attributes));
113 $assertSame($expected, $nameFor($product), $scenario . ' / ' . $type);
114 }
115 $scenarios[] = $scenario;
116 }
117
118 $configure('ناشر, نویسنده', 'yes', 'فروشگاه', 'اصل');
119 $product = new WC_Product_Simple();
120 $product->set_name('کتاب');
121 $product->set_attributes($customAttributes($book));
122 $assertSame('فروشگاه کتاب اصل (نشر چش�
123 ه, صادق هدایت)', $nameFor($product), 'static prefix and suffix');
124 $configure('ناشر, نویسنده', 'no', 'فروشگاه', 'اصل');
125 $assertSame('فروشگاه کتاب اصل', $nameFor($product), 'disabled suffix');
126 $configure('ناشر, نویسنده');
127 $product->set_name(str_repeat('ک', 115));
128 $assertSame(str_repeat('ک', 115) . ' (نشر', $nameFor($product), 'Unicode title truncation');
129 $assertSame(120, mb_strlen($nameFor($product)), 'title length');
130 $scenarios[] = 'prefix, suffix, disabled feature and Unicode title limit';
131
132 // Exercise real WooCommerce taxonomy labels, terms and persisted products.
133 foreach (['ناشر', 'نویسنده'] as $label) {
134 $slug = 'suffix_e2e_' . strtolower(wp_generate_password(8, false));
135 $id = wc_create_attribute(['name' => $label, 'slug' => $slug, 'type' => 'select']);
136 if (is_wp_error($id)) throw new RuntimeException($id->get_error_message());
137 $globalAttributes[] = $id;
138 $taxonomy = wc_attribute_taxonomy_name($slug);
139 register_taxonomy($taxonomy, ['product'], ['label' => $label, 'public' => false]);
140 // WooCommerce normally fills this registry on the next request's init.
141 $GLOBALS['wc_product_attributes'][$taxonomy] = wc_get_attribute_taxonomies()['id:' . $id];
142 $assertSame($label, wc_attribute_label($taxonomy), 'registered taxonomy label');
143 $term = wp_insert_term($label === 'ناشر' ? 'نشر چش�
144 ه' : 'صادق هدایت', $taxonomy);
145 if (is_wp_error($term)) throw new RuntimeException($term->get_error_message());
146 $attribute = new WC_Product_Attribute();
147 $attribute->set_id($id);
148 $attribute->set_name($taxonomy);
149 $attribute->set_options([$term['term_id']]);
150 $taxonomyAttributes[$label] = $attribute;
151 }
152
153 foreach ([WC_Product_Simple::class, WC_Product_Variable::class] as $type) {
154 $product = new $type();
155 $product->set_name('کتاب');
156 $product->set_status('draft');
157 $product->set_attributes([$taxonomyAttributes['نویسنده'], $taxonomyAttributes['ناشر']]);
158 $products[] = $product->save();
159 $product = wc_get_product($product->get_id());
160 $assertSame('کتاب (نشر چش�
161 ه, صادق هدایت)', $nameFor($product), 'two real taxonomy attributes / ' . $type);
162 $product->set_attributes([$taxonomyAttributes['ناشر'], ...$customAttributes(['نویسنده' => ['بزرگ علوی']])]);
163 $product->save();
164 $assertSame('کتاب (نشر چش�
165 ه, بزرگ علوی)', $nameFor(wc_get_product($product->get_id())), 'mixed global and custom attributes / ' . $type);
166 }
167 $scenarios[] = 'persisted global and custom attributes on simple and variable products';
168
169 // Use the actual settings-save path with the submitted comma-separated value.
170 $_POST = ['sync_basalam_settings' => wp_slash([
171 SettingsConfig::PRODUCT_ATTRIBUTE_SUFFIX_ENABLED => 'yes',
172 SettingsConfig::PRODUCT_ATTRIBUTE_SUFFIX_PRIORITY => 'نویسنده، ناشر',
173 ])];
174 $assertSame(true, SettingsPageHandler::saveSettings(), 'settings save');
175 $refreshSettings();
176 $assertSame('نویسنده، ناشر', syncBasalamSettings()->getSettings(SettingsConfig::PRODUCT_ATTRIBUTE_SUFFIX_PRIORITY), 'saved names');
177 $product = new WC_Product_Simple();
178 $product->set_name('کتاب');
179 $product->set_attributes($customAttributes($book));
180 $assertSame('کتاب (صادق هدایت, نشر چش�
181 ه)', $nameFor($product), 'title after saving settings');
182 ob_start();
183 SettingPageComponents::renderAttributeSuffixPriority();
184 $input = ob_get_clean();
185 $assertSame(true, strpos($input, 'value="نویسنده، ناشر"') !== false, 'settings input retains saved value');
186 $assertSame(true, strpos($input, 'placeholder="�
187 ثال: ناشر, نویسنده"') !== false, 'two-attribute example');
188 $scenarios[] = 'settings save and rendered input';
189
190 echo wp_json_encode(['passed' => true, 'assertions' => $assertions, 'scenarios' => $scenarios], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . PHP_EOL;
191 } finally {
192 $_POST = $originalPost;
193 foreach ($products as $id) {
194 $product = wc_get_product($id);
195 if ($product) $product->delete(true);
196 }
197 foreach ($globalAttributes as $id) wc_delete_attribute($id);
198 if ($originalSettings === false) {
199 delete_option('sync_basalam_settings');
200 } else {
201 update_option('sync_basalam_settings', $originalSettings);
202 }
203 }
204