pEpForiOSTests/ReplicationServiceTests.swift
author buff <andreas@pep-project.org>
Tue, 14 May 2019 22:16:34 +0200
branchIOS-1521+IOS-1495
changeset 8616 a18e4cc9c07e
parent 8460 dd94d8674427
child 8617 863f7380e2d8
permissions -rw-r--r--
IOS-1521 visible mark for commented code please
     1 //
     2 //  ReplicationServiceTests.swift
     3 //  pEpForiOS
     4 //
     5 //  Created by hernani on 23/11/16.
     6 //  Copyright © 2016 p≡p Security S.A. All rights reserved.
     7 //
     8 
     9 import XCTest
    10 import CoreData
    11 
    12 @testable import MessageModel
    13 @testable import pEpForiOS
    14 
    15 class ReplicationServiceTests: XCTestCase {
    16     var persistenceSetup: PersistentSetup!
    17     var moc: NSManagedObjectContext!
    18 
    19     override func setUp() {
    20         super.setUp()
    21         persistenceSetup = PersistentSetup()
    22         moc = Record.Context.default
    23     }
    24 
    25     override func tearDown() {
    26         persistenceSetup = nil
    27         super.tearDown()
    28     }
    29 
    30     func testSyncOutgoing() {
    31         testSyncOutgoing(useCorrectSmtpAccount: true)
    32     }
    33 
    34     func testSyncOutgoingWithWrongAccount() {
    35         testSyncOutgoing(useCorrectSmtpAccount: false)
    36     }
    37 
    38     //!!!: random fail
    39 //    func testSyncOneTime() {
    40 //        XCTAssertNil(CdAccount.all())
    41 //        XCTAssertNil(CdFolder.all())
    42 //        XCTAssertNil(CdMessage.all())
    43 //
    44 //        let modelDelegate = MessageModelObserver()
    45 //        MessageModelConfig.messageFolderDelegate = modelDelegate
    46 //
    47 //        let replicationService = ReplicationService(parentName: #function)
    48 //
    49 //        let del = ReplicationServiceObserver(
    50 //            expAccountsSynced: expectation(description: "expSingleAccountSynced"))
    51 //        replicationService.unitTestDelegate = del
    52 //        replicationService.delegate = del
    53 //
    54 //        _ = SecretTestData().createWorkingCdAccount()
    55 //        Record.saveAndWait()
    56 //
    57 //        replicationService.start()
    58 //
    59 //        waitForExpectations(timeout: TestUtil.waitTime, handler: { error in
    60 //            XCTAssertNil(error)
    61 //        })
    62 //
    63 //        XCTAssertNotNil(del.accountInfo)
    64 //        XCTAssertNotNil(CdFolder.all())
    65 //
    66 //        guard let cdFolder = CdFolder.first(
    67 //            attributes: ["folderTypeRawValue": FolderType.inbox.rawValue]) else {
    68 //                XCTFail()
    69 //                return
    70 //        }
    71 //        XCTAssertGreaterThanOrEqual(cdFolder.messages?.count ?? 0, 0)
    72 //        let allCdMessages = cdFolder.messages?.sortedArray(
    73 //            using: [NSSortDescriptor(key: "uid", ascending: true)]) as? [CdMessage] ?? []
    74 //        XCTAssertGreaterThanOrEqual(allCdMessages.count, 0)
    75 //
    76 //        for cdMsg in allCdMessages {
    77 //            guard let parentF = cdMsg.parent else {
    78 //                XCTFail()
    79 //                continue
    80 //            }
    81 //            XCTAssertEqual(parentF.folderType, FolderType.inbox)
    82 //        }
    83 //
    84 //        let unifiedInbox = UnifiedInbox()
    85 //
    86 //        let unifiedMessageCount = unifiedInbox.messageCount()
    87 //        XCTAssertGreaterThanOrEqual(unifiedMessageCount, 0)
    88 //        for i in 0..<unifiedMessageCount {
    89 //            guard let msg = unifiedInbox.messageAt(index: i) else {
    90 //                XCTFail()
    91 //                continue
    92 //            }
    93 //
    94 //            XCTAssertTrue(msg.isValidMessage())
    95 //
    96 //            let pEpRating = Int16(msg.pEpRatingInt ?? -1)
    97 //            XCTAssertNotEqual(pEpRating, PEPUtil.pEpRatingNone)
    98 //            if !modelDelegate.contains(messageID: msg.messageID) {
    99 //                XCTFail()
   100 //            }
   101 //        }
   102 //
   103 //        let inbox = Folder.from(cdFolder: cdFolder)
   104 //        XCTAssertEqual(modelDelegate.messages.count, unifiedMessageCount)
   105 //
   106 //        for msg in modelDelegate.messages {
   107 //            let msgIsFlaggedDeleted = msg.imapFlags?.deleted ?? false
   108 //            XCTAssertTrue(!msgIsFlaggedDeleted)
   109 //            XCTAssertTrue(inbox.contains(message: msg))
   110 //            if !unifiedInbox.contains(message: msg) {
   111 //                XCTFail()
   112 //            }
   113 //        }
   114 //        XCTAssertFalse(modelDelegate.hasChangedMessages)
   115 //
   116 //        TestUtil.cancelReplicationServiceAndWait(replicationService: replicationService, testCase: self)
   117 //    }
   118 
   119     func testCancelSyncImmediately() {
   120         XCTAssertNil(CdAccount.all())
   121         XCTAssertNil(CdFolder.all())
   122         XCTAssertNil(CdMessage.all())
   123 
   124         let replicationService = ReplicationService(parentName: #function)
   125 
   126         _ = SecretTestData().createWorkingCdAccount(context: moc)
   127         Record.saveAndWait()
   128 
   129         for _ in 0...10 {
   130             replicationService.start()
   131             TestUtil.cancelReplicationServiceAndWait(replicationService: replicationService, testCase: self)
   132         }
   133 
   134         XCTAssertNil(CdFolder.all())
   135         XCTAssertNil(CdMessage.all())
   136     }
   137 
   138     class MySelfObserver: KickOffMySelfProtocol {
   139         let expMySelfed: XCTestExpectation?
   140         let queue = LimitedOperationQueue()
   141         let backgrounder: MockBackgrounder
   142 
   143         init(expMySelfed: XCTestExpectation?,
   144              expBackgroundTaskFinishedAtLeastOnce: XCTestExpectation?) {
   145             self.expMySelfed = expMySelfed
   146             backgrounder = MockBackgrounder(
   147                 expBackgroundTaskFinishedAtLeastOnce: expBackgroundTaskFinishedAtLeastOnce)
   148         }
   149 
   150         func startMySelf() {
   151             let op = MySelfOperation(parentName: #function, backgrounder: backgrounder)
   152             op.completionBlock = {
   153                 op.completionBlock = nil
   154                 self.expMySelfed?.fulfill()
   155             }
   156             queue.addOperation(op)
   157         }
   158     }
   159 
   160     //MARK: HELPER
   161 
   162     func testSyncOutgoing(useCorrectSmtpAccount: Bool) {
   163         XCTAssertNil(CdAccount.all())
   164         XCTAssertNil(CdFolder.all())
   165         XCTAssertNil(CdMessage.all())
   166 
   167         let modelDelegate = MessageModelObserver()
   168         MessageModelConfig.messageFolderDelegate = modelDelegate
   169 
   170         let cdAccount =
   171             useCorrectSmtpAccount ?
   172             SecretTestData().createWorkingCdAccount(context: moc) :
   173             SecretTestData().createSmtpTimeOutCdAccount(context: moc)
   174         Record.saveAndWait()
   175 
   176         TestUtil.syncAndWait(testCase: self)
   177 
   178         let from = CdIdentity(context: moc)
   179         from.userName = cdAccount.identity?.userName ?? "Unit 004"
   180         from.address = cdAccount.identity?.address ?? "unittest.ios.4@peptest.ch"
   181 
   182         let to = CdIdentity(context: moc)
   183         to.userName = "Unit 001"
   184         to.address = "unittest.ios.1@peptest.ch"
   185 
   186         guard let sentFolder = CdFolder.by(folderType: .sent, account: cdAccount) else {
   187             XCTFail()
   188             return
   189         }
   190         XCTAssertEqual((sentFolder.messages ?? NSSet()).count, 0)
   191 
   192         let numMails = 1
   193         let outgoingMails = try! TestUtil.createOutgoingMails(cdAccount: cdAccount,
   194                                                               testCase: self,
   195                                                               numberOfMails: numMails,
   196                                                               context: moc)
   197         let outgoingMessageIDs: [String] = outgoingMails
   198             .map() { $0.messageID ?? "" }
   199             .filter() { $0 != "" }
   200 
   201         // Verify outgoing mails
   202         for m in outgoingMails {
   203             XCTAssertEqual(m.parent?.folderType, FolderType.outbox)
   204             XCTAssertEqual(m.uid, Int32(0))
   205         }
   206 
   207         TestUtil.syncAndWait(testCase: self)
   208 
   209         // Check that the sent mails have been deleted
   210         Stack.refreshRegisteredObjects(mergeChanges: true, in: moc)
   211         if useCorrectSmtpAccount {
   212             for m in outgoingMails {
   213                 XCTAssertTrue(m.isDeleted)
   214             }
   215         }
   216 
   217         // sync
   218         TestUtil.syncAndWait(testCase: self)
   219 
   220         if useCorrectSmtpAccount {
   221             // those messages do not exist if we are using an incorrect account
   222             TestUtil.checkForExistanceAndUniqueness(uuids: outgoingMessageIDs)
   223         }
   224     }
   225 
   226     class MessageModelObserver: MessageFolderDelegate {
   227         var messages: [Message] {
   228             var messages = [Message]()
   229             for ms in messagesByID.values {
   230                 for m in ms {
   231                     messages.append(m)
   232                 }
   233             }
   234             return messages.sorted { m1, m2 in
   235                 if let d1 = m1.sent, let d2 = m2.sent {
   236                     return areInIncreasingOrder(d1: d1, d2: d2)
   237                 }
   238                 return false
   239             }
   240         }
   241         var messagesByID = [MessageID: [Message]]()
   242         var changedMessagesByID = [MessageID: Message]()
   243 
   244         var hasChangedMessages: Bool {
   245             return !changedMessagesByID.isEmpty
   246         }
   247 
   248         func contains(messageID: MessageID) -> Bool {
   249             return messagesByID[messageID] != nil
   250         }
   251 
   252         func areInIncreasingOrder(d1: Date, d2: Date) -> Bool {
   253             switch d1.compare(d2 as Date) {
   254             case .orderedAscending: return true
   255             default: return false
   256             }
   257         }
   258 
   259         func add(message: Message) {
   260             if let existing = messagesByID[message.uuid] {
   261                 var news = existing
   262                 news.append(message)
   263                 messagesByID[message.uuid] = news
   264             } else {
   265                 messagesByID[message.uuid] = [message]
   266             }
   267         }
   268 
   269         func didUpdate(message: Message) {
   270             // messages has been changed during the test
   271             XCTAssertNotNil(messagesByID[message.messageID])
   272             add(message: message)
   273             changedMessagesByID[message.messageID] = message
   274         }
   275 
   276         func didDelete(message: Message) {
   277             // this message has been deleted from the start, ignore
   278         }
   279 
   280         func didCreate(message: Message) {
   281             add(message: message)
   282         }
   283     }
   284 }