2323from crowdmail .services .parse import noteren
2424
2525HERE = os .path .dirname (os .path .abspath (__file__ ))
26- NOTEREN = os .path .join (
27- HERE , ".." , "crowdmail" , "services" , "parse" , "noteren.py"
28- )
26+ NOTEREN = os .path .join (HERE , ".." , "crowdmail" , "services" , "parse" , "noteren.py" )
2927SEGMENT_ID = "11111111-1111-1111-1111-111111111111"
3028INTEGRATION_ID = "22222222-2222-2222-2222-222222222222"
3129
3432# Fixtures
3533# --------------------------------------------------------------------------
3634
35+
3736def _git (gitdir , * args , stdin = None ):
3837 out = subprocess .run (
3938 ["git" , "--git-dir" , str (gitdir )] + list (args ),
4039 input = stdin ,
41- stdout = subprocess .PIPE ,
42- stderr = subprocess .PIPE ,
40+ capture_output = True ,
4341 check = True ,
4442 )
4543 return out .stdout .decode ().strip ()
4644
4745
4846def _make_email (msgid , subject , frm , body , date = "Mon, 1 Jan 2024 12:00:00 +0000" ):
49- hdr = (
50- f"From: { frm } \n "
51- f"Subject: { subject } \n "
52- f"Date: { date } \n "
53- f"Message-ID: <{ msgid } >\n "
54- "\n "
55- )
47+ hdr = f"From: { frm } \n Subject: { subject } \n Date: { date } \n Message-ID: <{ msgid } >\n \n "
5648 return (hdr + body ).encode ()
5749
5850
@@ -108,8 +100,7 @@ def inbox_repo(tmp_path):
108100def _run_noteren (* args ):
109101 return subprocess .run (
110102 [sys .executable , NOTEREN ] + list (args ),
111- stdout = subprocess .PIPE ,
112- stderr = subprocess .PIPE ,
103+ capture_output = True ,
113104 text = True ,
114105 )
115106
@@ -122,6 +113,7 @@ def _std_args():
122113# Unit tests for helper functions
123114# --------------------------------------------------------------------------
124115
116+
125117def test_message_id_cleanup_strips_angles ():
126118 assert noteren .message_id_cleanup ("<abc@host>" ) == "abc@host"
127119 assert noteren .message_id_cleanup (" <abc@host> " ) == "abc@host"
@@ -256,9 +248,7 @@ def fake_git_run(git_dir, args, stdin=None):
256248
257249
258250def test_get_email_from_git_missing_commit_exits (monkeypatch ):
259- monkeypatch .setattr (
260- noteren , "git_run_command" , lambda * args , ** kwargs : (0 , b"" , b"" )
261- )
251+ monkeypatch .setattr (noteren , "git_run_command" , lambda * args , ** kwargs : (0 , b"" , b"" ))
262252 with pytest .raises (SystemExit ):
263253 noteren .get_email_from_git ("/tmp/repo.git" , "deadbeef" )
264254
@@ -275,9 +265,7 @@ def fake_git_run(git_dir, args, stdin=None):
275265
276266
277267def _parse_email (raw , source , channel , git_id , blob_id ):
278- return noteren .parse_email (
279- raw , source , channel , git_id , blob_id , SEGMENT_ID , INTEGRATION_ID
280- )
268+ return noteren .parse_email (raw , source , channel , git_id , blob_id , SEGMENT_ID , INTEGRATION_ID )
281269
282270
283271def test_parse_email_extracts_attributes_and_reference ():
@@ -351,13 +339,7 @@ def test_parse_email_invalid_date_leaves_timestamp_empty():
351339
352340
353341def test_parse_email_falls_back_to_raw_body (monkeypatch ):
354- raw = (
355- b"From: A <a@example.com>\n "
356- b"Subject: s\n "
357- b"Message-ID: <msg@example.com>\n "
358- b"\n "
359- b"line one\n "
360- )
342+ raw = b"From: A <a@example.com>\n Subject: s\n Message-ID: <msg@example.com>\n \n line one\n "
361343 monkeypatch .setattr (noteren , "get_body" , lambda msg : None )
362344 parsed = _parse_email (raw , "src" , "chan" , "commit1" , "blob1" )
363345 assert "line one\n " in parsed ["activityData" ]["body" ]
@@ -400,9 +382,7 @@ def test_parse_id_writes_json(monkeypatch):
400382
401383
402384def test_parse_range_calls_parse_id_for_each_commit (monkeypatch ):
403- monkeypatch .setattr (
404- noteren , "git_run_command" , lambda * args , ** kwargs : (0 , b"c1\n c2\n " , b"" )
405- )
385+ monkeypatch .setattr (noteren , "git_run_command" , lambda * args , ** kwargs : (0 , b"c1\n c2\n " , b"" ))
406386 seen = []
407387 monkeypatch .setattr (
408388 noteren ,
@@ -542,9 +522,7 @@ def test_cmd_without_output_uses_stdout(monkeypatch):
542522
543523
544524def test_cmd_verbose_enables_debug_logging (monkeypatch ):
545- monkeypatch .setattr (
546- noteren , "parse_id" , lambda * args , ** kwargs : None
547- )
525+ monkeypatch .setattr (noteren , "parse_id" , lambda * args , ** kwargs : None )
548526 called = {}
549527 monkeypatch .setattr (
550528 noteren .logging ,
@@ -627,10 +605,9 @@ def test_cmd_rejects_both_id_and_range(monkeypatch):
627605# CLI / integration tests
628606# --------------------------------------------------------------------------
629607
608+
630609def test_cli_requires_id_or_range (inbox_repo ):
631- r = _run_noteren (
632- "--source=s" , "--channel=c" , "--git-dir" , inbox_repo ["gitdir" ], * _std_args ()
633- )
610+ r = _run_noteren ("--source=s" , "--channel=c" , "--git-dir" , inbox_repo ["gitdir" ], * _std_args ())
634611 assert r .returncode != 0
635612 assert "--git-range or --git-id" in r .stderr
636613
@@ -729,6 +706,7 @@ def test_cli_unknown_commit_fails(inbox_repo):
729706# Additional edge-case unit tests
730707# --------------------------------------------------------------------------
731708
709+
732710def test_get_body_returns_none_when_no_text_parts ():
733711 """A message that contains only text/html must cause get_body to return None."""
734712 msg = noteren .email .message .EmailMessage ()
@@ -753,21 +731,13 @@ def test_get_body_raw_blank_body_after_headers():
753731
754732def test_run_command_returns_nonzero_exit_code ():
755733 """_run_command must surface a non-zero return code from the child process."""
756- rc , out , err = noteren ._run_command (
757- [sys .executable , "-c" , "import sys; sys.exit(42)" ]
758- )
734+ rc , out , err = noteren ._run_command ([sys .executable , "-c" , "import sys; sys.exit(42)" ])
759735 assert rc == 42
760736
761737
762738def test_parse_email_no_message_id_gives_empty_source_id ():
763739 """A message without a Message-ID header must yield sourceId == ''."""
764- raw = (
765- b"From: A <a@example.com>\n "
766- b"Subject: s\n "
767- b"Date: Mon, 1 Jan 2024 12:00:00 +0000\n "
768- b"\n "
769- b"body\n "
770- )
740+ raw = b"From: A <a@example.com>\n Subject: s\n Date: Mon, 1 Jan 2024 12:00:00 +0000\n \n body\n "
771741 parsed = _parse_email (raw , "src" , "chan" , "c1" , "b1" )
772742 assert parsed ["activityData" ]["sourceId" ] == ""
773743
@@ -851,7 +821,7 @@ def test_parse_email_multipart_alternative_uses_text_plain():
851821 b"Date: Mon, 1 Jan 2024 12:00:00 +0000\n "
852822 b"Message-ID: <multi@example.com>\n "
853823 b"MIME-Version: 1.0\n "
854- b" Content-Type: multipart/alternative; boundary=\ " boundary\ "\n "
824+ b' Content-Type: multipart/alternative; boundary="boundary"\n '
855825 b"\n "
856826 b"--boundary\n "
857827 b"Content-Type: text/plain; charset=utf-8\n "
@@ -886,13 +856,7 @@ def test_parse_email_url_contains_message_id():
886856
887857def test_parse_email_url_with_no_message_id ():
888858 """When Message-ID is absent the url must end with a trailing slash and empty id."""
889- raw = (
890- b"From: A <a@example.com>\n "
891- b"Subject: s\n "
892- b"Date: Mon, 1 Jan 2024 12:00:00 +0000\n "
893- b"\n "
894- b"body\n "
895- )
859+ raw = b"From: A <a@example.com>\n Subject: s\n Date: Mon, 1 Jan 2024 12:00:00 +0000\n \n body\n "
896860 parsed = _parse_email (raw , "src" , "chan" , "c1" , "b1" )
897861 assert parsed ["activityData" ]["url" ] == "https://lore.kernel.org/r/"
898862
@@ -956,19 +920,22 @@ def _c1_argv(inbox_repo):
956920 "noteren.py" ,
957921 "--source=https://example.com/0.git" ,
958922 "--channel=test-list" ,
959- "--git-dir" , inbox_repo ["gitdir" ],
960- "--segment-id" , SEGMENT_ID ,
961- "--integration-id" , INTEGRATION_ID ,
962- "--git-id" , inbox_repo ["c1" ],
923+ "--git-dir" ,
924+ inbox_repo ["gitdir" ],
925+ "--segment-id" ,
926+ SEGMENT_ID ,
927+ "--integration-id" ,
928+ INTEGRATION_ID ,
929+ "--git-id" ,
930+ inbox_repo ["c1" ],
963931 ]
964932
965933
966934def test_main_entry_point_via_subprocess (inbox_repo ):
967935 """Running noteren.py as __main__ must work end-to-end."""
968936 r = subprocess .run (
969937 [sys .executable , NOTEREN ] + _c1_argv (inbox_repo )[1 :],
970- stdout = subprocess .PIPE ,
971- stderr = subprocess .PIPE ,
938+ capture_output = True ,
972939 text = True ,
973940 )
974941 assert r .returncode == 0 , r .stderr
0 commit comments