diff --git a/.env.testing b/.env.testing index 9d8e653ca..e87932525 100644 --- a/.env.testing +++ b/.env.testing @@ -13,6 +13,7 @@ DB_PORT=3306 DB_DATABASE=bagisto_testing DB_USERNAME=bagisto DB_PASSWORD=secret +DB_PREFIX= BROADCAST_DRIVER=log CACHE_DRIVER=file diff --git a/.gitignore b/.gitignore index 8c9f19aa2..db81adbec 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /public/js /public/vendor /public/themes +/public/fonts /vendor /.idea /.vscode diff --git a/app/Console/Commands/GenerateProducts.php b/app/Console/Commands/GenerateProducts.php index f72681fb1..b1899c0b5 100644 --- a/app/Console/Commands/GenerateProducts.php +++ b/app/Console/Commands/GenerateProducts.php @@ -61,6 +61,7 @@ class GenerateProducts extends Command try { $result = $this->generateProduct->create(); } catch (\Exception $e) { + report($e); continue; } diff --git a/bin/codecept b/bin/codecept new file mode 120000 index 000000000..a43e3ac1e --- /dev/null +++ b/bin/codecept @@ -0,0 +1 @@ +../vendor/bin/codecept \ No newline at end of file diff --git a/bin/test.sh b/bin/test.sh new file mode 100755 index 000000000..6f82ff04a --- /dev/null +++ b/bin/test.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +printf "### start preparation ###\n" + + WORKPATH=$(dirname ${0}) + printf ">> workpath is %s\n" ${WORKPATH} + + LOG_DIR="${WORKPATH}/../storage/logs/tests" + printf ">> log-dir is %s\n" ${LOG_DIR} + + printf ">> create and truncate log dir\n" + mkdir -p ${LOG_DIR} + rm -rf ${LOG_DIR}/* + + printf ">> truncate and migrate database\n" + php artisan migrate:fresh --env=testing --quiet + +printf "### finish preparation ###\n" + +printf "### start tests ###\n" + + SUCCESS=1 + execSuite() { + ${WORKPATH}/../vendor/bin/codecept run ${1} \ + --xml report_${1}.xml ${CODECEPT_OPTIONS} | tee ${LOG_DIR}/tests_${1}.log + if [[ ${PIPESTATUS[0]} -ne 0 ]] + then + SUCCESS=0 + fi + } + + execSuite unit + execSuite functional + + if [[ ${?} -ne 0 ]] + then + SUCCESS=0 + fi + +printf "### finish tests ###\n" + +if [[ ${SUCCESS} -eq 1 ]] +then + printf ">> all tests are \e[01;32mgreen\e[0m\n" + exit 0 +else + printf ">> at least one test is \e[01;31mred\e[0m\n" + exit 1 +fi diff --git a/package.json b/package.json index 103d618f3..dc5c0e6c3 100755 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "resolve-url-loader": "^3.1.0", "sass": "^1.24.5", "sass-loader": "^8.0.2", - "vue": "^2.5.7", + "vue": "^2.6.11", "vue-template-compiler": "^2.6.11" }, "dependencies": { diff --git a/packages/Webkul/Admin/src/DataGrids/AddressDataGrid.php b/packages/Webkul/Admin/src/DataGrids/AddressDataGrid.php index b9db127b1..e41c82191 100644 --- a/packages/Webkul/Admin/src/DataGrids/AddressDataGrid.php +++ b/packages/Webkul/Admin/src/DataGrids/AddressDataGrid.php @@ -52,7 +52,7 @@ class AddressDataGrid extends DataGrid $queryBuilder = DB::table('customer_addresses as ca') ->leftJoin('countries', 'ca.country', '=', 'countries.code') ->leftJoin('customers as c', 'ca.customer_id', '=', 'c.id') - ->addSelect('ca.id as address_id', 'ca.address1', 'ca.country', DB::raw('' . DB::getTablePrefix() . 'countries.name as country_name'), 'ca.state', 'ca.city', 'ca.postcode', 'ca.phone', 'ca.default_address') + ->addSelect('ca.id as address_id', 'ca.company_name', 'ca.vat_id', 'ca.address1', 'ca.country', DB::raw('' . DB::getTablePrefix() . 'countries.name as country_name'), 'ca.state', 'ca.city', 'ca.postcode', 'ca.phone', 'ca.default_address') ->where('c.id', $customer->id); $queryBuilder = $queryBuilder->leftJoin('country_states', function($qb) { @@ -65,6 +65,8 @@ class AddressDataGrid extends DataGrid ->addSelect(DB::raw(DB::getTablePrefix() . 'country_states.default_name as state_name')); $this->addFilter('address_id', 'ca.id'); + $this->addFilter('company_name', 'ca.company_name'); + $this->addFilter('vat_id', 'ca.vat_id'); $this->addFilter('address1', 'ca.address1'); $this->addFilter('city', 'ca.city'); $this->addFilter('state_name', DB::raw(DB::getTablePrefix() . 'country_states.default_name')); @@ -77,6 +79,7 @@ class AddressDataGrid extends DataGrid public function addColumns() { + $this->addColumn([ 'index' => 'address_id', 'label' => trans('admin::app.customers.addresses.address-id'), @@ -131,6 +134,15 @@ class AddressDataGrid extends DataGrid 'filterable' => true ]); + $this->addColumn([ + 'index' => 'vat_id', + 'label' => trans('admin::app.customers.addresses.vat_id'), + 'type' => 'string', + 'searchable' => true, + 'sortable' => true, + 'filterable' => true + ]); + $this->addColumn([ 'index' => 'default_address', 'label' => trans('admin::app.customers.addresses.default-address'), diff --git a/packages/Webkul/Admin/src/DataGrids/CustomerDataGrid.php b/packages/Webkul/Admin/src/DataGrids/CustomerDataGrid.php index 7345ea683..a8b501d27 100755 --- a/packages/Webkul/Admin/src/DataGrids/CustomerDataGrid.php +++ b/packages/Webkul/Admin/src/DataGrids/CustomerDataGrid.php @@ -135,7 +135,8 @@ class CustomerDataGrid extends DataGrid 'type' => 'Edit', 'method' => 'GET', //use post only for redirects only 'route' => 'admin.customer.addresses.index', - 'icon' => 'icon list-icon' + 'icon' => 'icon list-icon', + 'title' => trans('admin::app.customers.customers.addresses') ]); $this->addAction([ diff --git a/packages/Webkul/Admin/src/Http/Controllers/Customer/AddressController.php b/packages/Webkul/Admin/src/Http/Controllers/Customer/AddressController.php index 2f89fa8d6..d44921463 100644 --- a/packages/Webkul/Admin/src/Http/Controllers/Customer/AddressController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Customer/AddressController.php @@ -2,6 +2,7 @@ namespace Webkul\Admin\Http\Controllers\Customer; +use Webkul\Customer\Rules\VatIdRule; use Webkul\Admin\Http\Controllers\Controller; use Webkul\Customer\Repositories\CustomerRepository as Customer; use Webkul\Customer\Repositories\CustomerAddressRepository as CustomerAddress; @@ -20,25 +21,26 @@ class AddressController extends Controller * @var array */ protected $_config; - + /** * Customer Repository object * * @var object - */ + */ protected $customer; - + /** * CustomerAddress Repository object * * @var object - */ + */ protected $customerAddress; - + /** * Create a new controller instance. * - * @param Webkul\Customer\Repositories\CustomerAddressRepository $customerAddress + * @param Webkul\Customer\Repositories\CustomerAddressRepository $customerAddress + * * @return void */ public function __construct( @@ -59,7 +61,7 @@ class AddressController extends Controller * @return Mixed */ public function index($id) - { + { $customer = $this->customer->find($id); return view($this->_config['view'], compact('customer')); @@ -84,20 +86,24 @@ class AddressController extends Controller */ public function store() { - request()->merge(['address1' => implode(PHP_EOL, array_filter(request()->input('address1')))]); + request()->merge([ + 'address1' => implode(PHP_EOL, array_filter(request()->input('address1'))), + ]); $data = collect(request()->input())->except('_token')->toArray(); $this->validate(request(), [ - 'address1' => 'string|required', - 'country' => 'string|required', - 'state' => 'string|required', - 'city' => 'string|required', - 'postcode' => 'required', - 'phone' => 'required' + 'company_name' => 'string', + 'address1' => 'string|required', + 'country' => 'string|required', + 'state' => 'string|required', + 'city' => 'string|required', + 'postcode' => 'required', + 'phone' => 'required', + 'vat_id' => new VatIdRule(), ]); - if ( $this->customerAddress->create($data) ) { + if ($this->customerAddress->create($data)) { session()->flash('success', trans('admin::app.customers.addresses.success-create')); return redirect()->route('admin.customer.addresses.index', ['id' => $data['customer_id']]); @@ -131,19 +137,21 @@ class AddressController extends Controller request()->merge(['address1' => implode(PHP_EOL, array_filter(request()->input('address1')))]); $this->validate(request(), [ - 'address1' => 'string|required', - 'country' => 'string|required', - 'state' => 'string|required', - 'city' => 'string|required', - 'postcode' => 'required', - 'phone' => 'required' + 'company_name' => 'string', + 'address1' => 'string|required', + 'country' => 'string|required', + 'state' => 'string|required', + 'city' => 'string|required', + 'postcode' => 'required', + 'phone' => 'required', + 'vat_id' => new VatIdRule(), ]); $data = collect(request()->input())->except('_token')->toArray(); $address = $this->customerAddress->find($id); - if ( $address ) { + if ($address) { $this->customerAddress->update($data, $id); @@ -157,7 +165,8 @@ class AddressController extends Controller /** * Remove the specified resource from storage. * - * @param int $id + * @param int $id + * * @return \Illuminate\Http\Response */ public function destroy($id) diff --git a/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerController.php b/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerController.php index 5c9930e84..20a9a6205 100755 --- a/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerController.php +++ b/packages/Webkul/Admin/src/Http/Controllers/Customer/CustomerController.php @@ -31,14 +31,14 @@ class CustomerController extends Controller */ protected $customerRepository; - /** + /** * CustomerGroupRepository object * * @var array */ protected $customerGroupRepository; - /** + /** * ChannelRepository object * * @var array @@ -74,13 +74,13 @@ class CustomerController extends Controller * Display a listing of the resource. * * @return \Illuminate\View\View - */ + */ public function index() { return view($this->_config['view']); } - /** + /** * Show the form for creating a new resource. * * @return \Illuminate\View\View @@ -91,10 +91,10 @@ class CustomerController extends Controller $channelName = $this->channelRepository->all(); - return view($this->_config['view'], compact('customerGroup','channelName')); + return view($this->_config['view'], compact('customerGroup', 'channelName')); } - /** + /** * Store a newly created resource in storage. * * @return \Illuminate\Http\Response @@ -102,16 +102,16 @@ class CustomerController extends Controller public function store() { $this->validate(request(), [ - 'first_name' => 'string|required', - 'last_name' => 'string|required', - 'gender' => 'required', - 'email' => 'required|unique:customers,email', - 'date_of_birth' => 'date|before:today' + 'first_name' => 'string|required', + 'last_name' => 'string|required', + 'gender' => 'required', + 'email' => 'required|unique:customers,email', + 'date_of_birth' => 'date|before:today', ]); $data = request()->all(); - $password = rand(100000,10000000); + $password = rand(100000, 10000000); $data['password'] = bcrypt($password); @@ -122,7 +122,7 @@ class CustomerController extends Controller try { Mail::queue(new NewCustomerNotification($customer, $password)); } catch (\Exception $e) { - + report($e); } session()->flash('success', trans('admin::app.response.create-success', ['name' => 'Customer'])); @@ -133,7 +133,8 @@ class CustomerController extends Controller /** * Show the form for editing the specified resource. * - * @param int $id + * @param int $id + * * @return \Illuminate\View\View */ public function edit($id) @@ -147,20 +148,21 @@ class CustomerController extends Controller return view($this->_config['view'], compact('customer', 'customerGroup', 'channelName')); } - /** + /** * Update the specified resource in storage. * - * @param int $id + * @param int $id + * * @return \Illuminate\Http\Response */ public function update($id) { $this->validate(request(), [ - 'first_name' => 'string|required', - 'last_name' => 'string|required', - 'gender' => 'required', - 'email' => 'required|unique:customers,email,'. $id, - 'date_of_birth' => 'date|before:today' + 'first_name' => 'string|required', + 'last_name' => 'string|required', + 'gender' => 'required', + 'email' => 'required|unique:customers,email,' . $id, + 'date_of_birth' => 'date|before:today', ]); $this->customerRepository->update(request()->all(), $id); @@ -173,7 +175,8 @@ class CustomerController extends Controller /** * Remove the specified resource from storage. * - * @param int $id + * @param int $id + * * @return \Illuminate\Http\Response */ public function destroy($id) @@ -186,7 +189,7 @@ class CustomerController extends Controller session()->flash('success', trans('admin::app.response.delete-success', ['name' => 'Customer'])); return response()->json(['message' => true], 200); - } catch(\Exception $e) { + } catch (\Exception $e) { session()->flash('error', trans('admin::app.response.delete-failed', ['name' => 'Customer'])); } @@ -213,13 +216,13 @@ class CustomerController extends Controller public function storeNote() { $this->validate(request(), [ - 'notes' => 'string|nullable' + 'notes' => 'string|nullable', ]); $customer = $this->customerRepository->find(request()->input('_customer')); $noteTaken = $customer->update([ - 'notes' => request()->input('notes') + 'notes' => request()->input('notes'), ]); if ($noteTaken) { @@ -245,7 +248,7 @@ class CustomerController extends Controller $customer = $this->customerRepository->find($customerId); $customer->update([ - 'status' => $updateOption + 'status' => $updateOption, ]); } @@ -265,7 +268,7 @@ class CustomerController extends Controller foreach ($customerIds as $customerId) { $this->customerRepository->deleteWhere([ - 'id' => $customerId + 'id' => $customerId, ]); } diff --git a/packages/Webkul/Admin/src/Listeners/Order.php b/packages/Webkul/Admin/src/Listeners/Order.php index 895c05539..5b8495589 100755 --- a/packages/Webkul/Admin/src/Listeners/Order.php +++ b/packages/Webkul/Admin/src/Listeners/Order.php @@ -10,13 +10,15 @@ use Webkul\Admin\Mail\NewShipmentNotification; use Webkul\Admin\Mail\NewInventorySourceNotification; use Webkul\Admin\Mail\CancelOrderNotification; use Webkul\Admin\Mail\NewRefundNotification; + /** * Order event handler * * @author Jitendra Singh * @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com) */ -class Order { +class Order +{ /** * @param mixed $order @@ -30,7 +32,7 @@ class Order { Mail::queue(new NewAdminNotification($order)); } catch (\Exception $e) { - + report($e); } } @@ -42,12 +44,13 @@ class Order { public function sendNewInvoiceMail($invoice) { try { - if ($invoice->email_sent) + if ($invoice->email_sent) { return; + } Mail::queue(new NewInvoiceNotification($invoice)); } catch (\Exception $e) { - + report($e); } } @@ -61,7 +64,7 @@ class Order { try { Mail::queue(new NewRefundNotification($refund)); } catch (\Exception $e) { - + report($e); } } @@ -73,25 +76,28 @@ class Order { public function sendNewShipmentMail($shipment) { try { - if ($shipment->email_sent) + if ($shipment->email_sent) { return; + } Mail::queue(new NewShipmentNotification($shipment)); Mail::queue(new NewInventorySourceNotification($shipment)); } catch (\Exception $e) { - + report($e); } } - /* + /** * @param mixed $order - * */ - public function sendCancelOrderMail($order){ - try{ + * + */ + public function sendCancelOrderMail($order) + { + try { Mail::queue(new CancelOrderNotification($order)); - }catch (\Exception $e){ - \Log::error('Error occured when sending email '.$e->getMessage()); + } catch (\Exception $e) { + report($e); } } } \ No newline at end of file diff --git a/packages/Webkul/Admin/src/Resources/lang/ar/app.php b/packages/Webkul/Admin/src/Resources/lang/ar/app.php index 2f7acfa1d..0287d9194 100644 --- a/packages/Webkul/Admin/src/Resources/lang/ar/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/ar/app.php @@ -760,10 +760,19 @@ return [ 'state' => 'State', 'select-state' => 'اختر منطقة أو ولاية أو مقاطعة.', 'country' => 'Country', + 'other' => 'Other', 'male' => 'Male', 'female' => 'Female', 'phone' => 'Phone', 'group-default' => 'لا يستطيع حذف افتراضي المجموعة.', + 'edit-help-title' => 'Edit Customer', + 'delete-help-title' => 'Delete Customer', + 'addresses' => 'Addresses', + 'mass-destroy-success' => 'Customers deleted successfully', + 'mass-update-success' => 'Customers updated successfully', + 'status' => 'Status', + 'active' => 'Active', + 'in-active' => 'Inactive' ], 'reviews' => [ 'title' => 'باء-الاستعراضات', diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index adae4ecc7..25a79fa1a 100755 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -334,7 +334,7 @@ return [ 'item-status' => 'Item Status', 'item-ordered' => 'Ordered (:qty_ordered)', 'item-invoice' => 'Invoiced (:qty_invoiced)', - 'item-shipped' => 'shipped (:qty_shipped)', + 'item-shipped' => 'Shipped (:qty_shipped)', 'item-canceled' => 'Canceled (:qty_canceled)', 'item-refunded' => 'Refunded (:qty_refunded)', 'price' => 'Price', @@ -867,6 +867,7 @@ return [ 'addresses' => [ 'title' => ':customer_name\'s Addresses List', + 'vat_id' => 'Vat id', 'create-title' => 'Create Customer\'s Address', 'edit-title' => 'Update Customer\'s Address', 'title-orders' => ':customer_name\'s Orders List', @@ -917,12 +918,14 @@ return [ 'state' => 'State', 'select-state' => 'Select a region, state or province.', 'country' => 'Country', + 'other' => 'Other', 'male' => 'Male', 'female' => 'Female', 'phone' => 'Phone', 'group-default' => 'Cannot delete the default group.', 'edit-help-title' => 'Edit Customer', 'delete-help-title' => 'Delete Customer', + 'addresses' => 'Addresses', 'mass-destroy-success' => 'Customers deleted successfully', 'mass-update-success' => 'Customers updated successfully', 'status' => 'Status', diff --git a/packages/Webkul/Admin/src/Resources/lang/fa/app.php b/packages/Webkul/Admin/src/Resources/lang/fa/app.php index 7c8d247f6..8a0eb3992 100644 --- a/packages/Webkul/Admin/src/Resources/lang/fa/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/fa/app.php @@ -802,11 +802,13 @@ return [ 'state' => 'استان', 'select-state' => 'یک منطقه ، ایالت یا استان را انتخاب کنید.', 'country' => 'کشور', + 'other' => 'Other', 'male' => 'مرد', 'female' => 'زن', 'group-default' => 'نمی توان گروه پیش فرض را حذف کرد.', 'edit-help-title' => 'ویرایش مشتری', 'delete-help-title' => 'حذف مشتری', + 'addresses' => 'Addresses', 'mass-destroy-success' => 'مشتریان با موفقیت حذف شدند', 'mass-update-success' => 'مشتریان با موفقیت به روز شدند', 'status' => 'وضعیت', diff --git a/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php b/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php index 1c8a5d7d2..5c11fd620 100755 --- a/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/pt_BR/app.php @@ -791,12 +791,14 @@ return [ 'state' => 'Estado', 'select-state' => 'Selecione uma região, estado ou província.', 'country' => 'País', + 'other' => 'Other', 'male' => 'Masculino', 'female' => 'Feminino', 'phone' => 'Telefone', 'group-default' => 'Não possível excluir o grupo de cliente.', 'edit-help-title' => 'Editar cliente', 'delete-help-title' => 'Excluir cliente', + 'addresses' => 'Addresses', 'mass-destroy-success' => 'Clientes excluídos com sucesso', 'mass-update-success' => 'Clientes atualizados com sucesso', 'status' => 'Status', diff --git a/packages/Webkul/Admin/src/Resources/views/catalog/categories/create.blade.php b/packages/Webkul/Admin/src/Resources/views/catalog/categories/create.blade.php index 39c5df661..680837501 100755 --- a/packages/Webkul/Admin/src/Resources/views/catalog/categories/create.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/catalog/categories/create.blade.php @@ -39,7 +39,7 @@
- + @{{ errors.first('name') }}
@@ -96,7 +96,7 @@
-
- +
- +
- +
@@ -71,7 +71,7 @@ var EmailTarget = window.location.href.concat('/EmailConfig.php'); - $.ajax({type : 'POST', url : EmailTarget, data : mailformData, dataType : 'json', encode : true}) + $.ajax({type : 'POST', url : EmailTarget, data : mailformData, dataType : 'json', encode : true}) .done(function(data) { if (!data.success) { // handle errors @@ -112,7 +112,7 @@ } else { $('#admin').hide(); $('#email').hide(); - $('#finish').show(); + $('#finish').show(); } }); // stop the form from submitting the normal way and refreshing the page diff --git a/public/installer/index.php b/public/installer/index.php index c49424f86..395084dbf 100755 --- a/public/installer/index.php +++ b/public/installer/index.php @@ -25,15 +25,7 @@ -
+
+ Powered by Bagisto, A Community Project by + Webkul +
+ diff --git a/storage/app/db-blade-compiler/views/.gitignore b/storage/app/db-blade-compiler/views/.gitignore old mode 100755 new mode 100644 diff --git a/tests/_support/FunctionalTester.php b/tests/_support/FunctionalTester.php index 38b53fd7d..41b348f5a 100644 --- a/tests/_support/FunctionalTester.php +++ b/tests/_support/FunctionalTester.php @@ -5,7 +5,7 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Route; use Webkul\User\Models\Admin; - +use Webkul\Customer\Models\Customer; /** * Inherited Methods @@ -31,26 +31,65 @@ class FunctionalTester extends \Codeception\Actor */ /** - * Login as default administrator + * Set the logged in user to the admin identity. + * + * @param \Webkul\User\Models\Admin|null $admin + * + * @throws \Exception + * @returns Admin */ - public function loginAsAdmin(): void + public function loginAsAdmin(Admin $admin = null): Admin { $I = $this; - Auth::guard('admin')->login($I->grabRecord(Admin::class, ['email' => 'admin@example.com'])); + if (! $admin) { + $admin = $I->grabRecord(Admin::class, ['email' => 'admin@example.com']); + } + + if (! $admin) { + throw new \Exception( + 'Admin user not found in database. Please ensure Seeders are executed'); + } + + Auth::guard('admin') + ->login($admin); + $I->seeAuthentication('admin'); + + return $admin; } /** - * Go to a specific route and check if admin guard is applied on it + * Set the logged in user to the customer identity. * - * @param string $name name of the route - * @param array|null $params params the route will be created with + * @param \Webkul\User\Models\Customer|null $customer + * + * @throws \Exception + * @returns Customer */ - public function amOnAdminRoute(string $name, array $params = null): void + public function loginAsCustomer(Customer $customer = null): Customer { $I = $this; - $I->amOnRoute($name, $params); + + if (! $customer) { + $customer = $I->have(Customer::class); + } + + Auth::guard('customer') + ->login($customer); + + $I->seeAuthentication('customer'); + + return $customer; + } + + /** + * @param string $name + */ + public function amOnAdminRoute(string $name) + { + $I = $this; + $I->amOnRoute($name); $I->seeCurrentRouteIs($name); /** @var RouteCollection $routes */ diff --git a/tests/_support/Helper/DataMocker.php b/tests/_support/Helper/DataMocker.php new file mode 100644 index 000000000..536e2dbef --- /dev/null +++ b/tests/_support/Helper/DataMocker.php @@ -0,0 +1,29 @@ +have(Attribute::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.catalog'), '//*[contains(@class, "navbar-left")]'); + $I->click(__('admin::app.layouts.attributes'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.catalog.attributes.index'); + $I->see($attribute->id, '//script[@type="text/x-template"]'); + $I->see($attribute->admin_name, '//script[@type="text/x-template"]'); + } + + public function testCreate(FunctionalTester $I): void + { + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.catalog.attributes.index'); + + $I->click('Add Attribute', '//*[contains(@class, "page-action")]'); + $I->seeCurrentRouteIs('admin.catalog.attributes.create'); + + $I->click('Save Attribute', '//*[contains(@class, "page-action")]'); + $I->seeFormHasErrors(); + + $testData = $this->fillForm($I); + $I->click('Save Attribute', '//*[contains(@class, "page-action")]'); + + $I->dontSeeFormErrors(); + $I->seeCurrentRouteIs('admin.catalog.attributes.index'); + $I->seeRecord(Attribute::class, $testData); + } + + public function testEdit(FunctionalTester $I): void + { + $attribute = $I->have(Attribute::class, ['use_in_flat' => 0]); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.catalog.attributes.index'); + + $route = route('admin.catalog.attributes.edit', ['id' => $attribute->id]); + $I->seeInSource($route); + $I->amOnPage($route); + $I->seeCurrentRouteIs('admin.catalog.attributes.edit'); + + $I->fillField('admin_name', ''); + $I->click('Save Attribute', '//*[contains(@class, "page-action")]'); + $I->seeFormHasErrors(); + + $testData = $this->fillForm($I, true); + $testData['id'] = $attribute->id; + $I->click('Save Attribute', '//*[contains(@class, "page-action")]'); + + $I->dontSeeFormErrors(); + $I->seeRecord(Attribute::class, $testData); + $I->seeCurrentRouteIs('admin.catalog.attributes.index'); + } + + /** + * @param FunctionalTester $I + * + * @param bool $skipType + * + * @return array with the test-data + */ + private function fillForm(FunctionalTester $I, bool $skipType = false): array + { + $testData = [ + 'code' => $I->fake()->word, + 'type' => $I->fake()->randomElement([ + 'text', + 'textarea', + 'price', + 'boolean', + 'select', + 'multiselect' + ]), + 'admin_name' => $I->fake()->word, + ]; + + $I->fillField('code', $testData['code']); + $I->fillField('admin_name', $testData['admin_name']); + + if ($skipType) { + unset($testData['type']); + } else { + $I->selectOption('type', $testData['type']); + } + + return $testData; + } +} diff --git a/tests/functional/Admin/Catalog/AttributeFamilyCest.php b/tests/functional/Admin/Catalog/AttributeFamilyCest.php new file mode 100644 index 000000000..9c17e02d6 --- /dev/null +++ b/tests/functional/Admin/Catalog/AttributeFamilyCest.php @@ -0,0 +1,86 @@ +have(AttributeFamily::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.catalog'), '//*[contains(@class, "navbar-left")]'); + $I->click(__('admin::app.layouts.attribute-families'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.catalog.families.index'); + $I->see($attributeFamily->id, '//script[@type="text/x-template"]'); + $I->see($attributeFamily->name, '//script[@type="text/x-template"]'); + } + + public function testCreate(FunctionalTester $I): void + { + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.catalog.families.index'); + + $I->click(__('admin::app.catalog.families.add-family-btn-title'), '//*[contains(@class, "page-action")]'); + $I->seeCurrentRouteIs('admin.catalog.families.create'); + + $I->click(__('admin::app.catalog.families.save-btn-title'), '//*[contains(@class, "page-action")]'); + $I->seeFormHasErrors(); + + $testData = $this->fillForm($I); + $I->click(__('admin::app.catalog.families.save-btn-title'), '//*[contains(@class, "page-action")]'); + + $I->dontSeeFormErrors(); + $I->seeCurrentRouteIs('admin.catalog.families.index'); + $I->seeRecord(AttributeFamily::class, $testData); + } + + public function testEdit(FunctionalTester $I): void + { + $attributeFamily = $I->have(AttributeFamily::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.catalog.families.index'); + + $route = route('admin.catalog.families.edit', ['id' => $attributeFamily->id]); + $I->seeInSource($route); + $I->amOnPage($route); + $I->seeCurrentRouteIs('admin.catalog.families.edit'); + + $I->fillField('name', ''); + $I->click(__('admin::app.catalog.families.save-btn-title'), '//*[contains(@class, "page-action")]'); + $I->seeFormHasErrors(); + + $testData = $this->fillForm($I); + $testData['id'] = $attributeFamily->id; + $I->click(__('admin::app.catalog.families.save-btn-title'), '//*[contains(@class, "page-action")]'); + + $I->dontSeeFormErrors(); + $I->seeRecord(AttributeFamily::class, $testData); + $I->seeCurrentRouteIs('admin.catalog.families.index'); + } + + /** + * @param FunctionalTester $I + * + * @return array with the test-data + */ + private function fillForm(FunctionalTester $I): array + { + $testData = [ + 'code' => $I->fake()->word, + 'name' => $I->fake()->word, + ]; + + $I->fillField('code', $testData['code']); + $I->fillField('name', $testData['name']); + + return $testData; + } +} diff --git a/tests/functional/Admin/Catalog/CategoryCest.php b/tests/functional/Admin/Catalog/CategoryCest.php new file mode 100644 index 000000000..a4dbaccda --- /dev/null +++ b/tests/functional/Admin/Catalog/CategoryCest.php @@ -0,0 +1,23 @@ +have(Category::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.catalog'), '//*[contains(@class, "navbar-left")]'); + $I->click(__('admin::app.layouts.categories'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.catalog.categories.index'); + $I->see($category->id, '//script[@type="text/x-template"]'); + $I->see($category->name, '//script[@type="text/x-template"]'); + } +} diff --git a/tests/functional/Product/ProductCest.php b/tests/functional/Admin/Catalog/ProductCest.php similarity index 69% rename from tests/functional/Product/ProductCest.php rename to tests/functional/Admin/Catalog/ProductCest.php index f8f4b18bf..d666fd90a 100644 --- a/tests/functional/Product/ProductCest.php +++ b/tests/functional/Admin/Catalog/ProductCest.php @@ -1,7 +1,6 @@ faker = Factory::create(); @@ -55,22 +54,38 @@ class ProductCest } - public function selectEmptyAttributeOptionOnProductCreation(FunctionalTester $I) + public function testIndex(FunctionalTester $I): void + { + $product = $I->haveProduct([], ['simple']); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.catalog'), '//*[contains(@class, "navbar-left")]'); + $I->seeCurrentRouteIs('admin.catalog.products.index'); + $I->click(__('admin::app.layouts.products'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.catalog.products.index'); + $I->see($product->id, '//script[@type="text/x-template"]'); + $I->see($product->name, '//script[@type="text/x-template"]'); + } + + public function selectEmptyAttributeOptionOnProductCreation(FunctionalTester $I): void { $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.catalog.products.index'); - $I->amOnAdminRoute('admin.catalog.products.create'); - $I->see(__('admin::app.catalog.products.add-title'), 'h1'); + $I->click(__('admin::app.catalog.products.add-product-btn-title'), '//*[contains(@class, "page-action")]'); + $I->seeCurrentRouteIs('admin.catalog.products.create'); - $I->selectOption('select#type', 'simple'); + $I->selectOption('type', 'simple'); $attributeFamily = $I->grabRecord(AttributeFamily::class, [ 'code' => 'default', ]); - $I->selectOption('select#attribute_family_id', $attributeFamily->id); + $I->selectOption('attribute_family_id', $attributeFamily->id); - $sku = $this->faker->uuid; + $sku = $this->faker->randomNumber(3); $I->fillField('sku', $sku); $I->click(__('admin::app.catalog.products.save-btn-title')); @@ -89,8 +104,8 @@ class ProductCest $I->fillField('price', $this->faker->randomFloat(2)); $I->fillField('weight', $this->faker->randomDigit); - $I->fillField('#short_description', $this->faker->paragraph(1, true)); - $I->fillField('#description', $this->faker->paragraph(5, true)); + $I->fillField('short_description', $this->faker->paragraph(1, true)); + $I->fillField('description', $this->faker->paragraph(5, true)); $I->click(__('admin::app.catalog.products.save-btn-title')); diff --git a/tests/functional/Admin/Customer/CustomerCest.php b/tests/functional/Admin/Customer/CustomerCest.php new file mode 100644 index 000000000..4ac5d4bb6 --- /dev/null +++ b/tests/functional/Admin/Customer/CustomerCest.php @@ -0,0 +1,26 @@ +have(Customer::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.customers'), '//*[contains(@class, "navbar-left")]'); + $I->seeCurrentRouteIs('admin.customer.index'); + $I->click(__('admin::app.layouts.customers'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.customer.index'); + $I->see($customer->id, '//script[@type="text/x-template"]'); + $I->see($customer->name, '//script[@type="text/x-template"]'); + } +} diff --git a/tests/functional/Admin/Customer/GroupsCest.php b/tests/functional/Admin/Customer/GroupsCest.php new file mode 100644 index 000000000..22db609e2 --- /dev/null +++ b/tests/functional/Admin/Customer/GroupsCest.php @@ -0,0 +1,25 @@ +have(CustomerGroup::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.customers'), '//*[contains(@class, "navbar-left")]'); + $I->click(__('admin::app.layouts.groups'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.groups.index'); + $I->see($group->id, '//script[@type="text/x-template"]'); + $I->see($group->name, '//script[@type="text/x-template"]'); + } +} diff --git a/tests/functional/Admin/Customer/NewsletterSubscriptionCest.php b/tests/functional/Admin/Customer/NewsletterSubscriptionCest.php new file mode 100644 index 000000000..f52aef90d --- /dev/null +++ b/tests/functional/Admin/Customer/NewsletterSubscriptionCest.php @@ -0,0 +1,24 @@ +have(SubscribersList::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.customers'), '//*[contains(@class, "navbar-left")]'); + $I->click(__('admin::app.layouts.newsletter-subscriptions'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.customers.subscribers.index'); + $I->see($subscriber->id, '//script[@type="text/x-template"]'); + $I->see($subscriber->email, '//script[@type="text/x-template"]'); + } +} diff --git a/tests/functional/Admin/Customer/ReviewCest.php b/tests/functional/Admin/Customer/ReviewCest.php new file mode 100644 index 000000000..bd04f1c81 --- /dev/null +++ b/tests/functional/Admin/Customer/ReviewCest.php @@ -0,0 +1,26 @@ +haveProduct([], ['simple']); + $review = $I->have(ProductReview::class, ['product_id' => $product->id]); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.customers'), '//*[contains(@class, "navbar-left")]'); + $I->click(__('admin::app.layouts.reviews'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.customer.review.index'); + $I->see($review->id, '//script[@type="text/x-template"]'); + $I->see($review->title, '//script[@type="text/x-template"]'); + } +} diff --git a/tests/functional/Admin/Sales/InvoiceCest.php b/tests/functional/Admin/Sales/InvoiceCest.php new file mode 100644 index 000000000..7a82812dd --- /dev/null +++ b/tests/functional/Admin/Sales/InvoiceCest.php @@ -0,0 +1,28 @@ +have(OrderAddress::class); + $invoice = $I->have(Invoice::class, + [ + 'order_id' => $orderAddress->order_id, + 'order_address_id' => $orderAddress->id, + ]); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.sales'), '//*[contains(@class, "navbar-left")]'); + $I->click(__('admin::app.layouts.invoices'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.sales.invoices.index'); + $I->see($invoice->id, '//script[@type="text/x-template"]'); + } +} diff --git a/tests/functional/Admin/Sales/OrderCest.php b/tests/functional/Admin/Sales/OrderCest.php new file mode 100644 index 000000000..f48aa0aa9 --- /dev/null +++ b/tests/functional/Admin/Sales/OrderCest.php @@ -0,0 +1,26 @@ +have(Order::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.sales'), '//*[contains(@class, "navbar-left")]'); + $I->seeCurrentRouteIs('admin.sales.orders.index'); + $I->click(__('admin::app.layouts.orders'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.sales.orders.index'); + $I->see($order->id, '//script[@type="text/x-template"]'); + $I->see($order->sub_total, '//script[@type="text/x-template"]'); + } +} diff --git a/tests/functional/Admin/Sales/RefundCest.php b/tests/functional/Admin/Sales/RefundCest.php new file mode 100644 index 000000000..c9fbc943c --- /dev/null +++ b/tests/functional/Admin/Sales/RefundCest.php @@ -0,0 +1,23 @@ +have(Refund::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.sales'), '//*[contains(@class, "navbar-left")]'); + $I->click(__('admin::app.layouts.refunds'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.sales.refunds.index'); + $I->see($refund->id, '//script[@type="text/x-template"]'); + } +} diff --git a/tests/functional/Admin/Sales/ShipmentsCest.php b/tests/functional/Admin/Sales/ShipmentsCest.php new file mode 100644 index 000000000..541598868 --- /dev/null +++ b/tests/functional/Admin/Sales/ShipmentsCest.php @@ -0,0 +1,24 @@ +have(Shipment::class); + + $I->loginAsAdmin(); + $I->amOnAdminRoute('admin.dashboard.index'); + $I->click(__('admin::app.layouts.sales'), '//*[contains(@class, "navbar-left")]'); + $I->click(__('admin::app.layouts.shipments'), '//*[contains(@class, "aside-nav")]'); + + $I->seeCurrentRouteIs('admin.sales.shipments.index'); + $I->see($shipment->id, '//script[@type="text/x-template"]'); + $I->see($shipment->total_qty, '//script[@type="text/x-template"]'); + } +} diff --git a/tests/functional/Customer/CustomerCest.php b/tests/functional/Customer/CustomerCest.php new file mode 100644 index 000000000..b3c0f9256 --- /dev/null +++ b/tests/functional/Customer/CustomerCest.php @@ -0,0 +1,125 @@ +loginAsCustomer(); + + $I->amOnPage('/'); + + $I->click('Profile'); + + $I->click('Edit'); + + $I->selectOption('gender', 'Other'); + + $I->click('Update Profile'); + + $I->dontSeeInSource('The old password does not match.'); + + $I->seeInSource('Profile updated successfully.'); + + $I->seeRecord(Customer::class, [ + 'id' => $customer->id, + 'gender' => 'Other', + ]); + } + + public function updateCustomerAddress(FunctionalTester $I) + { + $I->wantTo('Instantiate a european faker factory to have the vat provider available'); + $faker = Faker\Factory::create('at_AT'); + + $formCssSelector = '#customer-address-form'; + + $I->loginAsCustomer(); + + $I->amOnPage('/'); + + $I->click('Profile'); + + $I->click('Address'); + + $I->click('Add Address'); + + $this->fields = [ + 'company_name' => $faker->company, + 'vat_id' => 'INVALIDVAT', + 'address1[]' => $faker->streetAddress, + 'country' => $faker->countryCode, + 'state' => $faker->state, + 'city' => $faker->city, + 'postcode' => $faker->postcode, + 'phone' => $faker->phoneNumber, + ]; + + foreach ($this->fields as $key => $value) { + // the following fields are being rendered via javascript so we ignore them: + if (! in_array($key, [ + 'country', + 'state', + ])) { + $selector = 'input[name="' . $key . '"]'; + $I->fillField($selector, $value); + } + } + + $I->wantTo('Ensure that the company_name field is being displayed'); + $I->seeElement('.account-table-content > div:nth-child(2) > input:nth-child(2)'); + + // we need to use this css selector to hit the correct
. There is another one at the + // page header (search) + $I->submitForm($formCssSelector, $this->fields); + $I->seeInSource('The given vat id has a wrong format'); + + $I->wantTo('enter a valid vat id'); + $this->fields['vat_id'] = $faker->vat(false); + + $I->submitForm($formCssSelector, $this->fields); + + $I->seeInSource('Address have been successfully added.'); + + $this->assertCustomerAddress($I); + + $I->wantTo('Update the created customer address again'); + + $I->click('Edit'); + + $oldcompany = $this->fields['company_name']; + $this->fields['company_name'] = $faker->company; + + $I->submitForm($formCssSelector, $this->fields); + + $I->seeInSource('Address updated successfully.'); + + $I->dontSeeRecord(CustomerAddress::class, [ + 'company_name' => $oldcompany, + ]); + + $this->assertCustomerAddress($I); + } + + /** + * @param \FunctionalTester $I + * @param array $fields + */ + private function assertCustomerAddress(FunctionalTester $I): void + { + $I->seeRecord(CustomerAddress::class, [ + 'company_name' => $this->fields['company_name'], + 'vat_id' => $this->fields['vat_id'], + 'address1' => $this->fields['address1[]'], + 'country' => $this->fields['country'], + 'state' => $this->fields['state'], + 'city' => $this->fields['city'], + 'phone' => $this->fields['phone'], + 'postcode' => $this->fields['postcode'], + ]); + } +} \ No newline at end of file