def test_regularfields_only_leaves(self): class OnlyLeavesRegularFields(EntityCellRegularFieldsField): only_leaves = True class OnlyLeavesEntityCellsField(EntityCellsField): field_classes = {OnlyLeavesRegularFields} field = OnlyLeavesEntityCellsField(model=FakeContact) fname1 = 'first_name' self.assertListEqual( [EntityCellRegularField.build(FakeContact, fname1)], field.clean(f'regular_field-{fname1}'), ) fname2 = 'sector__title' self.assertListEqual( [EntityCellRegularField.build(FakeContact, fname2)], field.clean(f'regular_field-{fname2}'), ) fname3 = 'sector' self.assertFieldValidationError( EntityCellRegularFieldsField, 'not_leaf', field.clean, f'regular_field-{fname3}', message_args={'value': fname3}, )
def test_eq(self): cell1 = EntityCellRegularField.build(model=FakeDocument, name='title') # Other is not an EntityCell self.assertNotEqual(None, cell1) self.assertNotEqual('whatever', cell1) self.assertEqual( EntityCellRegularField.build(model=FakeDocument, name='title'), cell1) # Value is different self.assertNotEqual( EntityCellRegularField.build(model=FakeDocument, name='linked_folder'), cell1) # Model is different self.assertNotEqual( EntityCellRegularField.build(model=FakeFolder, name='title'), cell1) # Class is different class TestCell(EntityCell): type_id = 'test' def __init__(self, model, value): super().__init__(model=model, value=value) self.assertNotEqual(TestCell(model=FakeDocument, value='title'), cell1)
def test_custom_brick_errors01(self): cbci = CustomBrickConfigItem.objects.create( id='tests-organisations01', name='General', content_type=FakeOrganisation, cells=[ EntityCellRegularField.build(FakeOrganisation, 'name'), EntityCellRegularField.build(FakeOrganisation, 'description'), ], ) # Inject error by bypassing checks CustomBrickConfigItem.objects.filter(id=cbci.id) \ .update(json_cells=cbci.json_cells.replace('description', 'invalid')) cbci = self.refresh(cbci) self.assertEqual(1, len(cbci.cells)) with self.assertNoException(): deserialized = jsonloads(cbci.json_cells) self.assertEqual([{ 'type': 'regular_field', 'value': 'name' }], deserialized)
def test_relation_brick02(self): "All ctypes configured + Relation instance." rtype = RelationType.create( ('test-subject_rented', 'is rented by'), ('test-object_rented', 'rents', [FakeContact, FakeOrganisation]), )[0] # rbi = RelationBrickItem.create(rtype.id) rbi = RelationBrickItem.objects.create_if_needed(rtype) self.assertIsInstance(rbi, RelationBrickItem) self.assertIsNotNone(rbi.pk) self.assertEqual(rtype.id, rbi.relation_type_id) get_ct = ContentType.objects.get_for_model rbi.set_cells(get_ct(FakeContact), [EntityCellRegularField.build(FakeContact, 'last_name')]) rbi.save() self.assertFalse(self.refresh(rbi).all_ctypes_configured) rbi.set_cells(get_ct(FakeOrganisation), [EntityCellRegularField.build(FakeOrganisation, 'name')]) rbi.save() self.assertTrue(self.refresh(rbi).all_ctypes_configured) # --- self.assertEqual(rbi, RelationBrickItem.objects.create_if_needed(rtype))
def test_populate_entities_fields04(self): "Regular fields: invalid subfields." self.login() cell1 = EntityCellRegularField.build(model=FakeContact, name='last_name') cell2 = EntityCellRegularField.build(model=FakeContact, name='user__username') cell2.value = 'user__invalid' # filter_string='__icontains' hf = HeaderFilter.create( pk='test-hf', name=u'Contact view', model=FakeContact, cells_desc=[cell1, cell2], ) create_contact = partial(FakeContact.objects.create, user=self.user) create_contact(first_name='Nagate', last_name='Tanikaze') create_contact(first_name='Shizuka', last_name='Hoshijiro') hf = self.refresh(hf) new_cells = hf.cells self.assertEqual(1, len(new_cells)) self.assertCellEqual(cell1, hf.cells[0])
def test_regular_field_m2m(self): cell = EntityCellRegularField.build(model=FakeContact, name='languages') self.assertTrue(cell.is_multiline) cell = EntityCellRegularField.build(model=FakeContact, name='languages__name') self.assertTrue(cell.is_multiline)
def test_regular_field_fk_subfield01(self): cell = EntityCellRegularField.build(model=FakeContact, name='position__title') self.assertEqual('regular_field-position__title', cell.key) cell = EntityCellRegularField.build(model=FakeContact, name='image__name') self.assertEqual('regular_field-image__name', cell.key)
def test_regular_field_fk(self): cell = EntityCellRegularField.build(model=FakeContact, name='position') self.assertEqual('regular_field-position', cell.key) self.assertEqual(settings.CSS_DEFAULT_LISTVIEW, cell.listview_css_class) cell = EntityCellRegularField.build(model=FakeContact, name='image') self.assertEqual(settings.CSS_DEFAULT_LISTVIEW, cell.listview_css_class)
def test_build_4_field05(self): "Basic ForeignKey subfield." cell = EntityCellRegularField.build(model=FakeContact, name='position__title') self.assertEqual('regular_field-position__title', cell.key) # self.assertEqual('position__title__icontains', cell.filter_string) cell = EntityCellRegularField.build(model=FakeContact, name='image__name') self.assertEqual('regular_field-image__name', cell.key)
def test_relation_brick01(self): rtype = RelationType.create( ('test-subject_loves', 'loves'), ('test-object_loved', 'is loved by'), )[0] rbi = RelationBrickItem.objects.create_if_needed(rtype.id) self.assertIsInstance(rbi, RelationBrickItem) self.assertIsNotNone(rbi.pk) self.assertEqual(rtype.id, rbi.relation_type_id) get_ct = ContentType.objects.get_for_model ct_contact = get_ct(FakeContact) ct_orga = get_ct(FakeOrganisation) ct_img = get_ct(FakeImage) rbi = self.refresh(rbi) # Test persistence self.assertIsNone(rbi.get_cells(ct_contact)) self.assertIsNone(rbi.get_cells(ct_orga)) self.assertIsNone(rbi.get_cells(ct_img)) self.assertIs(rbi.all_ctypes_configured, False) rbi.set_cells( ct_contact, [ EntityCellRegularField.build(FakeContact, 'last_name'), EntityCellFunctionField.build(FakeContact, 'get_pretty_properties'), ], ) rbi.set_cells(ct_orga, [EntityCellRegularField.build(FakeOrganisation, 'name')]) rbi.save() rbi = self.refresh(rbi) # Test persistence self.assertIsNone(rbi.get_cells(ct_img)) self.assertIs(rbi.all_ctypes_configured, False) cells_contact = rbi.get_cells(ct_contact) self.assertEqual(2, len(cells_contact)) cell_contact = cells_contact[0] self.assertIsInstance(cell_contact, EntityCellRegularField) self.assertEqual('last_name', cell_contact.value) cell_contact = cells_contact[1] self.assertIsInstance(cell_contact, EntityCellFunctionField) self.assertEqual('get_pretty_properties', cell_contact.value) self.assertEqual(1, len(rbi.get_cells(ct_orga))) # --- self.assertEqual(rbi, RelationBrickItem.objects.create_if_needed(rtype.id))
def test_custom_block_errors02(self): cbci = CustomBrickConfigItem.objects.create( id='tests-organisations01', name='General', content_type=ContentType.objects.get_for_model(FakeOrganisation), cells=[EntityCellRegularField.build(FakeOrganisation, 'name'), EntityCellRegularField.build(FakeOrganisation, 'invalid'), ], ) cbci = self.refresh(cbci) self.assertEqual(1, len(cbci.cells))
def _build_hf_n_contacts(self): user = self.user create_orga = partial(FakeOrganisation.objects.create, user=user) self.organisations = organisations = { name: create_orga(name=name) for name in ('Bebop', 'Swordfish') } rtype_pilots = RelationType.create(('test-subject_pilots', 'pilots'), ('test-object_pilots', 'is piloted by') )[0] create_ptype = CremePropertyType.create ptype_beautiful = create_ptype(str_pk='test-prop_beautiful', text='is beautiful') ptype_girl = create_ptype(str_pk='test-prop_girl', text='is a girl') create_contact = partial(FakeContact.objects.create, user=user) self.contacts = contacts = { first_name: create_contact(first_name=first_name, last_name=last_name) for first_name, last_name in [('Spike', 'Spiegel'), ('Jet', 'Black'), ('Faye', 'Valentine'), ('Edward', 'Wong'), ] } create_rel = partial(Relation.objects.create, user=user, type=rtype_pilots, object_entity=organisations['Bebop'], ) create_rel(subject_entity=contacts['Jet']) create_rel(subject_entity=contacts['Spike']) create_rel(subject_entity=contacts['Spike'], object_entity=organisations['Swordfish']) create_prop = CremeProperty.objects.create create_prop(type=ptype_girl, creme_entity=contacts['Faye']) create_prop(type=ptype_girl, creme_entity=contacts['Edward']) create_prop(type=ptype_beautiful, creme_entity=contacts['Faye']) cells = [ EntityCellRegularField.build(model=FakeContact, name='civility'), EntityCellRegularField.build(model=FakeContact, name='last_name'), EntityCellRegularField.build(model=FakeContact, name='first_name'), EntityCellRelation(model=FakeContact, rtype=rtype_pilots), # TODO: EntityCellCustomField EntityCellFunctionField.build(model=FakeContact, func_field_name='get_pretty_properties'), ] hf = HeaderFilter.create(pk='test-hf_contact', name='Contact view', model=FakeContact, cells_desc=cells, ) # return cells return hf
def test_build_4_field08(self): "ManyToMany." cell = EntityCellRegularField.build(model=FakeContact, name='languages') # self.assertTrue(cell.has_a_filter) # self.assertFalse(cell.sortable) self.assertTrue(cell.is_multiline) # self.assertEqual('languages', cell.filter_string) cell = EntityCellRegularField.build(model=FakeContact, name='languages__name') # self.assertTrue(cell.has_a_filter) # self.assertFalse(cell.sortable) self.assertTrue(cell.is_multiline)
def test_copy03(self): "Attribute <_sub_fields> (content) & sub-widgets' choices." field1 = EntityCellsField(model=FakeContact) field2 = deepcopy(field1) field1.model = FakeOrganisation self.assertIsNot(field1._sub_fields[0], field2._sub_fields[0]) self.assertIsNot(field1._sub_fields[0].widget, field2._sub_fields[0].widget) self.assertIsNot(field1.widget, field2.widget) self.assertIsNot(field1.widget._sub_widgets[0], field2.widget._sub_widgets[0]) self.assertEqual(FakeOrganisation, field1.model) self.assertEqual(FakeOrganisation, field1.widget.model) self.assertEqual(FakeContact, field2.model) self.assertEqual(FakeContact, field2.widget.model) contact_fname = 'first_name' contact_value = f'regular_field-{contact_fname}' self.assertFieldValidationError( UniformEntityCellsField, 'invalid_value', field1.clean, contact_value, message_args={'value': contact_fname}, ) self.assertListEqual( [EntityCellRegularField.build(FakeContact, contact_fname)], field2.clean(contact_value)) choices1 = self._find_sub_widget(field1, 'regular_field').choices choices2 = self._find_sub_widget(field2, 'regular_field').choices self.assertCellInChoices(contact_value, choices=choices2) self.assertCellNotInChoices(contact_value, choices=choices1) orga_fname = 'capital' orga_value = f'regular_field-{orga_fname}' self.assertFieldValidationError( UniformEntityCellsField, 'invalid_value', field2.clean, orga_value, message_args={'value': orga_fname}, ) self.assertListEqual( [EntityCellRegularField.build(FakeOrganisation, orga_fname)], field1.clean(orga_value)) self.assertCellInChoices(orga_value, choices=choices1) self.assertCellNotInChoices(orga_value, choices=choices2)
def test_edit01(self): self.login() field1 = 'first_name' hf = HeaderFilter.objects.create_if_needed( pk='tests-hf_contact', name='Contact view', model=FakeContact, is_custom=True, cells_desc=[ EntityCellRegularField.build(model=FakeContact, name=field1) ], ) url = hf.get_edit_absolute_url() response = self.assertGET200(url) self.assertTemplateUsed(response, 'creme_core/forms/header-filter.html') self.assertIn( _('Edit the view of list «%(view)s»') % {'view': hf.name}, response.content.decode()) with self.assertNoException(): context = response.context cells_f = context['form'].fields['cells'] submit_label = context['submit_label'] self.assertListEqual(hf.cells, cells_f.initial) self.assertEqual(_('Save the modified view'), submit_label) name = 'Entity view v2' field2 = 'last_name' response = self.client.post( url, data={ 'name': name, 'cells': f'regular_field-{field1},regular_field-{field2}', }, ) self.assertNoFormError(response, status=302) hf = self.refresh(hf) self.assertEqual(name, hf.name) self.assertTrue(hf.is_custom) self.assertListEqual([ EntityCellRegularField.build(FakeContact, field1), EntityCellRegularField.build(FakeContact, field2), ], hf.cells) self.assertRedirects(response, FakeContact.get_lv_absolute_url())
def test_build_4_field04(self): "ForeignKey." cell = EntityCellRegularField.build(model=FakeContact, name='position') self.assertEqual('regular_field-position', cell.key) # self.assertEqual('position', cell.filter_string) self.assertEqual(settings.CSS_DEFAULT_LISTVIEW, cell.listview_css_class) cell = EntityCellRegularField.build(model=FakeContact, name='image') # self.assertEqual('image__header_filter_search_field__icontains', # cell.filter_string # ) self.assertEqual(settings.CSS_DEFAULT_LISTVIEW, cell.listview_css_class)
def test_filterlist01(self): user = self.login() create_hf = partial( HeaderFilter.create, name='Orga view', model=FakeOrganisation, cells_desc=[ EntityCellRegularField.build( model=FakeOrganisation, name='name', ), ], ) hf1 = create_hf(pk='test-hf_orga1') hf2 = create_hf(pk='test-hf_orga2', user=user) hf3 = create_hf(pk='test-hf_contact', model=FakeContact, name='Contact view') hf4 = create_hf(pk='test-hf_orga3', user=self.other_user) ct = self.orga_ct hfl = HeaderFilterList(ct, user) self.assertIn(hf1, hfl) self.assertIn(hf2, hfl) self.assertIn(hf4, hfl) self.assertEqual(hf1, hfl.select_by_id(hf1.id)) self.assertEqual(hf2, hfl.select_by_id(hf2.id)) self.assertEqual(hf2, hfl.select_by_id('unknown_id', hf2.id)) self.assertEqual(hf1.can_view(user), (True, 'OK')) self.assertEqual(hf1.can_view(user, ct), (True, 'OK')) self.assertEqual(hf3.can_view(user, ct), (False, 'Invalid entity type')) self.assertNotIn(hf3, hfl)
def test_create01(self): self.login() name = 'Contact view' pk = 'tests-hf_contact' hf = HeaderFilter.create(pk=pk, name=name, model=FakeContact, is_custom=True) self.assertEqual(pk, hf.pk) self.assertEqual(name, hf.name) self.assertIsNone(hf.user) self.assertEqual(self.contact_ct, hf.entity_type) self.assertIs(hf.is_custom, True) self.assertIs(hf.is_private, False) self.assertEqual('[]', hf.json_cells) self.assertFalse(hf.cells) hf.cells = [ EntityCellRegularField.build(model=FakeContact, name='first_name') ] hf.save() hf = self.refresh(hf) self.assertEqual(1, len(hf.cells)) with self.assertNoException(): deserialized = json_loads(hf.json_cells) self.assertEqual([{ 'type': 'regular_field', 'value': 'first_name' }], deserialized)
def _get_cells(self, model): cells = [] for cell_cls, data in self._cells: cell = None if cell_cls is EntityCellRegularField: cell = EntityCellRegularField.build(model=model, name=data) elif cell_cls is EntityCellFunctionField: cell = EntityCellFunctionField.build(model, func_field_name=data) else: # EntityCellRelation rtype = self._get_relationtype(data) if rtype is False: logger.warning( 'SmartColumnsRegistry: relation type "%s" does not exist', data) else: cell = EntityCellRelation(model=model, rtype=rtype) # Has no sense here: # EntityCellActions : not configurable in HeaderFilter form # EntityCellCustomField : dynamically created by user # TODO: other types if cell is not None: cells.append(cell) return cells
def test_functionfield03(self): "<sorter_class> attribute." class PhoneSorter(AbstractCellSorter): def get_field_name(this, cell): return 'modified' # NB: it has no sense, it's just for testing purposes... class PhoneFunctionField(FunctionField): name = 'phone_or_mobile' verbose_name = 'Phone or mobile' sorter_class = PhoneSorter # def __call__(self, entity, user): # return self.result_type(entity.phone or entity.mobile) function_field = PhoneFunctionField() sorter = QuerySorter() cells = [ EntityCellRegularField.build(model=FakeOrganisation, name='name'), EntityCellFunctionField(model=FakeOrganisation, func_field=function_field), ] key = cells[1].key sortinfo = sorter.get(model=FakeOrganisation, cells=cells, cell_key=key) self.assertEqual(('modified', 'name', 'cremeentity_ptr_id'), sortinfo.field_names) self.assertEqual(key, sortinfo.main_cell_key) self.assertTrue(sortinfo.main_order.asc)
def test_regularfield_registry06(self): "register_model_field(): sub-registry." user1 = self.user user2 = CremeUser( username='******', email='*****@*****.**', first_name='Chie', last_name='Uru', ) class MyField1(lv_form.ListViewSearchField): pass class MyField2(lv_form.ListViewSearchField): pass class MyRegistry(lv_search.AbstractListViewSearchFieldRegistry): def get_field(self, *, cell, user, **kwarg): cls = MyField1 if user.username == user1.username else MyField2 return cls(cell=cell, user=user) registry = lv_search.RegularFieldSearchRegistry()\ .register_model_field( model=FakeContact, field_name='first_name', sfield_builder=MyRegistry ) cell = EntityCellRegularField.build(model=FakeContact, name='first_name') get_field = registry.get_field self.assertIsInstance(get_field(cell=cell, user=user1), MyField1) self.assertIsInstance(get_field(cell=cell, user=user2), MyField2)
def test_relation_block02(self): "All ctypes configured" rtype = RelationType.create(('test-subject_rented', 'is rented by'), ('test-object_rented', 'rents', [FakeContact, FakeOrganisation]), )[0] rbi = RelationBrickItem.create(rtype.id) get_ct = ContentType.objects.get_for_model rbi.set_cells(get_ct(FakeContact), [EntityCellRegularField.build(FakeContact, 'last_name')]) rbi.save() self.assertFalse(self.refresh(rbi).all_ctypes_configured) rbi.set_cells(get_ct(FakeOrganisation), [EntityCellRegularField.build(FakeOrganisation, 'name')]) rbi.save() self.assertTrue(self.refresh(rbi).all_ctypes_configured)
def __init__(self, descriptor, groups, *args, **kwargs): super().__init__(descriptor=descriptor, *args, **kwargs) cells_f = self.fields['cells'] cells_f.model = model = descriptor.model cells_f.required = False ignored_cells = [ *( cell for i, group in enumerate(groups) for cell in getattr(group, 'cells', ()) # extra group has no <cells> ), *( EntityCellRegularField.build(model=model, name=field_name) for field_name in descriptor.excluded_fields ), ] # TODO: move semantic to EntityCellCustomFormSpecial ?? if descriptor.form_type == CustomFormDescriptor.EDITION_FORM: ignored_cells.extend( EntityCellCustomFormSpecial(model=model, name=name) for name in ( EntityCellCustomFormSpecial.CREME_PROPERTIES, EntityCellCustomFormSpecial.RELATIONS, ) ) cells_f.ignored_cells = ignored_cells
def test_regular_field_month(self): ordinate_cell = EntityCellRegularField.build(FakeOrganisation, 'capital') user = self.create_user() report = Report.objects.create(user=user, name='Field Test', ct=FakeOrganisation) graph = ReportGraph.objects.create( user=user, name='Field Test', linked_report=report, # abscissa_cell_value='modified', abscissa_type=RGT_MONTH, abscissa_cell_value='modified', abscissa_type=ReportGraph.Group.MONTH, # ordinate_type=RGA_SUM, ordinate_type=ReportGraph.Aggregator.SUM, ordinate_cell_key=ordinate_cell.key, ) hand = RGHMonth(graph) # self.assertEqual(RGT_MONTH, hand.hand_id) self.assertEqual(ReportGraph.Group.MONTH, hand.hand_id) self.assertEqual(_('By months'), hand.verbose_name) self.assertIsNone(hand.abscissa_error) self.assertEqual(_('Last modification'), hand.verbose_abscissa) ordinate = hand.ordinate self.assertIsInstance(ordinate, RGASum) self.assertIsNone(ordinate.error)
def test_regularfield_registry07(self): "Choices + sub-registry" user1 = self.user user2 = CremeUser( username='******', email='*****@*****.**', first_name='Chie', last_name='Uru', ) class MyChoiceField1(lv_form.ListViewSearchField): pass class MyChoiceField2(lv_form.ListViewSearchField): pass class MyChoiceRegistry(lv_search.AbstractListViewSearchFieldRegistry): def get_field(self, *, cell, user, **kwarg): cls = MyChoiceField1 if user.username == user1.username else MyChoiceField2 return cls(cell=cell, user=user) registry = lv_search.RegularFieldSearchRegistry( ).register_choice_builder(MyChoiceRegistry) cell = EntityCellRegularField.build(model=FakeInvoiceLine, name='discount_unit') get_field = registry.get_field self.assertIsInstance(get_field(cell=cell, user=user1), MyChoiceField1) self.assertIsInstance(get_field(cell=cell, user=user2), MyChoiceField2) self.assertIsInstance(registry.choice_builder, MyChoiceRegistry)
def test_filterlist03(self): "Staff user -> can see all filters" user = self.login(is_staff=True) other_user = self.other_user cells = [ EntityCellRegularField.build(model=FakeOrganisation, name='name') ] def create_hf(id, **kwargs): return HeaderFilter.create(pk='test-hf_orga{}'.format(id), name='Orga view #{}'.format(id), model=FakeOrganisation, cells_desc=cells, **kwargs) hf1 = create_hf(1) with self.assertRaises(ValueError): create_hf(2, user=user) hf3 = create_hf(3, user=other_user) # This,one can not be seen by not staff users hf4 = create_hf(4, user=other_user, is_private=True, is_custom=True) hfl = HeaderFilterList(self.orga_ct, user) self.assertIn(hf1, hfl) self.assertIn(hf3, hfl) self.assertIn(hf4, hfl)
def test_cell_render04(self): "Assignment" user = self.login() ripley = FakeContact(user=user, first_name='Helen', last_name='Ripley', email='*****@*****.**') cell = EntityCellRegularField.build(model=FakeContact, name='email') with self.assertNoException(): template = Template( r'{% load creme_cells %}' r'{% cell_render cell=cell instance=helen user=user as cell_content %}' r'{{cell_content}}') render = template.render( Context({ 'cell': cell, 'helen': ripley, 'user': user })) self.assertEqual( '<a href="mailto:[email protected]">[email protected]</a>', render.strip()) # TODO: missing argument ?
def test_filtered_cells(self): hidden = 'first_name' FieldsConfig.objects.create( content_type=FakeContact, descriptions=[ (hidden, { FieldsConfig.HIDDEN: True }), ], ) rtype = self.get_object_or_fail(RelationType, id=REL_SUB_HAS) hf = HeaderFilter.objects.create_if_needed( pk='tests-hf_contact', name='Contact view', model=FakeContact, cells_desc=[ (EntityCellRegularField, { 'name': 'last_name' }), (EntityCellRegularField, { 'name': hidden }), EntityCellRelation(model=FakeContact, rtype=rtype), ], ) self.assertListEqual( [ EntityCellRegularField.build(FakeContact, 'last_name'), EntityCellRelation(model=FakeContact, rtype=rtype), ], hf.filtered_cells, )
def test_build_4_field03(self): "Boolean field." cell = EntityCellRegularField.build(model=FakeContact, name='is_a_nerd') # self.assertEqual('is_a_nerd__creme-boolean', cell.filter_string) self.assertEqual(settings.CSS_DEFAULT_LISTVIEW, cell.listview_css_class)
def _get_cells(self, entity, context): # cells = super(DocumentBrick, self)._get_cells(entity=entity, context=context) cells = super()._get_cells(entity=entity, context=context) cells.append( EntityCellRegularField.build(model=Document, name='categories')) return cells