diff --git a/.isort.cfg b/.isort.cfg
index eadf755729e482e809cef319028d5d601302a417..d782d6a4c0977e3da31323a2e490fefdbb435ab0 100644
--- a/.isort.cfg
+++ b/.isort.cfg
@@ -3,4 +3,4 @@
 line_length = 88
 multi_line_output = 3
 include_trailing_comma = true
-known_third_party = PyPDF2,arrow,bleach,bs4,captcha,celery,django,environ,faker,fastjsonschema,icalevnt,markdown,modelcluster,pirates,pytest,pytz,requests,sentry_sdk,snapshottest,taggit,wagtail,wagtailmetadata,weasyprint,yaml,zoneinfo
+known_third_party = PyPDF2,arrow,bleach,bs4,captcha,celery,django,environ,faker,fastjsonschema,icalevnt,markdown,modelcluster,pirates,pytest,pytz,requests,sentry_sdk,taggit,wagtail,wagtailmetadata,weasyprint,yaml,zoneinfo
diff --git a/calendar_utils/models.py b/calendar_utils/models.py
index d0717399d7fe8488c33bb9d2af879bac7951d466..4a072cda0aff77ae2f365ceaffb2246d30b62786 100644
--- a/calendar_utils/models.py
+++ b/calendar_utils/models.py
@@ -38,25 +38,27 @@ class Calendar(models.Model):
     past_events = EventsJSONField(encoder=DjangoJSONEncoder, null=True)
     future_events = EventsJSONField(encoder=DjangoJSONEncoder, null=True)
 
-    def update_source(self):
-        event_list = icalevents.events(
-            url=self.url,
-            start=date.today() - timedelta(days=30),
-            end=date.today() + timedelta(days=60),
-        )
+    def current_events(self):
+        return self.future_events[: self.CURRENT_NUM]
 
+    def handle_event_list(self, event_list):
         event_list_hash = str(hash(str(event_list)))
         if event_list_hash != self.event_hash:
             past, future = process_event_list(event_list)
             self.past_events = past
-            self.future_events = list(reversed(future))
+            self.future_events = future
             self.event_hash = event_list_hash
 
         self.last_update = arrow.utcnow().datetime
         self.save()
 
-    def current_events(self):
-        return self.future_events[: self.CURRENT_NUM]
+    def update_source(self):
+        event_list = icalevents.events(
+            url=self.url,
+            start=date.today() - timedelta(days=30),
+            end=date.today() + timedelta(days=60),
+        )
+        self.handle_event_list(event_list)
 
 
 class CalendarMixin(models.Model):
diff --git a/calendar_utils/parser.py b/calendar_utils/parser.py
index c87d3d35338f2b4143ba8f87bb9f872f67b29b91..e9220ffe14d38958c9d9ec3efdd825ecc68a9d29 100644
--- a/calendar_utils/parser.py
+++ b/calendar_utils/parser.py
@@ -9,7 +9,6 @@ from zoneinfo import ZoneInfo
 if TYPE_CHECKING:
     from icalevnt.icalparser import Event
 
-# FIXME "name" is "summary" and "begin" is "start" now
 EVENT_KEYS = ("start", "end", "all_day", "summary", "description", "location")
 
 
