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_overlaps(): overlaps = [[ datetime(2013, 1, 1, 12, 0), datetime(2013, 1, 1, 13, 0), datetime(2013, 1, 1, 12, 0), datetime(2013, 1, 1, 13, 0), ], [ datetime(2013, 1, 1, 11, 0), datetime(2013, 1, 1, 12, 0), datetime(2013, 1, 1, 12, 0), datetime(2013, 1, 1, 13, 0), ]] doesnt = [[ datetime(2013, 1, 1, 11, 0), datetime(2013, 1, 1, 11, 59, 59), datetime(2013, 1, 1, 12, 0), datetime(2013, 1, 1, 13, 0), ]] tz = 'Europe/Zurich' for dates in overlaps: assert sedate.overlaps(*dates) timezone_aware = [sedate.standardize_date(d, tz) for d in dates] assert sedate.overlaps(*timezone_aware) for dates in doesnt: assert not sedate.overlaps(*dates) timezone_aware = [sedate.standardize_date(d, tz) for d in dates] assert not sedate.overlaps(*timezone_aware)
def _prepare_range(self, start, end): if start: start = sedate.standardize_date(start, self.timezone) if end: end = sedate.standardize_date(end, self.timezone) return start, end
def test_align_date_to_day_summertime(): unaligned = sedate.standardize_date(datetime(2016, 3, 27, 1), 'Europe/Zurich') aligned = sedate.align_date_to_day(unaligned, 'Europe/Zurich', 'down') assert aligned.isoformat() == '2016-03-26T23:00:00+00:00' unaligned = sedate.standardize_date(datetime(2016, 3, 27, 4), 'Europe/Zurich') aligned = sedate.align_date_to_day(unaligned, 'Europe/Zurich', 'down') assert aligned.isoformat() == '2016-03-26T23:00:00+00:00' unaligned = sedate.standardize_date(datetime(2016, 3, 27, 1), 'Europe/Zurich') aligned = sedate.align_date_to_day(unaligned, 'Europe/Zurich', 'up') assert aligned.isoformat() == '2016-03-27T21:59:59.999999+00:00' unaligned = sedate.standardize_date(datetime(2016, 3, 27, 4), 'Europe/Zurich') aligned = sedate.align_date_to_day(unaligned, 'Europe/Zurich', 'up') assert aligned.isoformat() == '2016-03-27T21:59:59.999999+00:00'
def test_align_date_to_day_wintertime(): unaligned = sedate.standardize_date(datetime(2016, 10, 30, 1), 'Europe/Zurich') aligned = sedate.align_date_to_day(unaligned, 'Europe/Zurich', 'down') assert aligned.isoformat() == '2016-10-29T22:00:00+00:00' unaligned = sedate.standardize_date(datetime(2016, 10, 30, 4), 'Europe/Zurich') aligned = sedate.align_date_to_day(unaligned, 'Europe/Zurich', 'down') assert aligned.isoformat() == '2016-10-29T22:00:00+00:00' unaligned = sedate.standardize_date(datetime(2016, 10, 30, 1), 'Europe/Zurich') aligned = sedate.align_date_to_day(unaligned, 'Europe/Zurich', 'up') assert aligned.isoformat() == '2016-10-30T22:59:59.999999+00:00' unaligned = sedate.standardize_date(datetime(2016, 10, 30, 4), 'Europe/Zurich') aligned = sedate.align_date_to_day(unaligned, 'Europe/Zurich', 'up') assert aligned.isoformat() == '2016-10-30T22:59:59.999999+00:00'
def test_notice_apply_meta(session, categories, organizations, issues): notice = GazetteNotice() notice.apply_meta(session) assert notice.organization is None assert notice.category is None assert notice.first_issue is None notice.organization_id = 'invalid' notice.category_id = 'invalid' notice.issues = [str(IssueName(2020, 1))] notice.apply_meta(session) assert notice.organization is None assert notice.category is None assert notice.first_issue is None notice.organization_id = '100' notice.category_id = '12' notice.issues = [str(IssueName(2017, 46))] notice.apply_meta(session) assert notice.organization == 'State Chancellery' assert notice.category == 'Submissions' assert notice.first_issue == standardize_date(datetime(2017, 11, 17), 'UTC') notice.issues = [str(IssueName(2017, 46)), str(IssueName(2017, 40))] notice.apply_meta(session) assert notice.first_issue == standardize_date(datetime(2017, 10, 6), 'UTC')
def test_issue_collection(session): collection = IssueCollection(session) issue_1 = collection.add(name='2017-1', number=1, date=date(2017, 1, 2), deadline=standardize_date( datetime(2017, 1, 1, 12, 0), 'UTC')) issue_3 = collection.add(name='2017-3', number=3, date=date(2017, 3, 2), deadline=standardize_date( datetime(2017, 3, 1, 12, 0), 'UTC')) issue_2 = collection.add(name='2017-2', number=2, date=date(2017, 2, 2), deadline=standardize_date( datetime(2017, 2, 1, 12, 0), 'UTC')) issue_4 = collection.add(name='2018-1', number=1, date=date(2018, 1, 1), deadline=standardize_date( datetime(2017, 12, 20, 12, 0), 'UTC')) # test query assert [issue.name for issue in collection.query() ] == ['2017-1', '2017-2', '2017-3', '2018-1'] # test current issue with freeze_time("2017-01-01 11:00"): assert collection.current_issue == issue_1 with freeze_time("2017-01-01 13:00"): assert collection.current_issue == issue_2 with freeze_time("2017-02-10 13:00"): assert collection.current_issue == issue_3 with freeze_time("2017-12-10 13:00"): assert collection.current_issue == issue_4 with freeze_time("2018-04-10 13:00"): assert collection.current_issue is None # test by name assert collection.by_name('2017-1') == issue_1 assert collection.by_name('2017-2') == issue_2 assert collection.by_name('2017-3') == issue_3 assert collection.by_name('2018-1') == issue_4 assert collection.by_name('2018-2') is None # test years assert collection.years == [2017, 2018] assert collection.by_years() == OrderedDict(( (2017, [issue_1, issue_2, issue_3]), (2018, [issue_4]), )) assert collection.by_years(desc=True) == OrderedDict(( (2018, [issue_4]), (2017, [issue_3, issue_2, issue_1]), ))
def test_is_whole_day_summertime(): start = sedate.standardize_date(datetime(2014, 10, 26, 0, 0, 0), 'Europe/Zurich') end = sedate.standardize_date(datetime(2014, 10, 26, 23, 59, 59), 'Europe/Zurich') assert sedate.is_whole_day(start, end, 'Europe/Zurich') assert not sedate.is_whole_day(start, end, 'Europe/Istanbul')
def test_is_whole_day_wintertime(): start = sedate.standardize_date(datetime(2015, 3, 29, 0, 0, 0), 'Europe/Zurich') end = sedate.standardize_date(datetime(2015, 3, 29, 23, 59, 59), 'Europe/Zurich') assert sedate.is_whole_day(start, end, 'Europe/Zurich') assert not sedate.is_whole_day(start, end, 'Europe/Istanbul')
def test_issue(gazette_app, session): issue = Issue( id=0, name='2018-7', number=7, date=date(2017, 7, 1), deadline=standardize_date(datetime(2017, 6, 25, 12, 0), 'UTC'), ) issue.pdf = 'PDF'.encode('utf-8') session.add(issue) session.flush() issue = session.query(Issue).one() assert issue.id == 0 assert issue.name == '2018-7' assert issue.number == 7 assert issue.date == date(2017, 7, 1) assert issue.deadline == standardize_date(datetime(2017, 6, 25, 12, 0), 'UTC') assert issue.pdf.id assert issue.pdf.name == '2018-7.pdf' assert issue.pdf.type == 'gazette_issue' assert issue.pdf.reference.file.read().decode('utf-8') == 'PDF' # Test query etc assert len(issue.notices().all()) == 0 assert issue.notices('accepted').all() == [] assert issue.notices('submitted').all() == [] assert issue.in_use is False issues = [issue.name] session.add(GazetteNotice(title='d', issues=issues)) session.add(GazetteNotice(title='a', state='accepted', issues=issues)) session.add(GazetteNotice(title='s', state='submitted', issues=issues)) session.add(GazetteNotice(title='s', issues=['2018-1'])) session.add(GazetteNotice(title='s', issues=['2018-1', issue.name])) session.flush() assert len(issue.notices().all()) == 4 assert issue.notices('accepted').all()[0].title == 'a' assert issue.notices('submitted').one().title == 's' assert issue.in_use is True # Test date observer issue.date = date(2018, 7, 2) session.flush() dates = [i.first_issue for i in session.query(GazetteNotice)] dates = [d.date() for d in dates if d] assert set(dates) == set([issue.date]) # Test publish issue.publish(DummyRequest(session)) assert len(issue.notices().all()) == 4 assert issue.notices('accepted').all() == [] assert issue.notices('published').count() == 1
def is_valid_reservation_length(start, end, timezone): start = sedate.standardize_date(start, timezone) end = sedate.standardize_date(end, timezone) hours = (end - start).total_seconds() // 3600 if hours < 24: return True if sedate.is_whole_day(start, end, timezone) and hours <= 25: return True return False
def test_align_date_to_day_up(): unaligned = sedate.standardize_date(datetime(2012, 1, 24, 10), 'UTC') aligned = sedate.align_date_to_day(unaligned, 'Europe/Zurich', 'up') assert aligned.tzname() == 'UTC' assert aligned == sedate.standardize_date( datetime(2012, 1, 24, 23, 59, 59, 999999), 'Europe/Zurich') already_aligned = sedate.replace_timezone( datetime(2012, 1, 1, 23, 59, 59, 999999), 'Europe/Zurich') assert already_aligned == sedate.align_date_to_day(already_aligned, 'Europe/Zurich', 'up')
def test_layout_format(session, principal): request = DummyRequest(session, principal) layout = Layout(None, request) # Date assert layout.principal.time_zone == 'Europe/Zurich' assert layout.format_date(date(2019, 1, 2), 'date') == '02.01.2019' assert layout.format_date(datetime(2019, 1, 2, 12), 'date') == '02.01.2019' assert layout.format_date(datetime(2019, 1, 2, 12), 'date_long') == \ '2. Januar 2019' assert layout.format_date(datetime(2019, 1, 2, 12), 'datetime') == \ '02.01.2019 12:00' assert layout.format_date( standardize_date(datetime(2019, 1, 2, 12, 0), 'UTC'), 'date') == '02.01.2019' assert layout.format_date( standardize_date(datetime(2019, 1, 2, 12, 0), 'UTC'), 'datetime') == '02.01.2019 13:00' # Issue with raises(AssertionError): layout.format_issue(None) with raises(AssertionError): layout.format_issue('') assert layout.format_issue(Issue()) == 'No. , ' assert layout.format_issue(Issue(number=1, date=date(2017, 1, 2))) == 'No. 1, 02.01.2017' assert layout.format_issue( Issue(number=1, date=date(2017, 1, 2)), date_format='date_with_weekday') == 'No. 1, Montag 02.01.2017' assert layout.format_issue(Issue(name='2017-1', number=1, date=date(2017, 1, 2)), notice=GazetteNotice()) == 'No. 1, 02.01.2017' assert layout.format_issue( Issue(name='2017-1', number=1, date=date(2017, 1, 2)), notice=GazetteNotice(issues=['2017-1'])) == 'No. 1, 02.01.2017' assert layout.format_issue( Issue(name='2017-1', number=1, date=date(2017, 1, 2)), notice=GazetteNotice( _issues={'2017-1': 10})) == 'No. 1, 02.01.2017 / 10' # Text assert layout.format_text(None) == '' assert layout.format_text('abc') == 'abc' assert layout.format_text('a\nb\r\nc') == 'a<br>b<br>c'
def apply_meta(self, session): """ Updates the category, organization and issue date from the meta values. """ self.organization = None query = session.query(Organization.title) query = query.filter(Organization.name == self.organization_id).first() if query: self.organization = query[0] self.category = None query = session.query(Category.title) query = query.filter(Category.name == self.category_id).first() if query: self.category = query[0] self.first_issue = None if self._issues: query = session.query(Issue.date) query = query.filter(Issue.name.in_(self._issues.keys())) query = query.order_by(Issue.date).first() if query: self.first_issue = standardize_date(as_datetime(query[0]), 'UTC')
def migrate_issues(context): principal = getattr(context.app, 'principal', None) if not principal: return False issues = getattr(principal, '_issues', None) if not issues: return False if not context.has_table('gazette_issues'): return False session = context.app.session_manager.session() count = session.execute("select count(*) from gazette_issues") if count.scalar() != 0: return False collection = IssueCollection(session) for year, values in issues.items(): for number, dates in values.items(): assert dates.issue_date.year == year collection.add(name='{}-{}'.format(year, number), number=number, date=dates.issue_date, deadline=standardize_date(dates.deadline, 'UTC'))
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_standardize_aware_date(): aware_date = sedate.replace_timezone(datetime(2014, 10, 1, 13, 30), 'Europe/Zurich') normalized = sedate.standardize_date(aware_date, 'Europe/Zurich') assert normalized.tzname() == 'UTC' assert normalized.replace(tzinfo=None) == datetime(2014, 10, 1, 11, 30)
def update_model(self, model): model.number = self.number.data model.date = self.date_.data model.deadline = self.deadline.data model.name = str(IssueName(model.date.year, model.number)) # Convert the deadline from the local timezone to UTC if model.deadline: model.deadline = standardize_date(model.deadline, self.timezone.data)
def parsed_dates(self): result = [] DateRange = namedtuple('DateRange', ['start', 'end']) for date in json.loads(self.dates.data or '{}').get('values', []): try: start = isodate.parse_datetime(date['start'].replace(' ', 'T')) end = isodate.parse_datetime(date['end'].replace(' ', 'T')) except isodate.isoerror.ISO8601Error: continue result.append(DateRange( start=standardize_date(start, self.timezone), end=standardize_date(end, self.timezone) )) return result
def events(self, request): session = request.session stmt = self.attendee_calendar records = session.execute( select(stmt.c).where( and_(stmt.c.attendee_id == self.attendee_id, stmt.c.state == 'accepted', stmt.c.confirmed == True))) datestamp = utcnow() for record in records: event = icalendar.Event() event.add('uid', record.uid) event.add('summary', record.title) if record.note: event.add('description', record.note) event.add('dtstart', standardize_date(record.start, 'UTC')) event.add('dtend', standardize_date(record.end, 'UTC')) event.add('dtstamp', datestamp) event.add( 'url', request.class_link(VacationActivity, {'name': record.name})) if record.meeting_point: event.add('location', record.meeting_point) if record.lat and record.lon: event.add('geo', (float(record.lat), float(record.lon))) if record.meeting_point and record.lat and record.lon: event.add("X-APPLE-STRUCTURED-LOCATION", f"geo:{record.lat},{record.lon}", parameters={ "VALUE": "URI", "X-ADDRESS": record.meeting_point, "X-APPLE-RADIUS": "50", "X-TITLE": record.meeting_point }) yield event
def _import_issues(request, app): if not app.principal: return request.locale = locale headers = { 'number': request.translate(_("Number")), 'date': request.translate(_("Date")), 'deadline': request.translate(_("Deadline")) } session = app.session() issues = IssueCollection(session) if clear: click.secho("Deleting issues", fg='yellow') for category in issues.query(): session.delete(category) csvfile = convert_xls_to_csv( file, sheet_name=request.translate(_("Issues")) ) csv = CSVFile(csvfile, expected_headers=headers.values()) lines = list(csv.lines) columns = { key: csv.as_valid_identifier(value) for key, value in headers.items() } count = 0 for line in lines: count += 1 number = int(getattr(line, columns['number'])) date_ = parser.parse(getattr(line, columns['date'])).date() deadline = standardize_date( parser.parse(getattr(line, columns['deadline'])), timezone or request.app.principal.time_zone ) name = str(IssueName(date_.year, number)) issues.add( name=name, number=number, date=date_, deadline=deadline ) click.secho(f"{count} categorie(s) imported", fg='green') if dry_run: transaction.abort() click.secho("Aborting transaction", fg='yellow')
def test_group_reservation_timespans(scheduler): dates = [ (datetime(2015, 2, 5, 15), datetime(2015, 2, 5, 16)), (datetime(2015, 2, 6, 15), datetime(2015, 2, 6, 16)) ] group = scheduler.allocate(dates=dates, grouped=True)[0].group token = scheduler.reserve('*****@*****.**', group=group) scheduler.commit() reservation = scheduler.reservations_by_token(token)[0] timespans = reservation.timespans() assert len(timespans) == 2 assert timespans[0].start == standardize_date(dates[0][0], 'Europe/Zurich') assert timespans[0].end == standardize_date(dates[0][1], 'Europe/Zurich')\ - timedelta(microseconds=1) assert timespans[1].start == standardize_date(dates[1][0], 'Europe/Zurich') assert timespans[1].end == standardize_date(dates[1][1], 'Europe/Zurich')\ - timedelta(microseconds=1)
def get_publication(self, identifier): """ Fetches a single publication and adds it as an official notice. """ session = self.session response = get(f'{self.endpoint}/publications/{identifier}/xml') response.raise_for_status() response.encoding = 'utf-8' root = etree.fromstring(response.text.encode('utf-8')) subrubric = root.find('meta/subRubric').text converter = self.converters[subrubric](root) name = get_unique_notice_name(converter.title, session, GazetteNotice) author_date = converter.publication_date or None if author_date: author_date = standardize_date(author_date, 'UTC') expiry_date = converter.expiration_date or None if expiry_date: expiry_date = standardize_date(expiry_date, 'UTC') notice = GazetteNotice(id=uuid4(), name=name, state='imported', source=converter.source, title=converter.title, text=converter.text, organization_id=self.organization, category_id=self.category, issues=converter.issues(session), author_date=author_date, expiry_date=expiry_date) notice.apply_meta(session) session.add(notice) session.flush() MessageCollection(session, type='gazette_notice').add( channel_id=str(notice.id), meta={'event': _("imported")})
def test_event_collection_remove_stale_events(session): timezone = 'UTC' events = EventCollection(session) events.add( title='Event', timezone=timezone, start=datetime(2010, 6, 1, 10), end=datetime(2010, 6, 1, 10) + timedelta(hours=1), ) assert events.query().count() == 1 max_stale = standardize_date(datetime.today() + timedelta(days=2), 'UTC') events.remove_stale_events(max_stale=max_stale) assert events.query().count() == 0
def occurrence_dates(self, limit=True, localize=False): """ Returns the start dates of all occurrences. Returns non-localized dates per default. Limits the occurrences per default to this and the next year. """ occurrences = [self.start] if self.recurrence: occurrences = rrule.rrulestr(self.recurrence, dtstart=self.start) occurrences = list(map(lambda x: standardize_date(x, self.timezone), occurrences)) if localize: occurrences = list(map(lambda x: to_timezone(x, self.timezone), occurrences)) if limit: max_year = datetime.today().year + 1 occurrences = list(filter(lambda x: x.year <= max_year, occurrences)) return occurrences
def date_observer(self, date_): """ Changes the issue date of the notices when updating the date of the issue. At this moment, the transaction is not yet commited: Querying the current issue returns the old date. """ issues = object_session(self).query(Issue.name, Issue.date) issues = dict(issues.order_by(Issue.date)) issues[self.name] = date_ issues = { key: standardize_date(as_datetime(value), 'UTC') for key, value in issues.items() } for notice in self.notices(): dates = [issues.get(issue, None) for issue in notice._issues] dates = [date for date in dates if date] notice.first_issue = min(dates)
def remove_stale_events(self, max_stale=None): """ Remove events which have never been submitted and are created more than five days ago. """ if max_stale is None: max_stale = datetime.utcnow() - timedelta(days=5) max_stale = standardize_date(max_stale, 'UTC') events = self.session.query(Event).filter( Event.state == 'initiated', and_( or_(Event.created < max_stale, Event.created.is_(None)), or_(Event.modified < max_stale, Event.modified.is_(None)) ) ) for event in events: self.session.delete(event) self.session.flush()
def query(self, start=None, end=None, tags=None, outdated=False): """ Queries occurrences with the given parameters. Finds all occurrences with any of the given tags and within the given start and end date. Start and end date are assumed to be dates only and therefore without a timezone - we search for the given date in the timezone of the occurrence!. If no start date is given and ``outdated`` is not set, only current occurrences are returned. """ query = self.session.query(Occurrence) if start is not None: assert type(start) is date start = as_datetime(start) expressions = [] for timezone in self.used_timezones: localized_start = replace_timezone(start, timezone) localized_start = standardize_date(localized_start, timezone) expressions.append( and_( Occurrence.timezone == timezone, Occurrence.start >= localized_start ) ) query = query.filter(or_(*expressions)) elif not outdated: start = as_datetime(date.today()) expressions = [] for timezone in self.used_timezones: localized_start = replace_timezone(start, timezone) localized_start = standardize_date(localized_start, timezone) expressions.append( and_( Occurrence.timezone == timezone, Occurrence.start >= localized_start ) ) query = query.filter(or_(*expressions)) if end is not None: assert type(end) is date end = as_datetime(end) end = end + timedelta(days=1) expressions = [] for timezone in self.used_timezones: localized_end = replace_timezone(end, timezone) localized_end = standardize_date(localized_end, timezone) expressions.append( and_( Occurrence.timezone == timezone, Occurrence.end < localized_end ) ) query = query.filter(or_(*expressions)) if tags: query = query.filter(Occurrence._tags.has_any(array(tags))) query = query.order_by(Occurrence.start, Occurrence.title) return query
def create_issues(session): issues = IssueCollection(session) issues.add(name='2017-40', number=40, date=date(2017, 10, 6), deadline=standardize_date(datetime(2017, 10, 4, 12, 0), 'UTC')) issues.add(name='2017-41', number=41, date=date(2017, 10, 13), deadline=standardize_date(datetime(2017, 10, 11, 12, 0), 'UTC')) issues.add(name='2017-42', number=42, date=date(2017, 10, 20), deadline=standardize_date(datetime(2017, 10, 18, 12, 0), 'UTC')) issues.add(name='2017-43', number=43, date=date(2017, 10, 27), deadline=standardize_date(datetime(2017, 10, 25, 12, 0), 'UTC')) issues.add(name='2017-44', number=44, date=date(2017, 11, 3), deadline=standardize_date(datetime(2017, 11, 1, 12, 0), 'UTC')) issues.add(name='2017-45', number=45, date=date(2017, 11, 10), deadline=standardize_date(datetime(2017, 11, 8, 12, 0), 'UTC')) issues.add(name='2017-46', number=46, date=date(2017, 11, 17), deadline=standardize_date(datetime(2017, 11, 15, 12, 0), 'UTC')) issues.add(name='2017-47', number=47, date=date(2017, 11, 24), deadline=standardize_date(datetime(2017, 11, 22, 12, 0), 'UTC')) issues.add(name='2017-48', number=48, date=date(2017, 12, 1), deadline=standardize_date(datetime(2017, 11, 29, 12, 0), 'UTC')) issues.add(name='2017-49', number=49, date=date(2017, 12, 8), deadline=standardize_date(datetime(2017, 12, 6, 12, 0), 'UTC')) issues.add(name='2017-50', number=50, date=date(2017, 12, 15), deadline=standardize_date(datetime(2017, 12, 13, 12, 0), 'UTC')) issues.add(name='2017-51', number=51, date=date(2017, 12, 22), deadline=standardize_date(datetime(2017, 12, 20, 12, 0), 'UTC')) issues.add(name='2017-52', number=52, date=date(2017, 12, 29), deadline=standardize_date(datetime(2017, 12, 27, 12, 0), 'UTC')) issues.add(name='2018-1', number=1, date=date(2018, 1, 5), deadline=standardize_date(datetime(2018, 1, 3, 12, 0), 'UTC')) return issues.query().all()
def author_date_utc(self): if self.author_date.data: return standardize_date(as_datetime(self.author_date.data), 'UTC') return None
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 test_notice_form(session, categories, organizations, issues): users = UserCollection(session) user = users.add( username='******', realname='User', role='editor', password='******', ) user.phone_number = '+41415554433' notice = GazetteNotice( title='Title', text='A <b>text</b>.', author_place='Govikon', author_name='State Chancellerist', author_date=standardize_date(datetime(2018, 1, 1), 'UTC'), ) notice.organization_id = '200' notice.category_id = '13' notice.issues = ['2017-43'] notice.user = user # Test apply / update form = NoticeForm() form.request = DummyRequest(session) form.apply_model(notice) assert form.title.data == 'Title' assert form.organization.data == '200' assert form.category.data == '13' assert form.print_only.data is False assert form.at_cost.data == 'no' assert form.billing_address.data == '' assert form.text.data == 'A <b>text</b>.' assert form.author_place.data == 'Govikon' assert form.author_name.data == 'State Chancellerist' assert form.author_date.data == standardize_date(datetime(2018, 1, 1), 'UTC') assert form.issues.data == ['2017-43'] assert form.phone_number.data == '+41415554433' form.title.data = 'Notice' form.organization.data = '300' form.category.data = '11' form.print_only.data = True form.at_cost.data = 'yes' form.billing_address.data = 'someone\nsomewhere' form.text.data = 'A <b>notice</b>.' form.author_place.data = 'Govtown' form.author_name.data = 'Bureau of Public Affairs' form.author_date.data = standardize_date(datetime(2019, 1, 1), 'UTC') form.issues.data = ['2017-44'] form.phone_number.data = '796662211' form.update_model(notice) assert notice.title == 'Notice' assert notice.organization == 'Municipality' assert notice.category == 'Education' assert notice.print_only is True assert notice.at_cost is True assert notice.billing_address == 'someone\nsomewhere' assert notice.text == 'A <b>notice</b>.' assert notice.author_place == 'Govtown' assert notice.author_name == 'Bureau of Public Affairs' assert notice.author_date == standardize_date(datetime(2019, 1, 1), 'UTC') assert notice.issues == {'2017-44': None} assert notice.first_issue == standardize_date(datetime(2017, 11, 3), 'UTC') assert user.phone_number == '+41796662211' # Test validation form = NoticeForm() form.request = DummyRequest(session) assert not form.validate() form = NoticeForm() form.request = DummyRequest(session) form.issues.choices = [('2017-5', '2017-5')] form.organization.choices = [('onegov', 'onegov')] form.category.choices = [('important', 'important')] form.process( DummyPostData({ 'title': 'Title', 'organization': 'onegov', 'category': 'important', 'issues': ['2017-5'], 'text': 'Text', 'author_place': 'Govtown', 'author_name': 'Bureau of Public Affairs', 'author_date': '2019-01-01' })) assert form.validate() # Test UTC conversion assert form.author_date.data == date(2019, 1, 1) assert form.author_date_utc == standardize_date(datetime(2019, 1, 1), 'UTC') assert NoticeForm().author_date_utc is None # Test on request with freeze_time("2017-11-01 14:00"): form = NoticeForm() form.model = None form.request = DummyRequest(session) form.on_request() assert form.organization.choices == [('', 'Select one'), ('100', 'State Chancellery'), ('200', 'Civic Community'), ('300', 'Municipality'), ('410', 'Evangelical Reformed Parish'), ('430', 'Catholic Parish'), ('500', 'Corporation')] assert form.issues.choices == [ ('2017-45', 'No. 45, Freitag 10.11.2017'), ('2017-46', 'No. 46, Freitag 17.11.2017'), ('2017-47', 'No. 47, Freitag 24.11.2017'), ('2017-48', 'No. 48, Freitag 01.12.2017'), ('2017-49', 'No. 49, Freitag 08.12.2017'), ('2017-50', 'No. 50, Freitag 15.12.2017'), ('2017-51', 'No. 51, Freitag 22.12.2017'), ('2017-52', 'No. 52, Freitag 29.12.2017'), ('2018-1', 'No. 1, Freitag 05.01.2018'), ] assert form.category.choices == [ ('13', 'Commercial Register'), ('11', 'Education'), ('14', 'Elections'), ('12', 'Submissions'), ] assert form.print_only is None form = NoticeForm() form.model = None form.request = DummyRequest(session, private=True) form.on_request() assert form.organization.choices == [('', 'Select one'), ('100', 'State Chancellery'), ('200', 'Civic Community'), ('300', 'Municipality'), ('410', 'Evangelical Reformed Parish'), ('430', 'Catholic Parish'), ('500', 'Corporation')] assert form.issues.choices == [ ('2017-44', 'No. 44, Freitag 03.11.2017'), ('2017-45', 'No. 45, Freitag 10.11.2017'), ('2017-46', 'No. 46, Freitag 17.11.2017'), ('2017-47', 'No. 47, Freitag 24.11.2017'), ('2017-48', 'No. 48, Freitag 01.12.2017'), ('2017-49', 'No. 49, Freitag 08.12.2017'), ('2017-50', 'No. 50, Freitag 15.12.2017'), ('2017-51', 'No. 51, Freitag 22.12.2017'), ('2017-52', 'No. 52, Freitag 29.12.2017'), ('2018-1', 'No. 1, Freitag 05.01.2018'), ] assert form.category.choices == [ ('13', 'Commercial Register'), ('11', 'Education'), ('14', 'Elections'), ('12', 'Submissions'), ] assert form.issues.render_kw['data-hot-issue'] == '2017-44' assert form.print_only is not None
def test_unrestricted_notice_form(session, categories, organizations, issues): users = UserCollection(session) user = users.add( username='******', realname='User', role='editor', password='******', ) user.phone_number = '+41415554433' notice = GazetteNotice(title='Title', text='A <b>text</b>.') notice.organization_id = '200' notice.category_id = '13' notice.note = 'note' notice.issues = ['2017-43'] notice.user = user # Test apply / update form = UnrestrictedNoticeForm() form.request = DummyRequest(session) form.apply_model(notice) assert form.title.data == 'Title' assert form.organization.data == '200' assert form.category.data == '13' assert form.text.data == 'A <b>text</b>.' assert form.issues.data == ['2017-43'] assert form.phone_number.data == '+41415554433' assert form.note.data == 'note' form.title.data = 'Notice' form.organization.data = '300' form.category.data = '11' form.text.data = 'A <b>notice</b>.' form.issues.data = ['2017-44'] form.phone_number.data = '796662211' form.note.data = 'A note' form.update_model(notice) assert notice.title == 'Notice' assert notice.organization == 'Municipality' assert notice.category == 'Education' assert notice.text == 'A <b>notice</b>.' assert notice.issues == {'2017-44': None} assert notice.first_issue == standardize_date(datetime(2017, 11, 3), 'UTC') assert notice.note == 'A note' assert user.phone_number == '+41796662211' notice.state = 'published' form.issues.data = ['2017-45'] form.update_model(notice) assert notice.issues == {'2017-44': None} # Test on request with freeze_time("2019-11-01 14:00"): form = UnrestrictedNoticeForm() form.model = None form.request = DummyRequest(session) form.on_request() assert form.organization.choices == [('', 'Select one'), ('100', 'State Chancellery'), ('200', 'Civic Community'), ('300', 'Municipality'), ('410', 'Evangelical Reformed Parish'), ('420', '(Sikh Community)'), ('430', 'Catholic Parish'), ('500', 'Corporation')] assert form.issues.choices == [ ('2017-40', 'No. 40, Freitag 06.10.2017'), ('2017-41', 'No. 41, Freitag 13.10.2017'), ('2017-42', 'No. 42, Freitag 20.10.2017'), ('2017-43', 'No. 43, Freitag 27.10.2017'), ('2017-44', 'No. 44, Freitag 03.11.2017'), ('2017-45', 'No. 45, Freitag 10.11.2017'), ('2017-46', 'No. 46, Freitag 17.11.2017'), ('2017-47', 'No. 47, Freitag 24.11.2017'), ('2017-48', 'No. 48, Freitag 01.12.2017'), ('2017-49', 'No. 49, Freitag 08.12.2017'), ('2017-50', 'No. 50, Freitag 15.12.2017'), ('2017-51', 'No. 51, Freitag 22.12.2017'), ('2017-52', 'No. 52, Freitag 29.12.2017'), ('2018-1', 'No. 1, Freitag 05.01.2018') ] assert form.category.choices == [ ('13', 'Commercial Register'), ('10', '(Complaints)'), ('11', 'Education'), ('14', 'Elections'), ('12', 'Submissions'), ] # Test disable issues form = UnrestrictedNoticeForm() form.model = None form.request = DummyRequest(session) form.on_request() form.disable_issues() assert form.issues.validators == [] assert all([field.render_kw['disabled'] for field in form.issues])
def test_standardize_naive_date(): naive_date = datetime(2014, 10, 1, 13, 30) normalized = sedate.standardize_date(naive_date, 'Europe/Zurich') assert normalized.tzname() == 'UTC' assert normalized.replace(tzinfo=None) == datetime(2014, 10, 1, 11, 30)