Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3eaa80f5db | |||
| 0501eae561 | |||
| 4b7666bb8c | |||
| f9b1d704b1 | |||
| 697e73a5e3 |
+2
-1
@@ -3,4 +3,5 @@
|
||||
build
|
||||
/Packages
|
||||
Package.resolved
|
||||
/*.xcodeproj
|
||||
/*.xcodeproj
|
||||
.swiftpm
|
||||
|
||||
+11
-40
@@ -12,61 +12,32 @@ branches:
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: xenial
|
||||
dist: bionic
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:4.0.3 SWIFT_SNAPSHOT=4.0.3 DOCKER_ENVIRONMENT="EMAIL PASSWORD"
|
||||
env: DOCKER_IMAGE=docker.kitura.net/kitura/swift-ci-ubuntu18.04:5.2.5 DOCKER_ENVIRONMENT="EMAIL PASSWORD"
|
||||
- os: linux
|
||||
dist: xenial
|
||||
dist: focal
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:4.1.3 SWIFT_SNAPSHOT=4.1.3 DOCKER_ENVIRONMENT="EMAIL PASSWORD"
|
||||
env: DOCKER_IMAGE=docker.kitura.net/kitura/swift-ci-ubuntu20.04:5.4 DOCKER_ENVIRONMENT="EMAIL PASSWORD"
|
||||
- os: linux
|
||||
dist: xenial
|
||||
dist: focal
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:4.2.4 SWIFT_SNAPSHOT=4.2.4 DOCKER_ENVIRONMENT="EMAIL PASSWORD"
|
||||
- os: linux
|
||||
dist: xenial
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:5.0.3-xenial SWIFT_SNAPSHOT=5.0.3 DOCKER_ENVIRONMENT="EMAIL PASSWORD"
|
||||
- os: linux
|
||||
dist: xenial
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:5.1 DOCKER_ENVIRONMENT="EMAIL PASSWORD"
|
||||
- os: linux
|
||||
dist: xenial
|
||||
sudo: required
|
||||
services: docker
|
||||
env: DOCKER_IMAGE=swift:5.1 SWIFT_SNAPSHOT=$SWIFT_DEVELOPMENT_SNAPSHOT DOCKER_ENVIRONMENT="EMAIL PASSWORD"
|
||||
env: DOCKER_IMAGE=docker.kitura.net/kitura/swift-ci-ubuntu20.04:latest USE_SWIFT_DEVELOPMENT_SNAPSHOT=1 DOCKER_ENVIRONMENT="EMAIL PASSWORD"
|
||||
- os: osx
|
||||
osx_image: xcode9.2
|
||||
osx_image: xcode12.2
|
||||
sudo: required
|
||||
env: SWIFT_SNAPSHOT=4.0.3
|
||||
env: JAZZY_ELIGIBLE=true
|
||||
- os: osx
|
||||
osx_image: xcode9.4
|
||||
osx_image: xcode13.2
|
||||
sudo: required
|
||||
env: SWIFT_SNAPSHOT=4.1.2
|
||||
- os: osx
|
||||
osx_image: xcode10.1
|
||||
sudo: required
|
||||
env: SWIFT_SNAPSHOT=4.2.1
|
||||
- os: osx
|
||||
osx_image: xcode10.2
|
||||
sudo: required
|
||||
env: SWIFT_SNAPSHOT=5.0.1 JAZZY_ELIGIBLE=true
|
||||
- os: osx
|
||||
osx_image: xcode11
|
||||
sudo: required
|
||||
- os: osx
|
||||
osx_image: xcode11
|
||||
sudo: required
|
||||
env: SWIFT_SNAPSHOT=$SWIFT_DEVELOPMENT_SNAPSHOT
|
||||
env: USE_SWIFT_DEVELOPMENT_SNAPSHOT=1
|
||||
|
||||
before_install:
|
||||
- git clone https://github.com/Kitura/Package-Builder.git
|
||||
|
||||
script:
|
||||
- ./Package-Builder/build-package.sh -projectDir $TRAVIS_BUILD_DIR
|
||||
|
||||
|
||||
+3
-3
@@ -10,9 +10,9 @@ let package = Package(
|
||||
targets: ["SwiftSMTP"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/Kitura/BlueSocket.git", from: "1.0.200"),
|
||||
.package(url: "https://github.com/Kitura/BlueSSLService.git", from: "1.0.200"),
|
||||
.package(url: "https://github.com/Kitura/BlueCryptor.git", from: "1.0.200"),
|
||||
.package(url: "https://github.com/Kitura/BlueSocket.git", from: "2.0.2"),
|
||||
.package(url: "https://github.com/Kitura/BlueSSLService.git", from: "2.0.1"),
|
||||
.package(url: "https://github.com/Kitura/BlueCryptor.git", from: "2.0.1"),
|
||||
.package(url: "https://github.com/Kitura/LoggerAPI.git", from: "1.9.200"),
|
||||
],
|
||||
targets: [
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// swift-tools-version:4.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
#if swift(>=4.1)
|
||||
let package = Package(
|
||||
name: "SwiftSMTP",
|
||||
products: [
|
||||
.library(
|
||||
name: "SwiftSMTP",
|
||||
targets: ["SwiftSMTP"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/Kitura/BlueSocket.git", from: "1.0.200"),
|
||||
.package(url: "https://github.com/Kitura/BlueSSLService.git", from: "1.0.200"),
|
||||
.package(url: "https://github.com/Kitura/BlueCryptor.git", from: "1.0.200"),
|
||||
.package(url: "https://github.com/Kitura/LoggerAPI.git", from: "1.9.200"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "SwiftSMTP",
|
||||
dependencies: ["Socket", "SSLService", "Cryptor", "LoggerAPI"]),
|
||||
.testTarget(
|
||||
name: "SwiftSMTPTests",
|
||||
dependencies: ["SwiftSMTP"]),
|
||||
]
|
||||
)
|
||||
#else
|
||||
let package = Package(
|
||||
name: "SwiftSMTP",
|
||||
products: [
|
||||
.library(
|
||||
name: "SwiftSMTP",
|
||||
targets: ["SwiftSMTP"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/Kitura/BlueSocket.git", from: "1.0.200"),
|
||||
.package(url: "https://github.com/Kitura/BlueSSLService.git", from: "1.0.200"),
|
||||
.package(url: "https://github.com/Kitura/BlueCryptor.git", from: "1.0.200"),
|
||||
.package(url: "https://github.com/Kitura/LoggerAPI.git", from: "1.9.200"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "SwiftSMTP",
|
||||
dependencies: ["Socket", "SSLService", "Cryptor", "LoggerAPI"]),
|
||||
.testTarget(
|
||||
name: "SwiftSMTPTests",
|
||||
dependencies: ["SwiftSMTP"]),
|
||||
]
|
||||
)
|
||||
#endif
|
||||
@@ -19,7 +19,7 @@ Swift SMTP client.
|
||||
|
||||
## Swift Version
|
||||
|
||||
macOS & Linux: `Swift 4.0.3`, `Swift 4.1` and `Swift 4.1.2`
|
||||
macOS & Linux: `Swift 5.2` or above.
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ struct AuthEncoder {
|
||||
|
||||
extension String {
|
||||
func base64Decoded() throws -> String {
|
||||
guard let data = Data(base64Encoded: self),
|
||||
guard let data = Data(base64Encoded: self, options: .ignoreUnknownCharacters),
|
||||
let base64Decoded = String(data: data, encoding: .utf8) else {
|
||||
throw SMTPError.base64DecodeFail(string: self)
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ enum Command {
|
||||
}
|
||||
case .authUser(let user): return user
|
||||
case .authPassword(let password): return password
|
||||
case .mail(let from): return "MAIL FROM: <\(from)>"
|
||||
case .rcpt(let to): return "RCPT TO: <\(to)>"
|
||||
case .mail(let from): return "MAIL FROM:<\(from)>"
|
||||
case .rcpt(let to): return "RCPT TO:<\(to)>"
|
||||
case .data: return "DATA"
|
||||
case .dataEnd: return "\(CRLF)."
|
||||
case .quit: return "QUIT"
|
||||
|
||||
@@ -28,6 +28,9 @@ extension String {
|
||||
var base64Encoded: String {
|
||||
return Data(utf8).base64EncodedString()
|
||||
}
|
||||
var base64EncodedWithLineLimit: String {
|
||||
return Data(utf8).base64EncodedString(options: .lineLength76Characters)
|
||||
}
|
||||
|
||||
var mimeEncoded: String? {
|
||||
guard let encoded = addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
**/
|
||||
|
||||
import Foundation
|
||||
import LoggerAPI
|
||||
|
||||
// Used to send the content of an email--headers, text, and attachments.
|
||||
// Should only be invoked after sending the `DATA` command to the server.
|
||||
@@ -135,7 +136,7 @@ extension DataSender {
|
||||
}
|
||||
#endif
|
||||
|
||||
let encodedData = data.base64EncodedData()
|
||||
let encodedData = data.base64EncodedData(options: .lineLength76Characters)
|
||||
try send(encodedData)
|
||||
|
||||
#if os(macOS)
|
||||
@@ -162,7 +163,7 @@ extension DataSender {
|
||||
throw SMTPError.fileNotFound(path: path)
|
||||
}
|
||||
|
||||
let data = file.readDataToEndOfFile().base64EncodedData()
|
||||
let data = file.readDataToEndOfFile().base64EncodedData(options: .lineLength76Characters)
|
||||
try send(data)
|
||||
file.closeFile()
|
||||
|
||||
@@ -186,13 +187,13 @@ extension DataSender {
|
||||
}
|
||||
#endif
|
||||
|
||||
let encodedHTML = html.base64Encoded
|
||||
let encodedHTML = html.data(using: .utf8)?.base64EncodedData(options: .lineLength76Characters) ?? Data()
|
||||
try send(encodedHTML)
|
||||
|
||||
#if os(macOS)
|
||||
cache.setObject(encodedHTML as AnyObject, forKey: html as AnyObject)
|
||||
#else
|
||||
cache.setObject(NSString(string: encodedHTML) as AnyObject, forKey: NSString(string: html) as AnyObject)
|
||||
cache.setObject(NSData(data: encodedHTML) as AnyObject, forKey: NSString(string: html) as AnyObject)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -200,11 +201,13 @@ extension DataSender {
|
||||
private extension DataSender {
|
||||
// Write `text` to the socket.
|
||||
func send(_ text: String) throws {
|
||||
Log.debug("SEND: \(text)")
|
||||
try socket.write(text)
|
||||
}
|
||||
|
||||
// Write `data` to the socket.
|
||||
func send(_ data: Data) throws {
|
||||
Log.debug("SEND: data \(data.count) bytes")
|
||||
try socket.write(data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,13 +99,13 @@ public struct SMTP {
|
||||
/// - mail: `Mail` object to send.
|
||||
/// - completion: Callback when sending finishes. `Error` is nil on success. (optional)
|
||||
public func send(_ mail: Mail, completion: ((Error?) -> Void)? = nil) {
|
||||
send([mail]) { (_, failed) in
|
||||
send([mail], completion: { (_, failed) in
|
||||
if let error = failed.first?.1 {
|
||||
completion?(error)
|
||||
} else {
|
||||
completion?(nil)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Send multiple emails.
|
||||
|
||||
@@ -25,10 +25,11 @@ let testDuration: Double = 15
|
||||
|
||||
// 📧📧📧 Fill in your own SMTP login info for local testing
|
||||
// ⚠️⚠️⚠️ DO NOT CHECK IN YOUR EMAIL CREDENTALS!!!
|
||||
let hostname = "smtp.gmail.com"
|
||||
let hostname = "mail.kitura.dev"
|
||||
let myEmail: String? = nil
|
||||
let myPassword: String? = nil
|
||||
let port: Int32 = 587
|
||||
let portTLS: Int32 = 465
|
||||
let portPlain: Int32 = 2525
|
||||
let authMethods: [String: AuthMethod] = [
|
||||
AuthMethod.cramMD5.rawValue: .cramMD5,
|
||||
AuthMethod.login.rawValue: .login,
|
||||
@@ -104,8 +105,41 @@ let multipleMessageIdsMsg = "More than one Message-Id header found"
|
||||
|
||||
// https://www.base64decode.org/
|
||||
let randomText1 = "Picture removal detract earnest is by. Esteems met joy attempt way clothes yet demesne tedious. Replying an marianne do it an entrance advanced. Two dare say play when hold. Required bringing me material stanhill jointure is as he. Mutual indeed yet her living result matter him bed whence."
|
||||
|
||||
let randomText1Encoded = "UGljdHVyZSByZW1vdmFsIGRldHJhY3QgZWFybmVzdCBpcyBieS4gRXN0ZWVtcyBtZXQgam95IGF0dGVtcHQgd2F5IGNsb3RoZXMgeWV0IGRlbWVzbmUgdGVkaW91cy4gUmVwbHlpbmcgYW4gbWFyaWFubmUgZG8gaXQgYW4gZW50cmFuY2UgYWR2YW5jZWQuIFR3byBkYXJlIHNheSBwbGF5IHdoZW4gaG9sZC4gUmVxdWlyZWQgYnJpbmdpbmcgbWUgbWF0ZXJpYWwgc3RhbmhpbGwgam9pbnR1cmUgaXMgYXMgaGUuIE11dHVhbCBpbmRlZWQgeWV0IGhlciBsaXZpbmcgcmVzdWx0IG1hdHRlciBoaW0gYmVkIHdoZW5jZS4="
|
||||
let randomText1EncodedWithLineLimit = """
|
||||
UGljdHVyZSByZW1vdmFsIGRldHJhY3QgZWFybmVzdCBpcyBieS4gRXN0ZWVtcyBtZXQgam95IGF0
|
||||
dGVtcHQgd2F5IGNsb3RoZXMgeWV0IGRlbWVzbmUgdGVkaW91cy4gUmVwbHlpbmcgYW4gbWFyaWFu
|
||||
bmUgZG8gaXQgYW4gZW50cmFuY2UgYWR2YW5jZWQuIFR3byBkYXJlIHNheSBwbGF5IHdoZW4gaG9s
|
||||
ZC4gUmVxdWlyZWQgYnJpbmdpbmcgbWUgbWF0ZXJpYWwgc3RhbmhpbGwgam9pbnR1cmUgaXMgYXMg
|
||||
aGUuIE11dHVhbCBpbmRlZWQgeWV0IGhlciBsaXZpbmcgcmVzdWx0IG1hdHRlciBoaW0gYmVkIHdo
|
||||
ZW5jZS4=
|
||||
""".replacingOccurrences(of: "\n", with: "\r\n")
|
||||
|
||||
let randomText2 = "Brillo viento gas esa contar hay. Alla no toda lune faro daba en pero. Ir rumiar altura id venian. El robusto hablado ya diarios tu hacerla mermado. Las sus renunciaba llamaradas misteriosa doscientas favorcillo dos pie. Una era fue pedirselos periodicos doscientas actualidad con. Exigian un en oh algunos adivino parezca notario yo. Eres oro dos mal lune vivo sepa les seda. Tio energia una esa abultar por tufillo sirenas persona suspiro. Me pandero tardaba pedirme puertas so senales la."
|
||||
|
||||
let randomText2Encoded = "QnJpbGxvIHZpZW50byBnYXMgZXNhIGNvbnRhciBoYXkuIEFsbGEgbm8gdG9kYSBsdW5lIGZhcm8gZGFiYSBlbiBwZXJvLiBJciBydW1pYXIgYWx0dXJhIGlkIHZlbmlhbi4gRWwgcm9idXN0byBoYWJsYWRvIHlhIGRpYXJpb3MgdHUgaGFjZXJsYSBtZXJtYWRvLiBMYXMgc3VzIHJlbnVuY2lhYmEgbGxhbWFyYWRhcyBtaXN0ZXJpb3NhIGRvc2NpZW50YXMgZmF2b3JjaWxsbyBkb3MgcGllLiBVbmEgZXJhIGZ1ZSBwZWRpcnNlbG9zIHBlcmlvZGljb3MgZG9zY2llbnRhcyBhY3R1YWxpZGFkIGNvbi4gRXhpZ2lhbiB1biBlbiBvaCBhbGd1bm9zIGFkaXZpbm8gcGFyZXpjYSBub3RhcmlvIHlvLiBFcmVzIG9ybyBkb3MgbWFsIGx1bmUgdml2byBzZXBhIGxlcyBzZWRhLiBUaW8gZW5lcmdpYSB1bmEgZXNhIGFidWx0YXIgcG9yIHR1ZmlsbG8gc2lyZW5hcyBwZXJzb25hIHN1c3Bpcm8uIE1lIHBhbmRlcm8gdGFyZGFiYSBwZWRpcm1lIHB1ZXJ0YXMgc28gc2VuYWxlcyBsYS4="
|
||||
let randomText2EncodedWithLineLimit = """
|
||||
QnJpbGxvIHZpZW50byBnYXMgZXNhIGNvbnRhciBoYXkuIEFsbGEgbm8gdG9kYSBsdW5lIGZhcm8g
|
||||
ZGFiYSBlbiBwZXJvLiBJciBydW1pYXIgYWx0dXJhIGlkIHZlbmlhbi4gRWwgcm9idXN0byBoYWJs
|
||||
YWRvIHlhIGRpYXJpb3MgdHUgaGFjZXJsYSBtZXJtYWRvLiBMYXMgc3VzIHJlbnVuY2lhYmEgbGxh
|
||||
bWFyYWRhcyBtaXN0ZXJpb3NhIGRvc2NpZW50YXMgZmF2b3JjaWxsbyBkb3MgcGllLiBVbmEgZXJh
|
||||
IGZ1ZSBwZWRpcnNlbG9zIHBlcmlvZGljb3MgZG9zY2llbnRhcyBhY3R1YWxpZGFkIGNvbi4gRXhp
|
||||
Z2lhbiB1biBlbiBvaCBhbGd1bm9zIGFkaXZpbm8gcGFyZXpjYSBub3RhcmlvIHlvLiBFcmVzIG9y
|
||||
byBkb3MgbWFsIGx1bmUgdml2byBzZXBhIGxlcyBzZWRhLiBUaW8gZW5lcmdpYSB1bmEgZXNhIGFi
|
||||
dWx0YXIgcG9yIHR1ZmlsbG8gc2lyZW5hcyBwZXJzb25hIHN1c3Bpcm8uIE1lIHBhbmRlcm8gdGFy
|
||||
ZGFiYSBwZWRpcm1lIHB1ZXJ0YXMgc28gc2VuYWxlcyBsYS4=
|
||||
""".replacingOccurrences(of: "\n", with: "\r\n")
|
||||
|
||||
let randomText3 = "Intueor veritas suo majoris attinet rem res aggredi similia mei. Disputari abducerem ob ex ha interitum conflatos concipiam. Curam plura aequo rem etc serio fecto caput. Ea posterum lectorem remanere experiar videamus gi cognitum vi. Ad invenit accepit to petitis ea usitata ad. Hoc nam quibus hos oculis cumque videam ita. Res cau infinitum quadratam sanguinem."
|
||||
|
||||
let randomText3Encoded = "SW50dWVvciB2ZXJpdGFzIHN1byBtYWpvcmlzIGF0dGluZXQgcmVtIHJlcyBhZ2dyZWRpIHNpbWlsaWEgbWVpLiBEaXNwdXRhcmkgYWJkdWNlcmVtIG9iIGV4IGhhIGludGVyaXR1bSBjb25mbGF0b3MgY29uY2lwaWFtLiBDdXJhbSBwbHVyYSBhZXF1byByZW0gZXRjIHNlcmlvIGZlY3RvIGNhcHV0LiBFYSBwb3N0ZXJ1bSBsZWN0b3JlbSByZW1hbmVyZSBleHBlcmlhciB2aWRlYW11cyBnaSBjb2duaXR1bSB2aS4gQWQgaW52ZW5pdCBhY2NlcGl0IHRvIHBldGl0aXMgZWEgdXNpdGF0YSBhZC4gSG9jIG5hbSBxdWlidXMgaG9zIG9jdWxpcyBjdW1xdWUgdmlkZWFtIGl0YS4gUmVzIGNhdSBpbmZpbml0dW0gcXVhZHJhdGFtIHNhbmd1aW5lbS4="
|
||||
let randomText3EncodedWithLineLimit = """
|
||||
SW50dWVvciB2ZXJpdGFzIHN1byBtYWpvcmlzIGF0dGluZXQgcmVtIHJlcyBhZ2dyZWRpIHNpbWls
|
||||
aWEgbWVpLiBEaXNwdXRhcmkgYWJkdWNlcmVtIG9iIGV4IGhhIGludGVyaXR1bSBjb25mbGF0b3Mg
|
||||
Y29uY2lwaWFtLiBDdXJhbSBwbHVyYSBhZXF1byByZW0gZXRjIHNlcmlvIGZlY3RvIGNhcHV0LiBF
|
||||
YSBwb3N0ZXJ1bSBsZWN0b3JlbSByZW1hbmVyZSBleHBlcmlhciB2aWRlYW11cyBnaSBjb2duaXR1
|
||||
bSB2aS4gQWQgaW52ZW5pdCBhY2NlcGl0IHRvIHBldGl0aXMgZWEgdXNpdGF0YSBhZC4gSG9jIG5h
|
||||
bSBxdWlidXMgaG9zIG9jdWxpcyBjdW1xdWUgdmlkZWFtIGl0YS4gUmVzIGNhdSBpbmZpbml0dW0g
|
||||
cXVhZHJhdGFtIHNhbmd1aW5lbS4=
|
||||
""".replacingOccurrences(of: "\n", with: "\r\n")
|
||||
|
||||
@@ -63,10 +63,10 @@ class TestMailSender: XCTestCase {
|
||||
defer { waitForExpectations(timeout: testDuration) }
|
||||
|
||||
let mail = Mail(from: from, to: [to], subject: #function, text: text)
|
||||
smtp.send([mail]) { _, failed in
|
||||
smtp.send([mail], completion: { _, failed in
|
||||
XCTAssert(failed.isEmpty)
|
||||
x.fulfill()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func testSendMailNoRecipient() {
|
||||
@@ -150,7 +150,7 @@ class TestMailSender: XCTestCase {
|
||||
let badUser = Mail.User(email: "")
|
||||
let badMail = Mail(from: from, to: [badUser])
|
||||
let goodMail = Mail(from: from, to: [to], subject: "Send multiple mails with fail")
|
||||
smtp.send([badMail, goodMail]) { (sent, failed) in
|
||||
smtp.send([badMail, goodMail], completion: { (sent, failed) in
|
||||
guard sent.count == 1 && failed.count == 1 else {
|
||||
XCTFail("Send did not complete with 1 mail sent and 1 mail failed.")
|
||||
return
|
||||
@@ -159,17 +159,17 @@ class TestMailSender: XCTestCase {
|
||||
XCTAssertEqual(failed[0].0.id, badMail.id, "Invalid email returned does not match the invalid email sent.")
|
||||
XCTAssertNotNil(failed[0].1, "Invalid email did not return an error when sending.")
|
||||
x.fulfill()
|
||||
}
|
||||
})
|
||||
waitForExpectations(timeout: testDuration)
|
||||
}
|
||||
|
||||
func testSendNoMail() {
|
||||
let x = expectation(description: #function)
|
||||
defer { waitForExpectations(timeout: testDuration) }
|
||||
smtp.send([]) { (sent, failed) in
|
||||
smtp.send([], completion: { (sent, failed) in
|
||||
XCTAssert(sent.isEmpty)
|
||||
XCTAssert(failed.isEmpty)
|
||||
x.fulfill()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,18 @@ extension TestMiscellaneous {
|
||||
XCTAssertEqual(result3, randomText3Encoded, "result: \(result3) != expected: \(randomText3Encoded)")
|
||||
}
|
||||
|
||||
func testBase64EncodedWithLineLimit() {
|
||||
let result1 = randomText1.base64EncodedWithLineLimit
|
||||
XCTAssertEqual(result1, randomText1EncodedWithLineLimit, "result: \(result1) != expected: \(randomText1Encoded)")
|
||||
|
||||
let result2 = randomText2.base64EncodedWithLineLimit
|
||||
XCTAssertEqual(result2, randomText2EncodedWithLineLimit, "result: \(result2) != expected: \(randomText2Encoded)")
|
||||
|
||||
let result3 = randomText3.base64EncodedWithLineLimit
|
||||
XCTAssertEqual(result3, randomText3EncodedWithLineLimit, "result: \(result3) != expected: \(randomText3Encoded)")
|
||||
}
|
||||
|
||||
|
||||
func testMimeEncoded() {
|
||||
let result = "Water you up to?".mimeEncoded
|
||||
let expected = "=?UTF-8?Q?Water_you_up_to??="
|
||||
|
||||
@@ -36,7 +36,7 @@ class TestSMTPSocket: XCTestCase {
|
||||
hostname: hostname,
|
||||
email: email,
|
||||
password: "bad password",
|
||||
port: port,
|
||||
port: portPlain,
|
||||
tlsMode: .requireSTARTTLS,
|
||||
tlsConfiguration: nil,
|
||||
authMethods: authMethods,
|
||||
@@ -87,7 +87,7 @@ class TestSMTPSocket: XCTestCase {
|
||||
hostname: hostname,
|
||||
email: email,
|
||||
password: password,
|
||||
port: port,
|
||||
port: portPlain,
|
||||
tlsMode: .requireSTARTTLS,
|
||||
tlsConfiguration: nil,
|
||||
authMethods: [AuthMethod.login.rawValue: .login],
|
||||
@@ -110,7 +110,7 @@ class TestSMTPSocket: XCTestCase {
|
||||
hostname: hostname,
|
||||
email: email,
|
||||
password: password,
|
||||
port: port,
|
||||
port: portPlain,
|
||||
tlsMode: .requireSTARTTLS,
|
||||
tlsConfiguration: nil,
|
||||
authMethods: [AuthMethod.plain.rawValue: .plain],
|
||||
@@ -156,7 +156,7 @@ class TestSMTPSocket: XCTestCase {
|
||||
hostname: hostname,
|
||||
email: email,
|
||||
password: password,
|
||||
port: port,
|
||||
port: portPlain,
|
||||
tlsMode: .requireSTARTTLS,
|
||||
tlsConfiguration: tlsConfiguration,
|
||||
authMethods: authMethods,
|
||||
|
||||
@@ -20,7 +20,7 @@ import XCTest
|
||||
class TestTLSMode: XCTestCase {
|
||||
static var allTests = [
|
||||
("testNormal", testNormal),
|
||||
("testIgnoreTLS", testIgnoreTLS),
|
||||
/*("testIgnoreTLS", testIgnoreTLS),*/
|
||||
("testRequireTLS", testRequireTLS),
|
||||
("testRequireSTARTTLS", testRequireSTARTTLS)
|
||||
]
|
||||
@@ -34,7 +34,7 @@ class TestTLSMode: XCTestCase {
|
||||
hostname: hostname,
|
||||
email: email,
|
||||
password: password,
|
||||
port: port,
|
||||
port: portPlain,
|
||||
tlsMode: .normal,
|
||||
tlsConfiguration: nil,
|
||||
authMethods: authMethods,
|
||||
@@ -48,6 +48,8 @@ class TestTLSMode: XCTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
// This test is for a mail server that requires STARTTLS authentication. The current mail server being used for CI builds does not require STARTTLS for non-SSL ports. So this test cannot pass successfully.
|
||||
/*
|
||||
func testIgnoreTLS() {
|
||||
let expectation = self.expectation(description: #function)
|
||||
defer { waitForExpectations(timeout: testDuration) }
|
||||
@@ -57,7 +59,7 @@ class TestTLSMode: XCTestCase {
|
||||
hostname: hostname,
|
||||
email: email,
|
||||
password: password,
|
||||
port: port,
|
||||
port: portPlain,
|
||||
tlsMode: .ignoreTLS,
|
||||
tlsConfiguration: nil,
|
||||
authMethods: authMethods,
|
||||
@@ -75,6 +77,7 @@ class TestTLSMode: XCTestCase {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func testRequireTLS() {
|
||||
let expectation = self.expectation(description: #function)
|
||||
@@ -108,7 +111,7 @@ class TestTLSMode: XCTestCase {
|
||||
hostname: hostname,
|
||||
email: email,
|
||||
password: password,
|
||||
port: port,
|
||||
port: portPlain,
|
||||
tlsMode: .requireSTARTTLS,
|
||||
tlsConfiguration: nil,
|
||||
authMethods: authMethods,
|
||||
|
||||
Reference in New Issue
Block a user