mirror of
git://jb55.com/damus
synced 2024-09-18 19:23:49 +00:00
bf43842590
Testing of standard flow ------------------------ PASS Device: iPhone 14 Pro simulator iOS: 17.0 Damus: This commit Steps: 1. Delete and reinstall Damus 2. Go through onboarding until suggested users appear 3. Click "continue". Should slide into the post view. PASS 4. Post view should look similar to the Figma design file, but with examples as placeholders. PASS 5. Examples should switch every 3 seconds. PASS 6. Typing a first character causes the #introductions hashtag to be automatically added. PASS 7. Uploading an image makes progress view show up and not break layout. PASS 8. Clicking on "post" should post this note and dismiss onboarding view. PASS Testing of other flows ---------------------- PASS Device: iPhone 14 Pro simulator iOS: 17.0 Damus: This commit Special remark: Made local change to always show the onboarding suggestions, and speed up testing Coverage: 1. Clicking "skip" on suggested users view will skip into the post view. PASS 2. Clicking "cancel" on post view and then going to the normal post view reveals a blank draft. PASS 3. Clicking "cancel" dismisses onboarding view and does not post anything. PASS 4. Normal post view looks normal (not broken). PASS 5. Changing initial suggested post during onboarding, cancelling the post, and then re-entering normal post view reveals the draft with user modifications. PASS Changelog-Added: Suggest first post during onboarding Closes: https://github.com/damus-io/damus/issues/1338 Signed-off-by: Daniel D’Aquino <daniel@daquino.me> Signed-off-by: William Casarin <jb55@jb55.com>
170 lines
11 KiB
Swift
170 lines
11 KiB
Swift
//
|
||
// PostViewTests.swift
|
||
// damusTests
|
||
//
|
||
// Created by Daniel D’Aquino on 2023-08-19.
|
||
//
|
||
import Foundation
|
||
import XCTest
|
||
import SnapshotTesting
|
||
import SwiftUI
|
||
@testable import damus
|
||
import SwiftUI
|
||
|
||
final class PostViewTests: XCTestCase {
|
||
|
||
override func setUpWithError() throws {
|
||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||
}
|
||
|
||
override func tearDownWithError() throws {
|
||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||
}
|
||
|
||
func testTextWrapperViewWillWrapText() {
|
||
// Setup test variables to be passed into the TextViewWrapper
|
||
let tagModel: TagModel = TagModel()
|
||
var textHeight: CGFloat? = nil
|
||
let textHeightBinding: Binding<CGFloat?> = Binding(get: {
|
||
return textHeight
|
||
}, set: { newValue in
|
||
textHeight = newValue
|
||
})
|
||
|
||
// Setup the test view
|
||
let textEditorView = TextViewWrapper(
|
||
attributedText: .constant(NSMutableAttributedString(string: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")),
|
||
textHeight: textHeightBinding,
|
||
initialTextSuffix: nil,
|
||
cursorIndex: 9,
|
||
updateCursorPosition: { _ in return }
|
||
).environmentObject(tagModel)
|
||
let hostView = UIHostingController(rootView: textEditorView)
|
||
|
||
// Run snapshot check
|
||
assertSnapshot(matching: hostView, as: .image(on: .iPhoneSe(.portrait)))
|
||
}
|
||
|
||
/// Based on https://github.com/damus-io/damus/issues/1375
|
||
/// Tests whether the editor properly handles mention links after they have been added, to avoid manual editing of attributed links
|
||
func testMentionLinkEditorHandling() throws {
|
||
var content: NSMutableAttributedString
|
||
|
||
// Test normal insertion
|
||
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Hello"), replacementText: "@", replacementRange: NSRange(location: 0, length: 0), shouldBeAbleToChangeAutomatically: true)
|
||
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Hello "), replacementText: "@", replacementRange: NSRange(location: 6, length: 0), shouldBeAbleToChangeAutomatically: true)
|
||
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Helo "), replacementText: "l", replacementRange: NSRange(location: 3, length: 0), shouldBeAbleToChangeAutomatically: true)
|
||
|
||
// Test normal backspacing
|
||
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Hello"), replacementText: "", replacementRange: NSRange(location: 5, length: 1), shouldBeAbleToChangeAutomatically: true)
|
||
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Hello "), replacementText: "", replacementRange: NSRange(location: 6, length: 1), shouldBeAbleToChangeAutomatically: true)
|
||
checkMentionLinkEditorHandling(content: NSMutableAttributedString(string: "Helo "), replacementText: "", replacementRange: NSRange(location: 3, length: 1), shouldBeAbleToChangeAutomatically: true)
|
||
|
||
// Test normal insertion after mention link
|
||
content = NSMutableAttributedString(string: "Hello @user ")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 12, length: 0), shouldBeAbleToChangeAutomatically: true)
|
||
|
||
// Test insertion right at the end of a mention link, at the end of the text
|
||
content = NSMutableAttributedString(string: "Hello @user")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: ",", replacementRange: NSRange(location: 11, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 12, handleNewContent: { newManuallyEditedContent in
|
||
XCTAssertEqual(newManuallyEditedContent.string, "Hello @user,")
|
||
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 11, effectiveRange: nil))
|
||
})
|
||
|
||
// Test insertion right at the end of a mention link, in the middle of the text
|
||
content = NSMutableAttributedString(string: "Hello @user how are you?")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: ",", replacementRange: NSRange(location: 11, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 12, handleNewContent: { newManuallyEditedContent in
|
||
XCTAssertEqual(newManuallyEditedContent.string, "Hello @user, how are you?")
|
||
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 11, effectiveRange: nil))
|
||
})
|
||
|
||
// Test insertion in the middle of a mention link to check if the link is removed
|
||
content = NSMutableAttributedString(string: "Hello @user how are you?")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 8, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 9, handleNewContent: { newManuallyEditedContent in
|
||
XCTAssertEqual(newManuallyEditedContent.string, "Hello @uaser how are you?")
|
||
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 8, effectiveRange: nil))
|
||
})
|
||
|
||
// Test insertion in the middle of a mention link to check if the link is removed, at the end of the text
|
||
content = NSMutableAttributedString(string: "Hello @user")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 8, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 9, handleNewContent: { newManuallyEditedContent in
|
||
XCTAssertEqual(newManuallyEditedContent.string, "Hello @uaser")
|
||
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 8, effectiveRange: nil))
|
||
})
|
||
|
||
// Test backspacing right at the end of a mention link, at the end of the text
|
||
content = NSMutableAttributedString(string: "Hello @user")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: "", replacementRange: NSRange(location: 10, length: 1), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 10, handleNewContent: { newManuallyEditedContent in
|
||
XCTAssertEqual(newManuallyEditedContent.string, "Hello @use")
|
||
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 6, effectiveRange: nil))
|
||
})
|
||
|
||
// Test adding text right at the start of a mention link, to check that the link is removed
|
||
content = NSMutableAttributedString(string: "Hello @user")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 5))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 6, length: 0), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 7, handleNewContent: { newManuallyEditedContent in
|
||
XCTAssertEqual(newManuallyEditedContent.string, "Hello a@user")
|
||
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 7, effectiveRange: nil))
|
||
})
|
||
|
||
// Test that removing one link does not affect the other
|
||
content = NSMutableAttributedString(string: "Hello @user1 @user2")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 6))
|
||
content.addAttribute(.link, value: "damus:5678", range: NSRange(location: 13, length: 6))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: "", replacementRange: NSRange(location: 18, length: 1), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 18, handleNewContent: { newManuallyEditedContent in
|
||
XCTAssertEqual(newManuallyEditedContent.string, "Hello @user1 @user")
|
||
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 13, effectiveRange: nil))
|
||
XCTAssertNotNil(newManuallyEditedContent.attribute(.link, at: 6, effectiveRange: nil))
|
||
})
|
||
|
||
// Test that replacing a whole range intersecting with two links removes both links
|
||
content = NSMutableAttributedString(string: "Hello @user1 @user2")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 6))
|
||
content.addAttribute(.link, value: "damus:5678", range: NSRange(location: 13, length: 6))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: "a", replacementRange: NSRange(location: 10, length: 4), shouldBeAbleToChangeAutomatically: false, expectedNewCursorIndex: 11, handleNewContent: { newManuallyEditedContent in
|
||
XCTAssertEqual(newManuallyEditedContent.string, "Hello @useauser2")
|
||
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 6, effectiveRange: nil))
|
||
XCTAssertNil(newManuallyEditedContent.attribute(.link, at: 11, effectiveRange: nil))
|
||
})
|
||
|
||
// Test that replacing a whole range including two links removes both links naturally
|
||
content = NSMutableAttributedString(string: "Hello @user1 @user2, how are you?")
|
||
content.addAttribute(.link, value: "damus:1234", range: NSRange(location: 6, length: 6))
|
||
content.addAttribute(.link, value: "damus:5678", range: NSRange(location: 13, length: 6))
|
||
checkMentionLinkEditorHandling(content: content, replacementText: "", replacementRange: NSRange(location: 5, length: 28), shouldBeAbleToChangeAutomatically: true)
|
||
|
||
}
|
||
}
|
||
|
||
func checkMentionLinkEditorHandling(
|
||
content: NSMutableAttributedString,
|
||
replacementText: String,
|
||
replacementRange: NSRange,
|
||
shouldBeAbleToChangeAutomatically: Bool,
|
||
expectedNewCursorIndex: Int? = nil,
|
||
handleNewContent: ((NSMutableAttributedString) -> Void)? = nil) {
|
||
let bindingContent: Binding<NSMutableAttributedString> = Binding(get: {
|
||
return content
|
||
}, set: { newValue in
|
||
handleNewContent?(newValue)
|
||
})
|
||
let coordinator: TextViewWrapper.Coordinator = TextViewWrapper.Coordinator(attributedText: bindingContent, getFocusWordForMention: nil, updateCursorPosition: { newCursorIndex in
|
||
if let expectedNewCursorIndex {
|
||
XCTAssertEqual(newCursorIndex, expectedNewCursorIndex)
|
||
}
|
||
}, initialTextSuffix: nil)
|
||
let textView = UITextView()
|
||
textView.attributedText = content
|
||
|
||
XCTAssertEqual(coordinator.textView(textView, shouldChangeTextIn: replacementRange, replacementText: replacementText), shouldBeAbleToChangeAutomatically, "Expected shouldChangeTextIn to return \(shouldBeAbleToChangeAutomatically), but was \(!shouldBeAbleToChangeAutomatically)")
|
||
}
|
||
|
||
|
||
|