diff --git a/GliaWidgets.xcodeproj/project.pbxproj b/GliaWidgets.xcodeproj/project.pbxproj index 88f004aa8..24dcdff5b 100644 --- a/GliaWidgets.xcodeproj/project.pbxproj +++ b/GliaWidgets.xcodeproj/project.pbxproj @@ -195,6 +195,7 @@ 2188DEE92CEE2E3400FA3BEF /* SecureMessagingTopBannerViewStyle.RemoteConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2188DEE82CEE2E3400FA3BEF /* SecureMessagingTopBannerViewStyle.RemoteConfig.swift */; }; 2198B7AC2CAEB14D002C442B /* QueuesMonitor.Live.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2198B7AB2CAEB14D002C442B /* QueuesMonitor.Live.swift */; }; 2198B7AE2CB035A6002C442B /* QueuesMonitor.Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2198B7AD2CB035A6002C442B /* QueuesMonitor.Environment.swift */; }; + 21BADEB92D280E01000AD9CF /* MockConfiguration.json in Resources */ = {isa = PBXBuildFile; fileRef = 21BADEB82D280E01000AD9CF /* MockConfiguration.json */; }; 23D69155F4F4C5043173EF05 /* Pods_GliaWidgets.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7A5CDD05FB57D55971AA68A /* Pods_GliaWidgets.framework */; }; 3100D929296E946600DEC9CE /* SecureConversations.ConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3100D924296E946600DEC9CE /* SecureConversations.ConfirmationView.swift */; }; 3100D92A296E946600DEC9CE /* Theme+SecureConversationsConfirmation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3100D925296E946600DEC9CE /* Theme+SecureConversationsConfirmation.swift */; }; @@ -1281,6 +1282,7 @@ 2188DEE82CEE2E3400FA3BEF /* SecureMessagingTopBannerViewStyle.RemoteConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureMessagingTopBannerViewStyle.RemoteConfig.swift; sourceTree = ""; }; 2198B7AB2CAEB14D002C442B /* QueuesMonitor.Live.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueuesMonitor.Live.swift; sourceTree = ""; }; 2198B7AD2CB035A6002C442B /* QueuesMonitor.Environment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueuesMonitor.Environment.swift; sourceTree = ""; }; + 21BADEB82D280E01000AD9CF /* MockConfiguration.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = MockConfiguration.json; path = ../../../../../Downloads/MockConfiguration.json; sourceTree = ""; }; 235300A49A5836A51EB1C4E8 /* Pods-GliaWidgets.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GliaWidgets.release.xcconfig"; path = "Target Support Files/Pods-GliaWidgets/Pods-GliaWidgets.release.xcconfig"; sourceTree = ""; }; 2797F86D83B9055FAD6E596E /* Pods-SnapshotTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SnapshotTests.debug.xcconfig"; path = "Target Support Files/Pods-SnapshotTests/Pods-SnapshotTests.debug.xcconfig"; sourceTree = ""; }; 3100D924296E946600DEC9CE /* SecureConversations.ConfirmationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecureConversations.ConfirmationView.swift; sourceTree = ""; }; @@ -3428,6 +3430,14 @@ path = QueuesMonitor; sourceTree = ""; }; + 21BADEB72D280DF4000AD9CF /* Resources */ = { + isa = PBXGroup; + children = ( + 21BADEB82D280E01000AD9CF /* MockConfiguration.json */, + ); + path = Resources; + sourceTree = ""; + }; 3100D921296E943100DEC9CE /* Welcome */ = { isa = PBXGroup; children = ( @@ -4532,6 +4542,7 @@ 9A1992CE27D61F5400161AAE /* SnapshotTests */ = { isa = PBXGroup; children = ( + 21BADEB72D280DF4000AD9CF /* Resources */, C07F62752AC1BA0E003EFC97 /* extensions */, 846E822728996A5C008EFBF0 /* AlertViewControllerVoiceOverTests.swift */, AF22C8842A6154780004BF3C /* AlertViewControllerLayoutTests.swift */, @@ -5604,6 +5615,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 21BADEB92D280E01000AD9CF /* MockConfiguration.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/GliaWidgets/Sources/ViewController/Chat/ChatViewController.Mock.swift b/GliaWidgets/Sources/ViewController/Chat/ChatViewController.Mock.swift index 024763fbb..54d36945b 100644 --- a/GliaWidgets/Sources/ViewController/Chat/ChatViewController.Mock.swift +++ b/GliaWidgets/Sources/ViewController/Chat/ChatViewController.Mock.swift @@ -639,43 +639,56 @@ extension ChatViewController { return controller } - static func mockSecureMessagingBottomBannerView() -> ChatViewController { + static func mockSecureMessagingBottomBannerView(theme: Theme = Theme.mock()) -> ChatViewController { var chatViewModelEnv = ChatViewModel.Environment.mock chatViewModelEnv.fileManager.urlsForDirectoryInDomainMask = { _, _ in [.mock] } let chatViewModel = ChatViewModel.mock(environment: chatViewModelEnv) let transcriptModel = SecureConversations.TranscriptModel.init( isCustomCardSupported: false, - environment: .mock(), + environment: .mock(secureMessagingExpandedTopBannerItemsStyle: theme.chatStyle.secureMessagingExpandedTopBannerItemsStyle), availability: .mock(), deliveredStatusText: "deliveredStatusText", failedToDeliverStatusText: "failedToDeliverStatusText", interactor: .mock() ) - return .init(viewModel: .transcript(transcriptModel), environment: .mock()) + return .init(viewModel: .transcript(transcriptModel), environment: .mock(viewFactory: .mock(theme: theme))) } static func mockSecureMessagingTopAndBottomBannerView( - entryWidgetViewState: EntryWidget.ViewState = .loading + entryWidgetViewState: EntryWidget.ViewState = .loading, + theme: Theme = Theme.mock() ) -> ChatViewController { var chatViewModelEnv = ChatViewModel.Environment.mock chatViewModelEnv.fileManager.urlsForDirectoryInDomainMask = { _, _ in [.mock] } let transcriptModel = SecureConversations.TranscriptModel.init( isCustomCardSupported: false, - environment: .mock(createEntryWidget: { configuration in - let entryWidget = EntryWidget.mock(configuration: configuration) - entryWidget.viewState = entryWidgetViewState - return entryWidget - }), + environment: .mock( + createEntryWidget: { configuration in + let newConfig = EntryWidget.Configuration( + sizeConstraints: configuration.sizeConstraints, + showPoweredBy: configuration.showPoweredBy, + filterSecureConversation: configuration.filterSecureConversation, + mediaTypeSelected: configuration.mediaTypeSelected, + mediaTypeItemsStyle: theme.chat.secureMessagingExpandedTopBannerItemsStyle + ) + let entryWidget = EntryWidget.mock( + configuration: newConfig + ) + entryWidget.viewState = entryWidgetViewState + return entryWidget + }, + secureMessagingExpandedTopBannerItemsStyle: theme.chatStyle.secureMessagingExpandedTopBannerItemsStyle + ), availability: .mock(), deliveredStatusText: "deliveredStatusText", failedToDeliverStatusText: "failedToDeliverStatusText", interactor: .mock() ) - return .init(viewModel: .transcript(transcriptModel), environment: .mock()) + return .init(viewModel: .transcript(transcriptModel), environment: .mock(viewFactory: .mock(theme: theme))) } } diff --git a/SnapshotTests/ChatViewControllerLayoutTests.swift b/SnapshotTests/ChatViewControllerLayoutTests.swift index f6220229c..63e85112d 100644 --- a/SnapshotTests/ChatViewControllerLayoutTests.swift +++ b/SnapshotTests/ChatViewControllerLayoutTests.swift @@ -105,4 +105,42 @@ final class ChatViewControllerLayoutTests: SnapshotTestCase { viewController.assertSnapshot(as: .image, in: .portrait) viewController.assertSnapshot(as: .image, in: .landscape) } + + func test_secureMessagingBottomAndCollapsedTopBannerWithUnifiedUI() { + guard let config = retrieveRemoteConfiguration() else { + XCTFail("Could not find MockConfiguration json") + return + } + let theme = Theme(uiConfig: config, assetsBuilder: .standard) + let viewController = ChatViewController.mockSecureMessagingBottomBannerView(theme: theme) + viewController.updateViewConstraints() + viewController.assertSnapshot(as: .image, in: .portrait) + viewController.assertSnapshot(as: .image, in: .landscape) + } + + func test_secureMessagingBottomAndExpandedTopBannerWithUnifiedUI() { + guard let config = retrieveRemoteConfiguration() else { + XCTFail("Could not find MockConfiguration json") + return + } + let theme = Theme(uiConfig: config, assetsBuilder: .standard) + let mockEntryWidgetViewState = EntryWidget.ViewState.mediaTypes( + [.init(type: .chat), .init(type: .video), .init(type: .audio)] + ) + let viewController = ChatViewController.mockSecureMessagingTopAndBottomBannerView( + entryWidgetViewState: mockEntryWidgetViewState, + theme: theme + ) + viewController.updateViewConstraints() + + (viewController.view as? ChatView)?.isTopBannerExpanded = true + viewController.updateViewConstraints() + + viewController.view.frame = UIScreen.main.bounds + viewController.view.setNeedsLayout() + viewController.view.layoutIfNeeded() + + viewController.assertSnapshot(as: .image, in: .portrait) + viewController.assertSnapshot(as: .image, in: .landscape) + } } diff --git a/SnapshotTests/SnapshotTestCase.swift b/SnapshotTests/SnapshotTestCase.swift index 0c1394e6a..76b5ff88e 100644 --- a/SnapshotTests/SnapshotTestCase.swift +++ b/SnapshotTests/SnapshotTestCase.swift @@ -93,6 +93,19 @@ extension SnapshotTestCase { } } +extension SnapshotTestCase { + func retrieveRemoteConfiguration(_ fileName: String? = "MockConfiguration") -> RemoteConfiguration? { + guard + let url = Bundle(for: Self.self).url(forResource: fileName, withExtension: "json"), + let jsonData = try? Data(contentsOf: url), + let config = try? JSONDecoder().decode(RemoteConfiguration.self, from: .init(jsonData)) + else { + return nil + } + return config + } +} + extension Snapshotting where Value == UIView, Format == UIImage { /// Snapshots the current view with colored overlays of each accessibility element it contains, as well as an /// approximation of the description that VoiceOver will read for each element.