11"""Fixtures for Docker-based integration tests (Tier 2).
22
3- GreenMail provides a real SMTP+IMAP server for full send→ read roundtrip tests.
3+ GreenMail provides a real SMTP+IMAP server for full send/ read roundtrip tests.
44Tests auto-skip if Docker is not available.
5+
6+ Security modes tested:
7+ - NONE: SMTP port 3025, IMAP port 3143 (plaintext)
8+ - TLS: SMTPS port 3465, IMAPS port 3993 (Implicit TLS, self-signed)
9+ - STARTTLS: skipped (greenmail#135 — GreenMail does not support STARTTLS)
510"""
611
712from __future__ import annotations
2025
2126GREENMAIL_SMTP_PORT = 3025
2227GREENMAIL_IMAP_PORT = 3143
28+ GREENMAIL_SMTPS_PORT = 3465
29+ GREENMAIL_IMAPS_PORT = 3993
2330
2431
2532def pytest_collection_modifyitems (config , items ):
@@ -59,6 +66,12 @@ def _greenmail_is_ready() -> bool:
5966 # Test IMAP socket
6067 with socket .create_connection (("127.0.0.1" , GREENMAIL_IMAP_PORT ), timeout = 3 ):
6168 pass
69+ # Test SMTPS socket (TLS port)
70+ with socket .create_connection (("127.0.0.1" , GREENMAIL_SMTPS_PORT ), timeout = 3 ):
71+ pass
72+ # Test IMAPS socket (TLS port)
73+ with socket .create_connection (("127.0.0.1" , GREENMAIL_IMAPS_PORT ), timeout = 3 ):
74+ pass
6275 return True
6376 except Exception :
6477 return False
@@ -77,14 +90,21 @@ def greenmail(docker_services):
7790 "smtp_port" : GREENMAIL_SMTP_PORT ,
7891 "imap_host" : "127.0.0.1" ,
7992 "imap_port" : GREENMAIL_IMAP_PORT ,
93+ "smtps_port" : GREENMAIL_SMTPS_PORT ,
94+ "imaps_port" : GREENMAIL_IMAPS_PORT ,
8095 "user" : GREENMAIL_USER ,
8196 "password" : GREENMAIL_PASSWORD ,
8297 }
8398
8499
100+ # ---------------------------------------------------------------------------
101+ # Plaintext (NONE) fixtures
102+ # ---------------------------------------------------------------------------
103+
104+
85105@pytest .fixture ()
86106def greenmail_smtp_server (greenmail ) -> EmailServer :
87- """EmailServer config for GreenMail SMTP."""
107+ """EmailServer config for GreenMail SMTP (plaintext) ."""
88108 return EmailServer (
89109 host = greenmail ["smtp_host" ],
90110 port = greenmail ["smtp_port" ],
@@ -97,7 +117,7 @@ def greenmail_smtp_server(greenmail) -> EmailServer:
97117
98118@pytest .fixture ()
99119def greenmail_imap_server (greenmail ) -> EmailServer :
100- """EmailServer config for GreenMail IMAP."""
120+ """EmailServer config for GreenMail IMAP (plaintext) ."""
101121 return EmailServer (
102122 host = greenmail ["imap_host" ],
103123 port = greenmail ["imap_port" ],
@@ -110,11 +130,105 @@ def greenmail_imap_server(greenmail) -> EmailServer:
110130
111131@pytest .fixture ()
112132def greenmail_smtp_client (greenmail_smtp_server ) -> EmailClient :
113- """EmailClient wired to GreenMail SMTP."""
133+ """EmailClient wired to GreenMail SMTP (plaintext) ."""
114134 return EmailClient (greenmail_smtp_server , sender = GREENMAIL_USER )
115135
116136
117137@pytest .fixture ()
118138def greenmail_imap_client (greenmail_imap_server ) -> EmailClient :
119- """EmailClient wired to GreenMail IMAP."""
139+ """EmailClient wired to GreenMail IMAP (plaintext) ."""
120140 return EmailClient (greenmail_imap_server , sender = GREENMAIL_USER )
141+
142+
143+ # ---------------------------------------------------------------------------
144+ # Implicit TLS fixtures (SMTPS / IMAPS)
145+ # ---------------------------------------------------------------------------
146+
147+
148+ @pytest .fixture ()
149+ def greenmail_smtps_server (greenmail ) -> EmailServer :
150+ """EmailServer config for GreenMail SMTPS (Implicit TLS)."""
151+ return EmailServer (
152+ host = greenmail ["smtp_host" ],
153+ port = greenmail ["smtps_port" ],
154+ user_name = greenmail ["user" ],
155+ password = greenmail ["password" ],
156+ security = ConnectionSecurity .TLS ,
157+ verify_ssl = False ,
158+ )
159+
160+
161+ @pytest .fixture ()
162+ def greenmail_imaps_server (greenmail ) -> EmailServer :
163+ """EmailServer config for GreenMail IMAPS (Implicit TLS)."""
164+ return EmailServer (
165+ host = greenmail ["imap_host" ],
166+ port = greenmail ["imaps_port" ],
167+ user_name = greenmail ["user" ],
168+ password = greenmail ["password" ],
169+ security = ConnectionSecurity .TLS ,
170+ verify_ssl = False ,
171+ )
172+
173+
174+ @pytest .fixture ()
175+ def greenmail_smtps_client (greenmail_smtps_server ) -> EmailClient :
176+ """EmailClient wired to GreenMail SMTPS (Implicit TLS)."""
177+ return EmailClient (greenmail_smtps_server , sender = GREENMAIL_USER )
178+
179+
180+ @pytest .fixture ()
181+ def greenmail_imaps_client (greenmail_imaps_server ) -> EmailClient :
182+ """EmailClient wired to GreenMail IMAPS (Implicit TLS)."""
183+ return EmailClient (greenmail_imaps_server , sender = GREENMAIL_USER )
184+
185+
186+ # Note: GreenMail does not support STARTTLS on plaintext ports.
187+ # See https://github.com/greenmail-mail-test/greenmail/issues/135
188+ # STARTTLS is tested at Tier 1 (SMTP via aiosmtpd) and unit tests (IMAP).
189+
190+
191+ # ---------------------------------------------------------------------------
192+ # STARTTLS fixtures (upgrade on plaintext ports)
193+ # TODO(greenmail#135): GreenMail does not advertise STARTTLS on plaintext ports.
194+ # These fixtures are kept for when GreenMail adds STARTTLS support.
195+ # See: https://github.com/greenmail-mail-test/greenmail/issues/135
196+ # ---------------------------------------------------------------------------
197+
198+
199+ @pytest .fixture ()
200+ def greenmail_smtp_starttls_server (greenmail ) -> EmailServer :
201+ """EmailServer config for GreenMail SMTP with STARTTLS."""
202+ return EmailServer (
203+ host = greenmail ["smtp_host" ],
204+ port = greenmail ["smtp_port" ],
205+ user_name = greenmail ["user" ],
206+ password = greenmail ["password" ],
207+ security = ConnectionSecurity .STARTTLS ,
208+ verify_ssl = False ,
209+ )
210+
211+
212+ @pytest .fixture ()
213+ def greenmail_imap_starttls_server (greenmail ) -> EmailServer :
214+ """EmailServer config for GreenMail IMAP with STARTTLS."""
215+ return EmailServer (
216+ host = greenmail ["imap_host" ],
217+ port = greenmail ["imap_port" ],
218+ user_name = greenmail ["user" ],
219+ password = greenmail ["password" ],
220+ security = ConnectionSecurity .STARTTLS ,
221+ verify_ssl = False ,
222+ )
223+
224+
225+ @pytest .fixture ()
226+ def greenmail_smtp_starttls_client (greenmail_smtp_starttls_server ) -> EmailClient :
227+ """EmailClient wired to GreenMail SMTP with STARTTLS."""
228+ return EmailClient (greenmail_smtp_starttls_server , sender = GREENMAIL_USER )
229+
230+
231+ @pytest .fixture ()
232+ def greenmail_imap_starttls_client (greenmail_imap_starttls_server ) -> EmailClient :
233+ """EmailClient wired to GreenMail IMAP with STARTTLS."""
234+ return EmailClient (greenmail_imap_starttls_server , sender = GREENMAIL_USER )
0 commit comments