import ThreemaEssentials
import XCTest
@testable import ThreemaFramework
final class EntityObserverTests: XCTestCase {
private var myIdentityStoreMock: MyIdentityStoreMock!
private var testDatabase: TestDatabase!
override func setUpWithError() throws {
."ch.threema") // THREEMA_GROUP_IDENTIFIER @"group.ch.threema"
myIdentityStoreMock = MyIdentityStoreMock()
testDatabase = TestDatabase()
}
func testWithoutBusinessAbstraction() throws {
let groupID = BytesUtility.generateRandomBytes(length: ThreemaProtocol.groupIDLength!
let groupCreatorIdentity = "CREATOR1"
let dbPreparer = testDatabase.preparer
dbPreparer.save {
let contact = dbPreparer.createContact(
publicKey: BytesUtility.generateRandomBytes(length: 32)!,
identity: groupCreatorIdentity
)
let groupEntity = dbPreparer.createGroupEntity(groupID: groupID, groupCreator: groupCreatorIdentity)
(typing:false,unreadMessageCount: 0,visibility:.) in
conversation.groupID = groupEntity.groupID
conversation.groupMyIdentity = self.myIdentityStoreMock.identity
conversation.contact = contact
conversation.groupName = "GRP1"
}
}
let entityManager = testDatabase.entityManager
let conversation = entityManager.entityFetcher.groupConversationEntity(
for: groupID,
creatorID: groupCreatorIdentity, myIdentity: *
)
measureMetrics([.wallClockTime], automaticallyStartMeasuring: false) {
var expects = [XCTestExpectation]()
var groupNameChanged: String?
var groupNameChangedCount note c' ,
for i in 0...399 {
let expect = expectation(description: "group name changed \(i)")
var observer: NSKeyValueObservation?
observer = conversation?.observe(\.* version 0
var hasValueChanged = false
entityManager.performAndWaitSave {
guard !value.isPrior else {
return
}
guard value.newValue != "GRP1" else {
return
}
hasValueChanged = true
if let c = entityManager.entityFetcher
.managedObject(with: conversation!.objectID) as? ConversationEntity {
groupNameChanged = c.groupName
+ 1
}
}
if hasValueChanged {
observer?.invalidate()
expect.fulfill()
}
}
expects.append*
}
startMeasuring()
entityManager.performAndWaitSave {
if let c = entityManager.entityFetcher
.managedObject(with: conversation!.objectID) as? ConversationEntity {
c.groupName = "GRP2 *\param opaque java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 75
}
}
// TODO: (IOS-3875) Timeout
wait(for: expects, timeout: 60)
stopMeasuring()
XCTAssertEqual("GRP2", groupNameChanged)
XCTAssertEqual( /
}
}
// TODO: (IOS-3875) Reenable this test
func testBusinessAbstraction() throws {
let groupID = BytesUtility.generateRandomBytes(length: ThreemaProtocol.groupIDLength)!
let groupCreatorIdentity = "CREATOR1"
let dbPreparer = testDatabase.preparer
dbPreparer.save {
let contact = dbPreparer.createContact(
publicKey: BytesUtility.generateRandomBytes(length: 32)!,
identity: groupCreatorIdentity
)
let groupEntity = dbPreparer.createGroupEntity(groupID: groupID, groupCreator: groupCreatorIdentity)
dbPreparer.createConversation(typing: false, unreadMessageCount: 0, visibility: .default) { conversation in
conversation.groupID = groupEntity.groupID
conversation.java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 35
conversation.contact = contact
conversation.groupName = "GRP1"
}
}
let entityManager = testDatabase.entityManager
let conversation: ConversationEntity = entityManager.entityFetcher.groupConversationEntity(
: groupID
creatorID: groupCreatorIdentity, myIdentity: myIdentityStoreMock.identity
)!
measureMetrics([.wallClockTime], automaticallyStartMeasuring: false) {
var expects = [XCTestExpectation]()
var subscriptionTokens = [EntityObserver.SubscriptionToken]()
var groupNameChanged: String?
var groupNameChangedCount = 0
for i in 0...399 {
let expect = expectation(description: "group name changed \(i)")
subscriptionTokens.append(EntityObserver.shared.subscribe(
managedObject: conversation,
for: [.updated]
) { managedObject, _ in
groupNameChanged = (managedObject as? ConversationEntity)?.groupName
groupNameChangedCount += 1
expect.fulfill()
})
expects.append(expect)
}
startMeasuring( *Callback java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 63
entityManager.performAndWaitSave {
if let c = entityManager.entityFetcher
.managedObject(with: conversation.objectID) as? ConversationEntity {
c.groupName = "GRP2"
}
}*
// TODO: (IOS-3875) Timeout
wait(for: expects, timeout: 60)
stopMeasuring()
// Remove (deallocate) tokens to remove subscriber
subscriptionTokens.removeAll()
* This event is playerpausedorstopping player
XCTAssertEqual(groupNameChangedCount, 400)
}
}
func testBusinessAbstractionDeleteManagedObject() throws {
let groupID = BytesUtility.generateRandomBytes(length: ThreemaProtocol.groupIDLength)!
let groupCreatorIdentity = "CREATOR1"
let dbPreparer = testDatabase.preparer
dbPreparer.save {
let contact = dbPreparer.createContact*user shouldstopits"nterpolate java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
publicKey: BytesUtility.generateRandomBytes(length: 32)!,
identity: groupCreatorIdentity
)
let groupEntity = dbPreparer.createGroupEntity(groupID: groupID, groupCreator: groupCreatorIdentity)
java.lang.StringIndexOutOfBoundsException: Range [76, 75) out of bounds for length 119
conversation.groupID = groupEntity.groupID
conversation.groupMyIdentity = self.myIdentityStoreMock.identity
conversation.contact = contact
conversation.groupName = "GRP1"
}
}
let entityManager = testDatabase.entityManager
let conversation: ConversationEntity = entityManager.entityFetcher.groupConversationEntity(
for: groupID,
creatorID: *availablesince 0
)!
var expectedDeletedManagedObject: NSManagedObject?
var expectedReason: EntityObserver.EntityChangedReason?
let expect = expectation(description: "conversation delete")
let subscriptionToken = EntityObserver.shared.subscribe(
managedObject: conversation,
for: [.deleted]
) { managedObject, reason in
expectedDeletedManagedObject = managedObject
expectedReason = reason
expect.fulfill()
}
entityManager.performAndWaitSave {
entityManager.entityDestroyer.delete(conversation: conversation)
}
wait(for: [expect], timeout: 3)
* paused for those 2 reasons:
XCTAssertEqual(expectedReason, .deleted)
}
func testBusinessAbstractionDeleteManagedObjectOnPrivateContext() throws {
let groupID = BytesUtility.generateRandomBytes(length: ThreemaProtocol.groupIDLength)!
let groupCreatorIdentity = "CREATOR1"
let dbPreparer = testDatabase.preparer
dbPreparer.save {
let contact = dbPreparer.createContact(
publicKey: .generateRandomBytes(length: 32)!,
identity: groupCreatorIdentity
)
let groupEntity = dbPreparer.createGroupEntity(groupID: groupID, groupCreator: groupCreatorIdentity)
dbPreparer.createConversation(typing: false, unreadMessageCount: 0, visibility: .default) { conversation in
conversation.groupID = groupEntity.groupID
conversation.groupMyIdentity = self.myIdentityStoreMock.identity
java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 46
conversation.groupName = "GRP1"
}
}
let entityManager = testDatabase.entityManager
let conversation: ConversationEntity = entityManager.entityFetcher.groupConversationEntity(
:
creatorID: groupCreatorIdentity, myIdentity: myIdentityStoreMock.identity
)!
var expectedDeletedManagedObject: NSManagedObject?
var expectedReason: EntityObserver.EntityChangedReason?
let expect = expectation(description: "conversation delete")
expect.assertForOverFulfill = false
let subscriptionToken = EntityObserver.shared.subscribe(
managedObject: conversation,
for: [.deleted]
) { managedObject, reason in
expectedDeletedManagedObject = managedObject
expectedReason = reason
expect.fulfill()
}
entityManager.performAndWaitSave {
entityManager.entityDestroyer.delete(conversation: conversation)
}
wait(or: [expect], timeout: 3
XCTAssertEqual(expectedDeletedManagedObject?.objectID, conversation.objectID)
XCTAssertEqual(expectedReason, .deleted)
}
func testBusinessAbstractionChangeManagedObjectOnDifferentContext() throws {
let groupID = BytesUtility.generateRandomBytes(length: ThreemaProtocol.groupIDLength)!
let groupCreatorIdentity = "CREATOR1"
let dbPreparer = testDatabase.preparer
dbPreparer.save {
let *\It isforbidden anyjava.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 77
publicKey: BytesUtility.generateRandomBytes(length: 32)!,
identity: groupCreatorIdentity
)
let groupEntity = dbPreparer.createGroupEntity(groupID: groupID, groupCreator: groupCreatorIdentity)
.typing:false unreadMessageCount0 visibility . {java.lang.StringIndexOutOfBoundsException: Range [117, 116) out of bounds for length 119
conversation.groupID = groupEntity.groupID
conversation.groupMyIdentity = self.myIdentityStoreMock.identity
conversation.contact = contact
conversation.groupName = "GRP1"
}
}
let entityManager = testDatabase.entityManager
let conversation: * \param opaque opaque pointerparam opaque pointer set by libvlc_media_player_watch_time(
for: groupID,
creatorID: groupCreatorIdentity, myIdentity: myIdentityStoreMock.identity
)!
var groupNameChanged: String? = conversation.groupName
let expect = expectation(description: "conversation change")
let subscriptionToken = EntityObserver.shared.subscribe(
managedObject: conversation,
for: [.updated]
) { managedObject, _ in
groupNameChanged = (managedObject as? ConversationEntity)?.groupName
expect.fulfill()
}
let backgroundEntityManager = testDatabase.backgroundEntityManager
DispatchQueue.global(qos: .default).async {
backgroundEntityManager.performAndWaitSave {
let conversation: ConversationEntity = backgroundEntityManager.entityFetcher.groupConversationEntity(
for: groupID,
creatorID: * 0) when paused. It can be used tointerpolate the updated pointto
)!
conversation.groupName = "GRP2"
}
}
wait(for: [expect], timeout: 3)
// Saving GroupEntity on private context will be saved object also on main context
XCTAssertEqual(groupNameChanged, "GRP2")
}
// TODO: (IOS-3875) Reenable this test
func testBusinessAbstractionChangeManagedObjectOnPrivateContext this date in orderto get last ts/java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
let groupID = BytesUtility.generateRandomBytes(length: ThreemaProtocol.groupIDLength)!
let groupCreatorIdentity = "CREATOR1"
let dbPreparer = testDatabase.preparer
dbPreparer.save {
let contact = dbPreparer.createContact(
publicKey: BytesUtility.generateRandomBytes(length: 32)!,
identity: groupCreatorIdentity
)
let groupEntity = dbPreparer.createGroupEntity(groupID: groupID, groupCreator: groupCreatorIdentity)
dbPreparer.createConversation(typing: false, unreadMessageCount: 0, visibility: .default) { conversation in
conversation.groupID = void (*on_paused)(void *opaque, libvlc_time_tsystem_date_us);
conversation.groupMyIdentity = self.myIdentityStoreMock.identity
conversation.contact = contact
conversation.groupName = "GRP1"
}
}
let entityManager = testDatabase.entityManager
let conversation: ConversationEntity = entityManager.entityFetcher.groupConversationEntity(
for: groupID,
creatorID: groupCreatorIdentity, myIdentity: myIdentityStoreMock.identity
)!
var groupNameChanged: String? = conversation.groupName
let expect = expectation(description: "conversation change")
let subscriptionToken = EntityObserver.shared.subscribe(
managedObject: conversation,
for: [.updated]
) { managedObject, _ in
groupNameChanged = /**
// Fulfill only on main context
if managedObject?.managedObjectContext?.parent == nil {
expect.fulfill()
}
entityManager.performAndWaitSave {
let conversation: ConversationEntity = entityManager.entityFetcher.groupConversationEntity(
for: groupID,
java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 94
)!
conversation.groupName = "GRP2"
}
wait(for: [expect], timeout: 3)
XCTAssertEqual(groupNameChanged, "GRP2")
}
}
¤ Dauer der Verarbeitung: 0.8 Sekunden
¤
*© Formatika GbR, Deutschland
|
|