(cherry picked from commit b01929405d
)
# Conflicts:
# frappe/contacts/doctype/gender/gender.json
# frappe/contacts/doctype/salutation/salutation.json
version-14
@@ -26,48 +26,31 @@ context("Control Link", () => { | |||||
}); | }); | ||||
} | } | ||||
function get_dialog_with_user_link() { | |||||
function get_dialog_with_gender_link() { | |||||
return cy.dialog({ | return cy.dialog({ | ||||
title: "Link", | title: "Link", | ||||
fields: [ | fields: [ | ||||
{ | { | ||||
label: "Select User", | |||||
fieldname: "link", | |||||
fieldtype: "Link", | |||||
options: "User", | |||||
}, | |||||
], | |||||
'label': 'Select Gender', | |||||
'fieldname': 'link', | |||||
'fieldtype': 'Link', | |||||
'options': 'Gender', | |||||
} | |||||
] | |||||
}); | }); | ||||
} | } | ||||
it("should set the valid value", () => { | it("should set the valid value", () => { | ||||
get_dialog_with_link().as("dialog"); | get_dialog_with_link().as("dialog"); | ||||
cy.insert_doc( | |||||
"Property Setter", | |||||
{ | |||||
doctype: "Property Setter", | |||||
doc_type: "User", | |||||
property: "translate_link_fields", | |||||
property_type: "Check", | |||||
doctype_or_field: "DocType", | |||||
value: "0", | |||||
}, | |||||
true | |||||
); | |||||
cy.insert_doc( | |||||
"Property Setter", | |||||
{ | |||||
doctype: "Property Setter", | |||||
doc_type: "ToDo", | |||||
property: "show_title_field_in_link", | |||||
property_type: "Check", | |||||
doctype_or_field: "DocType", | |||||
value: "0", | |||||
}, | |||||
true | |||||
); | |||||
cy.insert_doc("Property Setter", { | |||||
"doctype": "Property Setter", | |||||
"doc_type": "ToDo", | |||||
"property": "show_title_field_in_link", | |||||
"property_type": "Check", | |||||
"doctype_or_field": "DocType", | |||||
"value": "0" | |||||
}, true); | |||||
cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link"); | cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link"); | ||||
@@ -132,32 +115,15 @@ context("Control Link", () => { | |||||
}); | }); | ||||
}); | }); | ||||
it("show title field in link", () => { | |||||
cy.insert_doc( | |||||
"Property Setter", | |||||
{ | |||||
doctype: "Property Setter", | |||||
doc_type: "User", | |||||
property: "translate_link_fields", | |||||
property_type: "Check", | |||||
doctype_or_field: "DocType", | |||||
value: "0", | |||||
}, | |||||
true | |||||
); | |||||
cy.insert_doc( | |||||
"Property Setter", | |||||
{ | |||||
doctype: "Property Setter", | |||||
doc_type: "ToDo", | |||||
property: "show_title_field_in_link", | |||||
property_type: "Check", | |||||
doctype_or_field: "DocType", | |||||
value: "1", | |||||
}, | |||||
true | |||||
); | |||||
it('show title field in link', () => { | |||||
cy.insert_doc("Property Setter", { | |||||
"doctype": "Property Setter", | |||||
"doc_type": "ToDo", | |||||
"property": "show_title_field_in_link", | |||||
"property_type": "Check", | |||||
"doctype_or_field": "DocType", | |||||
"value": "1" | |||||
}, true); | |||||
cy.clear_cache(); | cy.clear_cache(); | ||||
cy.wait(500); | cy.wait(500); | ||||
@@ -275,153 +241,92 @@ context("Control Link", () => { | |||||
); | ); | ||||
}); | }); | ||||
it("show translated text for link with show_title_field_in_link enabled", () => { | |||||
cy.insert_doc( | |||||
"Property Setter", | |||||
{ | |||||
doctype: "Property Setter", | |||||
doc_type: "ToDo", | |||||
property: "translate_link_fields", | |||||
property_type: "Check", | |||||
doctype_or_field: "DocType", | |||||
value: "1", | |||||
}, | |||||
true | |||||
); | |||||
cy.insert_doc( | |||||
"Property Setter", | |||||
{ | |||||
doctype: "Property Setter", | |||||
doc_type: "ToDo", | |||||
property: "show_title_field_in_link", | |||||
property_type: "Check", | |||||
doctype_or_field: "DocType", | |||||
value: "1", | |||||
}, | |||||
true | |||||
); | |||||
cy.window() | |||||
.its("frappe") | |||||
.then((frappe) => { | |||||
cy.insert_doc("Translation", { | |||||
doctype: "Translation", | |||||
language: frappe.boot.lang, | |||||
source_text: "this is a test todo for link", | |||||
translated_text: "this is a translated test todo for link", | |||||
}); | |||||
it('show translated text for Gender link field with language de with input in de', () => { | |||||
cy.call('frappe.tests.ui_test_helpers.insert_translations').then(() => { | |||||
cy.window().its('frappe').then(frappe => { | |||||
cy.set_value('User', frappe.user.name, {language: 'de'}); | |||||
}); | }); | ||||
cy.clear_cache(); | |||||
cy.wait(500); | |||||
cy.clear_cache(); | |||||
cy.wait(500); | |||||
get_dialog_with_gender_link().as('dialog'); | |||||
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link'); | |||||
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input'); | |||||
cy.wait('@search_link'); | |||||
cy.get('@input').type('Sonstiges', { delay: 100 }); | |||||
cy.wait('@search_link'); | |||||
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible'); | |||||
cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 }); | |||||
cy.get('.frappe-control[data-fieldname=link] input').blur(); | |||||
cy.get('@dialog').then(dialog => { | |||||
let field = dialog.get_field('link'); | |||||
let value = field.get_value(); | |||||
let label = field.get_label_value(); | |||||
cy.window() | |||||
.its("frappe") | |||||
.then((frappe) => { | |||||
if (!frappe.boot) { | |||||
frappe.boot = { | |||||
link_title_doctypes: ["ToDo"], | |||||
translatable_doctypes: ["ToDo"], | |||||
}; | |||||
} else { | |||||
frappe.boot.link_title_doctypes = ["ToDo"]; | |||||
frappe.boot.translatable_doctypes = ["ToDo"]; | |||||
} | |||||
expect(value).to.eq('Other'); | |||||
expect(label).to.eq('Sonstiges'); | |||||
}); | }); | ||||
}); | |||||
}); | |||||
get_dialog_with_link().as("dialog"); | |||||
cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link"); | |||||
it('show translated text for Gender link field with language de with input in en', () => { | |||||
cy.call('frappe.tests.ui_test_helpers.insert_translations').then(() => { | |||||
cy.window().its('frappe').then(frappe => { | |||||
cy.set_value('User', frappe.user.name, {language: 'de'}); | |||||
}); | |||||
cy.get(".frappe-control[data-fieldname=link] input").focus().as("input"); | |||||
cy.wait("@search_link"); | |||||
cy.get("@input").type("todo for link", { delay: 100 }); | |||||
cy.wait("@search_link"); | |||||
cy.get(".frappe-control[data-fieldname=link] ul").should("be.visible"); | |||||
cy.get(".frappe-control[data-fieldname=link] input").type("{enter}", { delay: 100 }); | |||||
cy.get(".frappe-control[data-fieldname=link] input").blur(); | |||||
cy.get("@dialog").then((dialog) => { | |||||
cy.get("@todos").then((todos) => { | |||||
let field = dialog.get_field("link"); | |||||
cy.clear_cache(); | |||||
cy.wait(500); | |||||
get_dialog_with_gender_link().as('dialog'); | |||||
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link'); | |||||
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input'); | |||||
cy.wait('@search_link'); | |||||
cy.get('@input').type('Other', { delay: 100 }); | |||||
cy.wait('@search_link'); | |||||
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible'); | |||||
cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 }); | |||||
cy.get('.frappe-control[data-fieldname=link] input').blur(); | |||||
cy.get('@dialog').then(dialog => { | |||||
let field = dialog.get_field('link'); | |||||
let value = field.get_value(); | let value = field.get_value(); | ||||
let label = field.get_label_value(); | let label = field.get_label_value(); | ||||
expect(value).to.eq(todos[0]); | |||||
expect(label).to.eq("this is a translated test todo for link"); | |||||
expect(value).to.eq('Other'); | |||||
expect(label).to.eq('Sonstiges'); | |||||
}); | }); | ||||
}); | }); | ||||
}); | }); | ||||
it("show translated text for link with show_title_field_in_link disabled", () => { | |||||
cy.insert_doc( | |||||
"Property Setter", | |||||
{ | |||||
doctype: "Property Setter", | |||||
doc_type: "User", | |||||
property: "translate_link_fields", | |||||
property_type: "Check", | |||||
doctype_or_field: "DocType", | |||||
value: "1", | |||||
}, | |||||
true | |||||
); | |||||
cy.insert_doc( | |||||
"Property Setter", | |||||
{ | |||||
doctype: "Property Setter", | |||||
doc_type: "ToDo", | |||||
property: "show_title_field_in_link", | |||||
property_type: "Check", | |||||
doctype_or_field: "DocType", | |||||
value: "0", | |||||
}, | |||||
true | |||||
); | |||||
cy.window() | |||||
.its("frappe") | |||||
.then((frappe) => { | |||||
cy.insert_doc("Translation", { | |||||
doctype: "Translation", | |||||
language: frappe.boot.lang, | |||||
source_text: "test@erpnext.com", | |||||
translated_text: "translatedtest@erpnext.com", | |||||
}); | |||||
}); | |||||
it('show text for Gender link field with language en', () => { | |||||
cy.window().its('frappe').then(frappe => { | |||||
cy.set_value('User', frappe.user.name, {language: 'en'}); | |||||
}); | |||||
cy.clear_cache(); | cy.clear_cache(); | ||||
cy.wait(500); | cy.wait(500); | ||||
cy.window() | |||||
.its("frappe") | |||||
.then((frappe) => { | |||||
if (!frappe.boot) { | |||||
frappe.boot = { | |||||
translatable_doctypes: ["User"], | |||||
}; | |||||
} else { | |||||
frappe.boot.translatable_doctypes = ["User"]; | |||||
} | |||||
}); | |||||
get_dialog_with_user_link().as("dialog"); | |||||
cy.intercept("POST", "/api/method/frappe.desk.search.search_link").as("search_link"); | |||||
cy.get(".frappe-control[data-fieldname=link] input").focus().as("input"); | |||||
cy.wait("@search_link"); | |||||
cy.get("@input").type("test@erpnext.com", { delay: 100 }); | |||||
cy.wait("@search_link"); | |||||
cy.get(".frappe-control[data-fieldname=link] ul").should("be.visible"); | |||||
cy.get(".frappe-control[data-fieldname=link] input").type("{enter}", { delay: 100 }); | |||||
cy.get(".frappe-control[data-fieldname=link] input").blur(); | |||||
cy.get("@dialog").then((dialog) => { | |||||
let field = dialog.get_field("link"); | |||||
get_dialog_with_gender_link().as('dialog'); | |||||
cy.intercept('POST', '/api/method/frappe.desk.search.search_link').as('search_link'); | |||||
cy.get('.frappe-control[data-fieldname=link] input').focus().as('input'); | |||||
cy.wait('@search_link'); | |||||
cy.get('@input').type('Non-Conforming', { delay: 100 }); | |||||
cy.wait('@search_link'); | |||||
cy.get('.frappe-control[data-fieldname=link] ul').should('be.visible'); | |||||
cy.get('.frappe-control[data-fieldname=link] input').type('{enter}', { delay: 100 }); | |||||
cy.get('.frappe-control[data-fieldname=link] input').blur(); | |||||
cy.get('@dialog').then(dialog => { | |||||
let field = dialog.get_field('link'); | |||||
let value = field.get_value(); | let value = field.get_value(); | ||||
let label = field.get_label_value(); | let label = field.get_label_value(); | ||||
expect(value).to.eq("test@erpnext.com"); | |||||
expect(label).to.eq("translatedtest@erpnext.com"); | |||||
expect(value).to.eq('Non-Conforming'); | |||||
expect(label).to.eq('Non-Conforming'); | |||||
}); | }); | ||||
}); | }); | ||||
}); | }); |
@@ -19,7 +19,7 @@ from frappe.social.doctype.energy_point_log.energy_point_log import get_energy_p | |||||
from frappe.social.doctype.energy_point_settings.energy_point_settings import ( | from frappe.social.doctype.energy_point_settings.energy_point_settings import ( | ||||
is_energy_point_enabled, | is_energy_point_enabled, | ||||
) | ) | ||||
from frappe.translate import get_lang_dict, get_messages_for_boot | |||||
from frappe.translate import get_lang_dict, get_messages_for_boot, get_translated_doctypes | |||||
from frappe.utils import add_user_info, cstr, get_time_zone | from frappe.utils import add_user_info, cstr, get_time_zone | ||||
from frappe.utils.change_log import get_versions | from frappe.utils.change_log import get_versions | ||||
from frappe.website.doctype.web_page_view.web_page_view import is_tracking_enabled | from frappe.website.doctype.web_page_view.web_page_view import is_tracking_enabled | ||||
@@ -100,7 +100,7 @@ def get_bootinfo(): | |||||
bootinfo.desk_settings = get_desk_settings() | bootinfo.desk_settings = get_desk_settings() | ||||
bootinfo.app_logo_url = get_app_logo() | bootinfo.app_logo_url = get_app_logo() | ||||
bootinfo.link_title_doctypes = get_link_title_doctypes() | bootinfo.link_title_doctypes = get_link_title_doctypes() | ||||
bootinfo.translatable_doctypes = get_translatable_doctypes() | |||||
bootinfo.translated_doctypes = get_translated_doctypes() | |||||
return bootinfo | return bootinfo | ||||
@@ -173,7 +173,10 @@ def get_user_pages_or_reports(parent, cache=False): | |||||
.from_(hasRole) | .from_(hasRole) | ||||
.from_(parentTable) | .from_(parentTable) | ||||
.select( | .select( | ||||
customRole[parent.lower()].as_("name"), customRole.modified, customRole.ref_doctype, *columns | |||||
customRole[parent.lower()].as_("name"), | |||||
customRole.modified, | |||||
customRole.ref_doctype, | |||||
*columns | |||||
) | ) | ||||
.where( | .where( | ||||
(hasRole.parent == customRole.name) | (hasRole.parent == customRole.name) | ||||
@@ -336,7 +339,9 @@ def get_success_action(): | |||||
def get_link_preview_doctypes(): | def get_link_preview_doctypes(): | ||||
from frappe.utils import cint | from frappe.utils import cint | ||||
link_preview_doctypes = [d.name for d in frappe.db.get_all("DocType", {"show_preview_popup": 1})] | |||||
link_preview_doctypes = [ | |||||
d.name for d in frappe.db.get_all("DocType", {"show_preview_popup": 1}) | |||||
] | |||||
customizations = frappe.get_all( | customizations = frappe.get_all( | ||||
"Property Setter", fields=["doc_type", "value"], filters={"property": "show_preview_popup"} | "Property Setter", fields=["doc_type", "value"], filters={"property": "show_preview_popup"} | ||||
) | ) | ||||
@@ -399,14 +404,6 @@ def set_time_zone(bootinfo): | |||||
} | } | ||||
def get_translatable_doctypes(): | |||||
dts = frappe.get_all("DocType", {"translate_link_fields": 1}, pluck="name") | |||||
custom_dts = frappe.get_all( | |||||
"Property Setter", {"property": "translate_link_fields", "value": "1"}, pluck="doc_type" | |||||
) | |||||
return dts + custom_dts | |||||
def load_country_doc(bootinfo): | def load_country_doc(bootinfo): | ||||
country = frappe.db.get_default("country") | country = frappe.db.get_default("country") | ||||
if not country: | if not country: | ||||
@@ -43,6 +43,7 @@ | |||||
"set_only_once": 0, | "set_only_once": 0, | ||||
"unique": 0 | "unique": 0 | ||||
} | } | ||||
<<<<<<< HEAD | |||||
], | ], | ||||
"has_web_view": 0, | "has_web_view": 0, | ||||
"hide_heading": 0, | "hide_heading": 0, | ||||
@@ -60,6 +61,15 @@ | |||||
"name": "Gender", | "name": "Gender", | ||||
"name_case": "", | "name_case": "", | ||||
"owner": "Administrator", | "owner": "Administrator", | ||||
======= | |||||
], | |||||
"links": [], | |||||
"modified": "2022-08-05 18:33:28.043370", | |||||
"modified_by": "Administrator", | |||||
"module": "Contacts", | |||||
"name": "Gender", | |||||
"owner": "Administrator", | |||||
>>>>>>> b01929405d (refactor: translatable doctypes) | |||||
"permissions": [ | "permissions": [ | ||||
{ | { | ||||
"amend": 0, | "amend": 0, | ||||
@@ -101,6 +111,7 @@ | |||||
"submit": 0, | "submit": 0, | ||||
"write": 0 | "write": 0 | ||||
} | } | ||||
<<<<<<< HEAD | |||||
], | ], | ||||
"quick_entry": 0, | "quick_entry": 0, | ||||
"read_only": 0, | "read_only": 0, | ||||
@@ -110,4 +121,12 @@ | |||||
"sort_order": "DESC", | "sort_order": "DESC", | ||||
"track_changes": 1, | "track_changes": 1, | ||||
"track_seen": 0 | "track_seen": 0 | ||||
======= | |||||
], | |||||
"sort_field": "modified", | |||||
"sort_order": "DESC", | |||||
"states": [], | |||||
"track_changes": 1, | |||||
"translated_doctype": 1 | |||||
>>>>>>> b01929405d (refactor: translatable doctypes) | |||||
} | } |
@@ -42,6 +42,7 @@ | |||||
"set_only_once": 0, | "set_only_once": 0, | ||||
"unique": 0 | "unique": 0 | ||||
} | } | ||||
<<<<<<< HEAD | |||||
], | ], | ||||
"has_web_view": 0, | "has_web_view": 0, | ||||
"hide_heading": 0, | "hide_heading": 0, | ||||
@@ -59,6 +60,15 @@ | |||||
"name": "Salutation", | "name": "Salutation", | ||||
"name_case": "", | "name_case": "", | ||||
"owner": "Administrator", | "owner": "Administrator", | ||||
======= | |||||
], | |||||
"links": [], | |||||
"modified": "2022-08-05 18:33:28.196387", | |||||
"modified_by": "Administrator", | |||||
"module": "Contacts", | |||||
"name": "Salutation", | |||||
"owner": "Administrator", | |||||
>>>>>>> b01929405d (refactor: translatable doctypes) | |||||
"permissions": [ | "permissions": [ | ||||
{ | { | ||||
"amend": 0, | "amend": 0, | ||||
@@ -120,6 +130,7 @@ | |||||
"submit": 0, | "submit": 0, | ||||
"write": 1 | "write": 1 | ||||
} | } | ||||
<<<<<<< HEAD | |||||
], | ], | ||||
"quick_entry": 0, | "quick_entry": 0, | ||||
"read_only": 0, | "read_only": 0, | ||||
@@ -130,3 +141,12 @@ | |||||
"track_changes": 1, | "track_changes": 1, | ||||
"track_seen": 0 | "track_seen": 0 | ||||
} | } | ||||
======= | |||||
], | |||||
"sort_field": "modified", | |||||
"sort_order": "DESC", | |||||
"states": [], | |||||
"track_changes": 1, | |||||
"translated_doctype": 1 | |||||
} | |||||
>>>>>>> b01929405d (refactor: translatable doctypes) |
@@ -47,7 +47,7 @@ | |||||
"view_settings", | "view_settings", | ||||
"title_field", | "title_field", | ||||
"show_title_field_in_link", | "show_title_field_in_link", | ||||
"translate_link_fields", | |||||
"translated_doctype", | |||||
"search_fields", | "search_fields", | ||||
"default_print_format", | "default_print_format", | ||||
"sort_field", | "sort_field", | ||||
@@ -595,7 +595,7 @@ | |||||
}, | }, | ||||
{ | { | ||||
"default": "0", | "default": "0", | ||||
"fieldname": "translate_link_fields", | |||||
"fieldname": "translated_doctype", | |||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"label": "Translate Link Fields" | "label": "Translate Link Fields" | ||||
} | } | ||||
@@ -680,7 +680,7 @@ | |||||
"link_fieldname": "reference_doctype" | "link_fieldname": "reference_doctype" | ||||
} | } | ||||
], | ], | ||||
"modified": "2022-02-28 21:56:52.116915", | |||||
"modified": "2022-08-05 18:33:27.315351", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Core", | "module": "Core", | ||||
"name": "DocType", | "name": "DocType", | ||||
@@ -716,5 +716,5 @@ | |||||
"sort_order": "DESC", | "sort_order": "DESC", | ||||
"states": [], | "states": [], | ||||
"track_changes": 1, | "track_changes": 1, | ||||
"translate_link_fields": 1 | |||||
"translated_doctype": 1 | |||||
} | } |
@@ -148,7 +148,7 @@ | |||||
"idx": 1, | "idx": 1, | ||||
"index_web_pages_for_search": 1, | "index_web_pages_for_search": 1, | ||||
"links": [], | "links": [], | ||||
"modified": "2022-01-12 20:18:18.496230", | |||||
"modified": "2022-08-05 18:33:27.694065", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Core", | "module": "Core", | ||||
"name": "Role", | "name": "Role", | ||||
@@ -171,5 +171,6 @@ | |||||
"sort_field": "modified", | "sort_field": "modified", | ||||
"sort_order": "ASC", | "sort_order": "ASC", | ||||
"states": [], | "states": [], | ||||
"track_changes": 1 | |||||
"track_changes": 1, | |||||
"translated_doctype": 1 | |||||
} | } |
@@ -29,7 +29,7 @@ | |||||
"view_settings_section", | "view_settings_section", | ||||
"title_field", | "title_field", | ||||
"show_title_field_in_link", | "show_title_field_in_link", | ||||
"translate_link_fields", | |||||
"translated_doctype", | |||||
"image_field", | "image_field", | ||||
"default_print_format", | "default_print_format", | ||||
"column_break_29", | "column_break_29", | ||||
@@ -315,7 +315,7 @@ | |||||
}, | }, | ||||
{ | { | ||||
"default": "0", | "default": "0", | ||||
"fieldname": "translate_link_fields", | |||||
"fieldname": "translated_doctype", | |||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"label": "Translate Link Fields" | "label": "Translate Link Fields" | ||||
} | } | ||||
@@ -326,7 +326,7 @@ | |||||
"index_web_pages_for_search": 1, | "index_web_pages_for_search": 1, | ||||
"issingle": 1, | "issingle": 1, | ||||
"links": [], | "links": [], | ||||
"modified": "2022-05-13 15:36:16.772277", | |||||
"modified": "2022-08-04 15:36:16.772277", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Custom", | "module": "Custom", | ||||
"name": "Customize Form", | "name": "Customize Form", | ||||
@@ -585,7 +585,7 @@ doctype_properties = { | |||||
"naming_rule": "Data", | "naming_rule": "Data", | ||||
"autoname": "Data", | "autoname": "Data", | ||||
"show_title_field_in_link": "Check", | "show_title_field_in_link": "Check", | ||||
"translate_link_fields": "Check", | |||||
"translated_doctype": "Check", | |||||
} | } | ||||
docfield_properties = { | docfield_properties = { | ||||
@@ -226,7 +226,7 @@ CREATE TABLE `tabDocType` ( | |||||
`sender_field` varchar(255) DEFAULT NULL, | `sender_field` varchar(255) DEFAULT NULL, | ||||
`show_title_field_in_link` int(1) NOT NULL DEFAULT 0, | `show_title_field_in_link` int(1) NOT NULL DEFAULT 0, | ||||
`migration_hash` varchar(255) DEFAULT NULL, | `migration_hash` varchar(255) DEFAULT NULL, | ||||
`translate_link_fields` int(1) NOT NULL DEFAULT 0, | |||||
`translated_doctype` int(1) NOT NULL DEFAULT 0, | |||||
PRIMARY KEY (`name`) | PRIMARY KEY (`name`) | ||||
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci; | ) ENGINE=InnoDB ROW_FORMAT=DYNAMIC CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci; | ||||
@@ -231,7 +231,7 @@ CREATE TABLE "tabDocType" ( | |||||
"sender_field" varchar(255) DEFAULT NULL, | "sender_field" varchar(255) DEFAULT NULL, | ||||
"show_title_field_in_link" smallint NOT NULL DEFAULT 0, | "show_title_field_in_link" smallint NOT NULL DEFAULT 0, | ||||
"migration_hash" varchar(255) DEFAULT NULL, | "migration_hash" varchar(255) DEFAULT NULL, | ||||
"translate_link_fields" smallint NOT NULL DEFAULT 0, | |||||
"translated_doctype" smallint NOT NULL DEFAULT 0, | |||||
PRIMARY KEY ("name") | PRIMARY KEY ("name") | ||||
) ; | ) ; | ||||
@@ -8,6 +8,7 @@ import re | |||||
import frappe | import frappe | ||||
from frappe import _, is_whitelisted | from frappe import _, is_whitelisted | ||||
from frappe.permissions import has_permission | from frappe.permissions import has_permission | ||||
from frappe.translate import get_translated_doctypes | |||||
from frappe.utils import cint, cstr, unique | from frappe.utils import cint, cstr, unique | ||||
@@ -115,7 +116,10 @@ def search_widget( | |||||
raise e | raise e | ||||
else: | else: | ||||
frappe.respond_as_web_page( | frappe.respond_as_web_page( | ||||
title="Invalid Method", html="Method not found", indicator_color="red", http_status_code=404 | |||||
title="Invalid Method", | |||||
html="Method not found", | |||||
indicator_color="red", | |||||
http_status_code=404, | |||||
) | ) | ||||
return | return | ||||
except Exception as e: | except Exception as e: | ||||
@@ -146,9 +150,22 @@ def search_widget( | |||||
filters = [] | filters = [] | ||||
or_filters = [] | or_filters = [] | ||||
translated_search_doctypes = frappe.get_hooks("translated_search_doctypes") | |||||
translated_doctypes = frappe.cache().hget( | |||||
"translated_doctypes", "doctypes", get_translated_doctypes | |||||
) | |||||
# build from doctype | # build from doctype | ||||
if txt: | if txt: | ||||
field_types = [ | |||||
"Data", | |||||
"Text", | |||||
"Small Text", | |||||
"Long Text", | |||||
"Link", | |||||
"Select", | |||||
"Read Only", | |||||
"Text Editor", | |||||
] | |||||
search_fields = ["name"] | search_fields = ["name"] | ||||
if meta.title_field: | if meta.title_field: | ||||
search_fields.append(meta.title_field) | search_fields.append(meta.title_field) | ||||
@@ -158,13 +175,8 @@ def search_widget( | |||||
for f in search_fields: | for f in search_fields: | ||||
fmeta = meta.get_field(f.strip()) | fmeta = meta.get_field(f.strip()) | ||||
if (doctype not in translated_search_doctypes) and ( | |||||
f == "name" | |||||
or ( | |||||
fmeta | |||||
and fmeta.fieldtype | |||||
in ["Data", "Text", "Small Text", "Long Text", "Link", "Select", "Read Only", "Text Editor"] | |||||
) | |||||
if (doctype not in translated_doctypes) and ( | |||||
f == "name" or (fmeta and fmeta.fieldtype in field_types) | |||||
): | ): | ||||
or_filters.append([doctype, f.strip(), "like", f"%{txt}%"]) | or_filters.append([doctype, f.strip(), "like", f"%{txt}%"]) | ||||
@@ -188,7 +200,8 @@ def search_widget( | |||||
# find relevance as location of search term from the beginning of string `name`. used for sorting results. | # find relevance as location of search term from the beginning of string `name`. used for sorting results. | ||||
formatted_fields.append( | formatted_fields.append( | ||||
"""locate({_txt}, `tab{doctype}`.`name`) as `_relevance`""".format( | """locate({_txt}, `tab{doctype}`.`name`) as `_relevance`""".format( | ||||
_txt=frappe.db.escape((txt or "").replace("%", "").replace("@", "")), doctype=doctype | |||||
_txt=frappe.db.escape((txt or "").replace("%", "").replace("@", "")), | |||||
doctype=doctype, | |||||
) | ) | ||||
) | ) | ||||
@@ -206,7 +219,7 @@ def search_widget( | |||||
else (cint(ignore_user_permissions) and has_permission(doctype, ptype=ptype)) | else (cint(ignore_user_permissions) and has_permission(doctype, ptype=ptype)) | ||||
) | ) | ||||
if doctype in translated_search_doctypes: | |||||
if doctype in translated_doctypes: | |||||
page_length = None | page_length = None | ||||
values = frappe.get_list( | values = frappe.get_list( | ||||
@@ -223,12 +236,13 @@ def search_widget( | |||||
strict=False, | strict=False, | ||||
) | ) | ||||
if doctype in translated_search_doctypes: | |||||
if doctype in translated_doctypes: | |||||
# Filtering the values array so that query is included in very element | # Filtering the values array so that query is included in very element | ||||
values = ( | values = ( | ||||
v | v | ||||
for v in values | for v in values | ||||
if re.search(f"{re.escape(txt)}.*", _(v.name if as_dict else v[0]), re.IGNORECASE) | if re.search(f"{re.escape(txt)}.*", _(v.name if as_dict else v[0]), re.IGNORECASE) | ||||
or re.search(f"{_(re.escape(txt))}.*", _(v.name if as_dict else v[0]), re.IGNORECASE) | |||||
) | ) | ||||
# Sorting the values array so that relevant results always come first | # Sorting the values array so that relevant results always come first | ||||
@@ -54,7 +54,7 @@ | |||||
"icon": "fa fa-globe", | "icon": "fa fa-globe", | ||||
"idx": 1, | "idx": 1, | ||||
"links": [], | "links": [], | ||||
"modified": "2020-02-24 15:44:31.837133", | |||||
"modified": "2022-08-05 18:33:27.880783", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Geo", | "module": "Geo", | ||||
"name": "Country", | "name": "Country", | ||||
@@ -84,5 +84,7 @@ | |||||
"quick_entry": 1, | "quick_entry": 1, | ||||
"sort_field": "country_name", | "sort_field": "country_name", | ||||
"sort_order": "ASC", | "sort_order": "ASC", | ||||
"track_changes": 1 | |||||
"states": [], | |||||
"track_changes": 1, | |||||
"translated_doctype": 1 | |||||
} | } |
@@ -373,5 +373,3 @@ override_whitelisted_methods = { | |||||
"frappe.core.doctype.file.file.move_file": "frappe.core.api.file.move_file", | "frappe.core.doctype.file.file.move_file": "frappe.core.api.file.move_file", | ||||
"frappe.core.doctype.file.file.zip_files": "frappe.core.api.file.zip_files", | "frappe.core.doctype.file.file.zip_files": "frappe.core.api.file.zip_files", | ||||
} | } | ||||
translated_search_doctypes = ["DocType", "Role", "Country", "Gender", "Salutation"] |
@@ -87,7 +87,7 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat | |||||
return this.is_translatable() ? __(value) : value; | return this.is_translatable() ? __(value) : value; | ||||
} | } | ||||
is_translatable() { | is_translatable() { | ||||
return in_list(frappe.boot?.translatable_doctypes || [], this.get_options()); | |||||
return in_list(frappe.boot?.translated_doctypes || [], this.get_options()); | |||||
} | } | ||||
set_link_title(value) { | set_link_title(value) { | ||||
let doctype = this.get_options(); | let doctype = this.get_options(); | ||||
@@ -382,22 +382,6 @@ frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlDat | |||||
me.$input.val(""); | me.$input.val(""); | ||||
} | } | ||||
}); | }); | ||||
this.$input.on("focus", function () { | |||||
if (!frappe.boot.translated_search_doctypes.includes(me.df.options)) { | |||||
me.show_untranslated(); | |||||
} | |||||
}); | |||||
this.$input.keydown((e) => { | |||||
let BACKSPACE = 8; | |||||
if ( | |||||
e.keyCode === BACKSPACE && | |||||
!frappe.boot.translated_search_doctypes.includes(me.df.options) | |||||
) { | |||||
me.show_untranslated(); | |||||
} | |||||
}); | |||||
} | } | ||||
show_untranslated() { | show_untranslated() { | ||||
@@ -184,7 +184,6 @@ def get(): | |||||
frappe.get_attr(hook)(bootinfo=bootinfo) | frappe.get_attr(hook)(bootinfo=bootinfo) | ||||
bootinfo["lang"] = frappe.translate.get_user_lang() | bootinfo["lang"] = frappe.translate.get_user_lang() | ||||
bootinfo["translated_search_doctypes"] = frappe.get_hooks("translated_search_doctypes") | |||||
bootinfo["disable_async"] = frappe.conf.disable_async | bootinfo["disable_async"] = frappe.conf.disable_async | ||||
bootinfo["setup_complete"] = cint(frappe.get_system_settings("setup_complete")) | bootinfo["setup_complete"] = cint(frappe.get_system_settings("setup_complete")) | ||||
@@ -333,3 +333,37 @@ def insert_doctype_with_child_table_record(name): | |||||
insert_child(doc, "Drag", "08189DIHAA2981", 0, 0.7, 342628, "2022-05-04") | insert_child(doc, "Drag", "08189DIHAA2981", 0, 0.7, 342628, "2022-05-04") | ||||
doc.insert() | doc.insert() | ||||
@frappe.whitelist() | |||||
def insert_translations(): | |||||
translation = [ | |||||
{ | |||||
"doctype": "Translation", | |||||
"language": "de", | |||||
"source_text": "Other", | |||||
"translated_text": "Sonstiges", | |||||
}, | |||||
{ | |||||
"doctype": "Translation", | |||||
"language": "de", | |||||
"source_text": "Genderqueer", | |||||
"translated_text": "Geschlechtsspezifisch", | |||||
}, | |||||
{ | |||||
"doctype": "Translation", | |||||
"language": "de", | |||||
"source_text": "Non-Conforming", | |||||
"translated_text": "Nicht konform", | |||||
}, | |||||
{ | |||||
"doctype": "Translation", | |||||
"language": "de", | |||||
"source_text": "Prefer not to say", | |||||
"translated_text": "Mache lieber keine Angabe", | |||||
}, | |||||
] | |||||
for doc in translation: | |||||
if not frappe.db.exists("doc"): | |||||
frappe.get_doc(doc).insert() |
@@ -23,7 +23,7 @@ from pypika.terms import PseudoColumn | |||||
import frappe | import frappe | ||||
from frappe.model.utils import InvalidIncludePath, render_include | from frappe.model.utils import InvalidIncludePath, render_include | ||||
from frappe.query_builder import DocType, Field | from frappe.query_builder import DocType, Field | ||||
from frappe.utils import cstr, get_bench_path, is_html, strip, strip_html_tags | |||||
from frappe.utils import cstr, get_bench_path, is_html, strip, strip_html_tags, unique | |||||
TRANSLATE_PATTERN = re.compile( | TRANSLATE_PATTERN = re.compile( | ||||
r"_\(\s*" # starts with literal `_(`, ignore following whitespace/newlines | r"_\(\s*" # starts with literal `_(`, ignore following whitespace/newlines | ||||
@@ -108,8 +108,8 @@ def get_parent_language(lang: str) -> str: | |||||
"""If the passed language is a variant, return its parent | """If the passed language is a variant, return its parent | ||||
Eg: | Eg: | ||||
1. zh-TW -> zh | |||||
2. sr-BA -> sr | |||||
1. zh-TW -> zh | |||||
2. sr-BA -> sr | |||||
""" | """ | ||||
is_language_variant = "-" in lang | is_language_variant = "-" in lang | ||||
if is_language_variant: | if is_language_variant: | ||||
@@ -1294,3 +1294,11 @@ def set_preferred_language_cookie(preferred_language): | |||||
def get_preferred_language_cookie(): | def get_preferred_language_cookie(): | ||||
return frappe.request.cookies.get("preferred_language") | return frappe.request.cookies.get("preferred_language") | ||||
def get_translated_doctypes(): | |||||
dts = frappe.get_all("DocType", {"translated_doctype": 1}, pluck="name") | |||||
custom_dts = frappe.get_all( | |||||
"Property Setter", {"property": "translated_doctype", "value": "1"}, pluck="doc_type" | |||||
) | |||||
return unique(dts + custom_dts) |
@@ -79,7 +79,8 @@ def is_valid_title(title) -> bool: | |||||
def _create_app_boilerplate(dest, hooks, no_git=False): | def _create_app_boilerplate(dest, hooks, no_git=False): | ||||
frappe.create_folder( | frappe.create_folder( | ||||
os.path.join(dest, hooks.app_name, hooks.app_name, frappe.scrub(hooks.app_title)), with_init=True | |||||
os.path.join(dest, hooks.app_name, hooks.app_name, frappe.scrub(hooks.app_title)), | |||||
with_init=True, | |||||
) | ) | ||||
frappe.create_folder( | frappe.create_folder( | ||||
os.path.join(dest, hooks.app_name, hooks.app_name, "templates"), with_init=True | os.path.join(dest, hooks.app_name, hooks.app_name, "templates"), with_init=True | ||||
@@ -249,8 +250,8 @@ app_license = "{app_license}" | |||||
# add methods and filters to jinja environment | # add methods and filters to jinja environment | ||||
# jinja = {{ | # jinja = {{ | ||||
# "methods": "{app_name}.utils.jinja_methods", | |||||
# "filters": "{app_name}.utils.jinja_filters" | |||||
# "methods": "{app_name}.utils.jinja_methods", | |||||
# "filters": "{app_name}.utils.jinja_filters" | |||||
# }} | # }} | ||||
# Installation | # Installation | ||||
@@ -276,11 +277,11 @@ app_license = "{app_license}" | |||||
# Permissions evaluated in scripted ways | # Permissions evaluated in scripted ways | ||||
# permission_query_conditions = {{ | # permission_query_conditions = {{ | ||||
# "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions", | |||||
# "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions", | |||||
# }} | # }} | ||||
# | # | ||||
# has_permission = {{ | # has_permission = {{ | ||||
# "Event": "frappe.desk.doctype.event.event.has_permission", | |||||
# "Event": "frappe.desk.doctype.event.event.has_permission", | |||||
# }} | # }} | ||||
# DocType Class | # DocType Class | ||||
@@ -288,7 +289,7 @@ app_license = "{app_license}" | |||||
# Override standard doctype classes | # Override standard doctype classes | ||||
# override_doctype_class = {{ | # override_doctype_class = {{ | ||||
# "ToDo": "custom_app.overrides.CustomToDo" | |||||
# "ToDo": "custom_app.overrides.CustomToDo" | |||||
# }} | # }} | ||||
# Document Events | # Document Events | ||||
@@ -296,10 +297,10 @@ app_license = "{app_license}" | |||||
# Hook on document methods and events | # Hook on document methods and events | ||||
# doc_events = {{ | # doc_events = {{ | ||||
# "*": {{ | |||||
# "on_update": "method", | |||||
# "on_cancel": "method", | |||||
# "on_trash": "method" | |||||
# "*": {{ | |||||
# "on_update": "method", | |||||
# "on_cancel": "method", | |||||
# "on_trash": "method" | |||||
# }} | # }} | ||||
# }} | # }} | ||||
@@ -307,21 +308,21 @@ app_license = "{app_license}" | |||||
# --------------- | # --------------- | ||||
# scheduler_events = {{ | # scheduler_events = {{ | ||||
# "all": [ | |||||
# "{app_name}.tasks.all" | |||||
# ], | |||||
# "daily": [ | |||||
# "{app_name}.tasks.daily" | |||||
# ], | |||||
# "hourly": [ | |||||
# "{app_name}.tasks.hourly" | |||||
# ], | |||||
# "weekly": [ | |||||
# "{app_name}.tasks.weekly" | |||||
# ], | |||||
# "monthly": [ | |||||
# "{app_name}.tasks.monthly" | |||||
# ], | |||||
# "all": [ | |||||
# "{app_name}.tasks.all" | |||||
# ], | |||||
# "daily": [ | |||||
# "{app_name}.tasks.daily" | |||||
# ], | |||||
# "hourly": [ | |||||
# "{app_name}.tasks.hourly" | |||||
# ], | |||||
# "weekly": [ | |||||
# "{app_name}.tasks.weekly" | |||||
# ], | |||||
# "monthly": [ | |||||
# "{app_name}.tasks.monthly" | |||||
# ], | |||||
# }} | # }} | ||||
# Testing | # Testing | ||||
@@ -333,14 +334,14 @@ app_license = "{app_license}" | |||||
# ------------------------------ | # ------------------------------ | ||||
# | # | ||||
# override_whitelisted_methods = {{ | # override_whitelisted_methods = {{ | ||||
# "frappe.desk.doctype.event.event.get_events": "{app_name}.event.get_events" | |||||
# "frappe.desk.doctype.event.event.get_events": "{app_name}.event.get_events" | |||||
# }} | # }} | ||||
# | # | ||||
# each overriding function accepts a `data` argument; | # each overriding function accepts a `data` argument; | ||||
# generated from the base implementation of the doctype dashboard, | # generated from the base implementation of the doctype dashboard, | ||||
# along with any modifications made in other Frappe apps | # along with any modifications made in other Frappe apps | ||||
# override_doctype_dashboards = {{ | # override_doctype_dashboards = {{ | ||||
# "Task": "{app_name}.task.get_dashboard_data" | |||||
# "Task": "{app_name}.task.get_dashboard_data" | |||||
# }} | # }} | ||||
# exempt linked doctypes from being automatically cancelled | # exempt linked doctypes from being automatically cancelled | ||||
@@ -352,40 +353,32 @@ app_license = "{app_license}" | |||||
# -------------------- | # -------------------- | ||||
# user_data_fields = [ | # user_data_fields = [ | ||||
# {{ | |||||
# "doctype": "{{doctype_1}}", | |||||
# "filter_by": "{{filter_by}}", | |||||
# "redact_fields": ["{{field_1}}", "{{field_2}}"], | |||||
# "partial": 1, | |||||
# }}, | |||||
# {{ | |||||
# "doctype": "{{doctype_2}}", | |||||
# "filter_by": "{{filter_by}}", | |||||
# "partial": 1, | |||||
# }}, | |||||
# {{ | |||||
# "doctype": "{{doctype_3}}", | |||||
# "strict": False, | |||||
# }}, | |||||
# {{ | |||||
# "doctype": "{{doctype_4}}" | |||||
# }} | |||||
# {{ | |||||
# "doctype": "{{doctype_1}}", | |||||
# "filter_by": "{{filter_by}}", | |||||
# "redact_fields": ["{{field_1}}", "{{field_2}}"], | |||||
# "partial": 1, | |||||
# }}, | |||||
# {{ | |||||
# "doctype": "{{doctype_2}}", | |||||
# "filter_by": "{{filter_by}}", | |||||
# "partial": 1, | |||||
# }}, | |||||
# {{ | |||||
# "doctype": "{{doctype_3}}", | |||||
# "strict": False, | |||||
# }}, | |||||
# {{ | |||||
# "doctype": "{{doctype_4}}" | |||||
# }} | |||||
# ] | # ] | ||||
# Authentication and authorization | # Authentication and authorization | ||||
# -------------------------------- | # -------------------------------- | ||||
# auth_hooks = [ | # auth_hooks = [ | ||||
# "{app_name}.auth.validate" | |||||
# "{app_name}.auth.validate" | |||||
# ] | # ] | ||||
# Translation | |||||
# -------------------------------- | |||||
# Make link fields search translated document names for these DocTypes | |||||
# Recommended only for DocTypes which have limited documents with untranslated names | |||||
# For example: Role, Gender, etc. | |||||
# translated_search_doctypes = [] | |||||
""" | """ | ||||
desktop_template = """from frappe import _ | desktop_template = """from frappe import _ | ||||
@@ -447,8 +440,8 @@ name: CI | |||||
on: | on: | ||||
push: | push: | ||||
branches: | |||||
- develop | |||||
branches: | |||||
- develop | |||||
pull_request: | pull_request: | ||||
concurrency: | concurrency: | ||||
@@ -457,79 +450,79 @@ concurrency: | |||||
jobs: | jobs: | ||||
tests: | tests: | ||||
runs-on: ubuntu-latest | |||||
strategy: | |||||
fail-fast: false | |||||
name: Server | |||||
services: | |||||
mariadb: | |||||
image: mariadb:10.6 | |||||
env: | |||||
MYSQL_ROOT_PASSWORD: root | |||||
ports: | |||||
- 3306:3306 | |||||
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 | |||||
steps: | |||||
- name: Clone | |||||
uses: actions/checkout@v2 | |||||
- name: Setup Python | |||||
uses: actions/setup-python@v2 | |||||
with: | |||||
python-version: '3.10' | |||||
- name: Setup Node | |||||
uses: actions/setup-node@v2 | |||||
with: | |||||
node-version: 14 | |||||
check-latest: true | |||||
- name: Cache pip | |||||
uses: actions/cache@v2 | |||||
with: | |||||
path: ~/.cache/pip | |||||
key: ${{{{ runner.os }}}}-pip-${{{{ hashFiles('**/*requirements.txt', '**/pyproject.toml', '**/setup.py', '**/setup.cfg') }}}} | |||||
restore-keys: | | |||||
${{{{ runner.os }}}}-pip- | |||||
${{{{ runner.os }}}}- | |||||
- name: Get yarn cache directory path | |||||
id: yarn-cache-dir-path | |||||
run: 'echo "::set-output name=dir::$(yarn cache dir)"' | |||||
- uses: actions/cache@v2 | |||||
id: yarn-cache | |||||
with: | |||||
path: ${{{{ steps.yarn-cache-dir-path.outputs.dir }}}} | |||||
key: ${{{{ runner.os }}}}-yarn-${{{{ hashFiles('**/yarn.lock') }}}} | |||||
restore-keys: | | |||||
${{{{ runner.os }}}}-yarn- | |||||
- name: Setup | |||||
run: | | |||||
pip install frappe-bench | |||||
bench init --skip-redis-config-generation --skip-assets --python "$(which python)" ~/frappe-bench | |||||
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'" | |||||
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'" | |||||
- name: Install | |||||
working-directory: /home/runner/frappe-bench | |||||
run: | | |||||
bench get-app {app_name} $GITHUB_WORKSPACE | |||||
bench setup requirements --dev | |||||
bench new-site --db-root-password root --admin-password admin test_site | |||||
bench --site test_site install-app {app_name} | |||||
bench build | |||||
env: | |||||
CI: 'Yes' | |||||
- name: Run Tests | |||||
working-directory: /home/runner/frappe-bench | |||||
run: | | |||||
bench --site test_site set-config allow_tests true | |||||
bench --site test_site run-tests --app {app_name} | |||||
env: | |||||
TYPE: server | |||||
runs-on: ubuntu-latest | |||||
strategy: | |||||
fail-fast: false | |||||
name: Server | |||||
services: | |||||
mariadb: | |||||
image: mariadb:10.6 | |||||
env: | |||||
MYSQL_ROOT_PASSWORD: root | |||||
ports: | |||||
- 3306:3306 | |||||
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 | |||||
steps: | |||||
- name: Clone | |||||
uses: actions/checkout@v2 | |||||
- name: Setup Python | |||||
uses: actions/setup-python@v2 | |||||
with: | |||||
python-version: '3.10' | |||||
- name: Setup Node | |||||
uses: actions/setup-node@v2 | |||||
with: | |||||
node-version: 14 | |||||
check-latest: true | |||||
- name: Cache pip | |||||
uses: actions/cache@v2 | |||||
with: | |||||
path: ~/.cache/pip | |||||
key: ${{{{ runner.os }}}}-pip-${{{{ hashFiles('**/*requirements.txt', '**/pyproject.toml', '**/setup.py', '**/setup.cfg') }}}} | |||||
restore-keys: | | |||||
${{{{ runner.os }}}}-pip- | |||||
${{{{ runner.os }}}}- | |||||
- name: Get yarn cache directory path | |||||
id: yarn-cache-dir-path | |||||
run: 'echo "::set-output name=dir::$(yarn cache dir)"' | |||||
- uses: actions/cache@v2 | |||||
id: yarn-cache | |||||
with: | |||||
path: ${{{{ steps.yarn-cache-dir-path.outputs.dir }}}} | |||||
key: ${{{{ runner.os }}}}-yarn-${{{{ hashFiles('**/yarn.lock') }}}} | |||||
restore-keys: | | |||||
${{{{ runner.os }}}}-yarn- | |||||
- name: Setup | |||||
run: | | |||||
pip install frappe-bench | |||||
bench init --skip-redis-config-generation --skip-assets --python "$(which python)" ~/frappe-bench | |||||
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL character_set_server = 'utf8mb4'" | |||||
mysql --host 127.0.0.1 --port 3306 -u root -proot -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'" | |||||
- name: Install | |||||
working-directory: /home/runner/frappe-bench | |||||
run: | | |||||
bench get-app {app_name} $GITHUB_WORKSPACE | |||||
bench setup requirements --dev | |||||
bench new-site --db-root-password root --admin-password admin test_site | |||||
bench --site test_site install-app {app_name} | |||||
bench build | |||||
env: | |||||
CI: 'Yes' | |||||
- name: Run Tests | |||||
working-directory: /home/runner/frappe-bench | |||||
run: | | |||||
bench --site test_site set-config allow_tests true | |||||
bench --site test_site run-tests --app {app_name} | |||||
env: | |||||
TYPE: server | |||||
""" | """ |