",
'name': "Odoo Studio: %s customization" % (self.testView.name)
})
self.start_tour("/web?debug=tests", 'web_studio_test_edit_with_xml_editor', login="admin", timeout=200)
self.assertEqual(studioView.arch, "
")
def test_enter_x2many_edition_and_add_field(self):
doesNotHaveGroup = self.env["res.groups"].create({
"name": "studio does not have"
})
doesNotHaveGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_doesnothavegroup",
"model": "res.groups",
"module": "web_studio",
"res_id": doesNotHaveGroup.id,
})
userView = self.env["ir.ui.view"].create({
"name": "simple user",
"model": "res.users",
"type": "form",
"arch": '''
'''.format(doesnothavegroup=doesNotHaveGroupXmlId.complete_name)
})
userViewXmlId = self.env["ir.model.data"].create({
"name": "studio_test_user_view",
"model": "ir.ui.view",
"module": "web_studio",
"res_id": userView.id,
})
self.testView.arch = '''
''' % userViewXmlId.complete_name
studioView = _get_studio_view(self.testView)
self.assertFalse(studioView.exists())
self.start_tour("/web?debug=tests", 'web_studio_enter_x2many_edition_and_add_field', login="admin", timeout=200)
studioView = _get_studio_view(self.testView)
assertViewArchEqual(self, studioView.arch, """
""".format(doesnothavegroup=doesNotHaveGroupXmlId.complete_name))
def test_enter_x2many_auto_inlined_subview(self):
userView = self.env["ir.ui.view"].create({
"name": "simple user",
"model": "res.users",
"type": "tree",
"arch": '''
'''
})
userViewXmlId = self.env["ir.model.data"].create({
"name": "studio_test_user_view",
"model": "ir.ui.view",
"module": "web_studio",
"res_id": userView.id,
})
self.testView.arch = '''
''' % userViewXmlId.complete_name
studioView = _get_studio_view(self.testView)
self.assertFalse(studioView.exists())
self.start_tour("/web?debug=tests", 'web_studio_enter_x2many_auto_inlined_subview', login="admin", timeout=200)
studioView = _get_studio_view(self.testView)
assertViewArchEqual(self, studioView.arch, """
""")
def test_enter_x2many_auto_inlined_subview_with_multiple_field_matching(self):
user_view = self.env["ir.ui.view"].create({
"name": "simple user",
"model": "res.users",
"type": "tree",
"arch": '''
'''
})
user_view_xml_id = self.env["ir.model.data"].create({
"name": "studio_test_user_view",
"model": "ir.ui.view",
"module": "web_studio",
"res_id": user_view.id,
})
self.testView.arch = '''
''' % (user_view_xml_id.complete_name, user_view_xml_id.complete_name)
studio_view = _get_studio_view(self.testView)
self.assertFalse(studio_view.exists())
self.start_tour("/web?debug=tests", 'web_studio_enter_x2many_auto_inlined_subview_with_multiple_field_matching',
login="admin", timeout=200)
studio_view = _get_studio_view(self.testView)
assertViewArchEqual(self, studio_view.arch, """
""")
def test_field_with_group(self):
operations = []
def edit_view_mocked(*args, **kwargs):
operations.extend(kwargs["operations"] if "operations" in kwargs else args[3])
watch_edit_view(self, edit_view_mocked)
doesNotHaveGroup = self.env["res.groups"].create({
"name": "studio does not have"
})
doesNotHaveGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_doesnothavegroup",
"model": "res.groups",
"module": "web_studio",
"res_id": doesNotHaveGroup.id,
})
self.testView.write({
"type": "tree",
"arch": '''
'''.format(doesnothavegroup=doesNotHaveGroupXmlId.complete_name)
})
self.testAction.write({
"view_ids": [Command.clear(), Command.create({"view_id": self.testView.id, "view_mode": "tree"})]
})
self.start_tour("/web?debug=tests", 'web_studio_field_with_group', login="admin", timeout=200)
self.assertEqual(len(operations), 1)
self.assertEqual(operations[0]["target"]["xpath_info"], [{'tag': 'tree', 'indice': 1}, {'tag': 'field', 'indice': 3}])
studioView = _get_studio_view(self.testView)
assertViewArchEqual(self, studioView.arch, """
""")
def test_elements_with_groups_form(self):
operations = []
def edit_view_mocked(*args, **kwargs):
operations.extend(kwargs["operations"] if "operations" in kwargs else args[3])
watch_edit_view(self, edit_view_mocked)
doesNotHaveGroup = self.env["res.groups"].create({
"name": "studio does not have"
})
doesNotHaveGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_doesnothavegroup",
"model": "res.groups",
"module": "web_studio",
"res_id": doesNotHaveGroup.id,
})
hasGroup = self.env["res.groups"].create({
"name": "studio has group",
"users": [Command.link(2)]
})
hasGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_hasgroup",
"model": "res.groups",
"module": "web_studio",
"res_id": hasGroup.id,
})
self.patch(type(self.env["res.partner"]).function, "groups", doesNotHaveGroupXmlId.complete_name)
self.testView.write({
"arch": '''
'''.format(doesnothavegroup=doesNotHaveGroupXmlId.complete_name, hasgroup=hasGroupXmlId.complete_name)
})
self.start_tour("/web", 'web_studio_elements_with_groups_form', login="admin", timeout=600000)
self.assertEqual(len(operations), 1)
self.assertEqual(operations[0]["target"]["xpath_info"], [{'indice': 1, 'tag': 'form'}, {'indice': 1, 'tag': 'group'}, {'indice': 3, 'tag': 'field'}])
studioView = _get_studio_view(self.testView)
assertViewArchEqual(self, studioView.arch, """
""")
def test_element_group_in_sidebar(self):
group = self.env["res.groups"].create({
"name": "Test Group",
"users": [Command.link(2)]
})
groupXmlId = self.env["ir.model.data"].create({
"name": "test_group",
"model": "res.groups",
"module": "web_studio",
"res_id": group.id,
})
self.testView.write({
"arch": '''
'''.format(group=groupXmlId.complete_name)
})
self.start_tour("/web?debug=tests", 'test_element_group_in_sidebar', login="admin", timeout=600000)
def test_create_one2many_lines_then_edit_name(self):
self.testView.arch = '''
'''
custom_fields_before_studio = self.env["ir.model.fields"].search([
("state", "=", "manual"),
])
self.start_tour("/web?debug=tests", 'web_studio_test_create_one2many_lines_then_edit_name', login="admin", timeout=30000)
custom_fields = self.env["ir.model.fields"].search_read([
("state", "=", "manual"),
("id", "not in", custom_fields_before_studio.ids),
], fields=["name", "ttype", "field_description"])
self.maxDiff = None
self.assertCountEqual(
[{key: val for key, val in field.items() if key != 'id'} for field in custom_fields],
[
{"name": "x_studio_new_name", 'ttype': 'one2many', 'field_description': 'new name'},
{"name": "x_name", 'ttype': 'char', 'field_description': 'Description'},
{"name": "x_res_partner_id", 'ttype': 'many2one', 'field_description': 'X Res Partner'},
{"name": "x_studio_sequence", 'ttype': 'integer', 'field_description': 'Sequence'},
]
)
def test_address_view_id_no_edit(self):
self.testView.write({
"arch": '''
'''
})
self.env.company.country_id.address_view_id = self.env.ref('base.view_partner_address_form')
self.start_tour("/web?debug=tests", 'web_studio_test_address_view_id_no_edit', login="admin", timeout=200)
def test_custom_selection_field_edit_values(self):
self.testView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_custom_selection_field_edit_values', login="admin", timeout=200)
selection_field = self.env["ir.model.fields"].search(
[
("state", "=", "manual"),
("model", "=", "res.partner"),
("ttype", "=", "selection")
],
limit=1
)
self.assertEqual(selection_field.selection_ids.mapped("name"), ["some value", "another value"])
def test_create_new_model_from_existing_view(self):
self.testView.write({
"model": "res.users",
"type": "kanban",
"arch": '''
'''
})
self.testAction.view_ids.view_mode = "kanban"
self.start_tour("/web?debug=tests", 'web_studio_test_create_new_model_from_existing_view', login="admin",
timeout=200)
def test_create_model_with_clickable_stages(self):
self.start_tour("/web?debug=tests", 'web_studio_test_create_model_with_clickable_stages', login="admin", timeout=200)
def test_enter_x2many_edition_with_multiple_subviews(self):
doesNotHaveGroup = self.env["res.groups"].create({
"name": "studio does not have"
})
doesNotHaveGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_doesnothavegroup",
"model": "res.groups",
"module": "web_studio",
"res_id": doesNotHaveGroup.id,
})
hasGroup = self.env["res.groups"].create({
"name": "studio has group",
"users": [Command.link(2)]
})
hasGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_hasgroup",
"model": "res.groups",
"module": "web_studio",
"res_id": hasGroup.id,
})
self.testView.arch = '''
'''.format(doesnothavegroup=doesNotHaveGroupXmlId.complete_name, hasgroup=hasGroupXmlId.complete_name)
self.start_tour("/web?debug=tests", 'web_studio_test_enter_x2many_edition_with_multiple_subviews',
login="admin", timeout=200)
def test_enter_x2many_edition_with_multiple_subviews_correct_xpath(self):
operations = []
def edit_view_mocked(*args, **kwargs):
operations.extend(kwargs["operations"] if "operations" in kwargs else args[3])
watch_edit_view(self, edit_view_mocked)
doesNotHaveGroup = self.env["res.groups"].create({
"name": "studio does not have"
})
doesNotHaveGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_doesnothavegroup",
"model": "res.groups",
"module": "web_studio",
"res_id": doesNotHaveGroup.id,
})
hasGroup = self.env["res.groups"].create({
"name": "studio has group",
"users": [Command.link(2)]
})
hasGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_hasgroup",
"model": "res.groups",
"module": "web_studio",
"res_id": hasGroup.id,
})
self.testView.arch = '''
'''.format(doesnothavegroup=doesNotHaveGroupXmlId.complete_name, hasgroup=hasGroupXmlId.complete_name)
self.start_tour("/web?debug=tests", 'web_studio_test_enter_x2many_edition_with_multiple_subviews_correct_xpath',
login="admin", timeout=200)
studioView = _get_studio_view(self.testView)
assertViewArchEqual(self, studioView.arch, """
""")
self.assertEqual(len(operations), 1)
self.assertDictEqual(operations[0], {
'type': 'add',
'target': {
'tag': 'field',
'attrs': {
'name': 'name'
},
'xpath_info': [
{
'tag': 'tree',
'indice': 2
},
{
'tag': 'field',
'indice': 1
},
],
'subview_xpath': "/form[1]/field[2]/tree[2]",
},
'position': 'before',
'node': {
'tag': 'field',
'attrs': {
'name': 'active',
'optional': 'show'
}
}
})
def test_studio_arch_has_measure_field_ids(self):
view = self.env["ir.ui.view"].create({
"name": "simple view",
"model": "res.partner",
"type": "pivot",
"arch": '''
'''
})
studio_view = self.env[view.model].with_context(studio=True).get_view(view.id, view.type)
field_id = self.env['ir.model.fields'].search([('model', '=', view.model), ('name', 'in', ['display_name'])]).ids[0]
assertViewArchEqual(self, studio_view["arch"], '''
'''.format(field_id=field_id))
def test_field_with_groups_in_tree_node_has_groups_too(self):
# The field has a group in python in which the user is
# The node has also a group in which the user is not
hasGroup = self.env["res.groups"].create({
"name": "studio has group",
"users": [Command.link(self.env.user.id)]
})
hasGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_hasgroup",
"model": "res.groups",
"module": "web_studio",
"res_id": hasGroup.id,
})
doesNotHaveGroup = self.env["res.groups"].create({
"name": "studio does not have"
})
doesNotHaveGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_doesnothavegroup",
"model": "res.groups",
"module": "web_studio",
"res_id": doesNotHaveGroup.id,
})
self.patch(type(self.env["res.partner"]).title, "groups", hasGroupXmlId.complete_name)
view = self.env["ir.ui.view"].create({
"name": "simple view",
"model": "res.partner",
"type": "tree",
"arch": '''
'''.format(doesnothavegroup=doesNotHaveGroupXmlId.complete_name)
})
arch = self.env[view.model].with_context(studio=True).get_view(view.id, view.type)["arch"]
studio_groups = json.dumps([{
"id": doesNotHaveGroup.id,
"name": doesNotHaveGroup.name,
"display_name": doesNotHaveGroup.display_name,
}])
xml_temp = E.field(name="title", column_invisible="True", groups=doesNotHaveGroupXmlId.complete_name, studio_groups=studio_groups)
expected = '''
{xml_stringified}
'''.format(xml_stringified=etree.tostring(xml_temp).decode("utf-8"))
assertViewArchEqual(self, arch, expected)
def test_studio_view_is_last(self):
# The studio view created should have, in all cases, a priority greater than all views
# that are part of the inheritance
self.testView.arch = '''
'''
self.env["ir.ui.view"].create({
"name": "simple view inherit",
"inherit_id": self.testView.id,
"mode": "extension",
"priority": 123,
"model": "res.partner",
"type": "form",
"arch": '''
'''
})
self.start_tour("/web?debug=tests", 'web_studio_test_studio_view_is_last', login="admin", timeout=200)
studioView = _get_studio_view(self.testView)
self.assertEqual(studioView.priority, 1230)
self.maxDiff = None
assertViewArchEqual(self, studioView["arch"], '''
''')
def test_edit_form_subview_attributes(self):
self.testView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_test_edit_form_subview_attributes', login="admin", timeout=200)
studioView = _get_studio_view(self.testView)
assertViewArchEqual(self, studioView.arch, """
false
""")
def test_x2many_two_levels_edition(self):
self.testView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_x2many_two_levels_edition', login="admin", timeout=200)
studioView = _get_studio_view(self.testView)
assertViewArchEqual(self, studioView.arch, '''
''')
def test_field_group_studio_no_fetch(self):
doesNotHaveGroup = self.env["res.groups"].create({
"name": "studio does not have"
})
doesNotHaveGroupXmlId = self.env["ir.model.data"].create({
"name": "studio_test_doesnothavegroup",
"model": "res.groups",
"module": "web_studio",
"res_id": doesNotHaveGroup.id,
})
self.patch(type(self.env["res.partner"]).function, "groups", doesNotHaveGroupXmlId.complete_name)
self.testViewForm = self.env["ir.ui.view"].create({
"name": "simple partner",
"model": "res.partner",
"type": "form",
"arch": '''
'''
})
self.testViewList = self.env["ir.ui.view"].create({
"name": "simple partner",
"model": "res.partner",
"type": "tree",
"arch": '''
'''
})
self.testViewKanban = self.env["ir.ui.view"].create({
"name": "simple partner",
"model": "res.partner",
"type": "kanban",
"arch": '''
'''
})
self.testAction.write({
"view_ids": [
Command.clear(),
Command.create({"view_id": self.testViewForm.id, "view_mode": "form"}),
Command.create({"view_id": self.testViewList.id, "view_mode": "tree"}),
Command.create({"view_id": self.testViewKanban.id, "view_mode": "kanban"}),
]
})
self.start_tour("/web?debug=tests", 'web_studio_field_group_studio_no_fetch', login="admin", timeout=200)
def test_monetary_create(self):
self.create_empty_app()
self.newView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_monetary_create', login="admin")
# There is a new currency and there is a new monetary
fields = self.env[self.newModel.model]._fields
currency_name_list = list(filter(lambda key: fields[key]._description_type == 'many2one' and fields[key]._description_relation == 'res.currency', fields.keys()))
monetary_name_list = list(filter(lambda key: fields[key].type == 'monetary', fields.keys()))
self.assertEqual(len(currency_name_list), 1)
self.assertEqual(len(monetary_name_list), 1)
# The studio arch contains the new monetary and the new currency
studioView = _get_studio_view(self.newView)
assertViewArchEqual(self, studioView.arch, f"""
""")
def test_monetary_change_currency_name(self):
self.create_empty_app()
currency = self.env["ir.model.fields"].create({
"name": "x_studio_currency_test",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "many2one",
"relation": "res.currency",
})
self.env["ir.model.fields"].create({
"name": "x_studio_monetary_test",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "monetary",
"currency_field": "x_studio_currency_test",
})
self.newView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_monetary_change_currency_name', login="admin")
self.assertEqual(currency.field_description, "NewCurrency")
def test_monetary_change_currency_field(self):
self.create_empty_app()
self.env["ir.model.fields"].create({
"name": "x_studio_currency_test",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "many2one",
"relation": "res.currency",
})
self.env["ir.model.fields"].create({
"name": "x_studio_currency_test2",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "many2one",
"relation": "res.currency",
})
monetary = self.env["ir.model.fields"].create({
"name": "x_studio_monetary_test",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "monetary",
"currency_field": "x_studio_currency_test",
})
self.newView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_monetary_change_currency_field', login="admin")
# The currency_field in the monetary field changed
self.assertEqual(monetary.currency_field, 'x_studio_currency_test2')
def test_monetary_change_currency_not_in_view(self):
self.create_empty_app()
self.env["ir.model.fields"].create({
"name": "x_studio_currency_test",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "many2one",
"relation": "res.currency",
})
self.env["ir.model.fields"].create({
"name": "x_studio_currency_test2",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "many2one",
"relation": "res.currency",
})
monetary = self.env["ir.model.fields"].create({
"name": "x_studio_monetary_test",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "monetary",
"currency_field": "x_studio_currency_test",
})
self.newView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_monetary_change_currency_not_in_view', login="admin")
# The currency_field in the monetary field changed
self.assertEqual(monetary.currency_field, 'x_studio_currency_test2')
studioView = _get_studio_view(self.newView)
assertViewArchEqual(self, studioView.arch, """
""")
def test_monetary_add_existing_monetary(self):
self.create_empty_app()
self.env["ir.model.fields"].create({
"name": "x_studio_currency_test",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "many2one",
"relation": "res.currency",
})
self.env["ir.model.fields"].create({
"name": "x_studio_monetary_test",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "monetary",
"currency_field": "x_studio_currency_test",
})
self.newView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_monetary_add_existing_monetary', login="admin")
# The studio arch contains the monetary and the associated currency
studioView = _get_studio_view(self.newView)
assertViewArchEqual(self, studioView.arch, """
""")
def test_monetary_create_monetary_with_existing_currency(self):
self.create_empty_app()
self.env["ir.model.fields"].create({
"name": "x_studio_currency_test",
"model": "x_test_model",
"model_id": self.newModel.id,
"ttype": "many2one",
"relation": "res.currency",
})
self.newView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_monetary_create_monetary_with_existing_currency', login="admin")
# There is only one currency and there is a new monetary
fields = self.env[self.newModel.model]._fields
currency_name_list = list(filter(lambda key: fields[key]._description_type == 'many2one' and fields[key]._description_relation == 'res.currency', fields.keys()))
monetary_name_list = list(filter(lambda key: fields[key].type == 'monetary', fields.keys()))
self.assertEqual(len(currency_name_list), 1)
self.assertEqual(len(monetary_name_list), 1)
# The studio arch contains the new monetary but no currency as it exist in the original arch
studioView = _get_studio_view(self.newView)
assertViewArchEqual(self, studioView.arch, f"""
""")
def test_move_similar_field(self):
self.testView.arch = '''
'''
self.start_tour("/web?debug=tests", 'web_studio_test_move_similar_field', login="admin", timeout=400)
studioView = _get_studio_view(self.testView)
assertViewArchEqual(self, studioView.arch, '''
''')
def create_user_view(self):
self.testView.write({
"name": "simple user",
"model": "res.users",
"arch": '''
'''
})
self.testAction.write({
"name": "simple user",
"res_model": "res.users",
})
self.testActionXmlId.name = "studio_test_user_action"
self.testMenu.name = "Studio Test User"
self.testMenuXmlId.name = "studio_test_user_menu"
def test_related_binary_field_with_filename(self):
self.create_user_view()
partner_field = self.env["ir.model.fields"].create({
"field_description": "New File",
"name": "x_new_file",
"ttype": "binary",
"model": "res.partner",
"model_id": self.env["ir.model"]._get('res.partner').id,
"state": "manual",
})
self.env["ir.model.fields"].create({
"field_description": "New File filename",
"name": "x_new_file_filename",
"ttype": "char",
"model": "res.partner",
"model_id": self.env["ir.model"]._get('res.partner').id,
"state": "manual",
})
self.start_tour("/web?debug=tests", 'web_studio_test_related_file', login="admin", timeout=400)
studioView = _get_studio_view(self.testView)
binary_field = self.env["ir.model.fields"].search([('model', '=', 'res.users'), ('ttype', '=', 'binary'), ('name', 'like', 'x_studio_related')])
self.assertEqual(len(binary_field), 1)
self.assertEqual(binary_field.related_field_id, partner_field)
assertViewArchEqual(self, studioView.arch,
'''
'''.format(binary_field=binary_field))
def test_nested_related_binary_field_with_filename(self):
self.create_user_view()
self.env["ir.model.fields"].create({
"field_description": "New File",
"name": "x_new_file",
"ttype": "binary",
"model": "res.partner.category",
"model_id": self.env["ir.model"]._get('res.partner.category').id,
"state": "manual",
})
self.env["ir.model.fields"].create({
"field_description": "New File filename",
"name": "x_new_file_filename",
"ttype": "char",
"model": "res.partner.category",
"model_id": self.env["ir.model"]._get('res.partner.category').id,
"state": "manual",
})
partner_field = self.env["ir.model.fields"].create({
"field_description": "New File",
"name": "x_new_related_file",
"ttype": "binary",
"model": "res.partner",
"model_id": self.env["ir.model"]._get('res.partner').id,
"state": "manual",
"related": "category_id.x_new_file"
})
self.env["ir.model.fields"].create({
"field_description": "New File filename",
"name": "x_new_related_file_filename",
"ttype": "char",
"model": "res.partner",
"model_id": self.env["ir.model"]._get('res.partner').id,
"state": "manual",
"related": "category_id.x_new_file_filename"
})
self.start_tour("/web?debug=tests", 'web_studio_test_related_file', login="admin", timeout=400)
studioView = _get_studio_view(self.testView)
binary_field = self.env["ir.model.fields"].search([('model', '=', 'res.users'), ('ttype', '=', 'binary'), ('name', 'like', 'x_studio_related')])
self.assertEqual(len(binary_field), 1)
self.assertEqual(binary_field.related_field_id, partner_field)
assertViewArchEqual(self, studioView.arch,
'''
'''.format(binary_field=binary_field))
def test_related_binary_field_without_filename(self):
self.create_user_view()
partner_field = self.env["ir.model.fields"].create({
"field_description": "New File",
"name": "x_new_file",
"ttype": "binary",
"model": "res.partner",
"model_id": self.env["ir.model"]._get('res.partner').id,
"state": "manual",
})
self.start_tour("/web?debug=tests", 'web_studio_test_related_file', login="admin", timeout=400)
studioView = _get_studio_view(self.testView)
binary_field = self.env["ir.model.fields"].search([('model', '=', 'res.users'), ('ttype', '=', 'binary'), ('name', 'like', 'x_studio_related')])
self.assertEqual(len(binary_field), 1)
self.assertEqual(binary_field.related_field_id, partner_field)
assertViewArchEqual(self, studioView.arch,
'''
'''.format(binary_field=binary_field))
def test_undo_new_field(self):
self.testView.arch = '''
'''
self.start_tour("/web?debug=tests", "web_studio_test_undo_new_field", login="admin", timeout=200)