mirror of
https://github.com/ProtonMail/ios-mail.git
synced 2026-05-15 09:50:39 +00:00
165 lines
5.6 KiB
Swift
165 lines
5.6 KiB
Swift
//
|
|
// Copyright (c) 2025 Proton Technologies AG
|
|
//
|
|
// This file is part of Proton Mail.
|
|
//
|
|
// Proton Mail is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Proton Mail is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Proton Mail. If not, see https://www.gnu.org/licenses/.
|
|
|
|
import Foundation
|
|
import Testing
|
|
import UIKit
|
|
import UniformTypeIdentifiers
|
|
|
|
@testable import InboxComposer
|
|
@testable import TestableShareExtension
|
|
|
|
final class DraftPrecomposerTests {
|
|
private let sut = DraftPrecomposer.self
|
|
private let draft = MockDraft.emptyMockDraft
|
|
private let fileManager = FileManager.default
|
|
private let testDir: URL
|
|
private let attachmentSourceDir: URL
|
|
private let attachmentUploadDir: URL
|
|
|
|
init() throws {
|
|
testDir = fileManager.temporaryDirectory.appending(path: UUID().uuidString, directoryHint: .isDirectory)
|
|
attachmentSourceDir = testDir.appending(path: "attachment_source", directoryHint: .isDirectory)
|
|
attachmentUploadDir = testDir.appending(path: "attachment_upload", directoryHint: .isDirectory)
|
|
|
|
for dir in [attachmentSourceDir, attachmentUploadDir] {
|
|
try fileManager.createDirectory(at: dir, withIntermediateDirectories: true)
|
|
}
|
|
|
|
draft.mockAttachmentList.attachmentUploadDirectoryURL = attachmentUploadDir
|
|
}
|
|
|
|
deinit {
|
|
try! fileManager.removeItem(at: testDir)
|
|
}
|
|
|
|
@Test
|
|
func populatingDraftWithoutAttachments() async throws {
|
|
let sharedContent = SharedContent(
|
|
subject: "A subject",
|
|
body: "Some body",
|
|
attachments: []
|
|
)
|
|
|
|
try await sut.populate(draft: draft, with: sharedContent)
|
|
|
|
#expect(draft.subject() == "A subject")
|
|
#expect(draft.body() == "Some body")
|
|
#expect(draft.mockAttachmentList.capturedAddCalls.count == 0)
|
|
}
|
|
|
|
@Test
|
|
func movesNonInlineAttachmentsToUploadDirectoryBeforeAdding() async throws {
|
|
let sourceURLs = (0..<3).map { index in
|
|
attachmentSourceDir.appending(path: "data-\(index).txt")
|
|
}
|
|
|
|
let sharedContent = SharedContent(
|
|
subject: nil,
|
|
body: nil,
|
|
attachments: try TestDataFactory.stubShortLivedData(in: sourceURLs)
|
|
)
|
|
|
|
try await sut.populate(draft: draft, with: sharedContent)
|
|
|
|
let expectedAttachmentPaths = sourceURLs.map {
|
|
attachmentUploadDir.appending(path: $0.lastPathComponent).path()
|
|
}
|
|
|
|
#expect(Set(draft.mockAttachmentList.capturedAddCalls.map(\.path)) == Set(expectedAttachmentPaths))
|
|
|
|
for path in expectedAttachmentPaths {
|
|
#expect(FileManager.default.fileExists(atPath: path))
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func insertsInlineAttachmentReferencesInBody() async throws {
|
|
let sourceURLs = (0..<3).map { index in
|
|
attachmentSourceDir.appending(path: "image-\(index).png")
|
|
}
|
|
|
|
let sharedContent = SharedContent(
|
|
subject: nil,
|
|
body: "Some body",
|
|
attachments: try TestDataFactory.stubImages(in: sourceURLs)
|
|
)
|
|
|
|
try await sut.populate(draft: draft, with: sharedContent)
|
|
|
|
let expectedBody = """
|
|
Some body<img src="cid:12345" style="max-width: 100%;"><br><img src="cid:12345" style="max-width: 100%;"><br><img src="cid:12345" style="max-width: 100%;"><br>
|
|
"""
|
|
#expect(draft.body() == expectedBody)
|
|
|
|
let expectedAttachmentPaths = sourceURLs.map {
|
|
attachmentUploadDir.appending(path: $0.lastPathComponent).path()
|
|
}
|
|
|
|
#expect(Set(draft.mockAttachmentList.capturedAddInlineCalls.map(\.path)) == Set(expectedAttachmentPaths))
|
|
}
|
|
|
|
@Test
|
|
func extractsImagesFromScreenshotPlists() async throws {
|
|
let sourceURLs = (0..<3).map { index in
|
|
attachmentSourceDir.appending(path: "image-\(index).png")
|
|
}
|
|
|
|
let sharedContent = SharedContent(
|
|
subject: nil,
|
|
body: "Some body",
|
|
attachments: try TestDataFactory.stubScreenshots(in: sourceURLs)
|
|
)
|
|
|
|
try await sut.populate(draft: draft, with: sharedContent)
|
|
|
|
let expectedBody = """
|
|
Some body<img src="cid:12345" style="max-width: 100%;"><br><img src="cid:12345" style="max-width: 100%;"><br><img src="cid:12345" style="max-width: 100%;"><br>
|
|
"""
|
|
#expect(draft.body() == expectedBody)
|
|
|
|
let expectedAttachmentPaths = sourceURLs.map {
|
|
attachmentUploadDir.appending(path: $0.lastPathComponent)
|
|
}
|
|
|
|
#expect(expectedAttachmentPaths.count == 3)
|
|
|
|
for url in expectedAttachmentPaths {
|
|
let data = try Data(contentsOf: url)
|
|
#expect(UIImage(data: data) != nil)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func handlesAttachmentLoadingFailures() async throws {
|
|
let sharedContent = SharedContent(
|
|
subject: nil,
|
|
body: "Some body",
|
|
attachments: [TestDataFactory.stubError()]
|
|
)
|
|
|
|
await #expect(throws: NSError.self) {
|
|
try await self.sut.populate(draft: self.draft, with: sharedContent)
|
|
}
|
|
|
|
#expect(draft.body() == .empty)
|
|
#expect(draft.mockAttachmentList.capturedAddCalls.count == 0)
|
|
#expect(draft.mockAttachmentList.capturedAddInlineCalls.count == 0)
|
|
}
|
|
}
|