Files
tradon/tests/test_field_multiselection.py
2025-12-26 13:11:43 +00:00

387 lines
12 KiB
Python
Executable File

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import unittest
from trytond import backend
from trytond.model.exceptions import (
RequiredValidationError, SelectionValidationError)
from trytond.pool import Pool
from trytond.tests.test_tryton import activate_module, with_transaction
from trytond.transaction import Transaction
class FieldMultiSelectionTestCase(unittest.TestCase):
"Test Field MultiSelection"
@classmethod
def setUpClass(cls):
activate_module('tests')
@with_transaction()
def test_create(self):
"Test create multi-selection"
Selection = Pool().get('test.multi_selection')
selection, selection_none = Selection.create([{
'selects': ['foo', 'bar'],
}, {
'selects': None,
}])
self.assertEqual(selection.selects, ('bar', 'foo'))
self.assertEqual(selection_none.selects, ())
@with_transaction()
def test_create_not_in(self):
"Test create multi-selection not in selection"
Selection = Pool().get('test.multi_selection')
with self.assertRaises(SelectionValidationError):
Selection.create([{
'selects': ('invalid'),
}])
@with_transaction()
def test_create_dynamic(self):
"Test create dynamic selection"
Selection = Pool().get('test.multi_selection')
selection_foo, selection_bar = Selection.create([{
'selects': ['foo'],
'dyn_selects': ['foo'],
}, {
'selects': ['bar'],
'dyn_selects': ['baz'],
}])
self.assertEqual(selection_foo.dyn_selects, ('foo',))
self.assertEqual(selection_bar.dyn_selects, ('baz',))
@with_transaction()
def test_create_dynamic_none(self):
"Test create dynamic selection None"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': ['foo'],
'dyn_selects': None,
}])
self.assertEqual(selection.dyn_selects, ())
@with_transaction()
def test_create_dynamic_not_in(self):
"Test create dynamic selection not in"
Selection = Pool().get('test.multi_selection')
with self.assertRaises(SelectionValidationError):
Selection.create([{
'selects': ['foo'],
'dyn_selects': ['foo', 'bar'],
}])
@with_transaction()
def test_create_static(self):
"Test create static selection"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'static_selects': ['foo', 'bar'],
}])
self.assertEqual(selection.static_selects, ('bar', 'foo'))
@with_transaction()
def test_create_static_none(self):
"Test create static selection None"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'static_selects': None,
}])
self.assertEqual(selection.static_selects, ())
@with_transaction()
def test_create_static_not_in(self):
"Test create static selection not in"
Selection = Pool().get('test.multi_selection')
with self.assertRaises(SelectionValidationError):
Selection.create([{
'static_selects': ['foo', 'bar', 'invalid'],
}])
@with_transaction()
def test_create_required_with_value(self):
"Test create selection required with value"
Selection = Pool().get('test.multi_selection_required')
selection, = Selection.create([{
'selects': ['foo', 'bar'],
}])
self.assertEqual(selection.selects, ('bar', 'foo'))
@with_transaction()
def test_create_required_without_value(self):
"Test create selection required without value"
Selection = Pool().get('test.multi_selection_required')
with self.assertRaises(RequiredValidationError):
Selection.create([{}])
@with_transaction()
def test_create_required_none(self):
"Test create selection required without value"
Selection = Pool().get('test.multi_selection_required')
with self.assertRaises(RequiredValidationError):
Selection.create([{
'selects': None,
}])
@with_transaction()
def test_create_required_empty(self):
"Test create selection required with empty value"
Selection = Pool().get('test.multi_selection_required')
with self.assertRaises(RequiredValidationError):
Selection.create([{
'selects': [],
}])
@with_transaction()
def test_write(self):
"Test write selection"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': ['foo'],
}])
Selection.write([selection], {
'selects': ['foo', 'bar'],
})
self.assertEqual(selection.selects, ('bar', 'foo'))
@with_transaction()
def test_string(self):
"Test string selection"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': ['foo', 'bar'],
}])
self.assertEqual(selection.selects_string, ["Bar", "Foo"])
@with_transaction()
def test_string_none(self):
"Test string selection none"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': None,
}])
self.assertEqual(selection.selects_string, [])
@with_transaction()
def test_search_equals(self):
"Test search selection equals"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': ['bar', 'foo'],
}])
foo_bar = Selection.search([
('selects', '=', ['foo', 'bar']),
])
foo = Selection.search([
('selects', '=', ['foo']),
])
self.assertEqual(foo_bar, [selection])
self.assertEqual(foo, [])
@with_transaction()
def test_search_equals_string(self):
"Test search selection equals string"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': ['foo'],
}])
foo = Selection.search([
('selects', '=', 'foo'),
])
self.assertEqual(foo, [])
@with_transaction()
def test_search_equals_none(self):
"Test search selection equals"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': None,
}])
selections = Selection.search([
('selects', '=', None),
])
self.assertEqual(selections, [selection])
@with_transaction()
def test_search_in_string(self):
"Test search selection in string"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': ['foo', 'bar'],
}])
foo = Selection.search([
('selects', 'in', 'foo'),
])
baz = Selection.search([
('selects', 'in', 'baz'),
])
self.assertEqual(foo, [selection])
self.assertEqual(baz, [])
@with_transaction()
def test_search_not_in_string(self):
"Test search selection not in string"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': ['foo', 'bar'],
}])
foo = Selection.search([
('selects', 'not in', 'foo'),
])
baz = Selection.search([
('selects', 'not in', 'baz'),
])
self.assertEqual(foo, [])
self.assertEqual(baz, [selection])
@with_transaction()
def test_search_in_list(self):
"Test search selection in list"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': ['foo', 'bar'],
}])
foo = Selection.search([
('selects', 'in', ['foo']),
])
baz = Selection.search([
('selects', 'in', ['baz']),
])
foo_baz = Selection.search([
('selects', 'in', ['foo', 'baz']),
])
empty = Selection.search([
('selects', 'in', []),
])
self.assertEqual(foo, [selection])
self.assertEqual(baz, [])
self.assertEqual(foo_baz, [selection])
self.assertEqual(empty, [])
@with_transaction()
def test_search_not_in_list(self):
"Test search selection not in list"
Selection = Pool().get('test.multi_selection')
selection, = Selection.create([{
'selects': ['foo', 'bar'],
}])
foo = Selection.search([
('selects', 'not in', ['foo']),
])
baz = Selection.search([
('selects', 'not in', ['baz']),
])
foo_baz = Selection.search([
('selects', 'not in', ['foo', 'baz']),
])
empty = Selection.search([
('selects', 'not in', []),
])
self.assertEqual(foo, [])
self.assertEqual(baz, [selection])
self.assertEqual(foo_baz, [])
self.assertEqual(empty, [selection])
@with_transaction()
def test_read_string(self):
"Test reading value and string"
Selection = Pool().get('test.multi_selection')
foo, foo_bar, null = Selection.create([{
'selects': ['foo'],
}, {
'selects': ['foo', 'bar'],
}, {
'selects': [],
}])
foo_read, foo_bar_read, null_read = Selection.read(
[foo.id, foo_bar.id, null.id], ['selects:string'])
self.assertEqual(foo_read['selects:string'], ["Foo"])
self.assertEqual(foo_bar_read['selects:string'], ["Bar", "Foo"])
self.assertEqual(null_read['selects:string'], [])
@with_transaction()
def test_read_string_dynamic_selection(self):
"Test reading value and string of a dynamic selection"
Selection = Pool().get('test.multi_selection')
foo, bar, null = Selection.create([{
'selects': ['foo'],
'dyn_selects': ['foo', 'foobar'],
}, {
'dyn_selects': ['bar', 'baz'],
}, {
'dyn_selects': [],
}])
foo_read, bar_read, null_read = Selection.read(
[foo.id, bar.id, null.id], ['dyn_selects:string'])
self.assertEqual(foo_read['dyn_selects:string'], ["Foo", "FooBar"])
self.assertEqual(bar_read['dyn_selects:string'], ["Bar", "Baz"])
self.assertEqual(null_read['dyn_selects:string'], [])
@unittest.skipIf(
backend.name != 'postgresql', 'jsonb only supported by postgresql')
class FieldMultiSelectionJSONBTestCase(FieldMultiSelectionTestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.setup_model()
@classmethod
@with_transaction()
def setup_model(cls):
connection = Transaction().connection
if backend.Database().get_version(connection) < (9, 2):
return
pool = Pool()
for model in ['test.multi_selection', 'test.multi_selection_required']:
Model = pool.get(model)
cursor = connection.cursor()
for name, field in Model._fields.items():
if field._type == 'multiselection':
cursor.execute('ALTER TABLE "%s" '
'ALTER COLUMN %s TYPE json USING %s::json' % (
Model._table, name, name))
Transaction().commit()