@@ -18,7 +17,7 @@ def split_event_dict_list(event_list: "list[dict]") -> tuple[list[dict], list[di
     singularity = arrow.utcnow().shift(hours=-2)
 
     past = [ev for ev in event_list if ev["end"] < singularity]
-    future = [ev for ev in event_list if ev["end"] > singularity]
+    future = list(reversed([ev for ev in event_list if ev["end"] > singularity]))
 
     return past, future
 
diff --git a/tests/calendar_utils/conftest.py b/tests/calendar_utils/conftest.py
index 36da9cecb1f63e7d2e8e5ce4f7ba79e82adf8dc8..dff52c421e8ab87857ccc2ed143e5dc33a37ae76 100644
--- a/tests/calendar_utils/conftest.py
+++ b/tests/calendar_utils/conftest.py
@@ -1,14 +1,65 @@
+import json
+from datetime import datetime
 from pathlib import Path
 
 import pytest
 from django.db import connection
+from icalevnt.icalparser import Event
 
 from calendar_utils.models import CalendarMixin
 
 
 @pytest.fixture(scope="session")
-def sample():
-    return (Path(__file__).parent / "sample.ics").read_text()
+def sample_response():
+    event_dict_list = json.loads(
+        (Path(__file__).parent / "samples" / "response.json").read_text()
+    )
+    event_list = []
+
+    for event_dict in event_dict_list:
+        event = Event()
+        event.start = datetime.fromisoformat(event_dict["start"])
+        event.end = datetime.fromisoformat(event_dict["end"])
+        event.summary = event_dict["summary"]
+        event.all_day = event_dict["all_day"]
+        event.description = event_dict["description"]
+        event.location = event_dict["location"]
+        event_list.append(event)
+
+    return event_list
+
+
+@pytest.fixture(scope="session")
+def sample_events():
+    event_dict_list = json.loads(
+        (Path(__file__).parent / "samples" / "response.json").read_text()
+    )
+    for event_dict in event_dict_list:
+        event_dict["start"] = datetime.fromisoformat(event_dict["start"])
+        event_dict["end"] = datetime.fromisoformat(event_dict["end"])
+    return event_dict_list
+
+
+@pytest.fixture(scope="session")
+def sample_past_events():
+    event_dict_list = json.loads(
+        (Path(__file__).parent / "samples" / "past_events.json").read_text()
+    )
+    for event_dict in event_dict_list:
+        event_dict["start"] = datetime.fromisoformat(event_dict["start"])
+        event_dict["end"] = datetime.fromisoformat(event_dict["end"])
+    return event_dict_list
+
+
+@pytest.fixture(scope="session")
+def sample_future_events():
+    event_dict_list = json.loads(
+        (Path(__file__).parent / "samples" / "future_events.json").read_text()
+    )
+    for event_dict in event_dict_list:
+        event_dict["start"] = datetime.fromisoformat(event_dict["start"])
+        event_dict["end"] = datetime.fromisoformat(event_dict["end"])
+    return event_dict_list
 
 
 class DummyModel(CalendarMixin):
diff --git a/tests/calendar_utils/sample.ics b/tests/calendar_utils/sample.ics
deleted file mode 100644
index bca5df66a3e13e2aaa5ccfcf4ad8ce12903f00df..0000000000000000000000000000000000000000
--- a/tests/calendar_utils/sample.ics
+++ /dev/null
@@ -1,230 +0,0 @@
-BEGIN:VCALENDAR
-PRODID:-//Google Inc//Google Calendar 70.9054//EN
-VERSION:2.0
-CALSCALE:GREGORIAN
-METHOD:PUBLISH
-X-WR-CALNAME:Piráti XOLK
-X-WR-TIMEZONE:Europe/Prague
-X-WR-CALDESC:Kalendář Pirátů olomouckého krajského sdružení.\nVíce zde: htt
- ps://olomoucky.pirati.cz\nnebo na našem facebooku: https://www.facebook.com
- /piratiOlomoucko/
-BEGIN:VTIMEZONE
-TZID:Europe/Prague
-X-LIC-LOCATION:Europe/Prague
-BEGIN:DAYLIGHT
-TZOFFSETFROM:+0100
-TZOFFSETTO:+0200
-TZNAME:CEST
-DTSTART:19700329T020000
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:+0200
-TZOFFSETTO:+0100
-TZNAME:CET
-DTSTART:19701025T030000
-RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTART;TZID=Europe/Prague:20200107T180000
-DTEND;TZID=Europe/Prague:20200107T210000
-RRULE:FREQ=MONTHLY;BYDAY=1TU
-DTSTAMP:20200519T130457Z
-UID:nmrttnjrbd0bjsmj4oabog7g46@google.com
-CREATED:20180926T191919Z
-DESCRIPTION:
-LAST-MODIFIED:20200505T161640Z
-LOCATION:PiCOlo\, 8. května 522/5\, 779 00 Olomouc\, Česko
-SEQUENCE:2
-STATUS:CONFIRMED
-SUMMARY:Veřejná schůze Pirátů Olomouckého kraje
-TRANSP:OPAQUE
-X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-APPLE-MAPKIT-HANDLE=CAESswEaEgkf60w
- rNMxIQBEtRW0jpz8xQCJaChHEjGVza8OhIHJlcHVibGlrYRICQ1oaCk9sb21vdWNrw70qB09sb2
- 1vdWMyB09sb21vdWM6Bjc3OSAwMFIKOC4ga3bEm3RuYVoBOGIMOC4ga3bEm3RuYSA4Kgw4LiBrd
- sSbdG5hIDgyDDguIGt2xJt0bmEgODIONzc5IDAwIE9sb21vdWMyEcSMZXNrw6EgcmVwdWJsaWth
- ODlAAQ==;X-APPLE-RADIUS=70.58737122558885;X-APPLE-REFERENCEFRAME=1;X-TITLE=
- "PiCOlo, 8. května 522/5, 779 00 Olomouc, Česko":geo:49.595342,17.248644
-X-APPLE-TRAVEL-ADVISORY-BEHAVIOR;ACKNOWLEDGED=20200505T161640Z:AUTOMATIC
-BEGIN:VALARM
-ACTION:NONE
-TRIGGER;VALUE=DATE-TIME:19760401T005545Z
-X-WR-ALARMUID:298355D7-4042-4B14-9109-5936F652F4AA
-UID:298355D7-4042-4B14-9109-5936F652F4AA
-ACKNOWLEDGED:20200505T161640Z
-X-APPLE-DEFAULT-ALARM:TRUE
-END:VALARM
-END:VEVENT
-BEGIN:VEVENT
-DTSTART:20200408T160000Z
-DTEND:20200408T173000Z
-DTSTAMP:20200519T130457Z
-UID:6e2plsoro6fu52ufhd7iq5fpd1@google.com
-CREATED:20200308T175153Z
-DESCRIPTION:
-LAST-MODIFIED:20200308T175206Z
-LOCATION:Picolo - Pirátské centrum Olomouc\, 8. května 522/5\, 779 00 Olomo
- uc\, Česko
-SEQUENCE:0
-STATUS:CONFIRMED
-SUMMARY:Setkání s místopředsedou Evropského parlamentu Marcelem Kolalokou
-TRANSP:OPAQUE
-BEGIN:VALARM
-ACTION:EMAIL
-TRIGGER;VALUE=DURATION:-PT1H
-SUMMARY:Default Mozilla Summary
-DESCRIPTION:Default Mozilla Description
-X-LIC-ERROR;X-LIC-ERRORTYPE=PARAMETER-VALUE-PARSE-ERROR:Got a VALUE paramet
- er with an illegal type for property: VALUE=DURATION
-END:VALARM
-BEGIN:VALARM
-ACTION:DISPLAY
-TRIGGER;VALUE=DURATION:-PT30M
-DESCRIPTION:Default Mozilla Description
-X-LIC-ERROR;X-LIC-ERRORTYPE=PARAMETER-VALUE-PARSE-ERROR:Got a VALUE paramet
- er with an illegal type for property: VALUE=DURATION
-END:VALARM
-END:VEVENT
-BEGIN:VEVENT
-DTSTART:20200301T140000Z
-DTEND:20200301T170000Z
-DTSTAMP:20200519T130457Z
-UID:2e3hpgkhl60mmne8012hghfnfp@google.com
-CREATED:20200226T180446Z
-DESCRIPTION:Tato událost má videohovor.\nPřipojit se: https://meet.google.c
- om/ahv-nrmw-kmp\n+1 484-696-1205 PIN: 546973991#
-LAST-MODIFIED:20200226T192157Z
-LOCATION:Koliba & Pivovar U Tří králů\, Finská 4592/8\, 796 01 Prostějov\,
- Česko
-SEQUENCE:0
-STATUS:CONFIRMED
-SUMMARY:Veřejná schůze Prostějovských Pirátů 01.03.2020
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-DTSTART:20200221T173000Z
-DTEND:20200221T210000Z
-DTSTAMP:20200519T130457Z
-UID:3o7vh5n89qlt79qorsfsbsmnjm@google.com
-CREATED:20200120T165424Z
-DESCRIPTION:Tradiční páteční deskohraní s Karlem Bezejmeným. K zapůjčení bud
- ou deskové hry všeho druhu – a to jak jednoduché\, tak náročnější pro ty\,
- kteří se nebojí u hry strávit delší dobu. Všechny pravidla Vám budou vysvět
- lena. Nemusíte se bát.
-LAST-MODIFIED:20200219T172956Z
-LOCATION:Picolo - Pirátské centrum Olomouc\, 8. května 522/5\, 779 00 Olomo
- uc\, Česko
-SEQUENCE:0
-STATUS:CONFIRMED
-SUMMARY:Páteční deskovky v Picolu - Karel Bezejmenný
-TRANSP:OPAQUE
-X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-APPLE-MAPKIT-HANDLE=CAES6wEI2TIaEgk
- czMsGPsxIQBF9BWnGoj8xQCJiChHEjGVza8OhIHJlcHVibGlrYRICQ1oaCk9sb21vdWNrw70qB0
- 9sb21vdWMyB09sb21vdWM6Bjc3OSAwMFIKOC4ga3bEm3RuYVoFNTIyLzViEDguIGt2xJt0bmEgN
- TIyLzUqEDguIGt2xJt0bmEgNTIyLzUyEDguIGt2xJt0bmEgNTIyLzUyDjc3OSAwMCBPbG9tb3Vj
- MhHEjGVza8OhIHJlcHVibGlrYTg5QABaIwohEhIJHMzLBj7MSEARfQVpxqI/MUAY2TIgh6v++tO
- opP88;X-APPLE-RADIUS=70.58737122607558;X-APPLE-REFERENCEFRAME=1;X-TITLE="Pi
- colo - Pirátské centrum Olomouc, 8. května 522/5, 779 00 Olomouc, Česko":ge
- o:49.595643,17.248577
-END:VEVENT
-BEGIN:VEVENT
-DTSTART:20200324T170000Z
-DTEND:20200324T183000Z
-DTSTAMP:20200519T130457Z
-UID:0lgp3r3r3s6a8fu0ubedd0lfov@google.com
-CREATED:20200210T181941Z
-DESCRIPTION:Přednáší MUDr. Marti Moron
-LAST-MODIFIED:20200210T181941Z
-LOCATION:
-SEQUENCE:0
-STATUS:CONFIRMED
-SUMMARY:Je kouření stejně škodlivé jako vapování?
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-DTSTART:20200217T173000Z
-DTEND:20200217T203000Z
-DTSTAMP:20200519T130457Z
-UID:ccr66c9p6kp6ab9k71j32b9k69im6b9p69hj8b9mchim2dpn6cp3idhl6o@google.com
-ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUE
- STS=0:mailto:0014epo7k8kbgpgq3gaudeodnc@group.calendar.google.com
-CREATED:20200118T124251Z
-DESCRIPTION:
-LAST-MODIFIED:20200203T194315Z
-LOCATION:Nebe počká\, 20\, Kratochvílova 122\, Město\, 750 02 Přerov\, Česk
- o
-SEQUENCE:2
-STATUS:CONFIRMED
-SUMMARY:Schůzka Piráti Přerov
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-DTSTART:20200123T170000Z
-DTEND:20200123T200000Z
-DTSTAMP:20200519T130457Z
-UID:28at6d7pbb6u7un4c8dhk54n3m@google.com
-CREATED:20200120T201202Z
-DESCRIPTION:
-LAST-MODIFIED:20200120T201202Z
-LOCATION:The 27 Music Bar\, Školní 24\, 796 01 Prostějov\, Česko
-SEQUENCE:0
-STATUS:CONFIRMED
-SUMMARY:Veřejná schůze Prostějovských Pirátů
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20200111
-DTEND;VALUE=DATE:20200113
-DTSTAMP:20200519T130457Z
-UID:c9i3gohj70rj8b9k65j68b9k70q3ibb16sqm4b9m6thm8dj4cpijcdhj6s@google.com
-CREATED:20191117T100010Z
-DESCRIPTION:
-LAST-MODIFIED:20200110T192704Z
-LOCATION:
-SEQUENCE:1
-STATUS:TENTATIVE
-SUMMARY:CF Ostrava
-TRANSP:OPAQUE
-X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC
-BEGIN:VALARM
-ACTION:AUDIO
-TRIGGER:-PT15H
-X-WR-ALARMUID:F3784E51-6388-41CD-B559-202442F2AE8D
-UID:F3784E51-6388-41CD-B559-202442F2AE8D
-ATTACH;VALUE=URI:Basso
-X-APPLE-DEFAULT-ALARM:TRUE
-ACKNOWLEDGED:20200110T192657Z
-END:VALARM
-END:VEVENT
-BEGIN:VEVENT
-DTSTART;TZID=Europe/Prague:20200115T180000
-DTEND;TZID=Europe/Prague:20200115T210000
-RRULE:FREQ=MONTHLY;BYDAY=3WE
-DTSTAMP:20200519T130457Z
-UID:mt8j5rq9jsh2p1ped9belnb234@google.com
-CREATED:20190906T082036Z
-DESCRIPTION:
-LAST-MODIFIED:20200109T171048Z
-LOCATION:
-SEQUENCE:3
-STATUS:CONFIRMED
-SUMMARY:Veřejná schůze Pirátů MS Olomouc
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-DTSTART;TZID=Europe/Prague:20190410T180000
-DTEND;TZID=Europe/Prague:20190410T210000
-DTSTAMP:20200519T130457Z
-UID:kfj8altfbk38ils1cs1247kv6c@google.com
-RECURRENCE-ID;TZID=Europe/Prague:20190410T180000
-CREATED:20180926T191919Z
-DESCRIPTION:
-LAST-MODIFIED:20191213T161303Z
-LOCATION:Jeseník
-SEQUENCE:1
-STATUS:CONFIRMED
-SUMMARY:Veřejná schůze Pirátů XOLK v Jeseníku
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
diff --git a/tests/calendar_utils/samples/future_events.json b/tests/calendar_utils/samples/future_events.json
new file mode 100644
index 0000000000000000000000000000000000000000..e2197bdf909985065f75294f99e287c08522a613
--- /dev/null
+++ b/tests/calendar_utils/samples/future_events.json
@@ -0,0 +1,98 @@
+[
+  {
+    "start": "2022-05-16T16:00:00+02:00",
+    "end": "2022-05-16T17:30:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-05-19T17:00:00+02:00",
+    "end": "2022-05-19T19:00:00+02:00",
+    "all_day": false,
+    "summary": "Proch\u00e1zka s architekty - Vize s\u00eddli\u0161t\u011b \u010e\u00e1blice",
+    "description": "Kr\u00e1sn\u00e9 Kobylisy por\u00e1daji tak\u00e9 proch\u00e1zku po s\u00eddlisti D\u00e1blice, na niz architekti a urbanist\u00e9 predstav\u00ed moznou budouci podobu ieho neizaj\u00edmav\u00e8 sich mist. Akci zakonc\u00ed pr\u00e1telsk\u00e9 posezen\u00ed v pivovaru Cobolis. Bud'te u toho!",
+    "location": "Kulturn\u00ed d\u016fm L\u00e1dv\u00ed\nBure\u0161ova 2, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-23T16:00:00+02:00",
+    "end": "2022-05-23T17:30:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-05-24T18:00:00+02:00",
+    "end": "2022-05-24T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Beseda o budouc\u00ed podob\u011b s\u00eddli\u0161t\u011b \u010e\u00e1blice",
+    "description": "Spolek Kr\u00e1sn\u00e9 Kobylisy a M\u00a2 Praha 8 v\u00e1s prostrednictvim radn\u00edho Tom\u00e1Se Hrebika zvou na besedu v Kulturn\u00edm dom\u00e8 L\u00e1dvi.\nCek\u00e1 s\u00eddlist\u00e9 promysleny rozvoj, nebo prom\u00e9na v betonovou dZungli? Jak\u00e9 se tvori pl\u00e1ny na ochranu s\u00eddlist\u00e9 pred nez\u00e1douci\nvystavbou? Pozv\u00e1n\u00ed prijali odborn\u00edci a architekturu a urbanistiku, z\u00e1stupci M\u00e8stsk\u00e9 c\u00e1sti Praha 8 a Magistr\u00e1tu hlavn\u00edho m\u00e8sta Prahy.",
+    "location": "Kulturn\u00ed d\u016fm L\u00e1dv\u00ed\nBure\u0161ova 2, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-27T09:30:00+02:00",
+    "end": "2022-05-27T12:00:00+02:00",
+    "all_day": false,
+    "summary": "Anthropoid80 - Rekonstrukce atent\u00e1tu",
+    "description": "",
+    "location": "Pam\u00e1tn\u00edk Operace Anthropoid\nV Hole\u0161ovi\u010dk\u00e1ch, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-27T14:00:00+02:00",
+    "end": "2022-05-27T22:00:00+02:00",
+    "all_day": false,
+    "summary": "Anthropoid80",
+    "description": "",
+    "location": "Thomayerovy sady\nThomayerovy sady, 180 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-28T11:00:00+02:00",
+    "end": "2022-05-28T22:00:00+02:00",
+    "all_day": false,
+    "summary": "Anthropoid80",
+    "description": "",
+    "location": "Thomayerovy sady\nThomayerovy sady, 180 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-06-02T18:00:00+02:00",
+    "end": "2022-06-02T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Krajsk\u00e1 sch\u016fze pra\u017esk\u00fdch Pir\u00e1t\u016f",
+    "description": "Op\u011bt tu m\u00e1me prvn\u00ed \u010dtvrtek v m\u011bs\u00edci a s n\u00edm pravidelnou sch\u016fzi kraje Praha. Dozv\u00edte se zpr\u00e1vy se Sn\u011bmovny, z Magistr\u00e1tu, z m\u011bstsk\u00fdch \u010d\u00e1st\u00ed, p\u0159edstav\u00ed se z\u00e1jemci o \u010dlenstv\u00ed a z\u00e1jemci o spolupr\u00e1ci s n\u00e1mi v\u016fbec.&nbsp;<br><br>",
+    "location": "Pir\u00e1tsk\u00e9 centrum Praha - PiCe, Na Mor\u00e1ni 360/3, 120 00 Praha-Nov\u00e9 M\u011bsto, \u010cesko"
+  },
+  {
+    "start": "2022-06-06T17:00:00+02:00",
+    "end": "2022-06-06T19:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - KDP (Komise pro dopravu)",
+    "description": "kontaktn\u00ed osoba: Michal Nov\u00e1k (Michal.Novak@pirati.cz)<br><a href=\"https://www.praha8.cz/Komise-pro-dopravu-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-06-20T16:00:00+02:00",
+    "end": "2022-06-20T17:30:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-06-22T14:00:00+02:00",
+    "end": "2022-06-22T17:00:00+02:00",
+    "all_day": false,
+    "summary": "Zastupitelstvo M\u010c Praha 8",
+    "description": "https://www.praha8.cz/Harmonogram-a-program-zasedani-zastupitelstva.html",
+    "location": "U Meteoru 6\nPraha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-07-07T18:00:00+02:00",
+    "end": "2022-07-07T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Krajsk\u00e1 sch\u016fze pra\u017esk\u00fdch Pir\u00e1t\u016f",
+    "description": "Op\u011bt tu m\u00e1me prvn\u00ed \u010dtvrtek v m\u011bs\u00edci a s n\u00edm pravidelnou sch\u016fzi kraje Praha. Dozv\u00edte se zpr\u00e1vy se Sn\u011bmovny, z Magistr\u00e1tu, z m\u011bstsk\u00fdch \u010d\u00e1st\u00ed, p\u0159edstav\u00ed se z\u00e1jemci o \u010dlenstv\u00ed a z\u00e1jemci o spolupr\u00e1ci s n\u00e1mi v\u016fbec.&nbsp;<br><br>",
+    "location": "Pir\u00e1tsk\u00e9 centrum Praha - PiCe, Na Mor\u00e1ni 360/3, 120 00 Praha-Nov\u00e9 M\u011bsto, \u010cesko"
+  }
+]
diff --git a/tests/calendar_utils/samples/past_events.json b/tests/calendar_utils/samples/past_events.json
new file mode 100644
index 0000000000000000000000000000000000000000..9e5ca0ebaba17739c9ae0da841f48044764aeaf6
--- /dev/null
+++ b/tests/calendar_utils/samples/past_events.json
@@ -0,0 +1,122 @@
+[
+  {
+    "start": "2022-05-09T18:00:00+02:00",
+    "end": "2022-05-09T21:00:00+02:00",
+    "all_day": false,
+    "summary": "P8: Sch\u016fzka MS",
+    "description": "V\u00edce informac\u00ed na: \nhttps://forum.pirati.cz/viewtopic.php?p=807442#p807442",
+    "location": "Rezidence ROSA\nSt\u0159elni\u010dn\u00e1 1680/8, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-09T17:00:00+02:00",
+    "end": "2022-05-09T19:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - KDP (Komise pro dopravu)",
+    "description": "kontaktn\u00ed osoba: Michal Nov\u00e1k (Michal.Novak@pirati.cz)<br><a href=\"https://www.praha8.cz/Komise-pro-dopravu-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-05-09T00:00:00+02:00",
+    "end": "2022-05-12T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba 13.\u201320. pozice - MS Praha 8 (1. kolo)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-05-06T14:00:00+02:00",
+    "end": "2022-05-06T15:00:00+02:00",
+    "all_day": false,
+    "summary": "Pietn\u00ed akt",
+    "description": "https://www.facebook.com/csol.cz/posts/4955450444502712.",
+    "location": "Kobylisk\u00e1 st\u0159elnice\nBojasova 13, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-05T18:00:00+02:00",
+    "end": "2022-05-05T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Krajsk\u00e1 sch\u016fze pra\u017esk\u00fdch Pir\u00e1t\u016f",
+    "description": "Op\u011bt tu m\u00e1me prvn\u00ed \u010dtvrtek v m\u011bs\u00edci a s n\u00edm pravidelnou sch\u016fzi kraje Praha. Dozv\u00edte se zpr\u00e1vy se Sn\u011bmovny, z Magistr\u00e1tu, z m\u011bstsk\u00fdch \u010d\u00e1st\u00ed, p\u0159edstav\u00ed se z\u00e1jemci o \u010dlenstv\u00ed a z\u00e1jemci o spolupr\u00e1ci s n\u00e1mi v\u016fbec.&nbsp;<br><br>",
+    "location": "Pir\u00e1tsk\u00e9 centrum Praha - PiCe, Na Mor\u00e1ni 360/3, 120 00 Praha-Nov\u00e9 M\u011bsto, \u010cesko"
+  },
+  {
+    "start": "2022-05-04T16:00:00+02:00",
+    "end": "2022-05-04T18:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - KKV\u010c (Komise pro kulturu a voln\u00fd \u010das)",
+    "description": "Sch\u016fze b\u00fdvaj\u00ed: Libe\u0148sk\u00fd z\u00e1mek, m\u00edstnost \u010d. 2, v dob\u011b pandemie online<br><br>kontaktn\u00ed osoba: <a href=\"https://praha8.pirati.cz/lide/martin-stanek/\">Martin Stan\u011bk</a>\u00a0-\u00a0<a href=\"mailto:Martin.Stanek@pirati.cz\">Martin.Stanek@pirati.cz</a>\u00a0- 775058555<br><br><a href=\"https://www.praha8.cz/Komise-pro-kulturu-a-volny-cas-2018-2022.html\">Str\u00e1nka komise na webu m\u011bstsk\u00e9 \u010d\u00e1sti</a><br><br><a href=\"https://forum.pirati.cz/viewtopic.php?f=943&amp;t=46454\">Z\u00e1pisy a jmenn\u00e9 hlasov\u00e1n\u00ed na f\u00f3ru</a>",
+    "location": "Libe\u0148sk\u00fd z\u00e1mek, 180 00 Prague-Prague 8, Czechia"
+  },
+  {
+    "start": "2022-04-27T14:00:00+02:00",
+    "end": "2022-04-27T18:00:00+02:00",
+    "all_day": false,
+    "summary": "Zastupitelstvo M\u010c Praha 8",
+    "description": "https://www.praha8.cz/Harmonogram-a-program-zasedani-zastupitelstva.html",
+    "location": "U Meteoru 6\nPraha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-04-25T00:00:00+02:00",
+    "end": "2022-04-28T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba m\u00edstop\u0159edsed\u016f MS Praha 8 (1. kolo)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-04-21T00:00:00+02:00",
+    "end": "2022-04-24T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba 7.\u201312. pozice - MS Praha 8 (2. kolo)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-04-20T19:00:00+02:00",
+    "end": "2022-04-20T21:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - Sch\u016fze ZK",
+    "description": "kontaktn\u00ed osoba: Michal Nov\u00e1k michal.novak@pirati.cz (mailto:michal.novak@pirati.cz)",
+    "location": "JITSI"
+  },
+  {
+    "start": "2022-04-20T18:00:00+02:00",
+    "end": "2022-04-20T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Sch\u016fzka k volb\u00e1m (KS Praha)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-04-19T16:00:00+02:00",
+    "end": "2022-04-19T17:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-04-19T00:00:00+02:00",
+    "end": "2022-04-22T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba 7.\u201312. pozice - MS Praha 8 (1. kolo)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-04-18T16:00:00+02:00",
+    "end": "2022-04-18T17:30:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-04-18T00:00:00+02:00",
+    "end": "2022-04-21T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba p\u0159edsedy MS Praha 8 (1. kolo)",
+    "description": "",
+    "location": ""
+  }
+]
diff --git a/tests/calendar_utils/samples/response.json b/tests/calendar_utils/samples/response.json
new file mode 100644
index 0000000000000000000000000000000000000000..ec375e012c838a691366138aabd651f76540ef13
--- /dev/null
+++ b/tests/calendar_utils/samples/response.json
@@ -0,0 +1,218 @@
+[
+  {
+    "start": "2022-07-07T18:00:00+02:00",
+    "end": "2022-07-07T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Krajsk\u00e1 sch\u016fze pra\u017esk\u00fdch Pir\u00e1t\u016f",
+    "description": "Op\u011bt tu m\u00e1me prvn\u00ed \u010dtvrtek v m\u011bs\u00edci a s n\u00edm pravidelnou sch\u016fzi kraje Praha. Dozv\u00edte se zpr\u00e1vy se Sn\u011bmovny, z Magistr\u00e1tu, z m\u011bstsk\u00fdch \u010d\u00e1st\u00ed, p\u0159edstav\u00ed se z\u00e1jemci o \u010dlenstv\u00ed a z\u00e1jemci o spolupr\u00e1ci s n\u00e1mi v\u016fbec.&nbsp;<br><br>",
+    "location": "Pir\u00e1tsk\u00e9 centrum Praha - PiCe, Na Mor\u00e1ni 360/3, 120 00 Praha-Nov\u00e9 M\u011bsto, \u010cesko"
+  },
+  {
+    "start": "2022-06-22T14:00:00+02:00",
+    "end": "2022-06-22T17:00:00+02:00",
+    "all_day": false,
+    "summary": "Zastupitelstvo M\u010c Praha 8",
+    "description": "https://www.praha8.cz/Harmonogram-a-program-zasedani-zastupitelstva.html",
+    "location": "U Meteoru 6\nPraha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-06-20T16:00:00+02:00",
+    "end": "2022-06-20T17:30:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-06-06T17:00:00+02:00",
+    "end": "2022-06-06T19:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - KDP (Komise pro dopravu)",
+    "description": "kontaktn\u00ed osoba: Michal Nov\u00e1k (Michal.Novak@pirati.cz)<br><a href=\"https://www.praha8.cz/Komise-pro-dopravu-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-06-02T18:00:00+02:00",
+    "end": "2022-06-02T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Krajsk\u00e1 sch\u016fze pra\u017esk\u00fdch Pir\u00e1t\u016f",
+    "description": "Op\u011bt tu m\u00e1me prvn\u00ed \u010dtvrtek v m\u011bs\u00edci a s n\u00edm pravidelnou sch\u016fzi kraje Praha. Dozv\u00edte se zpr\u00e1vy se Sn\u011bmovny, z Magistr\u00e1tu, z m\u011bstsk\u00fdch \u010d\u00e1st\u00ed, p\u0159edstav\u00ed se z\u00e1jemci o \u010dlenstv\u00ed a z\u00e1jemci o spolupr\u00e1ci s n\u00e1mi v\u016fbec.&nbsp;<br><br>",
+    "location": "Pir\u00e1tsk\u00e9 centrum Praha - PiCe, Na Mor\u00e1ni 360/3, 120 00 Praha-Nov\u00e9 M\u011bsto, \u010cesko"
+  },
+  {
+    "start": "2022-05-28T11:00:00+02:00",
+    "end": "2022-05-28T22:00:00+02:00",
+    "all_day": false,
+    "summary": "Anthropoid80",
+    "description": "",
+    "location": "Thomayerovy sady\nThomayerovy sady, 180 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-27T14:00:00+02:00",
+    "end": "2022-05-27T22:00:00+02:00",
+    "all_day": false,
+    "summary": "Anthropoid80",
+    "description": "",
+    "location": "Thomayerovy sady\nThomayerovy sady, 180 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-27T09:30:00+02:00",
+    "end": "2022-05-27T12:00:00+02:00",
+    "all_day": false,
+    "summary": "Anthropoid80 - Rekonstrukce atent\u00e1tu",
+    "description": "",
+    "location": "Pam\u00e1tn\u00edk Operace Anthropoid\nV Hole\u0161ovi\u010dk\u00e1ch, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-24T18:00:00+02:00",
+    "end": "2022-05-24T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Beseda o budouc\u00ed podob\u011b s\u00eddli\u0161t\u011b \u010e\u00e1blice",
+    "description": "Spolek Kr\u00e1sn\u00e9 Kobylisy a M\u00a2 Praha 8 v\u00e1s prostrednictvim radn\u00edho Tom\u00e1Se Hrebika zvou na besedu v Kulturn\u00edm dom\u00e8 L\u00e1dvi.\nCek\u00e1 s\u00eddlist\u00e9 promysleny rozvoj, nebo prom\u00e9na v betonovou dZungli? Jak\u00e9 se tvori pl\u00e1ny na ochranu s\u00eddlist\u00e9 pred nez\u00e1douci\nvystavbou? Pozv\u00e1n\u00ed prijali odborn\u00edci a architekturu a urbanistiku, z\u00e1stupci M\u00e8stsk\u00e9 c\u00e1sti Praha 8 a Magistr\u00e1tu hlavn\u00edho m\u00e8sta Prahy.",
+    "location": "Kulturn\u00ed d\u016fm L\u00e1dv\u00ed\nBure\u0161ova 2, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-23T16:00:00+02:00",
+    "end": "2022-05-23T17:30:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-05-19T17:00:00+02:00",
+    "end": "2022-05-19T19:00:00+02:00",
+    "all_day": false,
+    "summary": "Proch\u00e1zka s architekty - Vize s\u00eddli\u0161t\u011b \u010e\u00e1blice",
+    "description": "Kr\u00e1sn\u00e9 Kobylisy por\u00e1daji tak\u00e9 proch\u00e1zku po s\u00eddlisti D\u00e1blice, na niz architekti a urbanist\u00e9 predstav\u00ed moznou budouci podobu ieho neizaj\u00edmav\u00e8 sich mist. Akci zakonc\u00ed pr\u00e1telsk\u00e9 posezen\u00ed v pivovaru Cobolis. Bud'te u toho!",
+    "location": "Kulturn\u00ed d\u016fm L\u00e1dv\u00ed\nBure\u0161ova 2, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-16T16:00:00+02:00",
+    "end": "2022-05-16T17:30:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-05-09T18:00:00+02:00",
+    "end": "2022-05-09T21:00:00+02:00",
+    "all_day": false,
+    "summary": "P8: Sch\u016fzka MS",
+    "description": "V\u00edce informac\u00ed na: \nhttps://forum.pirati.cz/viewtopic.php?p=807442#p807442",
+    "location": "Rezidence ROSA\nSt\u0159elni\u010dn\u00e1 1680/8, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-09T17:00:00+02:00",
+    "end": "2022-05-09T19:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - KDP (Komise pro dopravu)",
+    "description": "kontaktn\u00ed osoba: Michal Nov\u00e1k (Michal.Novak@pirati.cz)<br><a href=\"https://www.praha8.cz/Komise-pro-dopravu-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-05-09T00:00:00+02:00",
+    "end": "2022-05-12T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba 13.\u201320. pozice - MS Praha 8 (1. kolo)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-05-06T14:00:00+02:00",
+    "end": "2022-05-06T15:00:00+02:00",
+    "all_day": false,
+    "summary": "Pietn\u00ed akt",
+    "description": "https://www.facebook.com/csol.cz/posts/4955450444502712.",
+    "location": "Kobylisk\u00e1 st\u0159elnice\nBojasova 13, 182 00 Praha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-05-05T18:00:00+02:00",
+    "end": "2022-05-05T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Krajsk\u00e1 sch\u016fze pra\u017esk\u00fdch Pir\u00e1t\u016f",
+    "description": "Op\u011bt tu m\u00e1me prvn\u00ed \u010dtvrtek v m\u011bs\u00edci a s n\u00edm pravidelnou sch\u016fzi kraje Praha. Dozv\u00edte se zpr\u00e1vy se Sn\u011bmovny, z Magistr\u00e1tu, z m\u011bstsk\u00fdch \u010d\u00e1st\u00ed, p\u0159edstav\u00ed se z\u00e1jemci o \u010dlenstv\u00ed a z\u00e1jemci o spolupr\u00e1ci s n\u00e1mi v\u016fbec.&nbsp;<br><br>",
+    "location": "Pir\u00e1tsk\u00e9 centrum Praha - PiCe, Na Mor\u00e1ni 360/3, 120 00 Praha-Nov\u00e9 M\u011bsto, \u010cesko"
+  },
+  {
+    "start": "2022-05-04T16:00:00+02:00",
+    "end": "2022-05-04T18:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - KKV\u010c (Komise pro kulturu a voln\u00fd \u010das)",
+    "description": "Sch\u016fze b\u00fdvaj\u00ed: Libe\u0148sk\u00fd z\u00e1mek, m\u00edstnost \u010d. 2, v dob\u011b pandemie online<br><br>kontaktn\u00ed osoba: <a href=\"https://praha8.pirati.cz/lide/martin-stanek/\">Martin Stan\u011bk</a>\u00a0-\u00a0<a href=\"mailto:Martin.Stanek@pirati.cz\">Martin.Stanek@pirati.cz</a>\u00a0- 775058555<br><br><a href=\"https://www.praha8.cz/Komise-pro-kulturu-a-volny-cas-2018-2022.html\">Str\u00e1nka komise na webu m\u011bstsk\u00e9 \u010d\u00e1sti</a><br><br><a href=\"https://forum.pirati.cz/viewtopic.php?f=943&amp;t=46454\">Z\u00e1pisy a jmenn\u00e9 hlasov\u00e1n\u00ed na f\u00f3ru</a>",
+    "location": "Libe\u0148sk\u00fd z\u00e1mek, 180 00 Prague-Prague 8, Czechia"
+  },
+  {
+    "start": "2022-04-27T14:00:00+02:00",
+    "end": "2022-04-27T18:00:00+02:00",
+    "all_day": false,
+    "summary": "Zastupitelstvo M\u010c Praha 8",
+    "description": "https://www.praha8.cz/Harmonogram-a-program-zasedani-zastupitelstva.html",
+    "location": "U Meteoru 6\nPraha, \u010cesk\u00e1 republika"
+  },
+  {
+    "start": "2022-04-25T00:00:00+02:00",
+    "end": "2022-04-28T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba m\u00edstop\u0159edsed\u016f MS Praha 8 (1. kolo)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-04-21T00:00:00+02:00",
+    "end": "2022-04-24T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba 7.\u201312. pozice - MS Praha 8 (2. kolo)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-04-20T19:00:00+02:00",
+    "end": "2022-04-20T21:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - Sch\u016fze ZK",
+    "description": "kontaktn\u00ed osoba: Michal Nov\u00e1k michal.novak@pirati.cz (mailto:michal.novak@pirati.cz)",
+    "location": "JITSI"
+  },
+  {
+    "start": "2022-04-20T18:00:00+02:00",
+    "end": "2022-04-20T20:00:00+02:00",
+    "all_day": false,
+    "summary": "Sch\u016fzka k volb\u00e1m (KS Praha)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-04-19T16:00:00+02:00",
+    "end": "2022-04-19T17:00:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-04-19T00:00:00+02:00",
+    "end": "2022-04-22T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba 7.\u201312. pozice - MS Praha 8 (1. kolo)",
+    "description": "",
+    "location": ""
+  },
+  {
+    "start": "2022-04-18T16:00:00+02:00",
+    "end": "2022-04-18T17:30:00+02:00",
+    "all_day": false,
+    "summary": "P8 - RR (Redak\u010dn\u00ed rada \u010dasopisu Osmi\u010dka)",
+    "description": "kontaktn\u00ed osoba: Martin \u0160t\u011brba (<a href=\"mailto:martin.sterba@pirati.cz\">martin.sterba@pirati.cz</a>)<br><a href=\"https://www.praha8.cz/Komise-Redakcni-rada-casopisu-Osmicka-2018-2022.html\">web</a>",
+    "location": ""
+  },
+  {
+    "start": "2022-04-18T00:00:00+02:00",
+    "end": "2022-04-21T00:00:00+02:00",
+    "all_day": true,
+    "summary": "Volba p\u0159edsedy MS Praha 8 (1. kolo)",
+    "description": "",
+    "location": ""
+  }
+]
diff --git a/tests/calendar_utils/snapshots/__init__.py b/tests/calendar_utils/snapshots/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/tests/calendar_utils/snapshots/snap_test_models.py b/tests/calendar_utils/snapshots/snap_test_models.py
deleted file mode 100644
index 2113b073ee3a35fd755c819cb5085573d24cfc13..0000000000000000000000000000000000000000
--- a/tests/calendar_utils/snapshots/snap_test_models.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# -*- coding: utf-8 -*-
-# snapshottest: v1 - https://goo.gl/zC4yUc
-from __future__ import unicode_literals
-
-from snapshottest import GenericRepr, Snapshot
-
-
-snapshots = Snapshot()
-
-snapshots['test_calendar__update_source 1'] = [
-    {
-        'all_day': False,
-        'begin': GenericRepr('FakeDatetime(2020, 1, 23, 17, 0, tzinfo=tzutc())'),
-        'description': '',
-        'duration': '18:00 - 21:00',
-        'end': GenericRepr('FakeDatetime(2020, 1, 23, 20, 0, tzinfo=tzutc())'),
-        'location': 'The 27 Music Bar, Školní 24, 796 01 Prostějov, Česko',
-        'name': 'Veřejná schůze Prostějovských Pirátů'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('FakeDatetime(2020, 1, 15, 18, 0, tzinfo=tzoffset(None, 3600))'),
-        'description': '',
-        'duration': '18:00 - 21:00',
-        'end': GenericRepr('FakeDatetime(2020, 1, 15, 21, 0, tzinfo=tzoffset(None, 3600))'),
-        'location': '',
-        'name': 'Veřejná schůze Pirátů MS Olomouc'
-    },
-    {
-        'all_day': True,
-        'begin': GenericRepr('FakeDatetime(2020, 1, 11, 0, 0, tzinfo=tzutc())'),
-        'description': '',
-        'duration': 'celý den',
-        'end': GenericRepr('FakeDatetime(2020, 1, 13, 0, 0, tzinfo=tzutc())'),
-        'location': '',
-        'name': 'CF Ostrava'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('FakeDatetime(2020, 1, 7, 18, 0, tzinfo=tzoffset(None, 3600))'),
-        'description': '',
-        'duration': '18:00 - 21:00',
-        'end': GenericRepr('FakeDatetime(2020, 1, 7, 21, 0, tzinfo=tzoffset(None, 3600))'),
-        'location': 'PiCOlo, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Veřejná schůze Pirátů Olomouckého kraje'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('FakeDatetime(2019, 4, 10, 18, 0, tzinfo=tzoffset(None, 7200))'),
-        'description': '',
-        'duration': '18:00 - 21:00',
-        'end': GenericRepr('FakeDatetime(2019, 4, 10, 21, 0, tzinfo=tzoffset(None, 7200))'),
-        'location': 'Jeseník',
-        'name': 'Veřejná schůze Pirátů XOLK v Jeseníku'
-    }
-]
-
-snapshots['test_calendar__update_source 2'] = [
-    {
-        'all_day': False,
-        'begin': GenericRepr('FakeDatetime(2020, 2, 17, 17, 30, tzinfo=tzutc())'),
-        'description': '',
-        'duration': '18:30 - 21:30',
-        'end': GenericRepr('FakeDatetime(2020, 2, 17, 20, 30, tzinfo=tzutc())'),
-        'location': 'Nebe počká, 20, Kratochvílova 122, Město, 750 02 Přerov, Česko',
-        'name': 'Schůzka Piráti Přerov'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('FakeDatetime(2020, 2, 21, 17, 30, tzinfo=tzutc())'),
-        'description': 'Tradiční páteční deskohraní s Karlem Bezejmeným. K zapůjčení budou deskové hry všeho druhu – a to jak jednoduché, tak náročnější pro ty,kteří se nebojí u hry strávit delší dobu. Všechny pravidla Vám budou vysvětlena. Nemusíte se bát.',
-        'duration': '18:30 - 22:00',
-        'end': GenericRepr('FakeDatetime(2020, 2, 21, 21, 0, tzinfo=tzutc())'),
-        'location': 'Picolo - Pirátské centrum Olomouc, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Páteční deskovky v Picolu - Karel Bezejmenný'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('FakeDatetime(2020, 3, 1, 14, 0, tzinfo=tzutc())'),
-        'description': '''Tato událost má videohovor.
-Připojit se: https://meet.google.com/ahv-nrmw-kmp
-+1 484-696-1205 PIN: 546973991#''',
-        'duration': '15:00 - 18:00',
-        'end': GenericRepr('FakeDatetime(2020, 3, 1, 17, 0, tzinfo=tzutc())'),
-        'location': 'Koliba & Pivovar U Tří králů, Finská 4592/8, 796 01 Prostějov,Česko',
-        'name': 'Veřejná schůze Prostějovských Pirátů 01.03.2020'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('FakeDatetime(2020, 3, 24, 17, 0, tzinfo=tzutc())'),
-        'description': 'Přednáší MUDr. Marti Moron',
-        'duration': '18:00 - 19:30',
-        'end': GenericRepr('FakeDatetime(2020, 3, 24, 18, 30, tzinfo=tzutc())'),
-        'location': '',
-        'name': 'Je kouření stejně škodlivé jako vapování?'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('FakeDatetime(2020, 4, 8, 16, 0, tzinfo=tzutc())'),
-        'description': '',
-        'duration': '18:00 - 19:30',
-        'end': GenericRepr('FakeDatetime(2020, 4, 8, 17, 30, tzinfo=tzutc())'),
-        'location': 'Picolo - Pirátské centrum Olomouc, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Setkání s místopředsedou Evropského parlamentu Marcelem Kolalokou'
-    }
-]
diff --git a/tests/calendar_utils/snapshots/snap_test_parser.py b/tests/calendar_utils/snapshots/snap_test_parser.py
deleted file mode 100644
index 908ad894ef13afe367cd7b762140aa52e123f475..0000000000000000000000000000000000000000
--- a/tests/calendar_utils/snapshots/snap_test_parser.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# -*- coding: utf-8 -*-
-# snapshottest: v1 - https://goo.gl/zC4yUc
-from __future__ import unicode_literals
-
-from snapshottest import GenericRepr, Snapshot
-
-
-snapshots = Snapshot()
-
-snapshots['test_parse_ical 1'] = [
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-04-08T16:00:00+00:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-04-08T17:30:00+00:00]>'),
-        'location': 'Picolo - Pirátské centrum Olomouc, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Setkání s místopředsedou Evropského parlamentu Marcelem Kolalokou'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-03-24T17:00:00+00:00]>'),
-        'description': 'Přednáší MUDr. Marti Moron',
-        'end': GenericRepr('<Arrow [2020-03-24T18:30:00+00:00]>'),
-        'location': '',
-        'name': 'Je kouření stejně škodlivé jako vapování?'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-03-01T14:00:00+00:00]>'),
-        'description': '''Tato událost má videohovor.
-Připojit se: https://meet.google.com/ahv-nrmw-kmp
-+1 484-696-1205 PIN: 546973991#''',
-        'end': GenericRepr('<Arrow [2020-03-01T17:00:00+00:00]>'),
-        'location': 'Koliba & Pivovar U Tří králů, Finská 4592/8, 796 01 Prostějov,Česko',
-        'name': 'Veřejná schůze Prostějovských Pirátů 01.03.2020'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-02-21T17:30:00+00:00]>'),
-        'description': 'Tradiční páteční deskohraní s Karlem Bezejmeným. K zapůjčení budou deskové hry všeho druhu – a to jak jednoduché, tak náročnější pro ty,kteří se nebojí u hry strávit delší dobu. Všechny pravidla Vám budou vysvětlena. Nemusíte se bát.',
-        'end': GenericRepr('<Arrow [2020-02-21T21:00:00+00:00]>'),
-        'location': 'Picolo - Pirátské centrum Olomouc, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Páteční deskovky v Picolu - Karel Bezejmenný'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-02-17T17:30:00+00:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-02-17T20:30:00+00:00]>'),
-        'location': 'Nebe počká, 20, Kratochvílova 122, Město, 750 02 Přerov, Česko',
-        'name': 'Schůzka Piráti Přerov'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-01-23T17:00:00+00:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-01-23T20:00:00+00:00]>'),
-        'location': 'The 27 Music Bar, Školní 24, 796 01 Prostějov, Česko',
-        'name': 'Veřejná schůze Prostějovských Pirátů'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-01-15T18:00:00+01:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-01-15T21:00:00+01:00]>'),
-        'location': '',
-        'name': 'Veřejná schůze Pirátů MS Olomouc'
-    },
-    {
-        'all_day': True,
-        'begin': GenericRepr('<Arrow [2020-01-11T00:00:00+00:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-01-13T00:00:00+00:00]>'),
-        'location': '',
-        'name': 'CF Ostrava'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-01-07T18:00:00+01:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-01-07T21:00:00+01:00]>'),
-        'location': 'PiCOlo, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Veřejná schůze Pirátů Olomouckého kraje'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2019-04-10T18:00:00+02:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2019-04-10T21:00:00+02:00]>'),
-        'location': 'Jeseník',
-        'name': 'Veřejná schůze Pirátů XOLK v Jeseníku'
-    }
-]
-
-snapshots['test_split_events 1'] = [
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-01-23T17:00:00+00:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-01-23T20:00:00+00:00]>'),
-        'location': 'The 27 Music Bar, Školní 24, 796 01 Prostějov, Česko',
-        'name': 'Veřejná schůze Prostějovských Pirátů'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-01-15T18:00:00+01:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-01-15T21:00:00+01:00]>'),
-        'location': '',
-        'name': 'Veřejná schůze Pirátů MS Olomouc'
-    },
-    {
-        'all_day': True,
-        'begin': GenericRepr('<Arrow [2020-01-11T00:00:00+00:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-01-13T00:00:00+00:00]>'),
-        'location': '',
-        'name': 'CF Ostrava'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-01-07T18:00:00+01:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-01-07T21:00:00+01:00]>'),
-        'location': 'PiCOlo, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Veřejná schůze Pirátů Olomouckého kraje'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2019-04-10T18:00:00+02:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2019-04-10T21:00:00+02:00]>'),
-        'location': 'Jeseník',
-        'name': 'Veřejná schůze Pirátů XOLK v Jeseníku'
-    }
-]
-
-snapshots['test_split_events 2'] = [
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-04-08T16:00:00+00:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-04-08T17:30:00+00:00]>'),
-        'location': 'Picolo - Pirátské centrum Olomouc, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Setkání s místopředsedou Evropského parlamentu Marcelem Kolalokou'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-03-24T17:00:00+00:00]>'),
-        'description': 'Přednáší MUDr. Marti Moron',
-        'end': GenericRepr('<Arrow [2020-03-24T18:30:00+00:00]>'),
-        'location': '',
-        'name': 'Je kouření stejně škodlivé jako vapování?'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-03-01T14:00:00+00:00]>'),
-        'description': '''Tato událost má videohovor.
-Připojit se: https://meet.google.com/ahv-nrmw-kmp
-+1 484-696-1205 PIN: 546973991#''',
-        'end': GenericRepr('<Arrow [2020-03-01T17:00:00+00:00]>'),
-        'location': 'Koliba & Pivovar U Tří králů, Finská 4592/8, 796 01 Prostějov,Česko',
-        'name': 'Veřejná schůze Prostějovských Pirátů 01.03.2020'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-02-21T17:30:00+00:00]>'),
-        'description': 'Tradiční páteční deskohraní s Karlem Bezejmeným. K zapůjčení budou deskové hry všeho druhu – a to jak jednoduché, tak náročnější pro ty,kteří se nebojí u hry strávit delší dobu. Všechny pravidla Vám budou vysvětlena. Nemusíte se bát.',
-        'end': GenericRepr('<Arrow [2020-02-21T21:00:00+00:00]>'),
-        'location': 'Picolo - Pirátské centrum Olomouc, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Páteční deskovky v Picolu - Karel Bezejmenný'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-02-17T17:30:00+00:00]>'),
-        'description': '',
-        'end': GenericRepr('<Arrow [2020-02-17T20:30:00+00:00]>'),
-        'location': 'Nebe počká, 20, Kratochvílova 122, Město, 750 02 Přerov, Česko',
-        'name': 'Schůzka Piráti Přerov'
-    }
-]
-
-snapshots['test_process_ical 1'] = [
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-01-23T17:00:00+00:00]>'),
-        'description': '',
-        'duration': '18:00 - 21:00',
-        'end': GenericRepr('<Arrow [2020-01-23T20:00:00+00:00]>'),
-        'location': 'The 27 Music Bar, Školní 24, 796 01 Prostějov, Česko',
-        'name': 'Veřejná schůze Prostějovských Pirátů'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-01-15T18:00:00+01:00]>'),
-        'description': '',
-        'duration': '18:00 - 21:00',
-        'end': GenericRepr('<Arrow [2020-01-15T21:00:00+01:00]>'),
-        'location': '',
-        'name': 'Veřejná schůze Pirátů MS Olomouc'
-    },
-    {
-        'all_day': True,
-        'begin': GenericRepr('<Arrow [2020-01-11T00:00:00+00:00]>'),
-        'description': '',
-        'duration': 'celý den',
-        'end': GenericRepr('<Arrow [2020-01-13T00:00:00+00:00]>'),
-        'location': '',
-        'name': 'CF Ostrava'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-01-07T18:00:00+01:00]>'),
-        'description': '',
-        'duration': '18:00 - 21:00',
-        'end': GenericRepr('<Arrow [2020-01-07T21:00:00+01:00]>'),
-        'location': 'PiCOlo, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Veřejná schůze Pirátů Olomouckého kraje'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2019-04-10T18:00:00+02:00]>'),
-        'description': '',
-        'duration': '18:00 - 21:00',
-        'end': GenericRepr('<Arrow [2019-04-10T21:00:00+02:00]>'),
-        'location': 'Jeseník',
-        'name': 'Veřejná schůze Pirátů XOLK v Jeseníku'
-    }
-]
-
-snapshots['test_process_ical 2'] = [
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-04-08T16:00:00+00:00]>'),
-        'description': '',
-        'duration': '18:00 - 19:30',
-        'end': GenericRepr('<Arrow [2020-04-08T17:30:00+00:00]>'),
-        'location': 'Picolo - Pirátské centrum Olomouc, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Setkání s místopředsedou Evropského parlamentu Marcelem Kolalokou'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-03-24T17:00:00+00:00]>'),
-        'description': 'Přednáší MUDr. Marti Moron',
-        'duration': '18:00 - 19:30',
-        'end': GenericRepr('<Arrow [2020-03-24T18:30:00+00:00]>'),
-        'location': '',
-        'name': 'Je kouření stejně škodlivé jako vapování?'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-03-01T14:00:00+00:00]>'),
-        'description': '''Tato událost má videohovor.
-Připojit se: https://meet.google.com/ahv-nrmw-kmp
-+1 484-696-1205 PIN: 546973991#''',
-        'duration': '15:00 - 18:00',
-        'end': GenericRepr('<Arrow [2020-03-01T17:00:00+00:00]>'),
-        'location': 'Koliba & Pivovar U Tří králů, Finská 4592/8, 796 01 Prostějov,Česko',
-        'name': 'Veřejná schůze Prostějovských Pirátů 01.03.2020'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-02-21T17:30:00+00:00]>'),
-        'description': 'Tradiční páteční deskohraní s Karlem Bezejmeným. K zapůjčení budou deskové hry všeho druhu – a to jak jednoduché, tak náročnější pro ty,kteří se nebojí u hry strávit delší dobu. Všechny pravidla Vám budou vysvětlena. Nemusíte se bát.',
-        'duration': '18:30 - 22:00',
-        'end': GenericRepr('<Arrow [2020-02-21T21:00:00+00:00]>'),
-        'location': 'Picolo - Pirátské centrum Olomouc, 8. května 522/5, 779 00 Olomouc, Česko',
-        'name': 'Páteční deskovky v Picolu - Karel Bezejmenný'
-    },
-    {
-        'all_day': False,
-        'begin': GenericRepr('<Arrow [2020-02-17T17:30:00+00:00]>'),
-        'description': '',
-        'duration': '18:30 - 21:30',
-        'end': GenericRepr('<Arrow [2020-02-17T20:30:00+00:00]>'),
-        'location': 'Nebe počká, 20, Kratochvílova 122, Město, 750 02 Přerov, Česko',
-        'name': 'Schůzka Piráti Přerov'
-    }
-]
diff --git a/tests/calendar_utils/test_models.py b/tests/calendar_utils/test_models.py
index 467745457288348db87a9fac1e7466affa1a18c7..62b2245e5628c74f746c445a4d1bcd6b359d4000 100644
--- a/tests/calendar_utils/test_models.py
+++ b/tests/calendar_utils/test_models.py
@@ -10,40 +10,45 @@ pytestmark = pytest.mark.django_db
 fake = Faker()
 
 
