Fix tests broken by the JSQ rewrite.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-10-25 11:37:04 -04:00
parent 418fef3358
commit 3927815a35
11 changed files with 411 additions and 431 deletions

View File

@ -10,6 +10,7 @@
3400C7931EAF89CD008A8584 /* SendExternalFileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3400C7911EAF89CD008A8584 /* SendExternalFileViewController.m */; };
3400C7961EAF99F4008A8584 /* SelectThreadViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3400C7951EAF99F4008A8584 /* SelectThreadViewController.m */; };
3400C7991EAFB772008A8584 /* ThreadViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3400C7981EAFB772008A8584 /* ThreadViewHelper.m */; };
340B02BA1FA0D6C700F9CFEC /* ConversationViewItemTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */; };
340CB2241EAC155C0001CAA1 /* ContactsViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 340CB2231EAC155C0001CAA1 /* ContactsViewHelper.m */; };
340CB2271EAC25820001CAA1 /* UpdateGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340CB2261EAC25820001CAA1 /* UpdateGroupViewController.m */; };
341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */ = {isa = PBXBuildFile; fileRef = 341F2C0E1F2B8AE700D07D6B /* DebugUIMisc.m */; };
@ -60,7 +61,6 @@
34B3F8911E8DF1710035BE1A /* ShowGroupMembersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F86B1E8DF1700035BE1A /* ShowGroupMembersViewController.m */; };
34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */; };
34B3F8941E8DF1710035BE1A /* HomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8701E8DF1700035BE1A /* HomeViewController.m */; };
34B3F8991E8DF1B90035BE1A /* TSMessageAdapterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8981E8DF1B90035BE1A /* TSMessageAdapterTest.m */; };
34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */; };
34B3F89F1E8DF5490035BE1A /* OWSTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F89E1E8DF5490035BE1A /* OWSTableViewController.m */; };
34B3F8A21E8EA6040035BE1A /* ViewControllerUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8A11E8EA6040035BE1A /* ViewControllerUtils.m */; };
@ -71,6 +71,10 @@
34C42D5B1F45F7A80072EC04 /* OWSNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C42D5A1F45F7A80072EC04 /* OWSNavigationController.m */; };
34C42D661F4734ED0072EC04 /* OWSContactOffersInteraction.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C42D631F4734ED0072EC04 /* OWSContactOffersInteraction.m */; };
34C42D671F4734ED0072EC04 /* TSUnreadIndicatorInteraction.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C42D651F4734ED0072EC04 /* TSUnreadIndicatorInteraction.m */; };
34C6B0A91FA0E46F00D35993 /* test-gif.gif in Resources */ = {isa = PBXBuildFile; fileRef = 34C6B0A51FA0E46F00D35993 /* test-gif.gif */; };
34C6B0AB1FA0E46F00D35993 /* test-mp3.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 34C6B0A71FA0E46F00D35993 /* test-mp3.mp3 */; };
34C6B0AC1FA0E46F00D35993 /* test-mp4.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 34C6B0A81FA0E46F00D35993 /* test-mp4.mp4 */; };
34C6B0AE1FA0E4AA00D35993 /* test-jpg.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 34C6B0AD1FA0E4AA00D35993 /* test-jpg.jpg */; };
34CA1C251F706B5400E51C51 /* NSAttributedString+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34CA1C241F706B5400E51C51 /* NSAttributedString+OWS.m */; };
34CA1C271F7156F300E51C51 /* MessageMetadataViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34CA1C261F7156F300E51C51 /* MessageMetadataViewController.swift */; };
34CA1C291F7164F700E51C51 /* MediaMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34CA1C281F7164F700E51C51 /* MediaMessageView.swift */; };
@ -315,7 +319,6 @@
B660F6D81C29868000687D6E /* CryptoToolsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6A71C29868000687D6E /* CryptoToolsTest.m */; };
B660F6DA1C29868000687D6E /* ExceptionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6AB1C29868000687D6E /* ExceptionsTest.m */; };
B660F6DB1C29868000687D6E /* FunctionalUtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6AD1C29868000687D6E /* FunctionalUtilTest.m */; };
B660F6DF1C29868000687D6E /* QueueTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6B21C29868000687D6E /* QueueTest.m */; };
B660F6E01C29868000687D6E /* UtilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6B41C29868000687D6E /* UtilTest.m */; };
B660F7171C29988E00687D6E /* OWSContactsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040918170B33006006FC /* OWSContactsManager.m */; };
B660F7181C29988E00687D6E /* CryptoTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 7038632418F70C0700D4A43F /* CryptoTools.m */; };
@ -406,6 +409,7 @@
3400C7971EAFB772008A8584 /* ThreadViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadViewHelper.h; sourceTree = "<group>"; };
3400C7981EAFB772008A8584 /* ThreadViewHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadViewHelper.m; sourceTree = "<group>"; };
340B02B61F9FD31800F9CFEC /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = translations/he.lproj/Localizable.strings; sourceTree = "<group>"; };
340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConversationViewItemTest.m; sourceTree = "<group>"; };
340CB2221EAC155C0001CAA1 /* ContactsViewHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsViewHelper.h; sourceTree = "<group>"; };
340CB2231EAC155C0001CAA1 /* ContactsViewHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsViewHelper.m; sourceTree = "<group>"; };
340CB2251EAC25820001CAA1 /* UpdateGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpdateGroupViewController.h; sourceTree = "<group>"; };
@ -494,7 +498,6 @@
34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalsNavigationController.m; sourceTree = "<group>"; };
34B3F86F1E8DF1700035BE1A /* HomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeViewController.h; sourceTree = "<group>"; };
34B3F8701E8DF1700035BE1A /* HomeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeViewController.m; sourceTree = "<group>"; };
34B3F8981E8DF1B90035BE1A /* TSMessageAdapterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSMessageAdapterTest.m; sourceTree = "<group>"; };
34B3F89A1E8DF3270035BE1A /* BlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlockListViewController.h; sourceTree = "<group>"; };
34B3F89B1E8DF3270035BE1A /* BlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BlockListViewController.m; sourceTree = "<group>"; };
34B3F89D1E8DF5490035BE1A /* OWSTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSTableViewController.h; sourceTree = "<group>"; };
@ -512,6 +515,10 @@
34C42D631F4734ED0072EC04 /* OWSContactOffersInteraction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactOffersInteraction.m; sourceTree = "<group>"; };
34C42D641F4734ED0072EC04 /* TSUnreadIndicatorInteraction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSUnreadIndicatorInteraction.h; sourceTree = "<group>"; };
34C42D651F4734ED0072EC04 /* TSUnreadIndicatorInteraction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSUnreadIndicatorInteraction.m; sourceTree = "<group>"; };
34C6B0A51FA0E46F00D35993 /* test-gif.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "test-gif.gif"; sourceTree = "<group>"; };
34C6B0A71FA0E46F00D35993 /* test-mp3.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "test-mp3.mp3"; sourceTree = "<group>"; };
34C6B0A81FA0E46F00D35993 /* test-mp4.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "test-mp4.mp4"; sourceTree = "<group>"; };
34C6B0AD1FA0E4AA00D35993 /* test-jpg.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "test-jpg.jpg"; sourceTree = "<group>"; };
34CA1C231F706B5400E51C51 /* NSAttributedString+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+OWS.h"; sourceTree = "<group>"; };
34CA1C241F706B5400E51C51 /* NSAttributedString+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+OWS.m"; sourceTree = "<group>"; };
34CA1C261F7156F300E51C51 /* MessageMetadataViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageMetadataViewController.swift; sourceTree = "<group>"; };
@ -800,8 +807,6 @@
B660F6AB1C29868000687D6E /* ExceptionsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExceptionsTest.m; sourceTree = "<group>"; };
B660F6AC1C29868000687D6E /* FunctionalUtilTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionalUtilTest.h; sourceTree = "<group>"; };
B660F6AD1C29868000687D6E /* FunctionalUtilTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FunctionalUtilTest.m; sourceTree = "<group>"; };
B660F6B11C29868000687D6E /* QueueTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QueueTest.h; sourceTree = "<group>"; };
B660F6B21C29868000687D6E /* QueueTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QueueTest.m; sourceTree = "<group>"; };
B660F6B31C29868000687D6E /* UtilTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UtilTest.h; sourceTree = "<group>"; };
B660F6B41C29868000687D6E /* UtilTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UtilTest.m; sourceTree = "<group>"; };
B661C211198EE2EA00548CA1 /* iOSVersions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iOSVersions.h; path = src/environment/iOSVersions.h; sourceTree = "<group>"; };
@ -1096,27 +1101,11 @@
34B3F8951E8DF1B90035BE1A /* ViewControllers */ = {
isa = PBXGroup;
children = (
34B3F8961E8DF1B90035BE1A /* Signals */,
340B02B91FA0D6C700F9CFEC /* ConversationViewItemTest.m */,
);
path = ViewControllers;
sourceTree = "<group>";
};
34B3F8961E8DF1B90035BE1A /* Signals */ = {
isa = PBXGroup;
children = (
34B3F8971E8DF1B90035BE1A /* TSMessageAdapters */,
);
path = Signals;
sourceTree = "<group>";
};
34B3F8971E8DF1B90035BE1A /* TSMessageAdapters */ = {
isa = PBXGroup;
children = (
34B3F8981E8DF1B90035BE1A /* TSMessageAdapterTest.m */,
);
path = TSMessageAdapters;
sourceTree = "<group>";
};
34BECE2C1F7ABCE000D7438D /* GifPicker */ = {
isa = PBXGroup;
children = (
@ -1127,6 +1116,17 @@
path = GifPicker;
sourceTree = "<group>";
};
34C6B0A41FA0E46F00D35993 /* Assets */ = {
isa = PBXGroup;
children = (
34C6B0A51FA0E46F00D35993 /* test-gif.gif */,
34C6B0AD1FA0E4AA00D35993 /* test-jpg.jpg */,
34C6B0A71FA0E46F00D35993 /* test-mp3.mp3 */,
34C6B0A81FA0E46F00D35993 /* test-mp4.mp4 */,
);
path = Assets;
sourceTree = "<group>";
};
34CE88E81F3237260098030F /* Profiles */ = {
isa = PBXGroup;
children = (
@ -1586,6 +1586,7 @@
B660F66C1C29867F00687D6E /* test */ = {
isa = PBXGroup;
children = (
34C6B0A41FA0E46F00D35993 /* Assets */,
B660F6731C29867F00687D6E /* call */,
B660F6751C29867F00687D6E /* contact */,
458E38381D6699110094BD24 /* Models */,
@ -1643,8 +1644,6 @@
B660F6AB1C29868000687D6E /* ExceptionsTest.m */,
B660F6AC1C29868000687D6E /* FunctionalUtilTest.h */,
B660F6AD1C29868000687D6E /* FunctionalUtilTest.m */,
B660F6B11C29868000687D6E /* QueueTest.h */,
B660F6B21C29868000687D6E /* QueueTest.m */,
B660F6B31C29868000687D6E /* UtilTest.h */,
B660F6B41C29868000687D6E /* UtilTest.m */,
45666F571D9B2880008FE134 /* OWSScrubbingLogFormatterTest.m */,
@ -2010,7 +2009,11 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
34C6B0AE1FA0E4AA00D35993 /* test-jpg.jpg in Resources */,
B660F6D41C29868000687D6E /* whisperFake.cer in Resources */,
34C6B0A91FA0E46F00D35993 /* test-gif.gif in Resources */,
34C6B0AC1FA0E46F00D35993 /* test-mp4.mp4 in Resources */,
34C6B0AB1FA0E46F00D35993 /* test-mp3.mp3 in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2415,11 +2418,11 @@
458967111DC117CC00E9DD21 /* AccountManagerTest.swift in Sources */,
45F659831E1BE77000444429 /* NonCallKitCallUIAdaptee.swift in Sources */,
456AC8351E3A776300A3C7FC /* WeakTimer.swift in Sources */,
340B02BA1FA0D6C700F9CFEC /* ConversationViewItemTest.m in Sources */,
458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */,
452D1EE81DCA90D100A57EC4 /* MesssagesBubblesSizeCalculatorTest.swift in Sources */,
451DE9FE1DC1A28200810E42 /* SyncPushTokensJob.swift in Sources */,
45F170AF1E2F0393003FC1F2 /* CallAudioSessionTest.swift in Sources */,
34B3F8991E8DF1B90035BE1A /* TSMessageAdapterTest.m in Sources */,
456F6E231E24133500FD2210 /* Platform.swift in Sources */,
4539B5871F79348F007141FF /* PushRegistrationManager.swift in Sources */,
4504493A1F45EE7D002D1ADA /* NSString+OWS.m in Sources */,
@ -2468,7 +2471,6 @@
456F6E201E2411A000FD2210 /* CallService.swift in Sources */,
45A663C61F92EC760027B59E /* GroupTableViewCell.swift in Sources */,
45E615171E8C59100018AD52 /* DisplayableTextFilter.swift in Sources */,
B660F6DF1C29868000687D6E /* QueueTest.m in Sources */,
B660F6BB1C29868000687D6E /* OWSContactsManagerTest.m in Sources */,
45A6DAD71EBBF85500893231 /* ReminderView.swift in Sources */,
B660F6D21C29868000687D6E /* PushManagerTest.m in Sources */,

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Binary file not shown.

View File

@ -4,16 +4,11 @@
import XCTest
class FakeiPhone6JSQMessagesCollectionViewFlowLayout: JSQMessagesCollectionViewFlowLayout {
// This value was nabbed by inspecting the super class layout.itemSize while debugging the `messageBubbleSizeForMessageData`.
// It requires the view to actually be rendered to get a proper size, so we're baking it in here.
// This will break if we change the layout.
override var itemWidth: CGFloat { return 367 }
}
/**
* This is a brittle test, which will break if our layout changes. It serves mostly as documentation for cases to
* consider when changing the bubble size calculator. Primarly these test cases came out of a bug introduced in iOS10,
* This is a brittle test, which will break if our layout changes.
*
* It serves mostly as documentation for cases to consider when changing the cell measurement logic.
* Primarly these test cases came out of a bug introduced in iOS10,
* which prevents us from computing proper bounding box for text that uses the UIEmoji font.
*
* If one of these tests breaks, it should be OK to update the expected value so long as you've tested the result renders
@ -22,84 +17,88 @@ class FakeiPhone6JSQMessagesCollectionViewFlowLayout: JSQMessagesCollectionViewF
*/
class MesssagesBubblesSizeCalculatorTest: XCTestCase {
let indexPath = IndexPath()
let layout = FakeiPhone6JSQMessagesCollectionViewFlowLayout()
let calculator = MessagesBubblesSizeCalculator()
let thread = TSContactThread()!
let contactsManager = OWSContactsManager()
func messageDataForForText(_ text: String?) -> JSQMessageData {
func viewItemForText(_ text: String?) -> ConversationViewItem {
let interaction = TSOutgoingMessage(timestamp: 0, in: thread, messageBody: text)
interaction.save()
return TSMessageAdapter.messageViewData(with: interaction, in: thread, contactsManager: self.contactsManager)
return ConversationViewItem(tsInteraction:interaction, isGroupThread:false)
}
func messageBubbleSize(for viewItem: ConversationViewItem) -> CGSize {
viewItem.clearCachedLayoutState()
let viewWidth = 367
let contentWidth = 367
return viewItem.cellSize(forViewWidth: Int32(viewWidth), contentWidth:Int32(contentWidth))
}
func testHeightForNilMessage() {
let text: String? = nil
let messageData = self.messageDataForForText(text)
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText(text)
let actual = messageBubbleSize(for: viewItem)
XCTAssertEqual(37, actual.height)
}
func testHeightForShort1LineMessage() {
let text = "foo"
let messageData = self.messageDataForForText(text)
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText(text)
let actual = messageBubbleSize(for: viewItem)
XCTAssertEqual(38, actual.height)
}
func testHeightForLong1LineMessage() {
let text = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 x"
let messageData = self.messageDataForForText(text)
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText(text)
let actual = messageBubbleSize(for: viewItem)
XCTAssertEqual(38, actual.height)
}
func testHeightForShort2LineMessage() {
let text = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 x 1"
let messageData = self.messageDataForForText(text)
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText(text)
let actual = messageBubbleSize(for: viewItem)
XCTAssertEqual(59, actual.height)
}
func testHeightForLong2LineMessage() {
let text = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 x 1 2 3 4 5 6 7 8 9 10 11 12 13 14 x"
let messageData = self.messageDataForForText(text)
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText(text)
let actual = messageBubbleSize(for: viewItem)
XCTAssertEqual(59, actual.height)
}
func testHeightForiOS10EmojiBug() {
let messageData = self.messageDataForForText("Wunderschönen Guten Morgaaaahhhn 😝 - hast du gut geschlafen ☺️😘")
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText("Wunderschönen Guten Morgaaaahhhn 😝 - hast du gut geschlafen ☺️😘")
let actual = messageBubbleSize(for: viewItem)
XCTAssertEqual(85.5, actual.height)
}
func testHeightForiOS10EmojiBug2() {
let messageData = self.messageDataForForText("Test test test test test test test test test test test test 😊❤️❤️")
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText("Test test test test test test test test test test test test 😊❤️❤️")
let actual = messageBubbleSize(for: viewItem)
XCTAssertEqual(62, actual.height)
}
func testHeightForChineseWithEmojiBug() {
let messageData = self.messageDataForForText("一二三四五六七八九十甲乙丙😝戊己庚辛壬圭咖啡牛奶餅乾水果蛋糕")
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText("一二三四五六七八九十甲乙丙😝戊己庚辛壬圭咖啡牛奶餅乾水果蛋糕")
let actual = messageBubbleSize(for: viewItem)
// erroneously seeing 69 with the emoji fix in place.
XCTAssertEqual(85.5, actual.height)
}
func testHeightForChineseWithoutEmojiBug() {
let messageData = self.messageDataForForText("一二三四五六七八九十甲乙丙丁戊己庚辛壬圭咖啡牛奶餅乾水果蛋糕")
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText("一二三四五六七八九十甲乙丙丁戊己庚辛壬圭咖啡牛奶餅乾水果蛋糕")
let actual = messageBubbleSize(for: viewItem)
// erroneously seeing 69 with the emoji fix in place.
XCTAssertEqual(81, actual.height)
}
func testHeightForiOS10DoubleSpaceNumbersBug() {
let messageData = self.messageDataForForText("")
let actual = calculator.messageBubbleSize(for: messageData, at: indexPath, with: layout)
let viewItem = self.viewItemForText("")
let actual = messageBubbleSize(for: viewItem)
// erroneously seeing 51 with emoji fix in place. It's the call to "fix string"
XCTAssertEqual(59, actual.height)
}

View File

@ -0,0 +1,347 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "ConversationViewItem.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <SignalServiceKit/SecurityUtils.h>
#import <SignalServiceKit/TSAttachmentStream.h>
#import <SignalServiceKit/TSOutgoingMessage.h>
#import <XCTest/XCTest.h>
@interface ConversationViewItem (Testing)
- (SEL)copyActionSelector;
- (SEL)saveActionSelector;
- (SEL)shareActionSelector;
- (SEL)deleteActionSelector;
- (SEL)metadataActionSelector;
@end
@interface ConversationViewItemTest : XCTestCase
@property (nonatomic, readonly) NSData *fakeAudioData;
@property (nonatomic, readonly) NSData *fakeImageData;
@end
@implementation ConversationViewItemTest
- (NSData *)fakeAudioData
{
NSString *fakeAudioString = @"QmxhY2tiaXJkIFJhdW0gRG90IE1QMw==";
return [[NSData alloc] initWithBase64EncodedString:fakeAudioString options:0];
}
- (NSData *)fakeVideoData
{
NSString *fakeVideoString = @"RmFrZSBWaWRlbyBEYXRh";
return [[NSData alloc] initWithBase64EncodedString:fakeVideoString options:0];
}
- (NSData *)fakeImageData
{
NSString *fakeString = @"RmFrZUltYWdlRGF0YQ==";
return [[NSData alloc] initWithBase64EncodedString:fakeString options:0];
}
- (void)setUp
{
[super setUp];
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
// Test canPerformAction
- (NSString *)fakeTextMessageText
{
return @"abc";
}
- (ConversationViewItem *)textViewItem
{
TSOutgoingMessage *message =
[[TSOutgoingMessage alloc] initWithTimestamp:1 inThread:nil messageBody:self.fakeTextMessageText];
[message save];
ConversationViewItem *viewItem = [[ConversationViewItem alloc] initWithTSInteraction:message isGroupThread:NO];
return viewItem;
}
- (ConversationViewItem *)viewItemWithAttachmentMimetype:(NSString *)mimeType filename:(NSString *)filename
{
OWSAssert(filename.length > 0);
NSString *resourcePath = [[NSBundle bundleForClass:[self class]] resourcePath];
NSString *filePath = [resourcePath stringByAppendingPathComponent:filename];
OWSAssert([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
TSAttachmentStream *attachment = [[TSAttachmentStream alloc] initWithContentType:mimeType sourceFilename:nil];
DataSource *dataSource = [DataSourcePath dataSourceWithFilePath:filePath];
BOOL success = [attachment writeDataSource:dataSource];
OWSAssert(success);
[attachment save];
NSMutableArray<NSString *> *attachmentIds = [@[
attachment.uniqueId,
] mutableCopy];
TSOutgoingMessage *message =
[[TSOutgoingMessage alloc] initWithTimestamp:1 inThread:nil messageBody:nil attachmentIds:attachmentIds];
[message save];
ConversationViewItem *viewItem = [[ConversationViewItem alloc] initWithTSInteraction:message isGroupThread:NO];
return viewItem;
}
- (ConversationViewItem *)stillImageViewItem
{
return [self viewItemWithAttachmentMimetype:@"image/jpeg" filename:@"test-jpg.jpg"];
}
- (ConversationViewItem *)animatedImageViewItem
{
return [self viewItemWithAttachmentMimetype:@"image/gif" filename:@"test-gif.gif"];
}
- (ConversationViewItem *)videoViewItem
{
return [self viewItemWithAttachmentMimetype:@"video/mp4" filename:@"test-mp4.mp4"];
}
- (ConversationViewItem *)audioViewItem
{
return [self viewItemWithAttachmentMimetype:@"audio/mp3" filename:@"test-mp3.mp3"];
}
- (void)testCanPerformEditingActionWithNonMediaMessage
{
ConversationViewItem *viewItem = self.textViewItem;
XCTAssertTrue([viewItem canPerformAction:viewItem.copyActionSelector]);
XCTAssertFalse([viewItem canPerformAction:viewItem.saveActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.shareActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.deleteActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.metadataActionSelector]);
XCTAssertFalse([viewItem canPerformAction:@selector(unknownAction:)]);
}
- (void)testCanPerformEditingActionWithPhotoMessage
{
ConversationViewItem *viewItem = self.stillImageViewItem;
XCTAssertTrue([viewItem canPerformAction:viewItem.copyActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.saveActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.shareActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.deleteActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.metadataActionSelector]);
XCTAssertFalse([viewItem canPerformAction:@selector(unknownAction:)]);
}
- (void)testCanPerformEditingActionWithAnimatedMessage
{
ConversationViewItem *viewItem = self.animatedImageViewItem;
XCTAssertTrue([viewItem canPerformAction:viewItem.copyActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.saveActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.shareActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.deleteActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.metadataActionSelector]);
XCTAssertFalse([viewItem canPerformAction:@selector(unknownAction:)]);
}
- (void)testCanPerformEditingActionWithVideoMessage
{
ConversationViewItem *viewItem = self.videoViewItem;
XCTAssertTrue([viewItem canPerformAction:viewItem.copyActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.saveActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.shareActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.deleteActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.metadataActionSelector]);
XCTAssertFalse([viewItem canPerformAction:@selector(unknownAction:)]);
}
- (void)testCanPerformEditingActionWithAudioMessage
{
ConversationViewItem *viewItem = self.audioViewItem;
XCTAssertTrue([viewItem canPerformAction:viewItem.copyActionSelector]);
XCTAssertFalse([viewItem canPerformAction:viewItem.saveActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.shareActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.deleteActionSelector]);
XCTAssertTrue([viewItem canPerformAction:viewItem.metadataActionSelector]);
XCTAssertFalse([viewItem canPerformAction:@selector(unknownAction:)]);
}
// Test Delete
- (void)testPerformDeleteEditingActionWithNonMediaMessage
{
ConversationViewItem *viewItem = self.textViewItem;
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
}
- (void)testPerformDeleteActionWithPhotoMessage
{
ConversationViewItem *viewItem = self.stillImageViewItem;
XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count);
NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject;
XCTAssertNotNil(attachmentId);
TSAttachment *_Nullable attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId];
XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]);
TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment;
NSString *_Nullable filePath = attachmentStream.filePath;
XCTAssertNotNil(filePath);
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
}
- (void)testPerformDeleteEditingActionWithAnimatedMessage
{
ConversationViewItem *viewItem = self.animatedImageViewItem;
XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count);
NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject;
XCTAssertNotNil(attachmentId);
TSAttachment *_Nullable attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId];
XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]);
TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment;
NSString *_Nullable filePath = attachmentStream.filePath;
XCTAssertNotNil(filePath);
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
}
- (void)testPerformDeleteEditingActionWithVideoMessage
{
ConversationViewItem *viewItem = self.videoViewItem;
XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count);
NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject;
XCTAssertNotNil(attachmentId);
TSAttachment *_Nullable attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId];
XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]);
TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment;
NSString *_Nullable filePath = attachmentStream.filePath;
XCTAssertNotNil(filePath);
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
}
- (void)testPerformDeleteEditingActionWithAudioMessage
{
ConversationViewItem *viewItem = self.audioViewItem;
XCTAssertEqual((NSUInteger)1, ((TSMessage *)viewItem.interaction).attachmentIds.count);
NSString *_Nullable attachmentId = ((TSMessage *)viewItem.interaction).attachmentIds.firstObject;
XCTAssertNotNil(attachmentId);
TSAttachment *_Nullable attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId];
XCTAssertTrue([attachment isKindOfClass:[TSAttachmentStream class]]);
TSAttachmentStream *_Nullable attachmentStream = (TSAttachmentStream *)attachment;
NSString *_Nullable filePath = attachmentStream.filePath;
XCTAssertNotNil(filePath);
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNotNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
[viewItem deleteAction];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:viewItem.interaction.uniqueId]);
XCTAssertNil([TSAttachment fetchObjectWithUniqueID:attachmentId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
}
// Test Copy
- (void)testPerformCopyEditingActionWithNonMediaMessage
{
// Reset the pasteboard.
UIPasteboard.generalPasteboard.items = @[];
XCTAssertNil(UIPasteboard.generalPasteboard.string);
ConversationViewItem *viewItem = self.textViewItem;
[viewItem copyAction];
XCTAssertEqualObjects(self.fakeTextMessageText, UIPasteboard.generalPasteboard.string);
}
- (void)testPerformCopyEditingActionWithStillImageMessage
{
// Reset the pasteboard.
UIPasteboard.generalPasteboard.items = @[];
XCTAssertNil(UIPasteboard.generalPasteboard.image);
XCTAssertNil([UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeJPEG]);
ConversationViewItem *viewItem = self.stillImageViewItem;
[viewItem copyAction];
NSData *_Nullable copiedData = [UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeJPEG];
XCTAssertTrue(copiedData.length > 0);
}
- (void)testPerformCopyEditingActionWithAnimatedImageMessage
{
// Reset the pasteboard.
UIPasteboard.generalPasteboard.items = @[];
XCTAssertNil(UIPasteboard.generalPasteboard.image);
XCTAssertNil([UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeGIF]);
ConversationViewItem *viewItem = self.animatedImageViewItem;
[viewItem copyAction];
NSData *_Nullable copiedData = [UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeGIF];
XCTAssertTrue(copiedData.length > 0);
}
- (void)testPerformCopyEditingActionWithVideoMessage
{
// Reset the pasteboard.
UIPasteboard.generalPasteboard.items = @[];
XCTAssertNil([UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeMPEG4]);
ConversationViewItem *viewItem = self.videoViewItem;
[viewItem copyAction];
NSData *_Nullable copiedData = [UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeMPEG4];
XCTAssertTrue(copiedData.length > 0);
}
- (void)testPerformCopyEditingActionWithMp3AudioMessage
{
// Reset the pasteboard.
UIPasteboard.generalPasteboard.items = @[];
XCTAssertNil([UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeMP3]);
ConversationViewItem *viewItem = self.audioViewItem;
[viewItem copyAction];
NSData *_Nullable copiedData = [UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeMP3];
XCTAssertTrue(copiedData.length > 0);
}
- (void)unknownAction:(id)sender
{
// It's easier to create this stub method than to suppress the "unknown selector" build warnings.
}
@end

View File

@ -1,335 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "TSAttachmentStream.h"
#import "TSOutgoingMessage.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <XCTest/XCTest.h>
@interface TSMessageAdapter (Testing)
// expose some private setters for ease of testing setup
@property (nonatomic, retain) NSString *messageBody;
@property JSQMediaItem *mediaItem;
@end
@interface TSMessageAdapterTest : XCTestCase
@property TSMessageAdapter *messageAdapter;
@property TSOutgoingMessage *message;
@property (readonly) NSData *fakeAudioData;
@property (readonly) NSData *fakeImageData;
@end
@implementation TSMessageAdapterTest
- (NSData *)fakeAudioData
{
NSString *fakeAudioString = @"QmxhY2tiaXJkIFJhdW0gRG90IE1QMw==";
return [[NSData alloc] initWithBase64EncodedString:fakeAudioString options:0];
}
- (NSData *)fakeVideoData
{
NSString *fakeVideoString = @"RmFrZSBWaWRlbyBEYXRh";
return [[NSData alloc] initWithBase64EncodedString:fakeVideoString options:0];
}
- (NSData *)fakeImageData
{
NSString *fakeString = @"RmFrZUltYWdlRGF0YQ==";
return [[NSData alloc] initWithBase64EncodedString:fakeString options:0];
}
- (void)setUp
{
[super setUp];
self.message = [[TSOutgoingMessage alloc] initWithTimestamp:1 inThread:nil messageBody:nil];
[self.message save];
self.messageAdapter = [TSMessageAdapter new];
self.messageAdapter.interaction = self.message;
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
// Test canPerformAction
- (void)testCanPerformEditingActionWithNonMediaMessage
{
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(delete:)]);
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(copy:)]);
XCTAssertFalse([self.messageAdapter canPerformEditingAction:NSSelectorFromString(@"save:")]);
//e.g. any other unsupported action
XCTAssertFalse([self.messageAdapter canPerformEditingAction:@selector(paste:)]);
}
- (void)testCanPerformEditingActionWithPhotoMessage
{
self.messageAdapter.mediaItem = [[TSPhotoAdapter alloc] init];
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(delete:)]);
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(copy:)]);
XCTAssertTrue([self.messageAdapter canPerformEditingAction:NSSelectorFromString(@"save:")]);
// e.g. any other unsupported action
XCTAssertFalse([self.messageAdapter canPerformEditingAction:@selector(paste:)]);
}
- (void)testCanPerformEditingActionWithAnimatedMessage
{
self.messageAdapter.mediaItem = [[TSAnimatedAdapter alloc] init];
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(delete:)]);
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(copy:)]);
XCTAssertTrue([self.messageAdapter canPerformEditingAction:NSSelectorFromString(@"save:")]);
// e.g. any other unsupported action
XCTAssertFalse([self.messageAdapter canPerformEditingAction:@selector(paste:)]);
}
- (void)testCanPerformEditingActionWithVideoMessage
{
TSAttachmentStream *videoAttachment =
[[TSAttachmentStream alloc] initWithContentType:@"video/mp4" sourceFilename:nil];
self.messageAdapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:videoAttachment incoming:NO];
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(delete:)]);
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(copy:)]);
XCTAssertTrue([self.messageAdapter canPerformEditingAction:NSSelectorFromString(@"save:")]);
// e.g. any other unsupported action
XCTAssertFalse([self.messageAdapter canPerformEditingAction:@selector(paste:)]);
}
- (void)testCanPerformEditingActionWithAudioMessage
{
TSAttachmentStream *audioAttachment =
[[TSAttachmentStream alloc] initWithContentType:@"audio/mp3" sourceFilename:nil];
self.messageAdapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:audioAttachment incoming:NO];
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(delete:)]);
XCTAssertTrue([self.messageAdapter canPerformEditingAction:@selector(copy:)]);
//e.g. Can't save an audio attachment at this time.
XCTAssertFalse([self.messageAdapter canPerformEditingAction:NSSelectorFromString(@"save:")]);
//e.g. any other unsupported action
XCTAssertFalse([self.messageAdapter canPerformEditingAction:@selector(paste:)]);
}
// Test Delete
- (void)testPerformDeleteEditingActionWithNonMediaMessage
{
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
[self.messageAdapter performEditingAction:@selector(delete:)];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
}
- (void)testPerformDeleteActionWithPhotoMessage
{
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
self.messageAdapter.mediaItem = [[TSPhotoAdapter alloc] init];
[self.messageAdapter performEditingAction:@selector(delete:)];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
// TODO assert files are deleted
}
- (void)testPerformDeleteEditingActionWithAnimatedMessage
{
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
self.messageAdapter.mediaItem = [[TSAnimatedAdapter alloc] init];
[self.messageAdapter performEditingAction:@selector(delete:)];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
// TODO assert files are deleted
}
- (void)testPerformDeleteEditingActionWithVideoMessage
{
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
NSError *error;
TSAttachmentStream *videoAttachment =
[[TSAttachmentStream alloc] initWithContentType:@"video/mp4" sourceFilename:nil];
[videoAttachment writeData:[NSData new] error:&error];
[videoAttachment save];
[self.message.attachmentIds addObject:videoAttachment.uniqueId];
[self.message save];
self.messageAdapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:videoAttachment incoming:NO];
// Sanity Check
XCTAssert([[NSFileManager defaultManager] fileExistsAtPath:videoAttachment.filePath]);
[self.messageAdapter performEditingAction:@selector(delete:)];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:videoAttachment.filePath]);
}
- (void)testPerformDeleteEditingActionWithAudioMessage
{
XCTAssertNotNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
NSError *error;
TSAttachmentStream *audioAttachment =
[[TSAttachmentStream alloc] initWithContentType:@"audio/mp3" sourceFilename:nil];
[audioAttachment writeData:[NSData new] error:&error];
[audioAttachment save];
[self.message.attachmentIds addObject:audioAttachment.uniqueId];
[self.message save];
// Sanity Check
XCTAssertNil(error);
XCTAssert([[NSFileManager defaultManager] fileExistsAtPath:audioAttachment.filePath]);
self.messageAdapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:audioAttachment incoming:NO];
[self.messageAdapter performEditingAction:@selector(delete:)];
XCTAssertNil([TSMessage fetchObjectWithUniqueID:self.message.uniqueId]);
XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:audioAttachment.filePath]);
}
// Test Copy
- (void)testPerformCopyEditingActionWithNonMediaMessage
{
self.messageAdapter.messageBody = @"My message text";
[self.messageAdapter performEditingAction:@selector(copy:)];
XCTAssertEqualObjects(@"My message text", UIPasteboard.generalPasteboard.string);
}
- (void)testPerformCopyEditingActionWithPhotoMessage
{
// reset the paste board for clean slate test
UIPasteboard.generalPasteboard.items = @[];
XCTAssertNil(UIPasteboard.generalPasteboard.image);
NSError *error;
TSAttachmentStream *attachment = [[TSAttachmentStream alloc] initWithContentType:@"image/jpeg" sourceFilename:nil];
[attachment writeData:self.fakeAudioData error:&error];
[attachment save];
// Sanity Check
XCTAssertNil(error);
XCTAssert([[NSFileManager defaultManager] fileExistsAtPath:attachment.filePath]);
[self.message.attachmentIds addObject:attachment.uniqueId];
[self.message save];
TSPhotoAdapter *photoAdapter = [[TSPhotoAdapter alloc] initWithAttachment:attachment incoming:NO];
// assign random image, since photoAdapter expects an image.
photoAdapter.image = [UIImage imageNamed:@"savephoto"];
self.messageAdapter.mediaItem = photoAdapter;
[self.messageAdapter performEditingAction:@selector(copy:)];
NSData *copiedData = [UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeJPEG];
XCTAssertEqualObjects(self.fakeAudioData, copiedData);
}
- (void)testPerformCopyEditingActionWithVideoMessage
{
// reset the paste board for clean slate test
UIPasteboard.generalPasteboard.items = @[];
NSError *error;
TSAttachmentStream *videoAttachment =
[[TSAttachmentStream alloc] initWithContentType:@"video/mp4" sourceFilename:nil];
[videoAttachment writeData:self.fakeVideoData error:&error];
self.messageAdapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:videoAttachment incoming:YES];
[self.messageAdapter performEditingAction:@selector(copy:)];
NSData *copiedData = [UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeMPEG4];
XCTAssertEqualObjects(self.fakeVideoData, copiedData);
}
- (void)testPerformCopyEditingActionWithMp3AudioMessage
{
UIPasteboard.generalPasteboard.items = @[];
XCTAssertNil([UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeMP3]);
NSError *error;
TSAttachmentStream *audioAttachment =
[[TSAttachmentStream alloc] initWithContentType:@"audio/mp3" sourceFilename:nil];
[audioAttachment writeData:self.fakeAudioData error:&error];
self.messageAdapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:audioAttachment incoming:NO];
[self.messageAdapter performEditingAction:@selector(copy:)];
XCTAssertEqualObjects(self.fakeAudioData, [UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeMP3]);
}
- (void)testPerformCopyEditingActionWithM4aAudioMessage
{
UIPasteboard.generalPasteboard.items = @[];
XCTAssertNil([UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeMPEG4Audio]);
NSError *error;
TSAttachmentStream *audioAttachment =
[[TSAttachmentStream alloc] initWithContentType:@"audio/x-m4a" sourceFilename:nil];
[audioAttachment writeData:self.fakeAudioData error:&error];
self.messageAdapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:audioAttachment incoming:NO];
[self.messageAdapter performEditingAction:@selector(copy:)];
XCTAssertEqualObjects(self.fakeAudioData, [UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeMPEG4Audio]);
}
- (void)testPerformCopyEditingActionWithGenericAudioMessage
{
UIPasteboard.generalPasteboard.items = @[];
XCTAssertNil([UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeAudio]);
NSError *error;
TSAttachmentStream *audioAttachment =
[[TSAttachmentStream alloc] initWithContentType:@"audio/wav" sourceFilename:nil];
[audioAttachment writeData:self.fakeAudioData error:&error];
self.messageAdapter.mediaItem = [[TSVideoAttachmentAdapter alloc] initWithAttachment:audioAttachment incoming:NO];
[self.messageAdapter performEditingAction:@selector(copy:)];
XCTAssertEqualObjects(self.fakeAudioData, [UIPasteboard.generalPasteboard dataForPasteboardType:(NSString *)kUTTypeAudio]);
}
// TODO - We don't currenlty have a good way of testing "copy of an animated message attachment"
// We need an attachment with some NSData, which requires getting into the crypto layer,
// which is outside of my realm.
//
// Since you can't currently PASTE images into our version of JSQMessageViewController, I tested this by pasting
// into native Messages client, and verifying the result was animated.
//
//- (void)testPerformCopyActionWithAnimatedMessage
//{
// // reset the paste board for clean slate test
// UIPasteboard.generalPasteboard.items = @[];
// XCTAssertNil(UIPasteboard.generalPasteboard.image);
//
// // "some-animated-gif" doesn't exist yet
// NSData *imageData = [[NSData alloc] initWithContentsOfFile:@"some-animated-gif"];
// //TODO build attachment with imageData
// TSAttachmentStream animatedAttachement = [[TSAttachmentStream alloc] initWithIdentifier:@"test-animated-attachment-id" data:imageDatq key:@"TODO" contentType:@"image/gif"];
// TSAnimatedAdapter *animatedAdapter = [[TSAnimatedAdapter alloc] initWithAttachment:animatedAttachment];
// animatedAdapter.image = image;
// self.messageAdapter.mediaItem = animatedAdapter;
// [self.messageAdapter performEditingAction:@selector(copy:)];
//
// // TODO XCTAssert that image is copied as a GIF (e.g. not convereted to a PNG, etc.)
// // We want to be sure that we can copy/paste an animated GIF from
// // one thread to the other, and ensure it's still animated.
//}
@end

View File

@ -1,5 +0,0 @@
#import <XCTest/XCTest.h>
@interface QueueTest : XCTestCase
@end

View File

@ -1,31 +0,0 @@
#import "Queue.h"
#import "QueueTest.h"
#import "TestUtil.h"
@implementation QueueTest
- (void)testQueue {
Queue *q = [Queue new];
test(q.count == 0);
testThrows(q.peek);
testThrows([q dequeue]);
[q enqueue:@5];
test(q.count == 1);
test([q.peek isEqualToNumber:@5]);
[q enqueue:@23];
test(q.count == 2);
test([q.peek isEqualToNumber:@5]);
test([[q dequeue] isEqualToNumber:@5]);
test(q.count == 1);
test([q.peek isEqualToNumber:@23]);
test([[q dequeue] isEqualToNumber:@23]);
test(q.count == 0);
testThrows(q.peek);
testThrows([q dequeue]);
}
@end

View File

@ -3,10 +3,13 @@
//
#import "MIMETypeUtil.h"
#if TARGET_OS_IPHONE
#import <MobileCoreServices/MobileCoreServices.h>
#else
#import <CoreServices/CoreServices.h>
#endif
NS_ASSUME_NONNULL_BEGIN