def test_notice_collection_used_issues(session): collection = GazetteNoticeCollection(session) issues = IssueCollection(session) a = issues.add(name='2017-1', number=1, date=date(2017, 1, 2), deadline=standardize_date(datetime(2017, 1, 1, 12, 0), 'UTC')) b = issues.add(name='2017-2', number=2, date=date(2017, 2, 2), deadline=standardize_date(datetime(2017, 2, 1, 12, 0), 'UTC')) c = issues.add(name='2017-3', number=3, date=date(2017, 3, 2), deadline=standardize_date(datetime(2017, 3, 1, 12, 0), 'UTC')) for issues in (('3', '2'), ('1', ), ('1', '3')): collection.add(title='', text='', organization_id='', category_id='', issues=[f'2017-{issue}' for issue in issues], user=None) assert collection.used_issues == [a, b, c]
def test_notice_collection_count_by_organization(session): collection = GazetteNoticeCollection(session) assert collection.count_by_organization() == [] organizations = OrganizationCollection(session) organizations.add_root(name='1', title='A') organizations.add_root(name='2', title='B') organizations.add_root(name='3', title='C') for organization, count in (('1', 2), ('2', 4), ('3', 10)): for x in range(count): collection.add(title='', text='', organization_id=organization, category_id='', issues=['2017-{}'.format(y) for y in range(x)], user=None) assert collection.count_by_organization() == [ ('A', 1), ('B', 6), ('C', 45), ] assert collection.count_by_organization() == \ collection.for_state('drafted').count_by_organization() collection.issues = ['2017-1', '2017-4'] assert collection.count_by_organization() == [('B', 2), ('C', 13)]
def test_notice_collection_own_user_id(session): users = UserCollection(session) user_a = users.add(username='******', password='******', role='admin') user_b = users.add(username='******', password='******', role='admin') user_c = users.add(username='******', password='******', role='admin') collection = GazetteNoticeCollection(session) for title, user, annotators in ( ('A', user_a, []), ('B', user_b, [user_a]), ('C', user_c, [user_a, user_b]), ): notice = collection.add(title=title, text='Text', organization_id='100', category_id='11', issues=['2017-46'], user=user) for annotator in annotators: notice.changes.append( GazetteNoticeChange( channel_id=str(notice.id), owner=str(annotator.id), )) assert collection.query().count() == 3 collection.own_user_id = str(user_a.id) assert collection.query().count() == 3 collection.own_user_id = str(user_b.id) assert collection.query().count() == 2 collection.own_user_id = str(user_c.id) assert collection.query().count() == 1
def test_notices_pdf_from_notices(gazette_app): session = gazette_app.session() with freeze_time("2017-01-01 12:00"): notice = GazetteNotice(title='first title', text='first text', author_place='first place', author_date=utcnow(), author_name='first author', state='submitted') notice.files.append(pdf_attachment('first attachment')) session.add(notice) session.flush() with freeze_time("2017-01-02 12:00"): notice = GazetteNotice(title='second title', text='second text', author_place='second place', author_date=utcnow(), author_name='second author', state='submitted') session.add(notice) session.flush() with freeze_time("2018-01-01 12:00"): request = DummyRequest(session, gazette_app.principal) notices = GazetteNoticeCollection(session) file = NoticesPdf.from_notices(notices, request) reader = PdfFileReader(file) assert [page.extractText() for page in reader.pages ] == [('© 2018 Govikon\n1\n' 'xxx\nfirst title\nfirst text\n' 'first place, 1. Januar 2017\nfirst author\n'), '© 2018 Govikon\n2\n', ('© 2018 Govikon\n3\n' 'xxx\nsecond title\nsecond text\n' 'second place, 2. Januar 2017\nsecond author\n')] file = NoticesPdf.from_notices(notices.for_order('title', 'desc'), request) reader = PdfFileReader(file) assert [page.extractText() for page in reader.pages ] == [('© 2018 Govikon\n1\n' 'xxx\nsecond title\nsecond text\n' 'second place, 2. Januar 2017\nsecond author\n' 'xxx\nfirst title\nfirst text\n' 'first place, 1. Januar 2017\nfirst author\n'), '© 2018 Govikon\n2\n']
def menu(self): result = [] if self.request.is_private(self.model): # Publisher and Admin result.append((_("Official Notices"), self.manage_notices_link, (isinstance(self.model, GazetteNoticeCollection) and 'statistics' not in self.request.url), [])) active = (isinstance(self.model, IssueCollection) or isinstance(self.model, OrganizationCollection) or isinstance(self.model, CategoryCollection) or isinstance(self.model, UserCollection) or isinstance(self.model, UserGroupCollection)) manage = [(_("Issues"), self.manage_issues_link, isinstance(self.model, IssueCollection), []), (_("Organizations"), self.manage_organizations_link, isinstance(self.model, OrganizationCollection), []), (_("Categories"), self.manage_categories_link, isinstance(self.model, CategoryCollection), []), (_("Groups"), self.manage_groups_link, isinstance(self.model, UserGroupCollection), []), (_("Users"), self.manage_users_link, isinstance(self.model, UserCollection), [])] result.append((_("Manage"), None, active, manage)) result.append( (_("Statistics"), self.request.link(GazetteNoticeCollection(self.session, state='accepted'), name='statistics'), (isinstance(self.model, GazetteNoticeCollection) and 'statistics' in self.request.url), [])) elif self.request.is_personal(self.model): # Editor result.append((_("Dashboard"), self.dashboard_link, isinstance(self.model, Principal), [])) result.append( (_("Published Official Notices"), self.request.link( GazetteNoticeCollection(self.session, state='published' if self.publishing else 'accepted')), isinstance(self.model, GazetteNoticeCollection), [])) return result
def get_notices(app, state, page=0, term=None, order=None, direction=None, from_date=None, to_date=None, categories=None, organizations=None, source=None, own=None): categories = [c for c in categories if c] if categories else None organizations = [c for c in organizations if c] if organizations else None return GazetteNoticeCollection(app.session(), state=state, page=page, term=term, order=order, direction=direction, from_date=from_date, to_date=to_date, categories=categories, organizations=organizations, source=source, own=own)
def test_notice_collection_used_categories(session): collection = GazetteNoticeCollection(session) categories = CategoryCollection(session) a = categories.add_root(name='1', title='A') b = categories.add_root(name='2', title='B') c = categories.add_root(name='3', title='C') for category, count in (('1', 2), ('2', 4), ('3', 1)): for x in range(count): collection.add(title='', text='', organization_id=None, category_id=category, issues=['2017-{}'.format(y) for y in range(x)], user=None) assert collection.used_categories == [a, b, c]
def test_category_form(session): request = DummyRequest(session) # Test apply / update # ... unused categories = CategoryCollection(session) category = categories.add_root(name='1', title='ABC', active=True) form = CategoryForm() form.request = request form.apply_model(category) assert form.title.data == 'ABC' assert form.active.data is True assert form.name.data == '1' form.title.data = 'DEF' form.active.data = False form.name.data = '3' form.update_model(category) assert category.title == 'DEF' assert category.active is False assert category.name == '3' # ... used category = categories.add_root(name='2', title='XYZ', active=True) GazetteNoticeCollection(session).add('title', 'text', '', '2', None, []) form.apply_model(category) assert form.name.render_kw == {'readonly': True} # Test validation # ... empty values form = CategoryForm() form.request = request assert not form.validate() # ... new model form = CategoryForm(DummyPostData({'title': 'title', 'name': '2'})) form.request = request assert not form.validate() assert 'This value already exists.' in form.errors['name'] form = CategoryForm(DummyPostData({'title': 'title', 'name': '5'})) form.request = request assert form.validate() # ... existing model form = CategoryForm(DummyPostData({'title': 'title', 'name': '3'})) form.model = categories.query().filter_by(name='2').one() form.request = request assert not form.validate() assert 'This value already exists.' in form.errors['name'] assert 'This value is in use.' in form.errors['name'] form = CategoryForm(DummyPostData({'title': 'title', 'name': '5'})) form.model = categories.query().filter_by(name='3').one() form.request = request assert form.validate()
def test_notice_collection_count_by_group(session): collection = GazetteNoticeCollection(session) assert collection.count_by_group() == [] groups = UserGroupCollection(session) group_a = groups.add(name='A') group_b = groups.add(name='B') groups.add(name='C') users = UserCollection(session) user_a = users.add('*****@*****.**', 'pw', 'editor', group=group_a) user_b = users.add('*****@*****.**', 'pw', 'editor', group=group_a) user_c = users.add('*****@*****.**', 'pw', 'admin') user_d = users.add('*****@*****.**', 'pw', 'publisher') user_e = users.add('*****@*****.**', 'pw', 'publisher', group=group_b) user_f = users.add('*****@*****.**', 'pw', 'publisher') user_g = users.add('*****@*****.**', 'pw', 'publisher') user_h = users.add('*****@*****.**', 'pw', 'publisher') for user, count in ( (user_a, 2), (user_b, 4), (user_c, 1), (user_d, 7), (user_e, 2), (user_f, 3), (user_g, 6), (user_h, 2), ): for x in range(count): collection.add(title='', text='', organization_id='', category_id='', issues=['2017-{}'.format(y) for y in range(x)], user=user) assert collection.count_by_group() == [('A', 7), ('B', 1)] assert collection.count_by_group() == \ collection.for_state('drafted').count_by_group() collection.issues = ['2017-2', '2017-4'] assert collection.count_by_group() == [('A', 1)]
def test_notice_collection_count_by_category(session): collection = GazetteNoticeCollection(session) assert collection.count_by_category() == [] categories = CategoryCollection(session) categories.add_root(name='1', title='A') categories.add_root(name='2', title='B') categories.add_root(name='3', title='C') for category, count in (('1', 2), ('2', 4), ('3', 1)): for x in range(count): collection.add(title='', text='', organization_id=None, category_id=category, issues=['2017-{}'.format(y) for y in range(x)], user=None) assert collection.count_by_category() == [('A', 1), ('B', 6)] assert collection.count_by_category() == \ collection.for_state('drafted').count_by_category() collection.issues = ['2017-0', '2017-2'] assert collection.count_by_category() == [('A', 1), ('B', 4)]
def test_notice_collection_issues(session, issues): collection = GazetteNoticeCollection(session) assert collection.from_date is None assert collection.to_date is None assert collection.issues is None assert collection.issues is None for start, end, length in ( (date(2015, 1, 1), date(2020, 1, 1), 14), (None, date(2020, 1, 1), 14), (date(2015, 1, 1), None, 14), (date(2017, 10, 14), date(2017, 11, 18), 5), (None, date(2017, 11, 18), 7), (date(2017, 10, 14), None, 12), (date(2017, 10, 20), date(2017, 10, 20), 1), (date(2017, 10, 21), date(2017, 10, 21), 0), (date(2017, 10, 1), date(2017, 9, 1), 0), ): collection = collection.for_dates(start, end) assert len(collection.issues) == length collection = collection.for_dates(date(2017, 12, 1), date(2017, 12, 10)) assert sorted(collection.issues) == ['2017-48', '2017-49']
def test_notice_collection(session, organizations, categories, issues): user = UserCollection(session).add(username='******', password='******', role='admin') collection = GazetteNoticeCollection(session) collection.add(title='Notice A', text='An <strong>important</strong> Notice!', organization_id='100', category_id='11', issues=['2017-46', '2017-47'], user=user) collection.add(title='Notice B', text='Another Notice', organization_id='200', category_id='13', issues={'2017-47', '2017-48'}, user=user) notice = collection.for_term('Notice A').query().one() assert notice.title == 'Notice A' assert notice.text == 'An <strong>important</strong> Notice!' assert notice.organization_id == '100' assert notice.organization == 'State Chancellery' assert notice.category_id == '11' assert notice.category == 'Education' assert notice.issues == {'2017-46': None, '2017-47': None} assert notice.first_issue == standardize_date(datetime(2017, 11, 17), 'UTC') assert notice.user == user assert notice.changes.one().event == 'created' assert notice.changes.one().user == user notice = collection.for_term('Notice B').query().one() assert notice.title == 'Notice B' assert notice.text == 'Another Notice' assert notice.organization_id == '200' assert notice.organization == 'Civic Community' assert notice.category_id == '13' assert notice.category == 'Commercial Register' assert notice.issues == {'2017-47': None, '2017-48': None} assert notice.first_issue == standardize_date(datetime(2017, 11, 24), 'UTC') assert notice.user == user assert notice.changes.one().event == 'created' assert notice.changes.one().user == user
def test_index_pdf_from_notices(gazette_app): session = gazette_app.session() with freeze_time("2017-01-01 12:00"): notice = GazetteNotice(title='first title', text='first text', organization_id='100', category_id='10', _issues={ '2017-40': '1', '2017-41': '3', }, state='accepted') session.add(notice) session.flush() with freeze_time("2017-01-02 12:00"): notice = GazetteNotice(title='second title', text='second text', organization_id='200', category_id='11', _issues={ '2017-40': '2', '2017-42': '4', }, state='published') session.add(notice) session.flush() with freeze_time("2018-01-01 12:00"): request = DummyRequest(session, gazette_app.principal) notices = GazetteNoticeCollection(session) file = IndexPdf.from_notices(notices, request) reader = PdfFileReader(file) assert [page.extractText() for page in reader.pages ] == [('© 2018 Govikon\n1\nGazette\nIndex\n' 'Organizations\n' 'C\n' 'Civic Community 2017-40-2, 2017-42-4\n' 'S\n' 'State Chancellery 2017-40-1, 2017-41-3\n'), ('Gazette\n© 2018 Govikon\n2\n' 'Categories\n' 'C\n' 'Complaints 2017-40-1, 2017-41-3\n' 'E\n' 'Education 2017-40-2, 2017-42-4\n')]
def view_dashboard(self, request): """ The dashboard view (for editors). Shows the drafted, submitted and rejected notices, shows warnings and allows to create a new notice. """ layout = Layout(self, request) user_ids, group_ids = get_user_and_group(request) collection = GazetteNoticeCollection(request.session, user_ids=user_ids, group_ids=group_ids) # rejected rejected = collection.for_state('rejected').query().all() if rejected: request.message(_("You have rejected messages."), 'warning') # drafted drafted = collection.for_state('drafted').query().all() now = utcnow() limit = now + timedelta(days=2) past_issues_selected = False deadline_reached_soon = False for notice in drafted: for issue in notice.issue_objects: if issue.deadline < now: past_issues_selected = True elif issue.deadline < limit: deadline_reached_soon = True if past_issues_selected: request.message(_("You have drafted messages with past issues."), 'warning') if deadline_reached_soon: request.message( _("You have drafted messages with issues close to the deadline."), 'warning') # submitted submitted = collection.for_state('submitted').query().all() new_notice = request.link(collection.for_state('drafted'), name='new-notice') return { 'layout': layout, 'title': _("Dashboard"), 'rejected': rejected, 'drafted': drafted, 'submitted': submitted, 'new_notice': new_notice, 'current_issue': layout.current_issue }
def test_notice_collection_for_categories(session): collection = GazetteNoticeCollection(session) categories = CategoryCollection(session) categories.add_root(name='1', title='A') categories.add_root(name='2', title='B') categories.add_root(name='3', title='C') for category, count in (('1', 2), ('2', 4), ('3', 1)): for x in range(count): collection.add(title='', text='', organization_id=None, category_id=category, issues=['2017-{}'.format(y) for y in range(x)], user=None) assert collection.for_categories(['1']).query().count() == 2 assert collection.for_categories(['2']).query().count() == 4 assert collection.for_categories(['3']).query().count() == 1 assert collection.for_categories(['1', '3']).query().count() == 3
def get_notice(app, name): return GazetteNoticeCollection(app.session()).by_name(name)
def test_organization_form(session): request = DummyRequest(session) # Test on request organizations = OrganizationCollection(session) parent = organizations.add_root(title='parent', active=True, order=1) child = organizations.add(parent=parent, title='child', active=True) other = organizations.add_root(title='other', active=True, order=2) other.external_name = 'xxx' form = OrganizationForm() form.request = request form.on_request() assert form.parent.choices == [('', '- none -'), ('1', 'parent'), ('3', 'other')] # Test apply / update # ... unused form.apply_model(parent) assert form.title.data == 'parent' assert form.active.data is True assert form.parent.data == '' assert form.name.data == '1' assert form.external_name.data is None form.apply_model(child) assert form.title.data == 'child' assert form.active.data is True assert form.parent.data == '1' assert form.name.data == '2' assert form.external_name.data is None form.apply_model(other) assert form.title.data == 'other' assert form.active.data is True assert form.parent.data == '' assert form.name.data == '3' assert form.external_name.data == 'xxx' form.title.data = 'DEF' form.active.data = False form.parent.data = '1' form.external_name.data = 'yyy' form.update_model(other) session.flush() session.expire(other) assert other.title == 'DEF' assert other.active is False assert other.parent == parent assert other.siblings.filter_by(id='3') assert other.name == '3' assert form.external_name.data == 'yyy' form.name.data = '4' form.update_model(other) assert other.name == '4' # ... used GazetteNoticeCollection(session).add('title', 'text', '4', '', None, []) form.apply_model(other) assert form.name.render_kw == {'readonly': True} # Test validation # ... empty values form = OrganizationForm() form.request = request assert not form.validate() # ... new model form = OrganizationForm( DummyPostData({ 'title': 'title', 'parent': '', 'name': '2' })) form.request = request assert not form.validate() assert 'This value already exists.' in form.errors['name'] form = OrganizationForm( DummyPostData({ 'title': 'title', 'parent': '', 'name': '5' })) form.request = request assert form.validate() # ... existing model form = OrganizationForm( DummyPostData({ 'title': 'title', 'parent': '', 'name': '2' })) form.model = organizations.query().filter_by(name='4').one() form.request = request assert not form.validate() assert 'This value already exists.' in form.errors['name'] assert 'This value is in use.' in form.errors['name'] form = OrganizationForm( DummyPostData({ 'title': 'title', 'parent': '', 'name': '5' })) form.model = organizations.query().filter_by(name='1').one() form.request = request assert form.validate()
def test_issue_form(session): request = DummyRequest(session, DummyPrincipal()) # Test apply / update # ... unused issues = IssueCollection(session) issue = issues.add(name='2018-1', number=1, date=date(2018, 1, 5), deadline=standardize_date(datetime(2018, 1, 4, 12, 0), 'UTC')) form = IssueForm() form.request = request form.on_request() form.apply_model(issue) assert form.number.data == 1 assert form.name.data == '2018-1' assert form.date_.data == date(2018, 1, 5) assert form.deadline.data == datetime(2018, 1, 4, 13, 0) form.number.data = 2 form.date_.data = date(2019, 1, 5) form.deadline.data = datetime(2019, 1, 4, 13, 0) form.update_model(issue) assert issue.number == 2 assert issue.name == '2019-2' assert issue.date == date(2019, 1, 5) assert issue.deadline == standardize_date(datetime(2019, 1, 4, 12, 0), 'UTC') # used issue = issues.add(name='2019-3', number=3, date=date(2019, 2, 5), deadline=standardize_date(datetime(2019, 2, 4, 12, 0), 'UTC')) notices = GazetteNoticeCollection(session) notices.add('title', 'text', '', '', None, ['2019-3']) form.apply_model(issue) assert form.number.render_kw == {'readonly': True} # Test validation # ... empty values form = IssueForm() form.request = request assert not form.validate() # ... new model form = IssueForm( DummyPostData({ 'number': '3', 'date_': '2019-03-05', 'deadline': '2019-03-04T12:00' })) form.request = request assert not form.validate() assert 'This value already exists.' in form.errors['name'] form = IssueForm( DummyPostData({ 'number': '5', 'date_': '2019-03-05', 'deadline': '2019-03-04T12:00' })) form.request = request assert form.validate() form = IssueForm( DummyPostData({ 'number': '3', 'date_': '2018-03-05', 'deadline': '2019-03-04T12:00' })) form.request = request assert form.validate() # ... existing model form = IssueForm( DummyPostData({ 'number': '2', 'date_': '2019-03-05', 'deadline': '2019-03-04T12:00' })) form.model = issues.query().filter_by(number='3').one() form.request = request assert not form.validate() assert 'This value already exists.' in form.errors['name'] assert 'This value is in use.' in form.errors['name'] form = IssueForm( DummyPostData({ 'number': '5', 'date_': '2019-03-05', 'deadline': '2019-03-04T12:00' })) form.model = issues.query().filter_by(number='2').one() form.request = request assert form.validate() # Datetimepicker forma form = IssueForm( DummyPostData({ 'number': '1', 'date_': '2020-01-01', 'deadline': '2011-01-01 12:00' })) form.request = request assert form.validate()
def manage_notices_link(self): return self.request.link( GazetteNoticeCollection(self.session, state='submitted'))
def view_notice(self, request): """ View a notice. View the notice and its meta data. This is the main view for the notices to do the state changes. """ layout = Layout(self, request) user_ids, group_ids = get_user_and_group(request) editor = request.is_personal(self) publisher = request.is_private(self) admin = request.is_secret(self) owner = self.user_id in user_ids same_group = self.group_id in group_ids def _action(label, name, class_, target='_self'): return (label, request.link(self, name), class_, target) action = { 'accept': _action(_("Accept"), 'accept', 'primary'), 'attachments': _action(_("Attachments"), 'attachments', 'secondary'), 'copy': (_("Copy"), request.link(GazetteNoticeCollection(request.session, state=self.state, source=self.id), name='new-notice'), 'secondary', '_self'), 'delete': _action(_("Delete"), 'delete', 'alert right'), 'edit_un': _action(_("Edit"), 'edit-unrestricted', 'secondary'), 'edit': _action(_("Edit"), 'edit', 'secondary'), 'preview': _action(_("Preview"), 'preview', 'secondary', '_blank'), 'reject': _action(_("Reject"), 'reject', 'alert right'), 'submit': _action(_("Submit"), 'submit', 'primary'), } actions = [] if self.state == 'drafted' or self.state == 'rejected': if publisher or (editor and (same_group or owner)): actions.append(action['submit']) actions.append(action['edit']) actions.append(action['delete']) if publisher: actions.append(action['attachments']) elif self.state == 'submitted': if publisher: actions.append(action['accept']) actions.append(action['edit']) actions.append(action['reject']) actions.append(action['attachments']) if admin: actions.append(action['delete']) elif self.state == 'accepted': actions.append(action['copy']) if publisher: actions.append(action['edit_un']) if admin: actions.append(action['attachments']) if publisher: actions.append(action['delete']) elif self.state == 'imported': if publisher: actions.append(action['accept']) actions.append(action['delete']) elif self.state == 'published': actions.append(action['copy']) if publisher: actions.append(action['edit_un']) if admin: actions.append(action['attachments']) actions.append(action['preview']) return { 'layout': layout, 'notice': self, 'actions': actions, 'publisher': publisher }
def test_notice_collection_on_request(session): collection = GazetteNoticeCollection(session) collection.on_request(DummyRequest(None)) assert collection.own_user_id is None collection.own = True collection.on_request(DummyRequest(None)) assert collection.own_user_id is None collection.on_request(DummyRequest(None, DummyIdentity(None))) assert collection.own_user_id is None collection.on_request(DummyRequest(None, DummyIdentity('[email protected]'))) assert collection.own_user_id is None users = UserCollection(session) user = users.add(username='******', password='******', role='admin') collection.on_request(DummyRequest(None, DummyIdentity('[email protected]'))) assert collection.own_user_id == str(user.id)
def delete_notice(self, request, form): """ Delete a notice. Editors may only delete their own drafted and rejected notices. Publishers may delete any drafted, rejected and accepted notices. Admins may delete any drafted, submitted, rejected and accepted notices. """ layout = Layout(self, request) is_secret = request.is_secret(self) is_private = request.is_private(self) if not is_private: user_ids, group_ids = get_user_and_group(request) if not ((self.group_id in group_ids) or (self.user_id in user_ids)): raise HTTPForbidden() if ((self.state == 'submitted' and not is_secret) or (self.state == 'accepted' and not is_private) or (self.state == 'published')): request.message( _("Only drafted or rejected official notices may be deleted."), 'alert') return { 'layout': layout, 'title': self.title, 'subtitle': _("Delete Official Notice"), 'show_form': False } if self.state == 'accepted': request.message(_("This official notice has already been accepted!"), 'warning') if form.submitted(request): collection = GazetteNoticeCollection(request.session) collection.delete(self) request.message(_("Official notice deleted."), 'success') return redirect(layout.dashboard_or_notices_link) return { 'message': _('Do you really want to delete "${item}"?', mapping={'item': self.title}), 'layout': layout, 'form': form, 'title': self.title, 'subtitle': _("Delete Official Notice"), 'button_text': _("Delete Official Notice"), 'button_class': 'alert', 'cancel': request.link(self) }
def test_notice_collection_query_deleted_user(session): groups = UserGroupCollection(session) group_a = groups.add(name="Group A") group_b = groups.add(name="Group B") users = UserCollection(session) user_a = users.add(realname="User A", username='******', password='******', role='admin', group=group_a) user_b = users.add(realname="User B", username='******', password='******', role='admin', group=group_b) notices = GazetteNoticeCollection(session) notice_a = notices.add(title='A', text='Text', organization_id='100', category_id='11', issues=['2017-46'], user=user_a) notice_b = notices.add(title='B', text='Text', organization_id='100', category_id='11', issues=['2017-46'], user=user_b) assert notices.query().count() == 2 assert notice_a.user is not None assert notice_b.user is not None assert notice_a.group is not None assert notice_b.group is not None assert notices.for_term("User A").query().one() == notice_a assert notices.for_term("User B").query().one() == notice_b assert notices.for_term("Group A").query().one() == notice_a assert notices.for_term("Group B").query().one() == notice_b users.delete(user_a.username) users.delete(user_b.username) groups.delete(group_a) groups.delete(group_b) commit() assert users.query().count() == 0 assert groups.query().count() == 0 notice_a = notices.query().filter(GazetteNotice.title == 'A').one() notice_b = notices.query().filter(GazetteNotice.title == 'B').one() assert notice_a.user is None assert notice_b.user is None assert notice_a.group is None assert notice_b.group is None assert notices.query().count() == 2 assert notices.for_term("User A").query().one() == notice_a assert notices.for_term("User B").query().one() == notice_b assert notices.for_term("Group A").query().one() == notice_a assert notices.for_term("Group B").query().one() == notice_b