IOS-471 adapts MessageModel - cleaner ImapFlags and ImapFields IOS-471-deleted-messages-disappear
authorbuff <andreas@pep-project.org>
Mon, 21 Aug 2017 16:04:50 +0200
branchIOS-471-deleted-messages-disappear
changeset 28048f0caacaa004
parent 2803 fffe1849953d
child 2805 f7525b13f5b8
IOS-471 adapts MessageModel - cleaner ImapFlags and ImapFields
pEpForiOS/Background/DecryptMessagesOperation.swift
pEpForiOS/Background/TrashMailsOperation.swift
pEpForiOS/Models/CdMessage+Extension.swift
pEpForiOS/UI/EmailDisplay/EmailListViewController.swift
pEpForiOS/UI/EmailDisplay/EmailViewController.swift
pEpForiOSTests/Background/TrashMailsOperationTest.swift
     1.1 --- a/pEpForiOS/Background/DecryptMessagesOperation.swift	Mon Aug 21 14:44:25 2017 +0200
     1.2 +++ b/pEpForiOS/Background/DecryptMessagesOperation.swift	Mon Aug 21 16:04:50 2017 +0200
     1.3 @@ -28,9 +28,11 @@
     1.4                  var outgoing = false
     1.5                  if let folderType = message.parent?.folderType {
     1.6                      outgoing = folderType.isOutgoing()
     1.7 -                } else {
     1.8 -                    outgoing = false
     1.9                  }
    1.10 +                //BUFF: cleanup
    1.11 +//                else {
    1.12 +//                    outgoing = false
    1.13 +//                }
    1.14  
    1.15                  let pepMessage = PEPUtil.pEp(cdMessage: message, outgoing: outgoing)
    1.16                  var pepDecryptedMessage: NSDictionary? = nil
    1.17 @@ -40,7 +42,7 @@
    1.18                  let color = session.decryptMessageDict(
    1.19                      pepMessage, dest: &pepDecryptedMessage, keys: &keys)
    1.20                  Log.info(component: self.comp,
    1.21 -                         content: "Decrypted message \(message.logString()) with color \(color)")
    1.22 +                         content: "Decrypted message \(message.logString()) with color \(color)") //BUFF: endless loop ??
    1.23  
    1.24                  self.numberOfMessagesDecrypted += 1
    1.25                  let theKeys = Array(keys ?? NSArray()) as? [String] ?? []
    1.26 @@ -67,10 +69,19 @@
    1.27                       PEP_rating_trusted,
    1.28                       PEP_rating_trusted_and_anonymized,
    1.29                       PEP_rating_fully_anonymous:
    1.30 -                    if let decrypted = pepDecryptedMessage {
    1.31 -                        message.update(pEpMessage: decrypted as! PEPMessage, pepColorRating: color)
    1.32 +                    //BUFF:
    1.33 +//                    if let decrypted = pepDecryptedMessage {
    1.34 +//                        message.update(pEpMessage: decrypted as! PEPMessage, pepColorRating: color)
    1.35 +//                        self.updateMessage(cdMessage: message, keys: theKeys)
    1.36 +//                    }
    1.37 +                    if let decrypted = pepDecryptedMessage as? PEPMessage {
    1.38 +                        message.update(pEpMessage: decrypted, pepColorRating: color)
    1.39                          self.updateMessage(cdMessage: message, keys: theKeys)
    1.40 +                    } else {
    1.41 +                        Log.shared.errorAndCrash(component: #function,
    1.42 +                                                 errorString:"Not sure if this is supposed to happen even I think it's not. If it is, remove the else block or lower the log ")
    1.43                      }
    1.44 +                    //FFUB
    1.45                      break
    1.46                  default:
    1.47                      Log.warn(
     2.1 --- a/pEpForiOS/Background/TrashMailsOperation.swift	Mon Aug 21 14:44:25 2017 +0200
     2.2 +++ b/pEpForiOS/Background/TrashMailsOperation.swift	Mon Aug 21 16:04:50 2017 +0200
     2.3 @@ -33,7 +33,7 @@
     2.4              }
     2.5              let p = NSPredicate(
     2.6                  format: "parent = %@ and imap.localFlags.flagDeleted = true and imap.trashedStatusRawValue = %d",
     2.7 -                folder, TrashedStatus.shouldBeTrashed.rawValue)
     2.8 +                folder, Message.TrashedStatus.shouldBeTrashed.rawValue)
     2.9              if let msg = CdMessage.first(predicate: p, in: self.context),
    2.10                  let cdIdent = msg.parent?.account?.identity {
    2.11                  result = (msg.pEpMessage(), cdIdent.pEpIdentity(), msg.objectID)
    2.12 @@ -55,7 +55,7 @@
    2.13              context.performAndWait {
    2.14                  if let obj = self.context.object(with: msgID) as? CdMessage {
    2.15                      let imap = obj.imapFields(context: self.context)
    2.16 -                    imap.trashedStatus = TrashedStatus.trashed
    2.17 +                    imap.trashedStatus = Message.TrashedStatus.trashed
    2.18                      obj.imap = imap
    2.19                      self.context.saveAndLogErrors()
    2.20                  } else {
    2.21 @@ -74,7 +74,7 @@
    2.22      static func foldersWithTrashedMessages(context: NSManagedObjectContext) -> [CdFolder] {
    2.23          let p = NSPredicate(
    2.24              format: "imap.localFlags.flagDeleted = true and imap.trashedStatusRawValue = %d",
    2.25 -            TrashedStatus.shouldBeTrashed.rawValue)
    2.26 +            Message.TrashedStatus.shouldBeTrashed.rawValue)
    2.27          let msgs = CdMessage.all(predicate: p, orderedBy: nil, in: context) as? [CdMessage] ?? []
    2.28          var folders = Set<CdFolder>()
    2.29          for m in msgs {
     3.1 --- a/pEpForiOS/Models/CdMessage+Extension.swift	Mon Aug 21 14:44:25 2017 +0200
     3.2 +++ b/pEpForiOS/Models/CdMessage+Extension.swift	Mon Aug 21 16:04:50 2017 +0200
     3.3 @@ -11,6 +11,7 @@
     3.4  import MessageModel
     3.5  
     3.6  extension CdMessage {
     3.7 +
     3.8      public func allRecipienst() -> NSOrderedSet {
     3.9          let recipients: NSMutableOrderedSet = []
    3.10          recipients.addObjects(from: (to?.array)!)
     4.1 --- a/pEpForiOS/UI/EmailDisplay/EmailListViewController.swift	Mon Aug 21 14:44:25 2017 +0200
     4.2 +++ b/pEpForiOS/UI/EmailDisplay/EmailListViewController.swift	Mon Aug 21 16:04:50 2017 +0200
     4.3 @@ -260,7 +260,6 @@
     4.4              }
     4.5  
     4.6              message.delete() // mark for deletion/trash
     4.7 -            message.save()
     4.8              self.tableView.reloadData()
     4.9          }
    4.10  
     5.1 --- a/pEpForiOS/UI/EmailDisplay/EmailViewController.swift	Mon Aug 21 14:44:25 2017 +0200
     5.2 +++ b/pEpForiOS/UI/EmailDisplay/EmailViewController.swift	Mon Aug 21 16:04:50 2017 +0200
     5.3 @@ -178,11 +178,12 @@
     5.4      
     5.5      @IBAction func archiveButtonTapped(_ sender: UIBarButtonItem) {
     5.6          //TODO: stubbed method
     5.7 +        Log.shared.errorAndCrash(component: #function, errorString:"Unimplemented Stub!")
     5.8      }
     5.9 -    
    5.10 +
    5.11 +    //BUFF: here
    5.12      @IBAction func deleteButtonTapped(_ sender: UIBarButtonItem) {
    5.13          message.delete() // mark for deletion/trash
    5.14 -        message.save()
    5.15          _ = navigationController?.popViewController(animated: true)
    5.16      }
    5.17      
     6.1 --- a/pEpForiOSTests/Background/TrashMailsOperationTest.swift	Mon Aug 21 14:44:25 2017 +0200
     6.2 +++ b/pEpForiOSTests/Background/TrashMailsOperationTest.swift	Mon Aug 21 16:04:50 2017 +0200
     6.3 @@ -14,7 +14,7 @@
     6.4  
     6.5  class TrashMailsOperationTest: CoreDataDrivenTestBase {
     6.6  
     6.7 -    func testTrashMessages() {
     6.8 +    func testTrashCdMessages() {
     6.9          let errorContainer = ErrorContainer()
    6.10  
    6.11          let imapLogin = LoginImapOperation(
    6.12 @@ -198,4 +198,196 @@
    6.13              XCTAssertTrue(trashed.imapFields().trashedStatus == .none)
    6.14          }
    6.15      }
    6.16 +
    6.17 +//    func testTrashMessages() {
    6.18 +//        let errorContainer = ErrorContainer()
    6.19 +//
    6.20 +//        let imapLogin = LoginImapOperation(
    6.21 +//            parentName: #function,
    6.22 +//            errorContainer: errorContainer, imapSyncData: imapSyncData)
    6.23 +//        imapLogin.completionBlock = {
    6.24 +//            imapLogin.completionBlock = nil
    6.25 +//            XCTAssertNotNil(self.imapSyncData.sync)
    6.26 +//        }
    6.27 +//
    6.28 +//        let expFoldersFetched = expectation(description: "expFoldersFetched")
    6.29 +//        let fetchFoldersOp = FetchFoldersOperation(
    6.30 +//            parentName: #function, imapSyncData: imapSyncData)
    6.31 +//        fetchFoldersOp.addDependency(imapLogin)
    6.32 +//        fetchFoldersOp.completionBlock = {
    6.33 +//            fetchFoldersOp.completionBlock = nil
    6.34 +//            expFoldersFetched.fulfill()
    6.35 +//        }
    6.36 +//
    6.37 +//        let queue = OperationQueue()
    6.38 +//        queue.addOperation(imapLogin)
    6.39 +//        queue.addOperation(fetchFoldersOp)
    6.40 +//
    6.41 +//        waitForExpectations(timeout: TestUtil.waitTime, handler: { error in
    6.42 +//            XCTAssertNil(error)
    6.43 +//            XCTAssertFalse(imapLogin.hasErrors())
    6.44 +//            XCTAssertFalse(fetchFoldersOp.hasErrors())
    6.45 +//        })
    6.46 +//
    6.47 +//        let from = CdIdentity.create()
    6.48 +//        from.userName = cdAccount.identity?.userName ?? "Unit 004"
    6.49 +//        from.address = cdAccount.identity?.address ?? "unittest.ios.4@peptest.ch"
    6.50 +//
    6.51 +//        let to = CdIdentity.create()
    6.52 +//        to.userName = "Unit 001"
    6.53 +//        to.address = "unittest.ios.1@peptest.ch"
    6.54 +//
    6.55 +//        guard let inboxFolder = CdFolder.by(folderType: .inbox, account: cdAccount) else {
    6.56 +//            XCTFail()
    6.57 +//            return
    6.58 +//        }
    6.59 +//        guard let draftsFolder = CdFolder.by(folderType: .drafts, account: cdAccount) else {
    6.60 +//            XCTFail()
    6.61 +//            return
    6.62 +//        }
    6.63 +//        guard let trashFolder = CdFolder.by(folderType: .trash, account: cdAccount) else {
    6.64 +//            XCTFail()
    6.65 +//            return
    6.66 +//        }
    6.67 +//
    6.68 +//        // Build emails
    6.69 +//        var originalMessages = [Message]()
    6.70 +//        let numMails = 3
    6.71 +//        for i in 1...numMails {
    6.72 +//            let cdMessage = CdMessage.create()
    6.73 +//            cdMessage.from = from
    6.74 +//            if i == 1 {
    6.75 +//                cdMessage.parent = draftsFolder
    6.76 +//            } else {
    6.77 +//                cdMessage.parent = inboxFolder
    6.78 +//            }
    6.79 +//            cdMessage.shortMessage = "Some subject \(i)"
    6.80 +//            cdMessage.longMessage = "Long message \(i)"
    6.81 +//            cdMessage.longMessageFormatted = "<h1>Long HTML \(i)</h1>"
    6.82 +//            cdMessage.sendStatus = SendStatus.none
    6.83 +//            cdMessage.addTo(cdIdentity: to)
    6.84 +//            let imapFields = CdImapFields.create()
    6.85 +//            let imapFlags = CdImapFlags.create()
    6.86 +//            imapFields.localFlags = imapFlags
    6.87 +//            imapFlags.flagDeleted = true
    6.88 +//            imapFields.trashedStatus = Message.TrashedStatus.none
    6.89 +//            cdMessage.imap = imapFields
    6.90 +//            guard let message =  cdMessage.message() else {
    6.91 +//                XCTFail("Not convertable?")
    6.92 +//            }
    6.93 +//            message.save()
    6.94 +//            originalMessages.append(message)
    6.95 +//
    6.96 +//        }
    6.97 +////        Record.saveAndWait()
    6.98 +//
    6.99 +//
   6.100 +//
   6.101 +//        let foldersWithTrashedMessages = TrashMailsOperation.foldersWithTrashedMessages(
   6.102 +//            context: Record.Context.default)
   6.103 +//        XCTAssertEqual(foldersWithTrashedMessages.count, 2)
   6.104 +//        if inboxFolder.name ?? "" < draftsFolder.name ?? "" {
   6.105 +//            XCTAssertEqual(foldersWithTrashedMessages[safe: 0], inboxFolder)
   6.106 +//            XCTAssertEqual(foldersWithTrashedMessages[safe: 1], draftsFolder)
   6.107 +//        } else {
   6.108 +//            XCTAssertEqual(foldersWithTrashedMessages[safe: 1], inboxFolder)
   6.109 +//            XCTAssertEqual(foldersWithTrashedMessages[safe: 0], draftsFolder)
   6.110 +//        }
   6.111 +//
   6.112 +//        if let msgs = CdMessage.all() as? [CdMessage] {
   6.113 +//            for m in msgs {
   6.114 +//                XCTAssertNotNil(m.messageID)
   6.115 +//                XCTAssertTrue(m.parent?.folderType == FolderType.inbox ||
   6.116 +//                    m.parent?.folderType == FolderType.drafts)
   6.117 +//                XCTAssertEqual(m.uid, Int32(0))
   6.118 +//                XCTAssertEqual(m.sendStatus, SendStatus.none)
   6.119 +//            }
   6.120 +//        } else {
   6.121 +//            XCTFail("No mesages?")
   6.122 +//        }
   6.123 +//
   6.124 +//        //BUFF: here:
   6.125 +//        let expTrashed = expectation(description: "expTrashed")
   6.126 +//
   6.127 +//        let trashMailsOp1 = TrashMailsOperation(
   6.128 +//            parentName: #function,
   6.129 +//            imapSyncData: imapSyncData, errorContainer: errorContainer, folder: inboxFolder)
   6.130 +//        let trashMailsOp2 = TrashMailsOperation(
   6.131 +//            parentName: #function,
   6.132 +//            imapSyncData: imapSyncData, errorContainer: errorContainer, folder: draftsFolder)
   6.133 +//        trashMailsOp2.addDependency(trashMailsOp1)
   6.134 +//        trashMailsOp2.completionBlock = {
   6.135 +//            trashMailsOp2.completionBlock = nil
   6.136 +//            expTrashed.fulfill()
   6.137 +//        }
   6.138 +//
   6.139 +//        queue.addOperation(trashMailsOp1)
   6.140 +//        queue.addOperation(trashMailsOp2)
   6.141 +//
   6.142 +//        waitForExpectations(timeout: TestUtil.waitTime, handler: { error in
   6.143 +//            XCTAssertNil(error)
   6.144 +//            XCTAssertFalse(trashMailsOp2.hasErrors())
   6.145 +//        })
   6.146 +//
   6.147 +//        Record.Context.default.refreshAllObjects()
   6.148 +//        XCTAssertEqual(trashFolder.messages?.count ?? 0, 0)
   6.149 +//
   6.150 +//        let expTrashFetched = expectation(description: "expTrashFetched")
   6.151 +//
   6.152 +//        let fetchTrashOp = FetchMessagesOperation(
   6.153 +//            parentName: #function, errorContainer: errorContainer, imapSyncData: imapSyncData,
   6.154 +//            folderName: trashFolder.name ?? "", messageFetchedBlock: nil)
   6.155 +//        fetchTrashOp.completionBlock = {
   6.156 +//            fetchTrashOp.completionBlock = nil
   6.157 +//            expTrashFetched.fulfill()
   6.158 +//        }
   6.159 +//
   6.160 +//        queue.addOperation(fetchTrashOp)
   6.161 +//
   6.162 +//        waitForExpectations(timeout: TestUtil.waitTime, handler: { error in
   6.163 +//            XCTAssertNil(error)
   6.164 +//            XCTAssertFalse(trashMailsOp2.hasErrors())
   6.165 +//        })
   6.166 +//
   6.167 +//        for m in originalMessages {
   6.168 +//            guard let mID = m.uuid else {
   6.169 +//                XCTFail()
   6.170 +//                continue
   6.171 +//            }
   6.172 +//            let uuidP = NSPredicate(format: "uuid = %@", mID)
   6.173 +//            guard let cdMessages = CdMessage.all(predicate: uuidP) else {
   6.174 +//                XCTFail()
   6.175 +//                continue
   6.176 +//            }
   6.177 +//            XCTAssertEqual(cdMessages.count, 2)
   6.178 +//
   6.179 +//            guard let folder = m.parent else {
   6.180 +//                XCTFail()
   6.181 +//                continue
   6.182 +//            }
   6.183 +//            XCTAssertTrue(folder.folderType == FolderType.inbox ||
   6.184 +//                folder.folderType == FolderType.drafts)
   6.185 +//            guard let imap = m.imap else {
   6.186 +//                XCTFail()
   6.187 +//                continue
   6.188 +//            }
   6.189 +//            // Check the original message's flags
   6.190 +//            XCTAssertTrue(imap.localFlags?.flagDeleted ?? false)
   6.191 +//            XCTAssertEqual(imap.trashedStatus, Message.TrashedStatus.trashed)
   6.192 +//            // Make sure the email now exists in the trash folder as well ...
   6.193 +//            let trashedP = NSPredicate(format: "parent = %@", trashFolder)
   6.194 +//            let trashedP1 = NSCompoundPredicate(andPredicateWithSubpredicates: [uuidP, trashedP])
   6.195 +//            let trashedCdMessage = CdMessage.first(predicate: trashedP1)
   6.196 +//            guard let trashed = trashedCdMessage,
   6.197 +//                let localFlags = trashed.imapFields().localFlags else {
   6.198 +//                    XCTFail("Message missing in trash folder? No flags?")
   6.199 +//                    return
   6.200 +//            }
   6.201 +//            // ... and check the newly created (in trash folder) message's flags
   6.202 +//            XCTAssertFalse(localFlags.flagDeleted)
   6.203 +//            //BUFF: unclear (to me) what the expected trashedStatus for a message in trash folder actually is.
   6.204 +//            // I _assume_ .none, as trashedStatus imu. signals the message has to be copied to trash folder. Which messages in trash folder should not
   6.205 +//            XCTAssertTrue(trashed.imapFields().trashedStatus == .none)
   6.206 +//        }
   6.207 +//    }
   6.208  }