def update(self): """Update a label. """ if self.request.form.get('form.delete', None): return self.remove() label_id = self.request.form.get('label_id', None) if not label_id: raise BadRequest('The "label_id" request argument is required.') jar = ILabelJar(self.context) label = jar.get(label_id) title = self.request.form.get('title', None) if title: label['title'] = title color = self.request.form.get('color', None) if color: label['color'] = color by_user = bool(self.request.form.get('by_user', False)) label['by_user'] = by_user jar.update(**label) return self._redirect()
def upgrade_to_2001(context): """ Add 'by_user' key to False in jar. Migrate annotation content on ILabelSupport to replace PersistentList by PersistentMapping. """ # take all elements who provides ftw.labels.interfaces.ILabelRoot or ILabelJarChild portal_catalog = api.portal.get_tool('portal_catalog') brains = portal_catalog(object_provides=(ILabelRoot.__identifier__, ILabelJarChild.__identifier__)) for brain in brains: jar = ILabelJar(brain.getObject()) for key in jar.storage.keys(): if 'by_user' not in jar.storage[key].keys(): # give default value if not exist jar.storage[key]['by_user'] = False # take all elements who provides ftw.labels.interfaces.IlabelSupport brains = portal_catalog(object_provides=ILabelSupport.__identifier__) # Transform PersistentList in PersistentMapping for brain in brains: obj = brain.getObject() labeling = ILabeling(obj) old_values = [label for label in labeling.storage] annotation = IAnnotations(obj) del annotation['ftw.labels:labeling'] labeling._storage = None labeling.update(old_values)
def setUp(self): super(TestLabeling, self).setUp() Labeling.user_id = lambda x: TEST_USER_ID # needed to avoid plone.api.portal.get error self.root = self.providing_stub([ILabelRoot, IAttributeAnnotatable]) self.document = self.providing_stub( [ILabelSupport, IAttributeAnnotatable]) self.set_parent(self.document, self.root) self.jar = ILabelJar(self.root)
def _updateFTWLabelsStorage(self): """ftw.labels jar was created using dict we need PersistentMappings...""" logger.info("Updating ftw.labels jar for every MeetingConfigs...") for cfg in self.tool.objectValues('MeetingConfig'): jar_storage = ILabelJar(cfg).storage for k, v in jar_storage.items(): jar_storage[k] = PersistentMapping(v) logger.info('Done.')
def after_create(self, obj): super(LabelRootBuilder, self).after_create(obj) jar = ILabelJar(obj) for title, color in self.labels: jar.add(title, color) if self.session.auto_commit: transaction.commit()
def after_create(self, obj): super(LabelRootBuilder, self).after_create(obj) jar = ILabelJar(obj) for title, color, by_user in self.labels: jar.add(title, color, by_user) if self.session.auto_commit: transaction.commit()
def test_update_label(self, browser): root = create( Builder('label root').with_labels(('Question', 'purple', False), ('Bug', 'red', True))) browser.login().open(root, view='labels-jar/update', data={ 'label_id': 'question', 'title': 'Questions and inquiries', 'color': 'green' }) self.assertItemsEqual([{ 'label_id': 'question', 'title': 'Questions and inquiries', 'color': 'green', 'by_user': False }, { 'label_id': 'bug', 'title': 'Bug', 'color': 'red', 'by_user': True }], ILabelJar(root).list())
def jar_discovery(context): """An ILabelJar adapter for non-ILabelRoot objects, walking up the acquisition chain for finding the ILabelJar. This allows to adapt any object, which is within an ILabelRoot, to ILabelJar without the need to find the root. """ return ILabelJar(aq_parent(aq_inner(context)))
def test_walks_up_the_acquisition_for_finding_jar(self): root = self.providing_stub(ILabelRoot) folder = self.set_parent(self.stub(), root) document = self.set_parent(self.stub(), folder) jar = ILabelJar(document) self.assertIsInstance(jar, LabelJar) self.assertEquals(root, jar.context)
def setUp(self): super(TestLabeling, self).setUp() self.root = self.providing_stub([ILabelRoot, IAttributeAnnotatable]) self.document = self.providing_stub([ILabelSupport, IAttributeAnnotatable]) self.set_parent(self.document, self.root) self.replay() self.jar = ILabelJar(self.root)
def test_raise_when_app_is_reached(self): app = self.providing_stub(IApplication) document = self.set_parent(self.stub(), app) with self.assertRaises(LookupError) as cm: ILabelJar(document) self.assertEquals( 'Could not find ILabelJar on any parents.' ' No parent seems to provide ILabelRoot.', str(cm.exception))
class Labeling(object): implements(ILabeling) adapts(ILabelSupport) def __init__(self, context): self.context = context self.jar = ILabelJar(self.context) def update(self, label_ids): available_labels = self.jar.storage.keys() for label_id in label_ids: if label_id not in available_labels: raise LookupError( 'Cannot activate label: ' 'the label "{0}" is not in the label jar. ' 'Following labels ids are available: {1}'.format( label_id, ', '.join(available_labels))) # Do not replace self.storage, since it is a PersistentList! self.storage[:] = label_ids def active_labels(self): labels = [] for label_id in self.storage: try: labels.append(self.jar.get(label_id)) except KeyError: pass return sorted(labels, key=lambda cls: make_sortable(cls['title'])) def available_labels(self): for label in self.jar.list(): label['active'] = (label.get('label_id') in self.storage) yield label @property def storage(self): if getattr(self, '_storage', None) is None: annotation = IAnnotations(self.context) if ANNOTATION_KEY not in annotation: annotation[ANNOTATION_KEY] = PersistentList() self._storage = annotation[ANNOTATION_KEY] return self._storage
def remove(self): """Remove a label. """ label_id = self.request.form.get('label_id', None) if not label_id: raise BadRequest('The "label_id" request argument is required.') ILabelJar(self.context).remove(label_id) return self._redirect(consider_referer=False)
def test_edit_label_form_delete_label(self, browser): root = create( Builder('label root').with_labels(('Feature', 'blue', True))) browser.login().open(root, view='labels-jar/edit_label?label_id=feature') browser.find('Delete label').click() self.assertEqual([], ILabelJar(root).list())
def setUp(self): """ """ super(TestLabels, self).setUp() self.doc1 = api.content.create(self.portal, 'Document', 'doc1') self.doc2 = api.content.create(self.portal, 'Document', 'doc2') # defined some labels alsoProvides(self.portal, ILabelRoot) adapted = ILabelJar(self.portal) adapted.add('Pers1', 'green', True) # label_id = pers1 adapted.add('Pers2', 'green', True) # label_id = pers2 adapted.add('Pers3', 'green', True) # label_id = pers3 adapted.add('Glob1', 'red', False) # label_id = glob1 adapted.add('Glob2', 'red', False) # label_id = glob2 adapted.add('Glob3', 'red', False) # label_id = glob3 # can label created objects for obj in (self.doc1, self.doc2): alsoProvides(obj, ILabelSupport) self.lab_doc1 = ILabeling(self.doc1) self.lab_doc2 = ILabeling(self.doc2) login(self.portal, TEST_USER_NAME)
def create(self): """Create a new label. """ title = self.request.form.get('title', None) if not title: api.portal.show_message( _(u'lable_title_is_missing', default=u'Please choose a title.'), self.request, 'error') return self._redirect() color = self.request.form.get('color', None) if not color: color = self._get_random_color() jar = ILabelJar(self.context) jar.get(jar.add(title, color)) return self._redirect()
def __call__(self, context): terms = [] try: adapted = ILabelJar(context) except: # noqa return SimpleVocabulary(terms) user = api.user.get_current() for label in adapted.list(): if label['by_user']: terms.append( SimpleVocabulary.createTerm( '%s:%s' % (user.id, label['label_id']), '%s_%s' % (user.id, label['label_id']), safe_unicode(label['title']))) else: terms.append( SimpleVocabulary.createTerm(label['label_id'], label['label_id'], safe_unicode(label['title']))) return SimpleVocabulary(terms)
def create(self): """Create a new label. """ title = self.request.form.get('title', None) if not title: api.portal.show_message( _(u'lable_title_is_missing', default=u'Please choose a title.'), self.request, 'error') return self._redirect() color = self.request.form.get('color', None) if not color: color = self._get_random_color() by_user = bool(self.request.form.get( 'by_user', False)) # received value is 'on' when checked jar = ILabelJar(self.context) jar.get(jar.add(title, color, by_user)) return self._redirect()
def create(self): """Create a new label. """ title = self.request.form.get('title', None) if not title: api.portal.show_message( _(u'lable_title_is_missing', default=u'Please choose a title.'), self.request, 'error') return self._redirect() color = self.request.form.get('color', None) if not color: color = self._get_random_color() by_user = bool(self.request.form.get('by_user', False)) # received value is 'on' when checked jar = ILabelJar(self.context) jar.get(jar.add(title, color, by_user)) return self._redirect()
def test_create_label_without_color_add_random_existing_color( self, browser): root = create(Builder('label root')) browser.login() for i in range(0, len(COLORS)): browser.open(root, view='labels-jar/create', data={'title': 'Question'}) selected_colors = [ label.get('color') for label in ILabelJar(root).list() ] self.assertEquals(len(COLORS), len(list(set(selected_colors))))
def _get_random_color(self): all_colors = list(COLORS) all_colors.extend(['{0}-light'.format(color) for color in COLORS]) used_colors = [ label.get('color') for label in ILabelJar(self.context).list() ] available_colors = tuple(set(all_colors) - set(used_colors)) if not available_colors: available_colors = all_colors return random.choice(available_colors)
def get_labels_vocabulary(self): terms, p_labels, g_labels = [], [], [] context = self.get_labeljar_context() try: adapted = ILabelJar(context) except: return SimpleVocabulary(terms), [], [] self.can_change_labels = is_permitted(self.brains, perm='ftw.labels: Change Labels') for label in adapted.list(): if label['by_user']: p_labels.append(label['label_id']) terms.append( SimpleVocabulary.createTerm( '%s:' % label['label_id'], label['label_id'], u'{} (*)'.format(safe_unicode(label['title'])))) else: g_labels.append(label['label_id']) if self.can_change_labels: terms.append( SimpleVocabulary.createTerm( label['label_id'], label['label_id'], safe_unicode(label['title']))) return SimpleVocabulary(terms), set(p_labels), g_labels
def test_edit_label_form_change_color(self, browser): root = create( Builder('label root').with_labels(('Feature', 'blue', True))) browser.login().open(root, view='labels-jar/edit_label?label_id=feature') browser.fill({'color': 'green'}).submit() self.assertEqual([{ 'label_id': 'feature', 'title': 'Feature', 'color': 'green', 'by_user': True }], ILabelJar(root).list())
def test_edit_label_form_change_by_user(self, browser): root = create( Builder('label root').with_labels(('Feature', 'blue', False))) browser.login().open(root, view='labels-jar/edit_label?label_id=feature') browser.find('by_user').value = 'on' browser.forms.get('form-0').submit() self.assertEqual([{ 'label_id': 'feature', 'title': 'Feature', 'color': 'blue', 'by_user': True }], ILabelJar(root).list())
def test_label_root_builder(self): root = create( Builder('label root').with_labels(('Questions', 'blue', False), ('Bugs', 'red', True))) self.assertItemsEqual([{ 'label_id': 'questions', 'title': 'Questions', 'color': 'blue', 'by_user': False }, { 'label_id': 'bugs', 'title': 'Bugs', 'color': 'red', 'by_user': True }], ILabelJar(root).list())
def test_create_label(self, browser): root = create(Builder('label root')) browser.login().open(root, view='labels-jar/create', data={ 'title': 'Question', 'color': 'purple', 'by_user': '******' }) self.assertEqual([{ 'label_id': 'question', 'title': 'Question', 'color': 'purple', 'by_user': True }], ILabelJar(root).list())
def __call__(self, context): context = get_context_with_request(context) tool = api.portal.get_tool('portal_plonemeeting') cfg = tool.getMeetingConfig(context) member_id = get_current_user_id(context.REQUEST) res = [] labels = ILabelJar(cfg).list() for label in labels: if label['by_user']: res.append( SimpleTerm('{0}:{1}'.format(member_id, label['label_id']), '{0}:{1}'.format(member_id, label['label_id']), '{0} (*)'.format(label['title']))) else: res.append( SimpleTerm(label['label_id'], label['label_id'], label['title'])) return SimpleVocabulary(res)
def __call__(self, context): res = [] context = get_context_with_request(context) tool = api.portal.get_tool('portal_plonemeeting') try: # in some case, like Plone Site creation, context is the Zope app... cfg = tool.getMeetingConfig(context) except: return SimpleVocabulary(res) if cfg and cfg.getEnableLabels(): labels = ILabelJar(cfg).list() for label in labels: if label['by_user']: title = '{0} (*)'.format(label['title']) else: title = label['title'] res.append( SimpleTerm(label['label_id'], label['label_id'], title)) return SimpleVocabulary(res)
def __init__(self, context): self.context = context self.jar = ILabelJar(self.context)
def test_label_jar_implements_interface(self): self.assertTrue(ILabelJar.implementedBy(LabelJar), 'LabelJar should implement ILabelJar') verifyClass(ILabelJar, LabelJar)
class Labeling(object): implements(ILabeling) adapts(ILabelSupport) def __init__(self, context): self.context = context self.jar = ILabelJar(self.context) def update(self, label_ids): jar_keys = self.jar.storage.keys() # removes deselected labels for label_id in self.storage.keys( ): # use keys to avoid RuntimeError: dictionary changed size during iteration if label_id not in jar_keys: continue # do we remove key ?? label = self.jar.get(label_id) if label_id not in label_ids: if not label['by_user']: self.storage.pop(label_id) # adds selected labels for label_id in label_ids: if label_id not in jar_keys: raise LookupError( 'Cannot activate label: ' 'the label "{0}" is not in the label jar. ' 'Following labels ids are available: {1}'.format( label_id, ', '.join(jar_keys))) if label_id not in self.storage: self.storage[label_id] = PersistentList() def pers_update(self, label_ids, activate): user_id = self.user_id() if not user_id: return False if activate: for label_id in label_ids: if label_id not in self.storage: self.storage[label_id] = PersistentList() if user_id not in self.storage[label_id]: self.storage[label_id].append(user_id) else: for label_id in label_ids: if label_id not in self.storage: continue if user_id in self.storage[label_id]: self.storage[label_id].remove(user_id) if not self.storage[label_id]: self.storage.pop(label_id) return True def active_labels(self): # selected labels labels = [] for label_id in self.storage: try: label = self.jar.get(label_id) if label['by_user']: if self.user_id() in self.storage[label_id]: labels.append(label) else: labels.append(label) except KeyError: pass return sorted(labels, key=lambda cls: make_sortable(cls['title'])) def available_labels(self): # possible labels, marking active ones labels = [[], []] for label in self.jar.list(): if label['by_user']: label['active'] = (label['label_id'] in self.storage and self.user_id() in self.storage[label['label_id']]) labels[0].append(label) else: label['active'] = (label.get('label_id') in self.storage) labels[1].append(label) labels[0].sort(key=lambda cls: make_sortable(cls['title'])) labels[1].sort(key=lambda cls: make_sortable(cls['title'])) return labels def user_id(default=None): """ Return current userid """ cur_user = api.user.get_current() if not cur_user: return default return cur_user.getId() @property def storage(self): if getattr(self, '_storage', None) is None: annotation = IAnnotations(self.context) if ANNOTATION_KEY not in annotation: annotation[ANNOTATION_KEY] = PersistentMapping() self._storage = annotation[ANNOTATION_KEY] return self._storage
def label_root_obj(self): try: return ILabelJar(self.context) except LookupError: return None
def _finishConfigFor(self, cfg, data): """When the MeetingConfig has been created, some parameters still need to be applied because they need the MeetingConfig to exist.""" # apply the meetingTopicStates to the 'searchnotdecidedmeetings' DashboardCollection updateCollectionCriterion( cfg.searches.searches_meetings.searchnotdecidedmeetings, 'review_state', list(data.meetingTopicStates)) # apply the maxDaysDecisions to the 'searchlastdecisions' DashboardCollection updateCollectionCriterion( cfg.searches.searches_decisions.searchlastdecisions, 'meeting_date', unicode(data.maxDaysDecisions)) # apply the decisionTopicStates to the 'searchlastdecisions' # and 'searchalldecision' DashboardCollections updateCollectionCriterion( cfg.searches.searches_decisions.searchlastdecisions, 'review_state', list(data.decisionTopicStates)) # select correct default view meetingAppDefaultView = data.meetingAppDefaultView if meetingAppDefaultView in cfg.searches.searches_items.objectIds(): cfg._set_default_faceted_search(meetingAppDefaultView) else: error = 'meetingAppDefaultView : No DashboardCollection with id %s' % meetingAppDefaultView raise PloneMeetingError(MEETING_CONFIG_ERROR % (cfg.Title(), cfg.getId(), error)) # now we can set values for dashboard...Filters fields as the 'searches' folder has been created for fieldName in ('dashboardItemsListingsFilters', 'dashboardMeetingAvailableItemsFilters', 'dashboardMeetingLinkedItemsFilters'): field = cfg.getField(fieldName) # we want to validate the vocabulay, as if enforceVocabulary was True error = field.validate_vocabulary( cfg, cfg.getField(field.getName()).get(cfg), {}) if error: raise PloneMeetingError(MEETING_CONFIG_ERROR % (cfg.Title(), cfg.getId(), error)) if data.addContactsCSV: output = import_contacts(self.portal, path=self.profilePath) logger.info(output) selectableOrderedContacts = cfg.getField( 'orderedContacts').Vocabulary(cfg).keys() cfg.setOrderedContacts(selectableOrderedContacts) # turn contact path to uid for org_storing_field in ('orderedContacts', ): org_storing_data = getattr(data, org_storing_field, []) if org_storing_data: contact_uids = [] for contact_path in org_storing_data: try: contact_uid = self.portal.contacts.restrictedTraverse( contact_path).UID() contact_uids.append(contact_uid) except KeyError: logger.warning( 'While computing "{0}", could not get contact at "{1}"' .format(org_storing_field, contact_path)) cfg.getField(org_storing_field).set(cfg, contact_uids) # set default labels if data.defaultLabels: jar = ILabelJar(cfg) update_labels_jar(jar, values=data.defaultLabels) # disable relevant dashboard collections for collection_path in data.disabled_collections: try: collection = cfg.searches.restrictedTraverse(collection_path) except AttributeError: logger.warning( 'While disabling collections, no collection found at {0}, ...' .format(collection_path)) collection.enabled = False collection.reindexObject(idxs=['enabled'])
class Labeling(object): implements(ILabeling) adapts(ILabelSupport) def __init__(self, context): self.context = context self.jar = ILabelJar(self.context) def update(self, label_ids): jar_keys = self.jar.storage.keys() # removes deselected labels for label_id in self.storage.keys(): # use keys to avoid RuntimeError: dictionary changed size during iteration if label_id not in jar_keys: continue # do we remove key ?? label = self.jar.get(label_id) if label_id not in label_ids: if not label['by_user']: self.storage.pop(label_id) # adds selected labels for label_id in label_ids: if label_id not in jar_keys: raise LookupError( 'Cannot activate label: ' 'the label "{0}" is not in the label jar. ' 'Following labels ids are available: {1}'.format( label_id, ', '.join(jar_keys))) if label_id not in self.storage: self.storage[label_id] = PersistentList() def pers_update(self, label_id, activate): user_id = self.user_id() if not user_id: return False if activate: if label_id not in self.storage: self.storage[label_id] = PersistentList() if user_id not in self.storage[label_id]: self.storage[label_id].append(user_id) else: if user_id in self.storage[label_id]: self.storage[label_id].remove(user_id) if not self.storage[label_id]: self.storage.pop(label_id) return True def active_labels(self): # selected labels labels = [] for label_id in self.storage: try: label = self.jar.get(label_id) if label['by_user']: if self.user_id() in self.storage[label_id]: labels.append(label) else: labels.append(label) except KeyError: pass return sorted(labels, key=lambda cls: make_sortable(cls['title'])) def available_labels(self): # possible labels, marking active ones labels = [[], []] for label in self.jar.list(): if label['by_user']: label['active'] = (label['label_id'] in self.storage and self.user_id() in self.storage[label['label_id']]) labels[0].append(label) else: label['active'] = (label.get('label_id') in self.storage) labels[1].append(label) labels[0].sort(key=lambda cls: make_sortable(cls['title'])) labels[1].sort(key=lambda cls: make_sortable(cls['title'])) return labels def user_id(default=None): """ Return current userid """ cur_user = api.user.get_current() if not cur_user: return default return cur_user.getId() @property def storage(self): if getattr(self, '_storage', None) is None: annotation = IAnnotations(self.context) if ANNOTATION_KEY not in annotation: annotation[ANNOTATION_KEY] = PersistentMapping() self._storage = annotation[ANNOTATION_KEY] return self._storage
def update_site(self): # add documentation message if 'doc' not in self.portal['messages-config']: add_message( 'doc', 'Documentation', u'<p>Vous pouvez consulter la <a href="http://www.imio.be/' u'support/documentation/topic/cp_app_ged" target="_blank">documentation en ligne de la ' u'dernière version</a>, ainsi que d\'autres documentations liées.</p>', msg_type='significant', can_hide=True, req_roles=['Authenticated'], activate=True) if 'doc2-0' in self.portal['messages-config']: api.content.delete(obj=self.portal['messages-config']['doc2-0']) # update front-page frontpage = self.portal['front-page'] if frontpage.Title() == 'Gestion du courrier 2.0': frontpage.setTitle(_("front_page_title")) frontpage.setDescription(_("front_page_descr")) frontpage.setText(_("front_page_text"), mimetype='text/html') # update portal title self.portal.title = 'Gestion du courrier' # for collective.externaleditor if 'MailingLoopTemplate' not in self.registry[ 'externaleditor.externaleditor_enabled_types']: self.registry['externaleditor.externaleditor_enabled_types'] = [ 'PODTemplate', 'ConfigurablePODTemplate', 'DashboardPODTemplate', 'SubTemplate', 'StyleTemplate', 'dmsommainfile', 'MailingLoopTemplate' ] # documentgenerator api.portal.set_registry_record( 'collective.documentgenerator.browser.controlpanel.' 'IDocumentGeneratorControlPanelSchema.raiseOnError_for_non_managers', True) # ftw.labels if not ILabelRoot.providedBy(self.imf): labels = { self.imf: [('Lu', 'green', True), ('Suivi', 'yellow', True)], self.omf: [], self.portal['tasks']: [] } for folder in labels: if not ILabelRoot.providedBy(folder): alsoProvides(folder, ILabelRoot) adapted = ILabelJar(folder) existing = [dic['title'] for dic in adapted.list()] for title, color, by_user in labels[folder]: if title not in existing: adapted.add(title, color, by_user) self.portal.manage_permission('ftw.labels: Manage Labels Jar', ('Manager', 'Site Administrator'), acquire=0) self.portal.manage_permission('ftw.labels: Change Labels', ('Manager', 'Site Administrator'), acquire=0) self.portal.manage_permission( 'ftw.labels: Change Personal Labels', ('Manager', 'Site Administrator', 'Member'), acquire=0) self.runProfileSteps('imio.dms.mail', steps=['imiodmsmail-mark-copy-im-as-read'], profile='singles') # INextPrevNotNavigable alsoProvides(self.portal['tasks'], INextPrevNotNavigable) # registry api.portal.set_registry_record( name= 'Products.CMFPlone.interfaces.syndication.ISiteSyndicationSettings.' 'search_rss_enabled', value=False) # activing versioning self.portal.portal_diff.setDiffForPortalType( 'task', {'any': "Compound Diff for Dexterity types"}) self.portal.portal_diff.setDiffForPortalType( 'dmsommainfile', {'any': "Compound Diff for Dexterity types"}) # change permission self.portal.manage_permission('imio.dms.mail: Write userid field', (), acquire=0) pf = self.portal.contacts['personnel-folder'] pf.manage_permission('imio.dms.mail: Write userid field', ('Manager', 'Site Administrator'), acquire=0) # ckeditor skin self.portal.portal_properties.ckeditor_properties.skin = 'moono-lisa' # update mailcontent options self.registry[ 'collective.dms.mailcontent.browser.settings.IDmsMailConfig.outgoingmail_edit_irn'] = u'hide' self.registry[ 'collective.dms.mailcontent.browser.settings.IDmsMailConfig.outgoingmail_increment_number'] = True # hide faceted actions paob = self.portal.portal_actions.object_buttons for act in ('faceted.sync', 'faceted.disable', 'faceted.enable', 'faceted.search.disable', 'faceted.search.enable', 'faceted.actions.disable', 'faceted.actions.enable'): if act in paob: paob[act].visible = False
def labels(self): return ILabelJar(self.label_root_obj).list()
class TestLabeling(MockTestCase): layer = ADAPTERS_ZCML_LAYER def setUp(self): super(TestLabeling, self).setUp() self.root = self.providing_stub([ILabelRoot, IAttributeAnnotatable]) self.document = self.providing_stub([ILabelSupport, IAttributeAnnotatable]) self.set_parent(self.document, self.root) self.replay() self.jar = ILabelJar(self.root) def test_adapter(self): self.assertTrue( queryAdapter(self.document, ILabeling), 'The labeling adapter is not registered for ILabeling') def test_available_labels(self): self.jar.add('Question', '#00FF00') labeling = ILabeling(self.document) self.assertEqual( [{'label_id': 'question', 'title': 'Question', 'color': '#00FF00', 'active': False}], list(labeling.available_labels())) def test_available_labels_empty(self): labeling = ILabeling(self.document) self.assertEqual([], list(labeling.available_labels())) def test_available_label(self): self.jar.add('Question', '#00FF00') labeling = ILabeling(self.document) labeling.update(['question']) self.assertEqual( [{'label_id': 'question', 'title': 'Question', 'color': '#00FF00', 'active': True}], list(labeling.available_labels())) def test_update__enable_labels(self): self.jar.add('Bug', 'red') self.jar.add('Question', 'green') self.jar.add('Feature', 'purple') labeling = ILabeling(self.document) self.assertEqual([], labeling.active_labels()) labeling.update(['bug', 'feature']) self.assertItemsEqual(['Bug', 'Feature'], label_titles(labeling.active_labels())) def test_update__disable_labels(self): self.jar.add('Bug', 'red') self.jar.add('Question', 'green') self.jar.add('Feature', 'purple') labeling = ILabeling(self.document) labeling.update(['bug', 'question', 'feature']) self.assertItemsEqual(['Bug', 'Feature', 'Question'], label_titles(labeling.active_labels())) labeling.update(['bug']) self.assertItemsEqual(['Bug'], label_titles(labeling.active_labels())) labeling.update([]) self.assertEqual([], labeling.active_labels()) def test_update_raises_LookupError_when_label_not_in_jar(self): self.assertEqual(0, len(self.jar.list())) self.jar.add('Question', '') labeling = ILabeling(self.document) with self.assertRaises(LookupError) as cm: labeling.update(['something']) self.assertEqual( 'Cannot activate label: the label' ' "something" is not in the label jar. ' 'Following labels ids are available: question', str(cm.exception)) def test_active_labels(self): self.jar.add('Question', '') self.jar.add('Bug', '') self.jar.add('Duplicate', '') labeling = ILabeling(self.document) labeling.update(['bug']) self.assertEqual( [{'label_id': 'bug', 'title': 'Bug', 'color': ''}], labeling.active_labels()) def test_active_labels_is_sorted(self): self.jar.add('Zeta-0', '') self.jar.add('zeta-1', '') self.jar.add('alpha-0', '') self.jar.add('\xc3\x84lpha-1', '') self.jar.add('Alpha-2', '') labeling = ILabeling(self.document) labeling.update([ 'zeta-0', 'zeta-1', 'alpha-0', 'alpha-1', 'alpha-2', ]) self.assertEqual( ['alpha-0', '\xc3\x84lpha-1', 'Alpha-2', 'Zeta-0', 'zeta-1'], [label.get('title') for label in labeling.active_labels()]) def test_active_labels_filters_deleted_labels(self): self.jar.add('Question', 'blue') self.jar.add('Bug', 'red') labeling = ILabeling(self.document) labeling.update(['question', 'bug']) self.jar.remove('bug') self.assertEqual( [{'label_id': 'question', 'title': 'Question', 'color': 'blue'}], list(labeling.active_labels()))