$values
+ * @param mixed $default
+ *
+ * @return mixed
+ */
+ public static function priorityValues(array $priority, \ArrayAccess $values, $default = null)
+ {
+ foreach ($priority as $key) {
+ if (isset($values[$key])) {
+ return $values[$key];
+ }
+ }
+
+ return $default;
+ }
+}
diff --git a/src/Event/Loader/Customer.php b/src/Event/Loader/Customer.php
new file mode 100644
index 0000000..dcf889c
--- /dev/null
+++ b/src/Event/Loader/Customer.php
@@ -0,0 +1,77 @@
+firstname;
+ $variables['customer_lastname'] = $customer->lastname;
+ $variables['customer_email'] = $customer->email;
+
+ $address_id = (int) \Address::getFirstCustomerAddressId($customer->id);
+ $id_address_delivery = $variables['id_address_delivery'] ?? null;
+ $id_address_invoice = $variables['id_address_invoice'] ?? null;
+
+ if ($address_id) {
+ if ($id_address_delivery && $id_address_delivery !== $address_id) {
+ // shipping address has precedence
+ $this->address($variables, new \Address((int) $id_address_delivery, (int) $variables['lang_id']));
+ } else {
+ $this->address($variables, new \Address((int) $address_id, (int) $variables['lang_id']));
+ }
+ }
+
+ if ($id_address_invoice) {
+ $this->address($variables, new \Address((int) $id_address_invoice, (int) $variables['lang_id']), true);
+ }
+ }
+
+ private function address(Variables $variables, \Address $address, bool $invoice = false): void
+ {
+ $prefix = $invoice ? 'customer_invoice' : 'customer';
+
+ $variables["{$prefix}_firstname"] = $address->firstname;
+ $variables["{$prefix}_lastname"] = $address->lastname;
+ $variables["{$prefix}_country_id"] = Strings::lower((string) \Country::getIsoById($address->id_country));
+ $variables["{$prefix}_company"] = $address->company;
+ $variables["{$prefix}_phone"] = $address->phone;
+ $variables["{$prefix}_mobile"] = $address->phone_mobile;
+ $variables["{$prefix}_address"] = Helpers::joinStreet('address1', 'address2', ['address1' => $address->address1, 'address2' => $address->address2], []);
+ $variables["{$prefix}_postcode"] = $address->postcode;
+ $variables["{$prefix}_city"] = $address->city;
+ $variables["{$prefix}_country"] = $address->country;
+ $variables["{$prefix}_vat_number"] = $address->vat_number;
+ }
+}
diff --git a/src/Event/Loader/Extension.php b/src/Event/Loader/Extension.php
new file mode 100644
index 0000000..d4cde2b
--- /dev/null
+++ b/src/Event/Loader/Extension.php
@@ -0,0 +1,35 @@
+database = $database;
+ }
+
+ public function load(Variables $variables, array $parameters = []): void
+ {
+ \Hook::exec('actionPrestaSmsExtendsVariables', [
+ 'variables' => $variables,
+ 'database' => $this->database,
+ ], null, false, true, false, (int) $variables['shop_id']);
+ }
+}
diff --git a/src/Event/Loader/Order.php b/src/Event/Loader/Order.php
new file mode 100644
index 0000000..6d9acc7
--- /dev/null
+++ b/src/Event/Loader/Order.php
@@ -0,0 +1,154 @@
+formatter = $formatter;
+ }
+
+ public function load(Variables $variables, array $parameters = []): void
+ {
+ if (!isset($variables['order_id'])) {
+ return;
+ }
+
+ $order = isset($parameters['order']) && $parameters['order'] instanceof \Order ? $parameters['order'] : new \Order((int) $variables['order_id']);
+
+ $currency = (array) \Currency::getCurrency($order->id_currency);
+
+ $variables['id_address_delivery'] = (int) $order->id_address_delivery;
+ $variables['id_address_invoice'] = (int) $order->id_address_invoice;
+
+ $variables['long_order_id'] = \sprintf('%06d', $variables['order_id']);
+ $variables['cart_id'] = (int) $order->id_cart;
+ $variables['carrier_id'] = (int) $order->id_carrier;
+ $variables['order_payment'] = $order->payment;
+ $variables['order_currency'] = $currency['iso_code'] ?? null;
+ $variables['order_total_paid'] = $this->formatter->format('number', $order->total_paid);
+ $variables['order_total_locale'] = $this->formatter->format('price', $order->total_paid, $variables['order_currency']);
+ $variables['order_reference'] = $order->reference;
+
+ $variables['order_datetime'] = $this->formatter->format('datetime', $order->date_add);
+ $variables['order_date'] = $this->formatter->format('date', $order->date_add);
+ $date = new \DateTime($order->date_add);
+ $variables['order_date1'] = $date->format('d.m.Y');
+ $variables['order_date2'] = $date->format('d/m/Y');
+ $variables['order_date3'] = $date->format('d-m-Y');
+ $variables['order_date4'] = $date->format('Y-m-d');
+ $variables['order_date5'] = $date->format('m.d.Y');
+ $variables['order_date6'] = $date->format('m/d/Y');
+ $variables['order_date7'] = $date->format('m-d-Y');
+ $variables['order_time'] = $this->formatter->format('time', $order->date_add);
+ $variables['order_time1'] = $date->format('H:i');
+
+ if ($variables['carrier_id']) {
+ $carrier = new \Carrier((int) $variables['carrier_id'], (int) $variables['lang_id']);
+ $order_carrier = new \OrderCarrier((int) $variables['order_id'], (int) $variables['lang_id']);
+ $variables['order_carrier_name'] = $carrier->name;
+ $variables['order_carrier_url'] = str_replace('@', $order_carrier->tracking_number, $carrier->url);
+ $variables['order_carrier_delay'] = $carrier->delay;
+ $variables['order_carrier_tracking_number'] = $order_carrier->tracking_number;
+ $variables['order_carrier_tracking_date'] = $this->formatter->format('datetime', $order_carrier->date_add);
+ $variables['order_carrier_price'] = $this->formatter->format('number', $order_carrier->shipping_cost_tax_incl);
+ $variables['order_carrier_weight'] = $this->formatter->format('number', $order_carrier->weight);
+ $variables['order_carrier_price_locale'] = $this->formatter->format('price', $order_carrier->shipping_cost_tax_incl, $variables['order_currency']);
+ }
+
+ $message = \Message::getMessagesByOrderId((int) $variables['order_id']);
+
+ if (isset($message['message'])) {
+ $variables['order_message'] = $message['message'];
+ }
+
+ $this->products($variables);
+
+ if (isset($variables['return_id'])) {
+ $this->returnProducts($variables, $order);
+ }
+ }
+
+ private function products(Variables $variables): void
+ {
+ $p1 = $p2 = $p3 = $p4 = $pr1 = $pr2 = $pr3 = $pr4 = [];
+
+ $list = \OrderDetail::getList((int) $variables['order_id']);
+
+ $filter = $variables['filter_products'] ?? [];
+
+ foreach ($list as $row) {
+ if (empty($filter) || in_array((int) $row['id_order_detail'], (array) $filter)) {
+ $p1[] = $row['product_quantity'] . 'x ' . $row['product_name'] . ' ' . $row['product_reference'];
+ $p2[] = $row['product_quantity'] . 'x ' . $row['product_name'];
+ $p3[] = $row['product_quantity'] . 'x (' . $row['product_id'] . ')' . $row['product_name'] . ' ' . $row['product_reference'];
+ $p4[] = $row['product_quantity'] . 'x ' . $row['product_reference'];
+
+ $price = $this->formatter->format('price', $row['product_price'], $variables['order_currency']);
+
+ $pr1[] = $row['product_quantity'] . ',' . $row['product_name'] . ',' . $price;
+ $pr2[] = $row['product_quantity'] . ';' . $row['product_name'] . ';' . $price;
+ $pr3[] = $row['product_quantity'] . ',' . $row['product_reference'] . ',' . $price;
+ $pr4[] = $row['product_quantity'] . ';' . $row['product_reference'] . ';' . $price;
+ }
+ }
+
+ $variables['order_products1'] = implode('; ', $p1);
+ $variables['order_products2'] = implode('; ', $p2);
+ $variables['order_products3'] = implode('; ', $p3);
+ $variables['order_products4'] = implode('; ', $p4);
+
+ $variables['order_products5'] = implode("\n", $p1);
+ $variables['order_products6'] = implode("\n", $p2);
+ $variables['order_products7'] = implode("\n", $p3);
+ $variables['order_products8'] = implode("\n", $p4);
+
+ $variables['order_smsprinter1'] = implode(';', $pr1);
+ $variables['order_smsprinter2'] = implode(';', $pr2);
+ $variables['order_smsprinter3'] = implode(';', $pr3);
+ $variables['order_smsprinter4'] = implode(';', $pr4);
+ }
+
+ private function returnProducts(Variables $variables, \Order $order): void
+ {
+ $return = new \OrderReturn((int) $variables['return_id'], (int) $variables['lang_id'], (int) $order->id_shop);
+ $return_detail = \OrderReturn::getOrdersReturnProducts($return->id, $order);
+
+ $p1 = $p2 = $p3 = $p4 = [];
+
+ foreach ($return_detail as $row) {
+ $p1[] = $row['product_quantity'] . 'x ' . $row['product_name'] . ' ' . $row['product_reference'];
+ $p2[] = $row['product_quantity'] . 'x ' . $row['product_name'];
+ $p3[] = $row['product_quantity'] . 'x (' . $row['product_id'] . ')' . $row['product_name'] . ' ' . $row['product_reference'];
+ $p4[] = $row['product_quantity'] . 'x ' . $row['product_reference'];
+ }
+
+ $variables['return_question'] = $return->question;
+ $variables['return_products1'] = implode('; ', $p1);
+ $variables['return_products2'] = implode('; ', $p2);
+ $variables['return_products3'] = implode('; ', $p3);
+ $variables['return_products4'] = implode('; ', $p4);
+
+ $variables['return_products5'] = implode("\n", $p1);
+ $variables['return_products6'] = implode("\n", $p2);
+ $variables['return_products7'] = implode("\n", $p3);
+ $variables['return_products8'] = implode("\n", $p4);
+ }
+}
diff --git a/src/Event/Loader/OrderStatus.php b/src/Event/Loader/OrderStatus.php
new file mode 100644
index 0000000..13a0ed9
--- /dev/null
+++ b/src/Event/Loader/OrderStatus.php
@@ -0,0 +1,29 @@
+name;
+ }
+}
diff --git a/src/Event/Loader/Post.php b/src/Event/Loader/Post.php
new file mode 100644
index 0000000..50483f8
--- /dev/null
+++ b/src/Event/Loader/Post.php
@@ -0,0 +1,48 @@
+ 'customer_firstname',
+ 'last_name' => 'customer_lastname',
+ 'phone' => 'customer_phone',
+ 'mobile' => 'customer_mobile',
+ 'phone_number' => 'customer_phone',
+ 'phone_mobile' => 'customer_mobile',
+ 'email' => 'customer_email',
+
+ 'shipping_first_name' => 'customer_firstname',
+ 'shipping_last_name' => 'customer_lastname',
+ 'shipping_phone' => 'customer_phone',
+ 'shipping_company' => 'customer_company',
+ 'shipping_country' => 'customer_country',
+
+ 'billing_first_name' => 'customer_firstname',
+ 'billing_last_name' => 'customer_lastname',
+ 'billing_phone' => 'customer_mobile',
+ 'billing_company' => 'customer_company',
+ 'billing_country' => 'customer_country',
+ 'bulkgate_marketing_message_opt_in' => 'marketing_message_opt_in',
+ ];
+
+ public function load(Variables $variables, array $parameters = []): void
+ {
+ foreach (self::Mapper as $key => $value) {
+ if (isset($_POST[$key])) {
+ $variables[$value] = \Tools::getValue($key);
+ }
+ }
+ }
+}
diff --git a/src/Event/Loader/Product.php b/src/Event/Loader/Product.php
new file mode 100644
index 0000000..ff609dd
--- /dev/null
+++ b/src/Event/Loader/Product.php
@@ -0,0 +1,51 @@
+formatter = $formatter;
+ }
+
+ public function load(Variables $variables, array $parameters = []): void
+ {
+ if (!isset($variables['product_id'])) {
+ return;
+ }
+
+ $product = isset($parameters['product']) && $parameters['product'] instanceof \Product ? $parameters['product'] : new \Product((int) $variables['product_id'], false, null, (int) $variables['shop_id']);
+
+ $variables['product_name'] = \Product::getProductName((int) $product->id);
+ $variables['product_description'] = \strip_tags(\is_array($product->description_short) ? $product->description_short[$variables['lang_id']] : $product->description);
+ $variables['product_manufacturer'] = $product->manufacturer_name;
+ $variables['product_price'] = $this->formatter->format('number', $product->price);
+ $variables['product_price_locale'] = $this->formatter->format('price', $product->price, $variables['shop_currency']);
+ $variables['product_quantity'] = \Product::getQuantity((int) $product->id);
+ $variables['product_minimal_quantity'] = (int) $product->minimal_quantity;
+ $variables['product_ref'] = $product->reference;
+ $variables['product_supplier'] = \Supplier::getNameById($product->id_supplier) ?: null;
+ $variables['product_supplier_ref'] = $product->supplier_reference;
+ $variables['product_supplier_id'] = $product->id_supplier;
+ $variables['product_ean13'] = $product->ean13;
+ $variables['product_upc'] = $product->upc;
+ $variables['product_isbn'] = $product->isbn;
+ }
+}
diff --git a/src/Event/Loader/Shop.php b/src/Event/Loader/Shop.php
new file mode 100644
index 0000000..46d9d63
--- /dev/null
+++ b/src/Event/Loader/Shop.php
@@ -0,0 +1,44 @@
+language = $language;
+ }
+
+ public function load(Variables $variables, array $parameters = []): void
+ {
+ if (!isset($variables['shop_id'])) {
+ return;
+ }
+
+ $shop = new \Shop((int) $variables['shop_id']);
+
+ $variables['shop_email'] = \Configuration::get('PS_SHOP_EMAIL', null, null, $shop->id) ?: null;
+ $variables['shop_phone'] = \Configuration::get('PS_SHOP_PHONE', null, null, $shop->id) ?: null;
+ $variables['shop_currency'] = \Currency::getIsoCodeById((int) \Configuration::get('PS_CURRENCY_DEFAULT', null, null, $shop->id));
+ $variables['shop_name'] = $shop->name;
+ $variables['shop_domain'] = $shop->getBaseURL();
+ $variables['lang_id'] ??= \Configuration::get('PS_LANG_DEFAULT', null, null, $shop->id); // $shop->getAssociatedLanguage()->getId();
+ $variables['lang_iso'] = $this->language->get((int) $variables['lang_id']);
+ }
+}
diff --git a/templates/.htaccess b/templates/.htaccess
deleted file mode 100644
index 22b9ed2..0000000
--- a/templates/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-Order Allow,Deny
-Deny from all
\ No newline at end of file
diff --git a/templates/base.tpl b/templates/base.tpl
deleted file mode 100644
index 50d68fb..0000000
--- a/templates/base.tpl
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
-
-
-
{$title|prestaSmsEscapeHtml}
-
-
-
-
-
-
-
-
-
-
-
{'Loading content'|prestaSmsTranslate}
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/templates/panel.tpl b/templates/panel.tpl
deleted file mode 100644
index c35eeff..0000000
--- a/templates/panel.tpl
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
- PrestaSMS
-
-
-
-
-
{'Loading content'|prestaSmsTranslate}
-
-
-
-
-
-
\ No newline at end of file
diff --git a/tests/Ajax/AuthenticateTest.phpt b/tests/Ajax/AuthenticateTest.phpt
new file mode 100644
index 0000000..52f6757
--- /dev/null
+++ b/tests/Ajax/AuthenticateTest.phpt
@@ -0,0 +1,58 @@
+shouldReceive('load')->with('static:application_token')->once()->andReturn('token');
+ $response->shouldReceive('send')->with(['token' => 'jwt'])->once();
+
+ $sign->shouldReceive('authenticate')->once()->andReturn('jwt');
+
+ $authenticate->run('redirect');
+
+ Assert::true(true);
+ }
+
+
+ public function testGuest(): void
+ {
+ $authenticate = new Authenticate(
+ $settings = Mockery::mock(Settings::class),
+ Mockery::mock(Sign::class)
+ );
+ $response = Mockery::mock('overload:' . JsonResponse::class);
+ $settings->shouldReceive('load')->with('static:application_token')->once()->andReturnNull();
+ $response->shouldReceive('send')->with(['redirect' => 'invalid_redirect'])->once();
+
+ $authenticate->run('invalid_redirect');
+
+ Assert::true(true);
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new AuthenticateTest())->run();
\ No newline at end of file
diff --git a/tests/Ajax/PluginSettingsChangeTest.phpt b/tests/Ajax/PluginSettingsChangeTest.phpt
new file mode 100644
index 0000000..5b231f3
--- /dev/null
+++ b/tests/Ajax/PluginSettingsChangeTest.phpt
@@ -0,0 +1,102 @@
+shouldReceive('load')->with('main:language')->once()->andReturn('en');
+ $settings->shouldReceive('set')->with('main:dispatcher', 'cron', ['type' => 'string'])->once();
+ $settings->shouldReceive('set')->with('main:synchronization', 'all', ['type' => 'string'])->once();
+ $settings->shouldReceive('set')->with('main:language', 'en', ['type' => 'string'])->once();
+ $settings->shouldReceive('set')->with('main:language_mutation', false, ['type' => 'bool'])->once();
+ $settings->shouldReceive('set')->with('main:delete_db', false, ['type' => 'bool'])->once();
+ $settings->shouldReceive('set')->with('main:address_preference', 'invoice', ['type' => 'string'])->once();
+ $settings->shouldReceive('set')->with('main:marketing_message_opt_in_enabled', true, ['type' => 'bool'])->once();
+ $settings->shouldReceive('set')->with('main:marketing_message_opt_in_label', 'xxx', ['type' => 'string'])->once();
+ $settings->shouldReceive('set')->with('main:marketing_message_opt_in_default', true, ['type' => 'bool'])->once();
+ $settings->shouldReceive('set')->with('main:marketing_message_opt_in_url', 'https://xxx', ['type' => 'string'])->once();
+ $synchronize->shouldReceive('synchronize')->with(true)->once();
+
+ Assert::same([
+ 'data' => [
+ 'layout' => [
+ 'server' => [
+ 'application_settings' => [
+ 'dispatcher' => 'cron',
+ 'synchronization' => 'all',
+ 'language' => 'en',
+ 'language_mutation' => false,
+ 'delete_db' => false,
+ 'address_preference' => 'invoice',
+ 'marketing_message_opt_in_enabled' => true,
+ 'marketing_message_opt_in_label' => 'xxx',
+ 'marketing_message_opt_in_default' => true,
+ 'marketing_message_opt_in_url' => 'https://xxx',
+ ],
+ ],
+ ],
+ ],
+ 'success' => ['saved'],
+ ], $plugin_settings->run([
+ 'dispatcher' => 'cron',
+ 'synchronization' => 'all',
+ 'language' => 'en',
+ 'language_mutation' => 0,
+ 'delete_db' => 0,
+ 'address_preference' => 'invoice',
+ 'marketing_message_opt_in_enabled' => true,
+ 'marketing_message_opt_in_label' => 'xxx',
+ 'marketing_message_opt_in_default' => 'true',
+ 'marketing_message_opt_in_url' => 'xxx',
+ 'invalid' => 'xxx',
+ ], fn () => 'eshop.com'));
+ }
+
+
+ public function testLanguageRedirect(): void
+ {
+ $plugin_settings = new PluginSettingsChange($settings = Mockery::mock(Settings::class), $synchronize = Mockery::mock(Synchronizer::class));
+
+ $settings->shouldReceive('load')->with('main:language')->once()->andReturn('en');
+ $settings->shouldReceive('set')->with('main:dispatcher', 'cron', ['type' => 'string'])->once();
+ $settings->shouldReceive('set')->with('main:synchronization', 'all', ['type' => 'string'])->once();
+ $settings->shouldReceive('set')->with('main:language', 'cs', ['type' => 'string'])->once();
+ $settings->shouldReceive('set')->with('main:language_mutation', false, ['type' => 'bool'])->once();
+ $settings->shouldReceive('set')->with('main:delete_db', false, ['type' => 'bool'])->once();
+ $synchronize->shouldReceive('synchronize')->with(true)->once();
+
+ Assert::same([
+ 'data' => ['redirect' => 'eshop.com']
+ ], $plugin_settings->run([
+ 'dispatcher' => 'cron',
+ 'synchronization' => 'all',
+ 'language' => 'cs',
+ 'language_mutation' => 0,
+ 'delete_db' => 0,
+ 'invalid' => 'xxx'
+ ], fn () => 'eshop.com'));
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new PluginSettingsChangeTest())->run();
\ No newline at end of file
diff --git a/tests/Database/ConnectionTest.phpt b/tests/Database/ConnectionTest.phpt
new file mode 100644
index 0000000..8e8af1f
--- /dev/null
+++ b/tests/Database/ConnectionTest.phpt
@@ -0,0 +1,73 @@
+shouldReceive('executeQuery')->with('SELECT * FROM test WHERE id = ?', [451])->once()->andReturn($result = Mockery::mock(Result::class));
+ $result->shouldReceive('fetchAll')->with(2)->once()->andReturn([['id' => 1, 'name' => 'test1'], ['id' => 2, 'name' => 'test2']]);
+
+ $collection = $connection->execute($connection->prepare('SELECT * FROM test WHERE id = %s', 451));
+
+ Assert::same(['id' => 1, 'name' => 'test1'], $collection[0]->toArray());
+ Assert::same(['id' => 2, 'name' => 'test2'], $collection[1]->toArray());
+
+ Assert::same(['SELECT * FROM test WHERE id = ?'], $connection->getSqlList());
+ }
+
+
+ public function testTableAndPrefix(): void
+ {
+ define('_DB_PREFIX_', 'ps_');
+ $connection = new Connection(Mockery::mock(DBALConnection::class));
+
+ Assert::same('ps_xxx', $connection->table('xxx'));
+
+ Assert::same('ps_', $connection->prefix());
+ }
+
+
+ public function testEscape(): void
+ {
+ $connection = new Connection($doctrine = Mockery::mock(DBALConnection::class));
+ $doctrine->shouldReceive('quote')->with('test')->once()->andReturn('ok');
+
+ Assert::same('ok', $connection->escape('test'));
+ }
+
+
+ public function testLastId(): void
+ {
+ $connection = new Connection($doctrine = Mockery::mock(DBALConnection::class));
+ $doctrine->shouldReceive('lastInsertId')->withNoArgs()->once()->andReturn(5);
+ $doctrine->shouldReceive('lastInsertId')->withNoArgs()->once()->andReturn('ok');
+ $doctrine->shouldReceive('lastInsertId')->withNoArgs()->once()->andReturn([]);
+
+ Assert::same(5, $connection->lastId());
+ Assert::same('ok', $connection->lastId());
+ Assert::same(0, $connection->lastId());
+ }
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new ConnectionTest())->run();
+
diff --git a/tests/Eshop/ConfigurationTest.phpt b/tests/Eshop/ConfigurationTest.phpt
new file mode 100644
index 0000000..403e524
--- /dev/null
+++ b/tests/Eshop/ConfigurationTest.phpt
@@ -0,0 +1,41 @@
+shouldReceive('getUrl')->once()->andReturn('https://eshop.cz/');
+ $shop->shouldReceive('getShopName')->once()->andReturn('Můj Eshop');
+
+ $config = new Configuration('8.1.0', $url_provider, $shop);
+
+ Assert::same('https://eshop.cz/', $config->url());
+ Assert::same('ps', $config->product());
+ Assert::same('8.1.0', $config->version());
+ Assert::same('Můj Eshop', $config->name());
+ }
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new ConfigurationTest())->run();
+
diff --git a/tests/Eshop/ExtensionTest.phpt b/tests/Eshop/ExtensionTest.phpt
new file mode 100644
index 0000000..8503ceb
--- /dev/null
+++ b/tests/Eshop/ExtensionTest.phpt
@@ -0,0 +1,42 @@
+shouldReceive('exec')->with('actionPrestaSmsExtendsVariables', [
+ 'variables' => $variables = new Variables(['shop_id' => 451]),
+ 'database' => $connection = Mockery::mock(Connection::class),
+ ], null, false, true, false, 451)->once()->andReturnNull();
+
+ $loader = new Extension($connection);
+
+ $loader->load($variables);
+
+ Assert::same(['shop_id' => 451], $variables->toArray());
+ }
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new ExtensionTest())->run();
+
diff --git a/tests/Eshop/LanguageTest.phpt b/tests/Eshop/LanguageTest.phpt
new file mode 100644
index 0000000..9c309c2
--- /dev/null
+++ b/tests/Eshop/LanguageTest.phpt
@@ -0,0 +1,60 @@
+shouldReceive('getLanguages')->once()->andReturn([
+ ['iso_code' => 'cs', 'name' => 'Čeština'],
+ ['iso_code' => 'en', 'name' => 'English'],
+ ]);
+
+ $language = new Language();
+
+ Assert::same([
+ 'cs' => 'Čeština',
+ 'en' => 'English',
+ ], $language->load());
+ }
+
+ public function testGet(): void
+ {
+ $psLanguage = Mockery::mock('alias:Language');
+ $psLanguage->shouldReceive('getIsoById')->with(8)->andReturn('cs');
+ $psLanguage->shouldReceive('getIsoById')->with(99)->andReturn(null);
+
+ $language = new Language();
+ Assert::same('cs', $language->get(8));
+ Assert::same('en', $language->get(99));
+ Assert::same('en', $language->get(null));
+ }
+
+ public function testHasMultiLanguageSupport(): void
+ {
+ $language = new Language();
+
+ Assert::true($language->hasMultiLanguageSupport());
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new LanguageTest())->run();
diff --git a/tests/Eshop/MultiStoreTest.phpt b/tests/Eshop/MultiStoreTest.phpt
new file mode 100644
index 0000000..3174972
--- /dev/null
+++ b/tests/Eshop/MultiStoreTest.phpt
@@ -0,0 +1,41 @@
+shouldReceive('getShops')->once()->andReturn([
+ ['id_shop' => 1, 'name' => 'Shop 1'],
+ ['id_shop' => 2, 'name' => 'Shop 2'],
+ ]);
+
+ Assert::same([
+ 1 => 'Shop 1',
+ 2 => 'Shop 2',
+ ], $multiStore->load());
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new MultiStoreTest())->run();
+
diff --git a/tests/Eshop/OrderStatusTest.phpt b/tests/Eshop/OrderStatusTest.phpt
new file mode 100644
index 0000000..812b922
--- /dev/null
+++ b/tests/Eshop/OrderStatusTest.phpt
@@ -0,0 +1,41 @@
+shouldReceive('getLanguageId')->once()->andReturn(8);
+ $order_state->shouldReceive('getOrderStates')->with(8)->once()->andReturn([
+ ['id_order_state' => 1, 'name' => 'Nová objednávka'],
+ ['id_order_state' => 2, 'name' => 'Odesláno'],
+ ]);
+
+ Assert::same([
+ 1 => 'Nová objednávka',
+ 2 => 'Odesláno',
+ ], $orderStatus->load());
+ }
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new OrderStatusTest())->run();
+
diff --git a/tests/Eshop/ReturnStatusTest.phpt b/tests/Eshop/ReturnStatusTest.phpt
new file mode 100644
index 0000000..ec37a5d
--- /dev/null
+++ b/tests/Eshop/ReturnStatusTest.phpt
@@ -0,0 +1,42 @@
+shouldReceive('getLanguageId')->once()->andReturn(8);
+ $return_state->shouldReceive('getOrderReturnStates')->with(8)->once()->andReturn([
+ ['id_order_return_state' => 1, 'name' => 'Čeká na schválení'],
+ ['id_order_return_state' => 2, 'name' => 'Vyřízeno'],
+ ]);
+
+ Assert::same([
+ 1 => 'Čeká na schválení',
+ 2 => 'Vyřízeno',
+ ], $returnStatus->load());
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new ReturnStatusTest())->run();
+
diff --git a/tests/Event/HelpersTest.phpt b/tests/Event/HelpersTest.phpt
new file mode 100644
index 0000000..dd73834
--- /dev/null
+++ b/tests/Event/HelpersTest.phpt
@@ -0,0 +1,29 @@
+ 1, 'v2' => 2, 'v3' => 3]);
+
+ Assert::same('test', Helpers::priorityValues([], $variables, 'test'));
+ Assert::same(3, Helpers::priorityValues(['v3'], $variables, 'test'));
+ Assert::same(1, Helpers::priorityValues(['v1', 'v3'], $variables, 'test'));
+ Assert::same(2, Helpers::priorityValues(['v2', 'v1', 'v3'], $variables, 'test'));
+ Assert::same(2, Helpers::priorityValues(['cc', 'v2', 'v1', 'v3'], $variables, 'test'));
+ }
+}
+
+(new HelpersTest())->run();
diff --git a/tests/Event/Loader/CustomerTest.phpt b/tests/Event/Loader/CustomerTest.phpt
new file mode 100644
index 0000000..0eddf8b
--- /dev/null
+++ b/tests/Event/Loader/CustomerTest.phpt
@@ -0,0 +1,75 @@
+shouldReceive('__construct')->with(123)->set('id', 123)->set('firstname', 'Jan')->set('lastname', 'Novák')->set('email', 'jan.novak@example.com');
+
+ $address = Mockery::mock('overload:Address');
+ $address->shouldReceive('getFirstCustomerAddressId')->with(123)->andReturn(10);
+ $address->shouldReceive('__construct')->with(10, 8)->set('firstname', 'Jan')->set('lastname', 'Novák')->set('id_country', 56)->set('company', 'Firma')->set('phone', '123456789')->set('phone_mobile', '987654321')->set('address1', 'Ulice 1')->set('address2', 'Patro 2')->set('postcode', '11000')->set('city', 'Praha')->set('country', 'Česká republika')->set('vat_number', 'CZ12345678');
+
+ $country = Mockery::mock('overload:Country');
+ $country->shouldReceive('getIsoById')->with(56)->andReturn('CZ');
+
+ $helpers = Mockery::mock('alias:BulkGate\Plugin\Event\Helpers');
+ $helpers->shouldReceive('joinStreet')->with('address1', 'address2', ['address1' => 'Ulice 1', 'address2' => 'Patro 2'], [])->andReturn('Ulice 1, Patro 2');
+
+ $variables = new Variables([
+ 'customer_id' => 123,
+ 'lang_id' => 8,
+ ]);
+
+ $loader = new Customer();
+ $loader->load($variables);
+
+ Assert::same([
+ 'customer_id' => 123,
+ 'lang_id' => 8,
+ 'customer_firstname' => 'Jan',
+ 'customer_lastname' => 'Novák',
+ 'customer_email' => 'jan.novak@example.com',
+ 'customer_country_id' => 'cz',
+ 'customer_company' => 'Firma',
+ 'customer_phone' => '123456789',
+ 'customer_mobile' => '987654321',
+ 'customer_address' => 'Ulice 1, Patro 2',
+ 'customer_postcode' => '11000',
+ 'customer_city' => 'Praha',
+ 'customer_country' => 'Česká republika',
+ 'customer_vat_number' => 'CZ12345678',
+ ], $variables->toArray());
+ }
+
+ public function testNotCustomerId(): void
+ {
+ $loader = new Customer();
+ $variables = new Variables();
+ $loader->load($variables);
+ Assert::same([], $variables->toArray());
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new CustomerTest())->run();
+
diff --git a/tests/Event/Loader/OrderStatusTest.phpt b/tests/Event/Loader/OrderStatusTest.phpt
new file mode 100644
index 0000000..a8cc5de
--- /dev/null
+++ b/tests/Event/Loader/OrderStatusTest.phpt
@@ -0,0 +1,55 @@
+shouldReceive('__construct')->with(5, 8)->once()->set('name', 'Shipped');
+
+ $variables = new Variables([
+ 'order_status_id' => 5,
+ 'lang_id' => 8,
+ ]);
+
+ $loader = new OrderStatus();
+ $loader->load($variables);
+
+ Assert::same([
+ 'order_status_id' => 5,
+ 'lang_id' => 8,
+ 'order_status' => 'Shipped',
+ ], $variables->toArray());
+ }
+
+ public function testNotOrderStatusId(): void
+ {
+ $variables = new Variables(['lang_id' => 8]);
+ $loader = new OrderStatus();
+ $loader->load($variables);
+
+ Assert::same(['lang_id' => 8], $variables->toArray());
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new OrderStatusTest())->run();
+
diff --git a/tests/Event/Loader/OrderTest.phpt b/tests/Event/Loader/OrderTest.phpt
new file mode 100644
index 0000000..373554b
--- /dev/null
+++ b/tests/Event/Loader/OrderTest.phpt
@@ -0,0 +1,247 @@
+shouldReceive('__construct')->with(123)->set('id', 123)->set('id_currency', 7)->set('id_address_delivery', 1)->set('id_address_invoice', 2)->set('id_cart', 10)->set('id_carrier', 20)->set('payment', 'Bankwire')->set('total_paid', 999.99)->set('reference', 'ORD123')->set('date_add', '2025-07-04 12:34:56')->set('id_shop', 451);
+
+ $currency = Mockery::mock('overload:Currency');
+ $currency->shouldReceive('getCurrency')->with(7)->andReturn(['iso_code' => 'CZK']);
+
+ $formatter = Mockery::mock(Formatter::class);
+ $formatter->shouldReceive('format')->with('number', 999.99)->andReturn('999,99');
+ $formatter->shouldReceive('format')->with('price', 999.99, 'CZK')->andReturn('999,99 CZK');
+ $formatter->shouldReceive('format')->with('datetime', '2025-07-04 12:34:56')->andReturn('4.7.2025 12:34');
+ $formatter->shouldReceive('format')->with('date', '2025-07-04 12:34:56')->andReturn('4.7.2025');
+ $formatter->shouldReceive('format')->with('time', '2025-07-04 12:34:56')->andReturn('12:34');
+
+ $carrier = Mockery::mock('overload:Carrier');
+ $carrier->shouldReceive('__construct')->with(20, 8)->set('name', 'PPL')->set('url', 'https://track/@')->set('delay', 'Next day');
+ $order_carrier = Mockery::mock('overload:OrderCarrier');
+ $order_carrier->shouldReceive('__construct')->with(123, 8)->set('tracking_number', 'TRACK123')->set('date_add', '2025-07-04 13:00:00')->set('shipping_cost_tax_incl', 100.0)->set('weight', 2.5);
+ $formatter->shouldReceive('format')->with('datetime', '2025-07-04 13:00:00')->andReturn('4.7.2025 13:00');
+ $formatter->shouldReceive('format')->with('number', 100.0)->andReturn('100,00');
+ $formatter->shouldReceive('format')->with('number', 2.5)->andReturn('2,50');
+ $formatter->shouldReceive('format')->with('price', 100.0, 'CZK')->andReturn('100,00 CZK');
+
+ $order_detail = Mockery::mock('overload:OrderDetail');
+ $order_detail->shouldReceive('getList')->with(123)->andReturn([
+ [
+ 'id_order_detail' => 1,
+ 'product_quantity' => 2,
+ 'product_name' => 'T-shirt',
+ 'product_reference' => 'TSHIRT',
+ 'product_id' => 101,
+ 'product_price' => 500.0,
+ ],
+ ]);
+ $formatter->shouldReceive('format')->with('price', 500.0, 'CZK')->andReturn('500,00 CZK');
+
+ $message = Mockery::mock('overload:Message');
+ $message->shouldReceive('getMessagesByOrderId')->with(123)->andReturn(['message' => 'Děkujeme za objednávku']);
+
+ $variables = new Variables([
+ 'order_id' => 123,
+ 'lang_id' => 8,
+ ]);
+
+ $loader = new Order($formatter);
+ $loader->load($variables);
+
+ Assert::same([
+ 'order_id' => 123,
+ 'lang_id' => 8,
+ 'id_address_delivery' => 1,
+ 'id_address_invoice' => 2,
+ 'long_order_id' => '000123',
+ 'cart_id' => 10,
+ 'carrier_id' => 20,
+ 'order_payment' => 'Bankwire',
+ 'order_currency' => 'CZK',
+ 'order_total_paid' => '999,99',
+ 'order_total_locale' => '999,99 CZK',
+ 'order_reference' => 'ORD123',
+ 'order_datetime' => '4.7.2025 12:34',
+ 'order_date' => '4.7.2025',
+ 'order_date1' => '04.07.2025',
+ 'order_date2' => '04/07/2025',
+ 'order_date3' => '04-07-2025',
+ 'order_date4' => '2025-07-04',
+ 'order_date5' => '07.04.2025',
+ 'order_date6' => '07/04/2025',
+ 'order_date7' => '07-04-2025',
+ 'order_time' => '12:34',
+ 'order_time1' => '12:34',
+ 'order_carrier_name' => 'PPL',
+ 'order_carrier_url' => 'https://track/TRACK123',
+ 'order_carrier_delay' => 'Next day',
+ 'order_carrier_tracking_number' => 'TRACK123',
+ 'order_carrier_tracking_date' => '4.7.2025 13:00',
+ 'order_carrier_price' => '100,00',
+ 'order_carrier_weight' => '2,50',
+ 'order_carrier_price_locale' => '100,00 CZK',
+ 'order_message' => 'Děkujeme za objednávku',
+ 'order_products1' => '2x T-shirt TSHIRT',
+ 'order_products2' => '2x T-shirt',
+ 'order_products3' => '2x (101)T-shirt TSHIRT',
+ 'order_products4' => '2x TSHIRT',
+ 'order_products5' => "2x T-shirt TSHIRT",
+ 'order_products6' => "2x T-shirt",
+ 'order_products7' => "2x (101)T-shirt TSHIRT",
+ 'order_products8' => "2x TSHIRT",
+ 'order_smsprinter1' => '2,T-shirt,500,00 CZK',
+ 'order_smsprinter2' => '2;T-shirt;500,00 CZK',
+ 'order_smsprinter3' => '2,TSHIRT,500,00 CZK',
+ 'order_smsprinter4' => '2;TSHIRT;500,00 CZK',
+ ], $variables->toArray());
+ }
+
+ public function testNotOrderId(): void
+ {
+ $formatter = Mockery::mock(Formatter::class);
+ $loader = new Order($formatter);
+ $loader->load($variables = new Variables());
+ Assert::same([], $variables->toArray());
+ }
+
+ public function testLoadWithReturn(): void
+ {
+ $order = Mockery::mock('overload:Order');
+ $order->shouldReceive('__construct')->with(123)->set('id', 123)->set('id_currency', 7)->set('id_address_delivery', 1)->set('id_address_invoice', 2)->set('id_cart', 10)->set('id_carrier', 20)->set('payment', 'Bankwire')->set('total_paid', 999.99)->set('reference', 'ORD123')->set('date_add', '2025-07-04 12:34:56')->set('id_shop', 451);
+
+ $currency = Mockery::mock('overload:Currency');
+ $currency->shouldReceive('getCurrency')->with(7)->andReturn(['iso_code' => 'CZK']);
+
+ $formatter = Mockery::mock(Formatter::class);
+ $formatter->shouldReceive('format')->with('number', 999.99)->andReturn('999,99');
+ $formatter->shouldReceive('format')->with('price', 999.99, 'CZK')->andReturn('999,99 CZK');
+ $formatter->shouldReceive('format')->with('datetime', '2025-07-04 12:34:56')->andReturn('4.7.2025 12:34');
+ $formatter->shouldReceive('format')->with('date', '2025-07-04 12:34:56')->andReturn('4.7.2025');
+ $formatter->shouldReceive('format')->with('time', '2025-07-04 12:34:56')->andReturn('12:34');
+
+ $carrier = Mockery::mock('overload:Carrier');
+ $carrier->shouldReceive('__construct')->with(20, 8)->set('name', 'PPL')->set('url', 'https://track/@')->set('delay', 'Next day');
+ $order_carrier = Mockery::mock('overload:OrderCarrier');
+ $order_carrier->shouldReceive('__construct')->with(123, 8)->set('tracking_number', 'TRACK123')->set('date_add', '2025-07-04 13:00:00')->set('shipping_cost_tax_incl', 100.0)->set('weight', 2.5);
+ $formatter->shouldReceive('format')->with('datetime', '2025-07-04 13:00:00')->andReturn('4.7.2025 13:00');
+ $formatter->shouldReceive('format')->with('number', 100.0)->andReturn('100,00');
+ $formatter->shouldReceive('format')->with('number', 2.5)->andReturn('2,50');
+ $formatter->shouldReceive('format')->with('price', 100.0, 'CZK')->andReturn('100,00 CZK');
+
+ $order_detail = Mockery::mock('overload:OrderDetail');
+ $order_detail->shouldReceive('getList')->with(123)->andReturn([
+ [
+ 'id_order_detail' => 1,
+ 'product_quantity' => 2,
+ 'product_name' => 'T-shirt',
+ 'product_reference' => 'TSHIRT',
+ 'product_id' => 101,
+ 'product_price' => 500.0,
+ ],
+ ]);
+ $formatter->shouldReceive('format')->with('price', 500.0, 'CZK')->andReturn('500,00 CZK');
+
+ $message = Mockery::mock('overload:Message');
+ $message->shouldReceive('getMessagesByOrderId')->with(123)->andReturn(['message' => 'Děkujeme za objednávku']);
+
+ $order_return = Mockery::mock('overload:OrderReturn');
+ $order_return->shouldReceive('__construct')->with(55, 8, 451)->set('id', 55)->set('question', 'Chci vrátit zboží');
+ $order_return->shouldReceive('getOrdersReturnProducts')->with(55, Mockery::type('object'))->andReturn([
+ [
+ 'product_quantity' => 1,
+ 'product_name' => 'T-shirt',
+ 'product_reference' => 'TSHIRT',
+ 'product_id' => 101,
+ ],
+ ]);
+
+ $variables = new Variables([
+ 'order_id' => 123,
+ 'lang_id' => 8,
+ 'return_id' => 55,
+ ]);
+
+ $loader = new Order($formatter);
+ $loader->load($variables);
+
+ Assert::same([
+ 'order_id' => 123,
+ 'lang_id' => 8,
+ 'return_id' => 55,
+ 'id_address_delivery' => 1,
+ 'id_address_invoice' => 2,
+ 'long_order_id' => '000123',
+ 'cart_id' => 10,
+ 'carrier_id' => 20,
+ 'order_payment' => 'Bankwire',
+ 'order_currency' => 'CZK',
+ 'order_total_paid' => '999,99',
+ 'order_total_locale' => '999,99 CZK',
+ 'order_reference' => 'ORD123',
+ 'order_datetime' => '4.7.2025 12:34',
+ 'order_date' => '4.7.2025',
+ 'order_date1' => '04.07.2025',
+ 'order_date2' => '04/07/2025',
+ 'order_date3' => '04-07-2025',
+ 'order_date4' => '2025-07-04',
+ 'order_date5' => '07.04.2025',
+ 'order_date6' => '07/04/2025',
+ 'order_date7' => '07-04-2025',
+ 'order_time' => '12:34',
+ 'order_time1' => '12:34',
+ 'order_carrier_name' => 'PPL',
+ 'order_carrier_url' => 'https://track/TRACK123',
+ 'order_carrier_delay' => 'Next day',
+ 'order_carrier_tracking_number' => 'TRACK123',
+ 'order_carrier_tracking_date' => '4.7.2025 13:00',
+ 'order_carrier_price' => '100,00',
+ 'order_carrier_weight' => '2,50',
+ 'order_carrier_price_locale' => '100,00 CZK',
+ 'order_message' => 'Děkujeme za objednávku',
+ 'order_products1' => '2x T-shirt TSHIRT',
+ 'order_products2' => '2x T-shirt',
+ 'order_products3' => '2x (101)T-shirt TSHIRT',
+ 'order_products4' => '2x TSHIRT',
+ 'order_products5' => "2x T-shirt TSHIRT",
+ 'order_products6' => "2x T-shirt",
+ 'order_products7' => "2x (101)T-shirt TSHIRT",
+ 'order_products8' => "2x TSHIRT",
+ 'order_smsprinter1' => '2,T-shirt,500,00 CZK',
+ 'order_smsprinter2' => '2;T-shirt;500,00 CZK',
+ 'order_smsprinter3' => '2,TSHIRT,500,00 CZK',
+ 'order_smsprinter4' => '2;TSHIRT;500,00 CZK',
+ 'return_question' => 'Chci vrátit zboží',
+ 'return_products1' => '1x T-shirt TSHIRT',
+ 'return_products2' => '1x T-shirt',
+ 'return_products3' => '1x (101)T-shirt TSHIRT',
+ 'return_products4' => '1x TSHIRT',
+ 'return_products5' => "1x T-shirt TSHIRT",
+ 'return_products6' => "1x T-shirt",
+ 'return_products7' => "1x (101)T-shirt TSHIRT",
+ 'return_products8' => "1x TSHIRT",
+ ], $variables->toArray());
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new OrderTest())->run();
diff --git a/tests/Event/Loader/PostTest.phpt b/tests/Event/Loader/PostTest.phpt
new file mode 100644
index 0000000..c403d91
--- /dev/null
+++ b/tests/Event/Loader/PostTest.phpt
@@ -0,0 +1,55 @@
+shouldReceive('getValue')->with('phone_number')->once()->andReturn('123456789');
+ $tools->shouldReceive('getValue')->with('phone_mobile')->once()->andReturn('987654321');
+
+ $_POST = [
+ 'phone_number' => '123456789',
+ 'phone_mobile' => '987654321',
+ ];
+
+ $variables = new Variables();
+ $loader = new Post();
+ $loader->load($variables);
+
+ Assert::same([
+ 'customer_phone' => '123456789',
+ 'customer_mobile' => '987654321',
+ ], $variables->toArray());
+ }
+
+ public function testEmptyPost(): void
+ {
+ $_POST = [];
+ $variables = new Variables();
+ $loader = new Post();
+ $loader->load($variables);
+ Assert::same([], $variables->toArray());
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new PostTest())->run();
diff --git a/tests/Event/Loader/ProductTest.phpt b/tests/Event/Loader/ProductTest.phpt
new file mode 100644
index 0000000..95e784f
--- /dev/null
+++ b/tests/Event/Loader/ProductTest.phpt
@@ -0,0 +1,80 @@
+shouldReceive('__construct')->with(123, false, null, 451)->set('id', 123)->set('description_short', ['8' => 'Short desc'])->set('description', 'Long desc')->set('manufacturer_name', 'TestMan')->set('price', 99.99)->set('minimal_quantity', 2)->set('reference', 'REF123')->set('id_supplier', 5)->set('supplier_reference', 'SUPREF')->set('ean13', 'EAN123')->set('upc', 'UPC123')->set('isbn', 'ISBN123');
+ $product->shouldReceive('getQuantity')->with(123)->andReturn(10);
+ $product->shouldReceive('getProductName')->with(123)->andReturn('Test Product');
+
+ $supplier = Mockery::mock('overload:Supplier');
+ $supplier->shouldReceive('getNameById')->with(5)->once()->andReturn('SupplierName');
+
+ $variables = new Variables([
+ 'product_id' => 123,
+ 'shop_id' => 451,
+ 'lang_id' => 8,
+ 'shop_currency' => 'CZK',
+ ]);
+
+ $loader = new Product($formatter = Mockery::mock(Formatter::class));
+ $formatter->shouldReceive('format')->with('number', 99.99)->once()->andReturn('99,99');
+ $formatter->shouldReceive('format')->with('price', 99.99, 'CZK')->once()->andReturn('99,99 CZK');
+
+ $loader->load($variables);
+
+ Assert::same([
+ 'product_id' => 123,
+ 'shop_id' => 451,
+ 'lang_id' => 8,
+ 'shop_currency' => 'CZK',
+ 'product_name' => 'Test Product',
+ 'product_description' => 'Short desc',
+ 'product_manufacturer' => 'TestMan',
+ 'product_price' => '99,99',
+ 'product_price_locale' => '99,99 CZK',
+ 'product_quantity' => 10,
+ 'product_minimal_quantity' => 2,
+ 'product_ref' => 'REF123',
+ 'product_supplier' => 'SupplierName',
+ 'product_supplier_ref' => 'SUPREF',
+ 'product_supplier_id' => 5,
+ 'product_ean13' => 'EAN123',
+ 'product_upc' => 'UPC123',
+ 'product_isbn' => 'ISBN123',
+ ], $variables->toArray());
+ }
+
+
+ public function testNotProductId(): void
+ {
+ $loader = new Product(Mockery::mock(Formatter::class));
+ $loader->load($variables = new Variables());
+
+ Assert::same([], $variables->toArray());
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new ProductTest())->run();
+
diff --git a/tests/Event/Loader/ShopTest.phpt b/tests/Event/Loader/ShopTest.phpt
new file mode 100644
index 0000000..b798662
--- /dev/null
+++ b/tests/Event/Loader/ShopTest.phpt
@@ -0,0 +1,68 @@
+shouldReceive('__construct')->set('id', 451)->set('name', 'PrestaShop Development');
+ $prestashop_shop->shouldReceive('getBaseURL')->withNoArgs()->once()->andReturn('https://bulkgate.com/');
+
+ $configuration = Mockery::mock('overload:Configuration');
+ $configuration->shouldReceive('get')->with('PS_SHOP_EMAIL', null, null, 451)->once()->andReturn('xxx@bulkgate.com');
+ $configuration->shouldReceive('get')->with('PS_SHOP_PHONE', null, null, 451)->once()->andReturn('+420777777777');
+ $configuration->shouldReceive('get')->with('PS_CURRENCY_DEFAULT', null, null, 451)->once()->andReturn('7');
+ $configuration->shouldReceive('get')->with('PS_LANG_DEFAULT', null, null, 451)->once()->andReturn('8');
+
+ $currency = Mockery::mock('overload:Currency');
+ $currency->shouldReceive('getIsoCodeById')->with(7)->once()->andReturn('CZK');
+
+ $variables = new Variables(['shop_id' => 451]);
+
+ $shop = new Shop($language = Mockery::mock(Language::class));
+ $language->shouldReceive('get')->with(8)->once()->andReturn('cs');
+
+ $shop->load($variables);
+
+ Assert::same([
+ 'shop_id' => 451,
+ 'shop_email' => 'xxx@bulkgate.com',
+ 'shop_phone' => '+420777777777',
+ 'shop_currency' => 'CZK',
+ 'shop_name' => 'PrestaShop Development',
+ 'shop_domain' => 'https://bulkgate.com/',
+ 'lang_id' => '8',
+ 'lang_iso' => 'cs',
+ ], $variables->toArray());
+ }
+
+
+ public function testNotShopId(): void
+ {
+ $shop = new Shop(Mockery::mock(Language::class));
+ $shop->load($variables = new Variables());
+
+ Assert::same([], $variables->toArray());
+ }
+
+
+ public function tearDown(): void
+ {
+ Mockery::close();
+ }
+}
+
+(new ShopTest())->run();
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 0000000..78c93ec
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,15 @@
+
+ BulkGate Debug
+ This page serves as a comprehensive tool for users to monitor, analyze, and troubleshoot the plugin, including tracking errors in the log. It also provides essential information and troubleshooting capabilities.
+
+ Requirements test
+
+
+
+
+ PHP Version
+
+
+ {{ php_version }}
+
+
+
+
+ Platform Version (Prestashop)
+
+
+ {{ platform_version }}
+
+
+
+
+ Module Version
+
+
+ {{ module_version }}
+
+
+
+
+ URL
+
+
+ {{ url }}
+
+
+ {% for requirement in requirements %}
+
+
+ {{ requirement.description }}
+
+
+ {{ requirement.passed ? "OK" : "FAIL " ~requirement.error }}
+
+
+ {% endfor %}
+
+
+
+ Error log
+ {% if errors %}
+
+
+
+
+ Date
+ Message
+ Version
+
+
+ {% for error in errors %}
+
+
+ {{ error.created | date('d.m. Y H:i:s') }}
+
+
+ {{ error.message }}
+
+
+ {% if error.parameters %}
+ platform
+
+ module
+ {% else %}
+ -
+ {% endif %}
+
+
+ {% endfor %}
+
+
+
+ {% else %}
+ No errors found.
+ {% endif %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/views/templates/admin/index.html.twig b/views/templates/admin/index.html.twig
new file mode 100644
index 0000000..4d3f057
--- /dev/null
+++ b/views/templates/admin/index.html.twig
@@ -0,0 +1,305 @@
+{% extends '@!PrestaShop/Admin/layout.html.twig' %}
+
+{% block javascripts %}
+ {{ parent() }}
+
+
+{% endblock %}
+
+{% block stylesheets %}
+
+{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/views/templates/admin/send-message.html.twig b/views/templates/admin/send-message.html.twig
new file mode 100644
index 0000000..44389a2
--- /dev/null
+++ b/views/templates/admin/send-message.html.twig
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ send_to_mobile {{ 'Send message' | trans }}
+
+