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