mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
@room pill (#1834)
* all users mention pill + red higlight for own mentions * more tests * changelog * removed useless if let
This commit is contained in:
@@ -418,9 +418,59 @@ class AttributedStringBuilderTests: XCTestCase {
|
||||
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
|
||||
XCTAssertNotNil(attributedStringFromHTML?.attachment)
|
||||
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
|
||||
XCTAssert(attributedStringFromPlain?.attachment.isNil == false)
|
||||
XCTAssertNotNil(attributedStringFromPlain?.attachment)
|
||||
}
|
||||
|
||||
func testAllUsersMentionAttachment() {
|
||||
let string = "@room"
|
||||
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
|
||||
checkAttachment(attributedString: attributedStringFromHTML, expectedRuns: 1)
|
||||
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
|
||||
checkAttachment(attributedString: attributedStringFromPlain, expectedRuns: 1)
|
||||
|
||||
let string2 = "Hello @room"
|
||||
let attributedStringFromHTML2 = attributedStringBuilder.fromHTML(string2)
|
||||
checkAttachment(attributedString: attributedStringFromHTML2, expectedRuns: 2)
|
||||
let attributedStringFromPlain2 = attributedStringBuilder.fromPlain(string2)
|
||||
checkAttachment(attributedString: attributedStringFromPlain2, expectedRuns: 2)
|
||||
|
||||
let string3 = "Hello @room how are you doing?"
|
||||
let attributedStringFromHTML3 = attributedStringBuilder.fromHTML(string3)
|
||||
checkAttachment(attributedString: attributedStringFromHTML3, expectedRuns: 3)
|
||||
let attributedStringFromPlain3 = attributedStringBuilder.fromPlain(string3)
|
||||
checkAttachment(attributedString: attributedStringFromPlain3, expectedRuns: 3)
|
||||
}
|
||||
|
||||
func testLinksHavePriorityOverAllUserMention() {
|
||||
let string = "https://test@room.org"
|
||||
let attributedStringFromHTML = attributedStringBuilder.fromHTML(string)
|
||||
checkLinkIn(attributedString: attributedStringFromHTML, expectedLink: string, expectedRuns: 1)
|
||||
let attributedStringFromPlain = attributedStringBuilder.fromPlain(string)
|
||||
checkLinkIn(attributedString: attributedStringFromPlain, expectedLink: string, expectedRuns: 1)
|
||||
|
||||
let string2 = "https://matrix.to/#/@roomusername:matrix.org"
|
||||
let attributedStringFromHTML2 = attributedStringBuilder.fromHTML(string2)
|
||||
checkLinkIn(attributedString: attributedStringFromHTML2, expectedLink: string2, expectedRuns: 1)
|
||||
checkAttachment(attributedString: attributedStringFromHTML2, expectedRuns: 1)
|
||||
let attributedStringFromPlain2 = attributedStringBuilder.fromPlain(string2)
|
||||
checkLinkIn(attributedString: attributedStringFromPlain2, expectedLink: string2, expectedRuns: 1)
|
||||
checkAttachment(attributedString: attributedStringFromPlain2, expectedRuns: 1)
|
||||
}
|
||||
|
||||
func testLinksAreIgnoredInCode() {
|
||||
let htmlString = "<pre><code>test https://matrix.org test</code></pre>"
|
||||
let attributedStringFromHTML = attributedStringBuilder.fromHTML(htmlString)
|
||||
XCTAssert(attributedStringFromHTML?.runs.count == 1)
|
||||
XCTAssertNil(attributedStringFromHTML?.link)
|
||||
}
|
||||
|
||||
func testAllUsersIsIgnoredInCode() {
|
||||
let htmlString = "<pre><code>test @room test</code></pre>"
|
||||
let attributedStringFromHTML = attributedStringBuilder.fromHTML(htmlString)
|
||||
XCTAssert(attributedStringFromHTML?.runs.count == 1)
|
||||
XCTAssertNil(attributedStringFromHTML?.attachment)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func checkLinkIn(attributedString: AttributedString?, expectedLink: String, expectedRuns: Int) {
|
||||
@@ -438,4 +488,19 @@ class AttributedStringBuilderTests: XCTestCase {
|
||||
|
||||
XCTFail("Couldn't find expected value.")
|
||||
}
|
||||
|
||||
private func checkAttachment(attributedString: AttributedString?, expectedRuns: Int) {
|
||||
guard let attributedString else {
|
||||
XCTFail("Could not build the attributed string")
|
||||
return
|
||||
}
|
||||
|
||||
XCTAssertEqual(attributedString.runs.count, expectedRuns)
|
||||
|
||||
for run in attributedString.runs where run.attachment != nil {
|
||||
return
|
||||
}
|
||||
|
||||
XCTFail("Couldn't find expected value.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,4 +64,13 @@ class MatrixEntityRegexTests: XCTestCase {
|
||||
XCTAssertFalse(MatrixEntityRegex.isMatrixEventIdentifier("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg:"))
|
||||
XCTAssertFalse(MatrixEntityRegex.isMatrixEventIdentifier("$Rqnc-F-dvnEYJTyHq_iKxU2bZ1CI92-kuZq3a5lr5Zg?"))
|
||||
}
|
||||
|
||||
func testAllUsers() {
|
||||
XCTAssertTrue(MatrixEntityRegex.containsMatrixAllUsers("@room"))
|
||||
XCTAssertTrue(MatrixEntityRegex.containsMatrixAllUsers("a@rooma"))
|
||||
XCTAssertTrue(MatrixEntityRegex.containsMatrixAllUsers("a @room a"))
|
||||
XCTAssertFalse(MatrixEntityRegex.containsMatrixAllUsers("a @roaom a"))
|
||||
XCTAssertFalse(MatrixEntityRegex.containsMatrixAllUsers("@roaom"))
|
||||
XCTAssertTrue(MatrixEntityRegex.containsMatrixAllUsers("@room\n"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
//
|
||||
// Copyright 2023 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import XCTest
|
||||
|
||||
@testable import ElementX
|
||||
|
||||
@MainActor
|
||||
class PillContextTests: XCTestCase {
|
||||
func testUser() async throws {
|
||||
let id = "@test:matrix.org"
|
||||
let proxyMock = RoomProxyMock(with: .init(displayName: "Test"))
|
||||
let subject = CurrentValueSubject<[RoomMemberProxyProtocol], Never>([])
|
||||
proxyMock.members = subject.asCurrentValuePublisher()
|
||||
let mock = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomProxy: proxyMock,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
let context = PillContext(roomContext: mock.context, data: PillTextAttachmentData(type: .user(userID: id), font: .preferredFont(forTextStyle: .body)))
|
||||
|
||||
XCTAssertFalse(context.viewState.isOwnMention)
|
||||
XCTAssertNil(context.viewState.avatarURL)
|
||||
XCTAssertNil(context.viewState.name)
|
||||
XCTAssertEqual(context.viewState.contentID, id)
|
||||
XCTAssertEqual(context.viewState.displayText, id)
|
||||
|
||||
let name = "Mr. Test"
|
||||
let avatarURL = URL(string: "https://test.jpg")
|
||||
subject.send([RoomMemberProxyMock(with: .init(userID: id, displayName: name, avatarURL: avatarURL, membership: .join))])
|
||||
await Task.yield()
|
||||
|
||||
XCTAssertFalse(context.viewState.isOwnMention)
|
||||
XCTAssertEqual(context.viewState.avatarURL, avatarURL)
|
||||
XCTAssertEqual(context.viewState.name, name)
|
||||
XCTAssertEqual(context.viewState.contentID, id)
|
||||
XCTAssertEqual(context.viewState.displayText, name)
|
||||
}
|
||||
|
||||
func testOwnUser() async throws {
|
||||
let id = "@test:matrix.org"
|
||||
let proxyMock = RoomProxyMock(with: .init(displayName: "Test", ownUserID: id))
|
||||
let subject = CurrentValueSubject<[RoomMemberProxyProtocol], Never>([])
|
||||
proxyMock.members = subject.asCurrentValuePublisher()
|
||||
let mock = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomProxy: proxyMock,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
let context = PillContext(roomContext: mock.context, data: PillTextAttachmentData(type: .user(userID: id), font: .preferredFont(forTextStyle: .body)))
|
||||
|
||||
XCTAssertTrue(context.viewState.isOwnMention)
|
||||
}
|
||||
|
||||
func testAllUsers() async throws {
|
||||
let avatarURL = URL(string: "https://matrix.jpg")
|
||||
let id = "test_room"
|
||||
let displayName = "Test"
|
||||
let proxyMock = RoomProxyMock(with: .init(id: id, displayName: displayName, avatarURL: avatarURL))
|
||||
let mockController = MockRoomTimelineController()
|
||||
mockController.roomProxy = proxyMock
|
||||
let mock = RoomScreenViewModel(timelineController: mockController,
|
||||
mediaProvider: MockMediaProvider(),
|
||||
roomProxy: proxyMock,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
let context = PillContext(roomContext: mock.context, data: PillTextAttachmentData(type: .allUsers, font: .preferredFont(forTextStyle: .body)))
|
||||
|
||||
XCTAssertTrue(context.viewState.isOwnMention)
|
||||
XCTAssertEqual(context.viewState.avatarURL, avatarURL)
|
||||
XCTAssertEqual(context.viewState.name, displayName)
|
||||
XCTAssertEqual(context.viewState.contentID, id)
|
||||
XCTAssertEqual(context.viewState.displayText, "@room")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user