diff --git a/.travis.yml b/.travis.yml
index 869fe959c00..a8a0d826145 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,11 @@ dist: trusty
python:
- "2.7"
+ - "3.6"
+
+env:
+ - TEST_TYPE="Server Side Test"
+ - TEST_TYPE="Patch Test"
services:
- mysql
@@ -39,18 +44,8 @@ before_script:
- bench start &
- sleep 10
-jobs:
- include:
- - stage: test
- script:
- - set -e
- - bench run-tests --app erpnext --coverage
- after_script:
- - coveralls -b apps/erpnext -d ../../sites/.coverage
- env: Server Side Test
- - # stage
- script:
- - wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
- - bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
- - bench migrate
- env: Patch Testing
+script:
+ - bash $TRAVIS_BUILD_DIR/travis/run-tests.sh
+
+after_script:
+ - coveralls -b apps/erpnext -d ../../sites/.coverage
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 7f0f60ff02e..186f3fd1e60 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -350,7 +350,7 @@ def filter_pricing_rules(args, pricing_rules):
if len(pricing_rules) > 1:
rate_or_discount = list(set([d.rate_or_discount for d in pricing_rules]))
if len(rate_or_discount) == 1 and rate_or_discount[0] == "Discount Percentage":
- pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \
+ pricing_rules = list(filter(lambda x: x.for_price_list==args.price_list, pricing_rules)) \
or pricing_rules
if len(pricing_rules) > 1 and not args.for_shopping_cart:
@@ -373,7 +373,7 @@ def apply_internal_priority(pricing_rules, field_set, args):
filtered_rules = []
for field in field_set:
if args.get(field):
- filtered_rules = filter(lambda x: x[field]==args[field], pricing_rules)
+ filtered_rules = list(filter(lambda x: x[field]==args[field], pricing_rules))
if filtered_rules: break
return filtered_rules or pricing_rules
diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
index 25301967080..638e57ed2b9 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
@@ -22,7 +22,7 @@ class TestTaxWithholdingCategory(unittest.TestCase):
invoices = []
# create invoices for lower than single threshold tax rate
- for _ in xrange(2):
+ for _ in range(2):
pi = create_purchase_invoice(supplier = "Test TDS Supplier")
pi.submit()
invoices.append(pi)
diff --git a/erpnext/accounts/report/sales_payment_summary/test_sales_payment_summary.py b/erpnext/accounts/report/sales_payment_summary/test_sales_payment_summary.py
index 62843e74efc..a51c4276301 100644
--- a/erpnext/accounts/report/sales_payment_summary/test_sales_payment_summary.py
+++ b/erpnext/accounts/report/sales_payment_summary/test_sales_payment_summary.py
@@ -47,8 +47,8 @@ class TestSalesPaymentSummary(unittest.TestCase):
pe.submit()
mop = get_mode_of_payments(filters)
- self.assertTrue('Credit Card' in mop.values()[0])
- self.assertTrue('Cash' in mop.values()[0])
+ self.assertTrue('Credit Card' in list(mop.values())[0])
+ self.assertTrue('Cash' in list(mop.values())[0])
# Cancel all Cash payment entry and check if this mode of payment is still fetched.
payment_entries = frappe.get_all("Payment Entry", filters={"mode_of_payment": "Cash", "docstatus": 1}, fields=["name", "docstatus"])
@@ -57,8 +57,8 @@ class TestSalesPaymentSummary(unittest.TestCase):
pe.cancel()
mop = get_mode_of_payments(filters)
- self.assertTrue('Credit Card' in mop.values()[0])
- self.assertTrue('Cash' not in mop.values()[0])
+ self.assertTrue('Credit Card' in list(mop.values())[0])
+ self.assertTrue('Cash' not in list(mop.values())[0])
def test_get_mode_of_payments_details(self):
filters = get_filters()
@@ -84,7 +84,7 @@ class TestSalesPaymentSummary(unittest.TestCase):
mopd = get_mode_of_payment_details(filters)
- mopd_values = mopd.values()[0]
+ mopd_values = list(mopd.values())[0]
for mopd_value in mopd_values:
if mopd_value[0] == "Credit Card":
cc_init_amount = mopd_value[1]
@@ -96,7 +96,7 @@ class TestSalesPaymentSummary(unittest.TestCase):
pe.cancel()
mopd = get_mode_of_payment_details(filters)
- mopd_values = mopd.values()[0]
+ mopd_values = list(mopd.values())[0]
for mopd_value in mopd_values:
if mopd_value[0] == "Credit Card":
cc_final_amount = mopd_value[1]
diff --git a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
index ac3c3507027..56425a0dcb4 100644
--- a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
+++ b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
@@ -36,7 +36,7 @@ class AssetValueAdjustment(Document):
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
get_depreciation_accounts(asset)
- depreciation_cost_center, depreciation_series = frappe.get_cached_value('Company', asset.company,
+ depreciation_cost_center, depreciation_series = frappe.get_cached_value('Company', asset.company,
["depreciation_cost_center", "series_for_depreciation_entry"])
je = frappe.new_doc("Journal Entry")
@@ -75,8 +75,8 @@ class AssetValueAdjustment(Document):
rate_per_day = flt(d.value_after_depreciation) / flt(total_days)
from_date = self.date
else:
- no_of_depreciations = len([e.name for e in asset.schedules
- if (cint(s.finance_book_id) == d.idx and not e.journal_entry)])
+ no_of_depreciations = len([s.name for s in asset.schedules
+ if (cint(s.finance_book_id) == d.idx and not s.journal_entry)])
value_after_depreciation = d.value_after_depreciation
for data in asset.schedules:
diff --git a/erpnext/assets/doctype/location/test_location.py b/erpnext/assets/doctype/location/test_location.py
index 22d25b5e11c..c98b0b0936c 100644
--- a/erpnext/assets/doctype/location/test_location.py
+++ b/erpnext/assets/doctype/location/test_location.py
@@ -25,9 +25,12 @@ class TestLocation(unittest.TestCase):
temp['features'][0]['properties']['feature_of'] = location
formatted_locations.extend(temp['features'])
- formatted_location_string = str(formatted_locations)
test_location = frappe.get_doc('Location', 'Test Location Area')
test_location.save()
- self.assertEqual(formatted_location_string, str(json.loads(test_location.get('location'))['features']))
+ test_location_features = json.loads(test_location.get('location'))['features']
+ ordered_test_location_features = sorted(test_location_features, key=lambda x: x['properties']['feature_of'])
+ ordered_formatted_locations = sorted(formatted_locations, key=lambda x: x['properties']['feature_of'])
+
+ self.assertEqual(ordered_formatted_locations, ordered_test_location_features)
self.assertEqual(area, test_location.get('area'))
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
index 124910e35de..1c39d8818c4 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
@@ -40,7 +40,7 @@ def get_products_details():
products_response = call_mws_method(products.get_matching_product,marketplaceid=marketplace,
asins=asin_list)
- matching_products_list = products_response.parsed
+ matching_products_list = products_response.parsed
for product in matching_products_list:
skus = [row["sku"] for row in sku_asin if row["asin"]==product.ASIN]
for sku in skus:
@@ -116,7 +116,7 @@ def call_mws_method(mws_method, *args, **kwargs):
mws_settings = frappe.get_doc("Amazon MWS Settings")
max_retries = mws_settings.max_retry_limit
- for x in xrange(0, max_retries):
+ for x in range(0, max_retries):
try:
response = mws_method(*args, **kwargs)
return response
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 2f2c40ef2d4..b5abb733b01 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -18,6 +18,7 @@ from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
from frappe.utils.csvutils import getlink
from erpnext.stock.utils import get_bin, validate_warehouse_company, get_latest_stock_qty
from erpnext.utilities.transaction_base import validate_uom_is_integer
+from six import text_type
class OverProductionError(frappe.ValidationError): pass
class StockOverProductionError(frappe.ValidationError): pass
@@ -591,10 +592,10 @@ def make_timesheet(production_order, company):
@frappe.whitelist()
def add_timesheet_detail(timesheet, args):
- if isinstance(timesheet, unicode):
+ if isinstance(timesheet, text_type):
timesheet = frappe.get_doc('Timesheet', timesheet)
- if isinstance(args, unicode):
+ if isinstance(args, text_type):
args = json.loads(args)
timesheet.append('time_logs', args)
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index b6083ef44c0..ae06b5dba35 100755
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -533,7 +533,7 @@ erpnext.patches.v11_0.create_department_records_for_each_company
erpnext.patches.v11_0.make_location_from_warehouse
erpnext.patches.v11_0.make_asset_finance_book_against_old_entries
erpnext.patches.v11_0.check_buying_selling_in_currency_exchange
-erpnext.patches.v11_0.move_item_defaults_to_child_table_for_multicompany #02-07-2018
+erpnext.patches.v11_0.move_item_defaults_to_child_table_for_multicompany #02-07-2018 #19-06-2019
erpnext.patches.v11_0.refactor_erpnext_shopify #2018-09-07
erpnext.patches.v11_0.rename_overproduction_percent_field
erpnext.patches.v11_0.update_backflush_subcontract_rm_based_on_bom
diff --git a/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py b/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py
index 01f84a03136..c7c76355400 100644
--- a/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py
+++ b/erpnext/patches/v11_0/move_item_defaults_to_child_table_for_multicompany.py
@@ -17,10 +17,8 @@ def execute():
frappe.reload_doc('stock', 'doctype', 'item_default')
frappe.reload_doc('stock', 'doctype', 'item')
- if frappe.db.a_row_exists('Item Default'): return
-
companies = frappe.get_all("Company")
- if len(companies) == 1:
+ if len(companies) == 1 and not frappe.get_all("Item Default", limit=1):
try:
frappe.db.sql('''
INSERT INTO `tabItem Default`
@@ -35,32 +33,64 @@ def execute():
except:
pass
else:
- item_details = frappe.get_all("Item", fields=["name", "default_warehouse", "buying_cost_center",
- "expense_account", "selling_cost_center", "income_account"], limit=100)
+ item_details = frappe.db.sql(""" SELECT name, default_warehouse,
+ buying_cost_center, expense_account, selling_cost_center, income_account
+ FROM tabItem
+ WHERE
+ name not in (select distinct parent from `tabItem Default`) and ifnull(disabled, 0) = 0"""
+ , as_dict=1)
- for item in item_details:
- item_defaults = []
+ items_default_data = {}
+ for item_data in item_details:
+ for d in [["default_warehouse", "Warehouse"], ["expense_account", "Account"],
+ ["income_account", "Account"], ["buying_cost_center", "Cost Center"],
+ ["selling_cost_center", "Cost Center"]]:
+ if item_data.get(d[0]):
+ company = frappe.get_value(d[1], item_data.get(d[0]), "company", cache=True)
- def insert_into_item_defaults(doc_field_name, doc_field_value, company):
- for d in item_defaults:
- if d.get("company") == company:
- d[doc_field_name] = doc_field_value
- return
- item_defaults.append({
- "company": company,
- doc_field_name: doc_field_value
- })
+ if item_data.name not in items_default_data:
+ items_default_data[item_data.name] = {}
- for d in [
- ["default_warehouse", "Warehouse"], ["expense_account", "Account"], ["income_account", "Account"],
- ["buying_cost_center", "Cost Center"], ["selling_cost_center", "Cost Center"]
- ]:
- if item.get(d[0]):
- company = frappe.get_value(d[1], item.get(d[0]), "company", cache=True)
- insert_into_item_defaults(d[0], item.get(d[0]), company)
+ company_wise_data = items_default_data[item_data.name]
- doc = frappe.get_doc("Item", item.name)
- doc.extend("item_defaults", item_defaults)
+ if company not in company_wise_data:
+ company_wise_data[company] = {}
- for child_doc in doc.item_defaults:
- child_doc.db_insert()
\ No newline at end of file
+ default_data = company_wise_data[company]
+ default_data[d[0]] = item_data.get(d[0])
+
+ to_insert_data = []
+
+ # items_default_data data structure will be as follow
+ # {
+ # 'item_code 1': {'company 1': {'default_warehouse': 'Test Warehouse 1'}},
+ # 'item_code 2': {
+ # 'company 1': {'default_warehouse': 'Test Warehouse 1'},
+ # 'company 2': {'default_warehouse': 'Test Warehouse 1'}
+ # }
+ # }
+
+ for item_code, companywise_item_data in items_default_data.items():
+ for company, item_default_data in companywise_item_data.items():
+ to_insert_data.append((
+ frappe.generate_hash("", 10),
+ item_code,
+ 'Item',
+ 'item_defaults',
+ company,
+ item_default_data.get('default_warehouse'),
+ item_default_data.get('expense_account'),
+ item_default_data.get('income_account'),
+ item_default_data.get('buying_cost_center'),
+ item_default_data.get('selling_cost_center'),
+ ))
+
+ if to_insert_data:
+ frappe.db.sql('''
+ INSERT INTO `tabItem Default`
+ (
+ `name`, `parent`, `parenttype`, `parentfield`, `company`, `default_warehouse`,
+ `expense_account`, `income_account`, `buying_cost_center`, `selling_cost_center`
+ )
+ VALUES {}
+ '''.format(', '.join(['%s'] * len(to_insert_data))), tuple(to_insert_data))
\ No newline at end of file
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index f1179033bed..32f0428fcd8 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -103,8 +103,8 @@ class TestTimesheet(unittest.TestCase):
{
"billable": 1,
"activity_type": "_Test Activity Type",
- "from_type": now_datetime(),
- "hours": 3,
+ "from_time": now_datetime(),
+ "to_time": now_datetime() + datetime.timedelta(hours=3),
"company": "_Test Company"
}
)
@@ -113,8 +113,8 @@ class TestTimesheet(unittest.TestCase):
{
"billable": 1,
"activity_type": "_Test Activity Type",
- "from_type": now_datetime(),
- "hours": 3,
+ "from_time": now_datetime(),
+ "to_time": now_datetime() + datetime.timedelta(hours=3),
"company": "_Test Company"
}
)
diff --git a/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py b/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py
index e1b6c4db4f9..e903c9f00a4 100644
--- a/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py
+++ b/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py
@@ -69,13 +69,13 @@ def get_gl_entries(filters):
gl_entries = frappe.db.sql("""
select
- gl.posting_date as GlPostDate, gl.name as GlName, gl.account, gl.transaction_date,
+ gl.posting_date as GlPostDate, gl.name as GlName, gl.account, gl.transaction_date,
sum(gl.debit) as debit, sum(gl.credit) as credit,
sum(gl.debit_in_account_currency) as debitCurr, sum(gl.credit_in_account_currency) as creditCurr,
- gl.voucher_type, gl.voucher_no, gl.against_voucher_type,
- gl.against_voucher, gl.account_currency, gl.against,
+ gl.voucher_type, gl.voucher_no, gl.against_voucher_type,
+ gl.against_voucher, gl.account_currency, gl.against,
gl.party_type, gl.party,
- inv.name as InvName, inv.title as InvTitle, inv.posting_date as InvPostDate,
+ inv.name as InvName, inv.title as InvTitle, inv.posting_date as InvPostDate,
pur.name as PurName, pur.title as PurTitle, pur.posting_date as PurPostDate,
jnl.cheque_no as JnlRef, jnl.posting_date as JnlPostDate, jnl.title as JnlTitle,
pay.name as PayName, pay.posting_date as PayPostDate, pay.title as PayTitle,
@@ -84,7 +84,7 @@ def get_gl_entries(filters):
emp.employee_name, emp.name as empName,
stu.title as student_name, stu.name as stuName,
member_name, mem.name as memName
-
+
from `tabGL Entry` gl
left join `tabSales Invoice` inv on gl.voucher_no = inv.name
left join `tabPurchase Invoice` pur on gl.voucher_no = pur.name
@@ -124,7 +124,7 @@ def get_result_as_list(data, filters):
if account_number[0] is not None:
CompteNum = account_number[0]
else:
- frappe.throw(_("Account number for account {0} is not available.
Please setup your Chart of Accounts correctly.").format(account.name))
+ frappe.throw(_("Account number for account {0} is not available.
Please setup your Chart of Accounts correctly.").format(d.get("account")))
if d.get("party_type") == "Customer":
CompAuxNum = d.get("cusName")
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 8bb8c618f29..7ee4a76ca66 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import flt, add_days, nowdate, add_months
+from frappe.utils import flt, add_days, nowdate, add_months, getdate
import unittest
test_dependencies = ["Product Bundle"]
@@ -18,7 +18,7 @@ class TestQuotation(unittest.TestCase):
self.assertTrue(quotation.payment_schedule)
- def test_make_sales_order_terms_not_copied(self):
+ def test_make_sales_order_terms_copied(self):
from erpnext.selling.doctype.quotation.quotation import make_sales_order
quotation = frappe.copy_doc(test_records[0])
@@ -29,7 +29,7 @@ class TestQuotation(unittest.TestCase):
sales_order = make_sales_order(quotation.name)
- self.assertFalse(sales_order.get('payment_schedule'))
+ self.assertTrue(sales_order.get('payment_schedule'))
def test_make_sales_order_with_different_currency(self):
from erpnext.selling.doctype.quotation.quotation import make_sales_order
@@ -109,10 +109,10 @@ class TestQuotation(unittest.TestCase):
sales_order.insert()
self.assertEqual(sales_order.payment_schedule[0].payment_amount, 8906.00)
- self.assertEqual(sales_order.payment_schedule[0].due_date, quotation.transaction_date)
+ self.assertEqual(sales_order.payment_schedule[0].due_date, getdate(quotation.transaction_date))
self.assertEqual(sales_order.payment_schedule[1].payment_amount, 8906.00)
self.assertEqual(
- sales_order.payment_schedule[1].due_date, add_days(quotation.transaction_date, 30)
+ sales_order.payment_schedule[1].due_date, getdate(add_days(quotation.transaction_date, 30))
)
def test_valid_till(self):
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 5c1f573c457..3866c934a8d 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -8,7 +8,7 @@ from frappe.utils import flt, cint, nowdate
from frappe import throw, _
import frappe.defaults
-from frappe.utils import getdate
+from frappe.utils import getdate, cint
from erpnext.controllers.buying_controller import BuyingController
from erpnext.accounts.utils import get_account_currency
from frappe.desk.notifications import clear_doctype_notifications
@@ -128,7 +128,7 @@ class PurchaseReceipt(BuyingController):
self.company, self.base_grand_total)
self.update_prevdoc_status()
- if self.per_billed < 100:
+ if cint(self.per_billed) < 100:
self.update_billing_status()
else:
self.status = "Completed"
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index c19228fea8b..dfcce5f820b 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -562,7 +562,7 @@ class TestStockEntry(unittest.TestCase):
for d in stock_entry.get("items"):
if d.item_code != "_Test FG Item 2":
rm_cost += flt(d.amount)
- fg_cost = filter(lambda x: x.item_code=="_Test FG Item 2", stock_entry.get("items"))[0].amount
+ fg_cost = list(filter(lambda x: x.item_code=="_Test FG Item 2", stock_entry.get("items")))[0].amount
self.assertEqual(fg_cost,
flt(rm_cost + bom_operation_cost + work_order.additional_operating_cost, 2))
diff --git a/erpnext/templates/pages/search_help.py b/erpnext/templates/pages/search_help.py
index 4a4b0dbd934..cd767b3099c 100644
--- a/erpnext/templates/pages/search_help.py
+++ b/erpnext/templates/pages/search_help.py
@@ -5,6 +5,7 @@ from jinja2 import utils
from html2text import html2text
from frappe.utils import sanitize_html
from frappe.utils.global_search import search
+from six import text_type
def get_context(context):
context.no_cache = 1
@@ -12,7 +13,7 @@ def get_context(context):
query = str(utils.escape(sanitize_html(frappe.form_dict.q)))
context.title = _('Help Results for')
context.query = query
-
+
context.route = '/search_help'
d = frappe._dict()
d.results_sections = get_help_results_sections(query)
@@ -73,7 +74,7 @@ def prepare_api_results(api, topics_data):
for topic in topics_data:
route = api.base_url + '/' + (api.post_route + '/' if api.post_route else "")
for key in api.post_route_key_list.split(','):
- route += unicode(topic[key])
+ route += text_type(topic[key])
results.append(frappe._dict({
'title': topic[api.post_title_key],
diff --git a/travis/run-tests.sh b/travis/run-tests.sh
new file mode 100755
index 00000000000..7cfd64833b7
--- /dev/null
+++ b/travis/run-tests.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -e
+
+if [[ $TEST_TYPE == 'Server Side Test' ]]; then
+ bench run-tests --app erpnext --coverage
+
+elif [[ $TEST_TYPE == 'Patch Test' ]]; then
+ wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
+ bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
+ bench migrate
+fi