-
-
Notifications
You must be signed in to change notification settings - Fork 21
feat(imap): mailbox commands #218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(imap): mailbox commands #218
Conversation
| struct IMAPClientTests { | ||
| @Test(.disabled(if: Server.server.isDisabled)) func connect() async throws { | ||
| let client: IMAPClient = IMAPClient(.server) | ||
| @Test(arguments: Server.allCases(disabled: false)) func allCommands(_ server: Server) async throws { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because IMAP commands are sequential and stateful, testing on live server works as one big named integration w/ a bunch of tests in logical order
|
|
||
| @Test(.disabled(if: Server.server.password.isEmpty)) func sendToRecipient() async throws { | ||
| try await SMTPClient(.server).send(.email, to: "recipient@example.com") | ||
| @Test(arguments: Server.allCases(disabled: false)) func send(server: Server) async throws { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updating SMTP live server testing to match IMAP
| } | ||
| let promise: EventLoopPromise<T.Result> = channel.eventLoop.makePromise(of: T.Result.self) | ||
| let tag: String = tag() // Hold onto specific auto-generated tag | ||
| let tag: String = UUID().uuidString(1) // Hold onto specific auto-generated tag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing against live IMAP servers (AOL, Gmail, Fastmail, iCloud, Outlook/Hotmail), there's no advantage to traditional, custom tags (a001-a999) over shortened UUIDs, which are less work/code that we own, and way less likely to collide.
| import NIOCore | ||
| import NIOIMAPCore | ||
|
|
||
| // Avoid republishing the entire (cluttered) NIOIMAP public interface with @_exported; instead |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The NIOIMAP models, in most cases, meet our (interface) needs, but we'll use only the ones we need directly, without republishing the entire NIOIMAP module interface. In some cases, e.g., Namespace and Message, we'll tailor our own models to suit.
| import NIOCore | ||
| import NIOIMAP | ||
|
|
||
| // Generic wrapper for void-result commands that succeed or fail only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The majority of IMAP commands (1) take no arguments and (2) succeed or fail with no returned payload. In which case, directly run the NIOIMAP command.
Building on top of
IMAPCommand, PR implements following mailbox-specific commands:All commands added to
IMAPClientpublic interface and tested byIMAPClientTests.allCommands. BothIMAPandSMTPtests are refactored to support testing with multiple live email accounts concurrently, configurable. IMAP tests currently pass against AOL, Gmail and iCloud accounts; Outlook fails basic auth.Additionally, errors and logging are streamlined for usefulness, legibility:
Mailbox commands not implemented here, to be implemented later in milestone:
Close #159; close #198