@@ -49,6 +49,47 @@ def revision(self, **kwargs: object) -> MockQuery:
4949 return MockQuery (self ._revision )
5050
5151
52+ @pytest .mark .asyncio
53+ async def test_announce_release_subject_and_body_does_not_expand_injected_tag (monkeypatch ) -> None :
54+ committee = SimpleNamespace (key = "myproject" , is_podling = False , display_name = "Apache MyProject" )
55+ project = SimpleNamespace (
56+ short_display_name = "Apache MyProject" ,
57+ name = "MyProject" ,
58+ key = "myproject" ,
59+ bug_database = "bug_database" ,
60+ download_page = "download_page" ,
61+ homepage = "homepage" ,
62+ lifecycle_page = "lifecycle_page" ,
63+ mailing_lists = "mailing_lists" ,
64+ repository = "repository" ,
65+ )
66+ release = SimpleNamespace (key = "myproject-1.0.0" , committee = committee , project = project )
67+ revision = SimpleNamespace (number = "1" , tag = "{{YOUR_FULL_NAME}}" )
68+
69+ monkeypatch .setattr (
70+ construct .config ,
71+ "get" ,
72+ lambda : SimpleNamespace (APP_HOST = "downloads.apache.org" , SVN_PUBLISH_URL = None ),
73+ )
74+ monkeypatch .setattr (construct .db , "session" , _mock_session_factory (MockDBSession (release , revision )))
75+
76+ _subject , body = await construct .announce_release_subject_and_body (
77+ "{{PROJECT_NAME}} {{VERSION}}" ,
78+ "Tag: {{TAG}}\n Name: {{YOUR_FULL_NAME}}" ,
79+ construct .AnnounceReleaseOptions (
80+ asfuid = "example" ,
81+ fullname = "Example User" ,
82+ project_key = safe .ProjectKey ("myproject" ),
83+ version_key = safe .VersionKey ("1.0.0" ),
84+ revision_number = safe .RevisionNumber ("1" ),
85+ ),
86+ )
87+
88+ tag_line , name_line = body .split ("\n " )
89+ assert tag_line == "Tag: {{YOUR_FULL_NAME}}"
90+ assert name_line == "Name: Example User"
91+
92+
5293@pytest .mark .asyncio
5394async def test_announce_release_subject_and_body_uses_podling_downloads_url (monkeypatch ) -> None :
5495 committee = SimpleNamespace (key = "myproject" , is_podling = True , display_name = "Apache MyProject (podling)" )
@@ -129,6 +170,16 @@ async def test_announce_release_subject_and_body_uses_top_level_downloads_url(mo
129170 assert body == "https://downloads.apache.org/downloads/myproject/"
130171
131172
173+ def test_substitute_does_not_rescan_replacement_values () -> None :
174+ result = construct ._substitute (
175+ "{{PROJECT_NAME}} {{VERSION}} {{UNKNOWN}}" ,
176+ {"PROJECT_NAME" : "{{VERSION}}" , "VERSION" : "1.0.0" },
177+ "announce_subject" ,
178+ )
179+
180+ assert result == "{{VERSION}} 1.0.0 {{UNKNOWN}}"
181+
182+
132183def _mock_session_factory (data : MockDBSession ):
133184 @contextlib .asynccontextmanager
134185 async def _session ():
0 commit comments