ungana

Unnamed repository; edit this file 'description' to name the repository.
Info | Log | Files | Refs | README

commit a17c24b7a7c12d97d671d2e08c8ad883412a3d7d
parent 2fdbc26d49ad2d0e4017b67fd12e9d52ec7b3e86
Author: Carlosokumu <carlosokumu254@gmail.com>
Date:   Sun,  7 Sep 2025 17:33:09 +0300

add  unit tests

Diffstat:
Atests/attachment/test_attachment_manager.py | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/cmd/test_args_parser.py | 37+++++++++++++++++++++++++++++++++++++
Atests/ical/test_ical_manager.py | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 168 insertions(+), 0 deletions(-)

diff --git a/tests/attachment/test_attachment_manager.py b/tests/attachment/test_attachment_manager.py @@ -0,0 +1,63 @@ +import unittest +import tempfile +import os +import stat +import hashlib + +from ungana.attachment.attachment_manager import AttachmentManager + +class TestAttachmentManager(unittest.TestCase): + + def setUp(self): + self.manager = AttachmentManager() + + def _make_temp_file(self, suffix, content=b"foo bar"): + """Helper to create a temp file with given content.""" + fd, path = tempfile.mkstemp(suffix=suffix) + with os.fdopen(fd, "wb") as f: + f.write(content) + return path + + def test_create_attachment_image_poster(self): + path = self._make_temp_file(".png", b"fakeimage") + result = self.manager.create_attachment(path, ctx="poster") + + self.assertEqual(result[0], "ATTACH") + self.assertTrue(result[1].startswith("sha256:")) + self.assertEqual(result[2]["CTX"], "poster") + self.assertEqual(result[2]["FMTTYPE"], "image/png") + + def test_create_attachment_text_long(self): + path = self._make_temp_file(".txt", b"xyz xyz xyz") + result = self.manager.create_attachment(path, ctx="long") + self.assertEqual(result[2]["FMTTYPE"], "text/plain") + + def test_create_attachment_file_not_found(self): + with self.assertRaises(FileNotFoundError): + self.manager.create_attachment("does_not_exist.txt", ctx="poster") + + def test_create_attachment_permission_denied(self): + path = self._make_temp_file(".txt") + os.chmod(path, 0) + try: + with self.assertRaises(PermissionError): + self.manager.create_attachment(path, ctx="long") + finally: + os.chmod(path, stat.S_IRUSR | stat.S_IWUSR) # clean up + + def test_validate_wrong_type_for_poster(self): + path = self._make_temp_file(".txt", b"not an image") + with self.assertRaises(ValueError): + self.manager.validate(path, ctx="poster") + + def test_validate_wrong_type_for_long(self): + path = self._make_temp_file(".png", b"fakeimage") + with self.assertRaises(ValueError): + self.manager.validate(path, ctx="long") + + def test_digest_correctness(self): + content = b"foobar" + path = self._make_temp_file(".txt", content) + digest = self.manager.digest(path) + expected = hashlib.sha256(content).hexdigest() + self.assertEqual(digest, expected) diff --git a/tests/cmd/test_args_parser.py b/tests/cmd/test_args_parser.py @@ -0,0 +1,37 @@ +import unittest +from unittest.mock import patch +import argparse + +from ungana.cmd.args_parser import ArgsParser + +class TestArgsParser(unittest.TestCase): + + def setUp(self): + self.parser = ArgsParser() + + def test_ensure_no_multiline_input_valid(self): + result = self.parser._ensure_no_multiline_input("foo bar") + self.assertEqual(result, "foo bar") + + def test_ensure_no_multiline_input_invalid(self): + with self.assertRaises(argparse.ArgumentTypeError): + self.parser._ensure_no_multiline_input("bad\nline") + + def test_process_contact_arg_with_params(self): + value, params = self.parser._process_contact_arg("Go pher|ALTREP=mailto:gophers@go.org") + self.assertEqual(value, "Go pher") + self.assertEqual(params, {"ALTREP": "mailto:gophers@go.org"}) + + def test_process_contact_arg_simple(self): + value, params = self.parser._process_contact_arg("gophers@go.org") + self.assertEqual(value, "gophers@go.org") + self.assertEqual(params, {}) + + + @patch("sys.argv", ["prog", "create", "-s", "Gophers Meetup", "--start", "2025-09-06 10:00", "-d", "Gophers yearly meetup", "-l", "Gopher Confrence Hall", "-o", "events@gophers.com"]) + def test_parse_args_create_command(self): + args = self.parser.parse_args() + self.assertEqual(args.command, "create") + self.assertEqual(args.summary, "Gophers Meetup") + self.assertEqual(args.location, "Gopher Confrence Hall") + diff --git a/tests/ical/test_ical_manager.py b/tests/ical/test_ical_manager.py @@ -0,0 +1,68 @@ +import unittest +import os +import tempfile +from datetime import datetime, timezone +from icalendar import Event +from ungana.ical.ical_manager import ICalManager + +class TestICalManager(unittest.TestCase): + + def setUp(self): + self.manager = ICalManager() + self.compulsory_event_fields = { + "start": datetime(2025, 9, 6, 10, 0, tzinfo=timezone.utc), + "summary": "Gophers Meetup", + "location": "Gopher Confrence Hall", + "description": "Gophers yearly meetup", + "organizer": "mailto:events@gophers.com", + "uid": "test-uid-123" + } + + def test_create_event_basic(self): + event = self.manager.create_event(self.compulsory_event_fields) + self.assertIsInstance(event, Event) + self.assertEqual(str(event["summary"]), "Gophers Meetup") + self.assertEqual(str(event["organizer"]), "mailto:events@gophers.com") + self.assertEqual(str(event["uid"]), "test-uid-123") + + def test_create_event_with_duration(self): + data = self.compulsory_event_fields.copy() + data["duration"] = "PT1H" # 1 hour ISO duration + event = self.manager.create_event(data) + self.assertIn("duration", event) + + def test_create_event_with_contact(self): + data = self.compulsory_event_fields.copy() + data["contact"] = "Foo bar" + event = self.manager.create_event(data) + self.assertIn("contact", event) + self.assertEqual(str(event["contact"]), "Foo bar") + + def test_create_event_with_attachments(self): + data = self.compulsory_event_fields.copy() + data["attachments"] = [ + "http://foo.com/foo.pdf", + ("ATTACH", "http://foo.com/foo.pdf", {"FMTTYPE": "application/pdf"}) + ] + event = self.manager.create_event(data) + self.assertIn("ATTACH", event) + + def test_load_nonexistent_file_returns_new_calendar(self): + cal = self.manager.load_ical_file("does_not_exist.ics") + self.assertEqual(cal["VERSION"], "2.0") + self.assertEqual(cal["PRODID"], "-//Ungana//mxm.dk//") + + def test_save_and_load_event(self): + event = self.manager.create_event(self.compulsory_event_fields) + with tempfile.TemporaryDirectory() as tmpdir: + filepath = os.path.join(tmpdir, "xyz.ics") + self.manager.save_ical_file(event, filepath) + + # Verify file exists + self.assertTrue(os.path.exists(filepath)) + + # Reload calendar + cal = self.manager.load_ical_file(filepath) + events = [c for c in cal.walk() if c.name == "VEVENT"] + self.assertEqual(len(events), 1) + self.assertEqual(str(events[0]["summary"]), "Gophers Meetup")