-@pytest.mark.freeze_time("2020-02-02")
-def test_calendar__update_source(sample, mocker, snapshot):
-    m_get = mocker.patch(
-        "calendar_utils.models.requests.get", return_value=mocker.Mock(text=sample)
-    )
+@pytest.mark.freeze_time("2022-05-13")
+def test_calendar__update_source(
+    sample_response, sample_past_events, sample_future_events
+):
+    """
+    Pokud se změní hash, přenačtou se eventy
+    """
     url = "http://foo"
-
     cal = Calendar.objects.create(url=url)
-    cal.update_source()
 
-    m_get.assert_called_once_with(url)
+    cal.handle_event_list(sample_response)
+
     cal.refresh_from_db()
-    assert cal.source == sample
-    assert cal.last_update == arrow.get("2020-02-02").datetime
-    snapshot.assert_match(cal.past_events)
-    snapshot.assert_match(cal.future_events)
 
+    assert cal.event_hash == str(hash(str(sample_response)))
+    assert cal.last_update == arrow.get("2022-05-13").datetime
+    assert sample_past_events == cal.past_events
+    assert sample_future_events == cal.future_events
 
-@pytest.mark.freeze_time("2020-03-30")
-def test_calendar__update_source__unchanged_source(sample, mocker):
-    m_get = mocker.patch(
-        "calendar_utils.models.requests.get", return_value=mocker.Mock(text=sample)
-    )
+
+@pytest.mark.freeze_time("2022-05-13")
+def test_calendar__update_source__unchanged_source(sample_response):
+    """
+    Pokud se nezmění hash, tak se nezmění ani eventy
+    """
     url = "http://foo"
