diff --git a/RiotSwiftUI/Modules/Common/InfoSheet/InfoView.swift b/RiotSwiftUI/Modules/Common/InfoSheet/InfoSheet.swift similarity index 82% rename from RiotSwiftUI/Modules/Common/InfoSheet/InfoView.swift rename to RiotSwiftUI/Modules/Common/InfoSheet/InfoSheet.swift index ae88ee61e..3ad961d46 100644 --- a/RiotSwiftUI/Modules/Common/InfoSheet/InfoView.swift +++ b/RiotSwiftUI/Modules/Common/InfoSheet/InfoSheet.swift @@ -16,7 +16,7 @@ import SwiftUI -struct InfoView: View { +struct InfoSheet: View { struct Action { let text: String let action: () -> Void @@ -65,8 +65,8 @@ struct InfoView: View { struct InfoView_Previews: PreviewProvider { static var previews: some View { - InfoView(title: "Verified sessions", - description: "Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.\n\nThis means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.", - action: .init(text: "GOT IT", action: {})) + InfoSheet(title: "Verified sessions", + description: "Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.\n\nThis means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.", + action: .init(text: "GOT IT", action: {})) } } diff --git a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessions.swift b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessions.swift index 2784d191e..b6be2047d 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessions.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserOtherSessions/View/UserOtherSessions.swift @@ -59,7 +59,7 @@ struct UserOtherSessions: View { .navigationBarBackButtonHidden(viewModel.isEditModeEnabled) .accentColor(theme.colors.accent) .bottomSheet(isPresented: $viewModel.showBottomSheet) { - InfoView(title: viewModel.viewState.bottomSheetTitle, + InfoSheet(title: viewModel.viewState.bottomSheetTitle, description: viewModel.viewState.bottomSheetDescription, action: .init(text: VectorL10n.userSessionGotIt, action: { viewModel.showBottomSheet = false })) } diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionName/View/UserSessionName.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionName/View/UserSessionName.swift index 6a9ad2715..5b8518fb5 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionName/View/UserSessionName.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionName/View/UserSessionName.swift @@ -31,9 +31,9 @@ struct UserSessionName: View { .toolbar { toolbar } .accentColor(theme.colors.accent) .bottomSheet(isPresented: $viewModel.showBottomSheet) { - InfoView(title: VectorL10n.userSessionRenameSessionTitle, - description: VectorL10n.userSessionRenameSessionDescription, - action: .init(text: VectorL10n.userSessionGotIt, action: { viewModel.showBottomSheet = false })) + InfoSheet(title: VectorL10n.userSessionRenameSessionTitle, + description: VectorL10n.userSessionRenameSessionDescription, + action: .init(text: VectorL10n.userSessionGotIt, action: { viewModel.showBottomSheet = false })) } } diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/MockUserSessionOverviewScreenState.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/MockUserSessionOverviewScreenState.swift index c831a5585..77ffc160d 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/MockUserSessionOverviewScreenState.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/MockUserSessionOverviewScreenState.swift @@ -23,8 +23,8 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable { // A case for each state you want to represent // with specific, minimal associated data that will allow you // mock that screen. - case currentSession - case otherSession + case currentSession(sessionState: UserSessionInfo.VerificationState) + case otherSession(sessionState: UserSessionInfo.VerificationState) case sessionWithPushNotifications(enabled: Bool) case remotelyTogglingPushersNotAvailable @@ -35,8 +35,10 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable { /// A list of screen state definitions static var allCases: [MockUserSessionOverviewScreenState] { - [.currentSession, - .otherSession, + [.currentSession(sessionState: .unverified), + .currentSession(sessionState: .verified), + .otherSession(sessionState: .verified), + .otherSession(sessionState: .unverified), .sessionWithPushNotifications(enabled: true), .sessionWithPushNotifications(enabled: false), .remotelyTogglingPushersNotAvailable] @@ -47,11 +49,11 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable { let session: UserSessionInfo let service: UserSessionOverviewServiceProtocol switch self { - case .currentSession: + case .currentSession(let state): session = UserSessionInfo(id: "alice", name: "iOS", deviceType: .mobile, - verificationState: .unverified, + verificationState: state, lastSeenIP: "10.0.0.10", lastSeenTimestamp: nil, applicationName: "Element iOS", @@ -65,11 +67,11 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable { isActive: true, isCurrent: true) service = MockUserSessionOverviewService() - case .otherSession: + case .otherSession(let state): session = UserSessionInfo(id: "1", name: "macOS", deviceType: .desktop, - verificationState: .verified, + verificationState: state, lastSeenIP: "1.0.0.1", lastSeenTimestamp: Date().timeIntervalSince1970 - 130_000, applicationName: "Element MacOS", @@ -126,3 +128,18 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable { return ([viewModel], AnyView(UserSessionOverview(viewModel: viewModel.context))) } } + +extension MockUserSessionOverviewScreenState: CustomStringConvertible { + var description: String { + switch self { + case .currentSession(let sessionState): + return "currentSession\(sessionState)" + case .otherSession(let sessionState): + return "otherSession\(sessionState)" + case .remotelyTogglingPushersNotAvailable: + return "remotelyTogglingPushersNotAvailable" + case .sessionWithPushNotifications(let enabled): + return "sessionWithPushNotifications\(enabled)" + } + } +} diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Test/UI/UserSessionOverviewUITests.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Test/UI/UserSessionOverviewUITests.swift index 7dfb4d04f..8cdb419a4 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Test/UI/UserSessionOverviewUITests.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Test/UI/UserSessionOverviewUITests.swift @@ -19,19 +19,19 @@ import XCTest class UserSessionOverviewUITests: MockScreenTestCase { func test_whenCurrentSessionSelected_correctNavTittleDisplayed() { - app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.currentSession.title) + app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.currentSession(sessionState: .unverified).title) let navTitle = VectorL10n.userSessionOverviewCurrentSessionTitle XCTAssertTrue(app.navigationBars[navTitle].staticTexts[navTitle].exists) } func test_whenOtherSessionSelected_correctNavTittleDisplayed() { - app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.otherSession.title) + app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.otherSession(sessionState: .verified).title) let navTitle = VectorL10n.userSessionOverviewSessionTitle XCTAssertTrue(app.navigationBars[navTitle].staticTexts[navTitle].exists) } func test_whenSessionOverviewPresented_sessionDetailsButtonExists() { - app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.currentSession.title) + app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.currentSession(sessionState: .unverified).title) XCTAssertTrue(app.buttons[VectorL10n.userSessionOverviewSessionDetailsButtonTitle].exists) } @@ -61,4 +61,30 @@ class UserSessionOverviewUITests: MockScreenTestCase { XCTAssertTrue(app.staticTexts[VectorL10n.userSessionPushNotifications].exists) XCTAssertTrue(app.staticTexts[VectorL10n.userSessionPushNotificationsMessage].exists) } + + func test_whenOtherSessionSelected_learnMoreButtonDoesnExist() { + let title = MockUserSessionOverviewScreenState.currentSession(sessionState: .verified).title + app.goToScreenWithIdentifier(title) + let buttonId = "\(VectorL10n.userOtherSessionVerifiedAdditionalInfo) \(VectorL10n.userSessionLearnMore)" + let button = app.buttons[buttonId] + XCTAssertFalse(button.exists) + } + + func test_whenOtherVerifiedSessionSelected_learnMoreButtonExists() { + app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.otherSession(sessionState: .verified).title) + let buttonId = "\(VectorL10n.userOtherSessionVerifiedAdditionalInfo) \(VectorL10n.userSessionLearnMore)" + let button = app.buttons[buttonId] + XCTAssertTrue(button.exists) + button.tap() + XCTAssertTrue(app.staticTexts[VectorL10n.userSessionVerifiedSessionTitle].exists) + } + + func test_whenOtherUnverifiedSessionSelected_learnMoreButtonExists() { + app.goToScreenWithIdentifier(MockUserSessionOverviewScreenState.otherSession(sessionState: .unverified).title) + let buttonId = "\(VectorL10n.userOtherSessionUnverifiedAdditionalInfo) \(VectorL10n.userSessionLearnMore)" + let button = app.buttons[buttonId] + XCTAssertTrue(button.exists) + button.tap() + XCTAssertTrue(app.staticTexts[VectorL10n.userSessionUnverifiedSessionTitle].exists) + } } diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/View/UserSessionOverview.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/View/UserSessionOverview.swift index 036d90a47..e2b7b02be 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/View/UserSessionOverview.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/View/UserSessionOverview.swift @@ -83,9 +83,9 @@ struct UserSessionOverview: View { } .accentColor(theme.colors.accent) .bottomSheet(isPresented: $viewModel.showBottomSheet) { - InfoView(title: viewModel.viewState.bottomSheetTitle, - description: viewModel.viewState.bottomSheetDescription, - action: .init(text: VectorL10n.userSessionGotIt, action: { viewModel.showBottomSheet = false })) + InfoSheet(title: viewModel.viewState.bottomSheetTitle, + description: viewModel.viewState.bottomSheetDescription, + action: .init(text: VectorL10n.userSessionGotIt, action: { viewModel.showBottomSheet = false })) } } }