+    event_hash = str(hash(str(sample_response)))
 
-    cal = Calendar.objects.create(url=url, source=sample)
-    cal.update_source()
+    cal = Calendar.objects.create(
+        url=url, event_hash=event_hash, past_events=[], future_events=[]
+    )
+    cal.handle_event_list(sample_response)
 
-    m_get.assert_called_once_with(url)
     cal.refresh_from_db()
-    assert cal.source == sample
-    assert cal.last_update == arrow.get("2020-03-30").datetime
-    assert cal.past_events is None
-    assert cal.future_events is None
+
+    assert cal.event_hash == event_hash
+    assert cal.last_update == arrow.get("2022-05-13").datetime
+    assert [] == cal.past_events
+    assert [] == cal.future_events
 
 
 def test_calendar__save_and_load_events():
diff --git a/tests/calendar_utils/test_parser.py b/tests/calendar_utils/test_parser.py
index 0ca996a4326e8dc6687cae2b77d38f3588a262bd..76d9a0b421f6a43c31022d29c932792447cf8b6c 100644
--- a/tests/calendar_utils/test_parser.py
+++ b/tests/calendar_utils/test_parser.py
@@ -5,14 +5,25 @@ import pytest
 from icalevnt.icalparser import Event
 from zoneinfo import ZoneInfo
 
-from calendar_utils.parser import set_event_duration  # process_ical,; split_events,
+from calendar_utils.parser import (
+    process_event_list,
+    set_event_duration,
+    split_event_dict_list,
+)
 
-#
-# @pytest.mark.freeze_time("2020-02-02")
-# def test_split_events(sample, snapshot):
-#     past_events, future_events = split_events(parse_ical(sample))
-#     snapshot.assert_match(past_events)
-#     snapshot.assert_match(future_events)
+
+@pytest.mark.freeze_time("2022-05-13")
+def test_split_events(sample_response, sample_future_events, sample_past_events):
+    past_events, future_events = process_event_list(sample_response)
+    assert sample_past_events == past_events
+    assert sample_future_events == future_events
+
+
+@pytest.mark.freeze_time("2022-05-13")
+def test_split_events(sample_events, sample_future_events, sample_past_events):
+    past_events, future_events = split_event_dict_list(sample_events)
+    assert sample_past_events == past_events
+    assert sample_future_events == future_events
 
 
 def test_set_event_duration__all_day():
@@ -43,10 +54,3 @@ def test_set_event_duration__days():
 
     out = set_event_duration(event)
     assert out.duration == "10:15 - 22:30 (4.2.)"
-
-
-# @pytest.mark.freeze_time("2020-02-02")
-# def test_process_ical(sample, snapshot):
-#     past_events, future_events = process_ical(sample)
-#     snapshot.assert_match(past_events)
-#     snapshot.assert_match(future_events)