From 8cedb4c8aa1b389ac041ec5e99299df6a792daae Mon Sep 17 00:00:00 2001 From: Yurii Dukhovnyi Date: Thu, 7 Sep 2023 00:00:26 +0300 Subject: [PATCH 1/2] Introduce list queue interface Added mechanism for fetching queue id dynamically and assigning into settings. MOB-2594 --- GliaWidgets/Public/Glia/Glia.swift | 27 ++++++++ GliaWidgets/Public/GliaError.swift | 1 + .../Cells/EnvironmentSettingsTextCell.swift | 14 +---- TestingApp/Settings/Cells/SettingsCell.swift | 22 +++---- .../Settings/Cells/SettingsColorCell.swift | 35 ++--------- .../Settings/Cells/SettingsFontCell.swift | 12 +--- .../Settings/Cells/SettingsSwitchCell.swift | 35 +---------- .../Settings/Cells/SettingsTextCell.swift | 61 +++++++++++++++---- .../Settings/SettingsViewController.swift | 34 +++++++++-- .../ViewController/ViewController.swift | 6 +- 10 files changed, 129 insertions(+), 118 deletions(-) diff --git a/GliaWidgets/Public/Glia/Glia.swift b/GliaWidgets/Public/Glia/Glia.swift index 00e1cb32a..84f2168bf 100644 --- a/GliaWidgets/Public/Glia/Glia.swift +++ b/GliaWidgets/Public/Glia/Glia.swift @@ -260,6 +260,33 @@ public class Glia { failure: { completion(.failure($0)) } ) } + + /// List all Queues of the configured site. + /// It is also possible to monitor Queues changes with [subscribeForUpdates](x-source-tag://subscribeForUpdates) method. + /// If the request is unsuccessful for any reason then the completion will have an Error. + /// - Parameters: + /// - completion: A callback that will return the Result struct with `Queue` list or `GliaCoreError` + /// + public func listQueues(_ completion: @escaping (Result<[Queue], Error>) -> Void) { + guard interactor != nil else { + completion(.failure(GliaError.sdkIsNotConfigured)) + return + } + + environment.coreSdk.listQueues { queues, error in + if let error { + completion(.failure(error)) + return + } + + if let queues { + completion(.success(queues)) + return + } + + completion(.failure(GliaError.internalError)) + } + } } // MARK: - Private diff --git a/GliaWidgets/Public/GliaError.swift b/GliaWidgets/Public/GliaError.swift index c1b669188..ee9349849 100644 --- a/GliaWidgets/Public/GliaError.swift +++ b/GliaWidgets/Public/GliaError.swift @@ -7,4 +7,5 @@ public enum GliaError: Error { case configuringDuringEngagementIsNotAllowed case clearingVisitorSessionDuringEngagementIsNotAllowed case startingEngagementWithNoQueueIdsIsNotAllowed + case internalError } diff --git a/TestingApp/Settings/Cells/EnvironmentSettingsTextCell.swift b/TestingApp/Settings/Cells/EnvironmentSettingsTextCell.swift index 2579772a6..25741da55 100644 --- a/TestingApp/Settings/Cells/EnvironmentSettingsTextCell.swift +++ b/TestingApp/Settings/Cells/EnvironmentSettingsTextCell.swift @@ -90,18 +90,8 @@ final class EnvironmentSettingsTextCell: SettingsCell { } private func layout() { - contentView.addSubview(stackView) - stackView.addArrangedSubview(segmentedControl) - stackView.addArrangedSubview(customEnvironmentUrlTextField) - stackView.translatesAutoresizingMaskIntoConstraints = false - var constraints = [NSLayoutConstraint](); defer { constraints.activate() } - let insets = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 20) - constraints += stackView.layoutInSuperview(edges: .vertical, insets: insets) - constraints += stackView.layoutInSuperview(edges: .trailing, insets: insets) - constraints += stackView.leadingAnchor.constraint( - equalTo: titleLabel.trailingAnchor, - constant: 10 - ) + contentStackView.addArrangedSubview(segmentedControl) + contentStackView.addArrangedSubview(customEnvironmentUrlTextField) } @objc diff --git a/TestingApp/Settings/Cells/SettingsCell.swift b/TestingApp/Settings/Cells/SettingsCell.swift index bae3e11a5..7883b753d 100644 --- a/TestingApp/Settings/Cells/SettingsCell.swift +++ b/TestingApp/Settings/Cells/SettingsCell.swift @@ -1,6 +1,9 @@ import UIKit class SettingsCell: UITableViewCell { + lazy var contentStackView = UIStackView.make(.horizontal, spacing: 8)( + titleLabel + ) let titleLabel = UILabel() init(title: String) { @@ -21,20 +24,17 @@ class SettingsCell: UITableViewCell { titleLabel.font = .systemFont(ofSize: 15) titleLabel.textColor = .darkGray titleLabel.numberOfLines = 0 + titleLabel.lineBreakMode = .byWordWrapping + titleLabel.minimumScaleFactor = 0.8 } private func layout() { - contentView.addSubview(titleLabel) - titleLabel.translatesAutoresizingMaskIntoConstraints = false + contentStackView.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(contentStackView) var constraints = [NSLayoutConstraint](); defer { constraints.activate() } - let insets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 0) - constraints += titleLabel.layoutInSuperview( - edges: .vertical, - insets: insets - ) - constraints += titleLabel.layoutInSuperview( - edges: .leading, - insets: insets - ) + let insets = UIEdgeInsets(top: 4, left: 16, bottom: 4, right: 16) + constraints += contentStackView.layoutInSuperview(insets: insets) + + titleLabel.setContentCompressionResistancePriority(.required, for: .horizontal) } } diff --git a/TestingApp/Settings/Cells/SettingsColorCell.swift b/TestingApp/Settings/Cells/SettingsColorCell.swift index 0fd3d56e6..70dd03acd 100644 --- a/TestingApp/Settings/Cells/SettingsColorCell.swift +++ b/TestingApp/Settings/Cells/SettingsColorCell.swift @@ -41,40 +41,15 @@ class SettingsColorCell: SettingsCell { } private func layout() { - contentView.addSubview(sampleView) - sampleView.translatesAutoresizingMaskIntoConstraints = false + contentStackView.addArrangedSubview(UIView()) + contentStackView.addArrangedSubview(sampleView) + contentStackView.addArrangedSubview(rgbTextField) + contentStackView.addArrangedSubview(alphaTextField) + var constraints = [NSLayoutConstraint](); defer { constraints.activate() } constraints += sampleView.match(value: 30) - constraints += sampleView.leadingAnchor.constraint( - greaterThanOrEqualTo: titleLabel.trailingAnchor, - constant: 20 - ) - constraints += sampleView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor) - - contentView.addSubview(rgbTextField) - rgbTextField.translatesAutoresizingMaskIntoConstraints = false constraints += rgbTextField.match(.width, value: 100) - constraints += rgbTextField.layoutInSuperview( - edges: .vertical, - insets: .init(top: 10, left: 0, bottom: 10, right: 0) - ) - constraints += rgbTextField.leadingAnchor.constraint( - equalTo: sampleView.trailingAnchor, - constant: 10 - ) - - contentView.addSubview(alphaTextField) - alphaTextField.translatesAutoresizingMaskIntoConstraints = false constraints += alphaTextField.match(.width, value: 50) - constraints += alphaTextField.centerYAnchor.constraint(equalTo: contentView.centerYAnchor) - constraints += alphaTextField.leadingAnchor.constraint( - equalTo: rgbTextField.trailingAnchor, - constant: 10 - ) - constraints += alphaTextField.layoutInSuperview( - edges: .trailing, - insets: UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 20) - ) } @objc private func updateSample() { diff --git a/TestingApp/Settings/Cells/SettingsFontCell.swift b/TestingApp/Settings/Cells/SettingsFontCell.swift index d094b9820..a5124e0c1 100644 --- a/TestingApp/Settings/Cells/SettingsFontCell.swift +++ b/TestingApp/Settings/Cells/SettingsFontCell.swift @@ -42,17 +42,7 @@ class SettingsFontCell: SettingsCell { } private func layout() { - contentView.addSubview(pickerView) - pickerView.translatesAutoresizingMaskIntoConstraints = false - var constraints = [NSLayoutConstraint](); defer { constraints.activate() } - constraints += pickerView.match(value: 240) - constraints += pickerView.leadingAnchor.constraint( - equalTo: titleLabel.trailingAnchor, - constant: 10 - ) - let insets = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 20) - constraints += pickerView.layoutInSuperview(edges: .vertical, insets: insets) - constraints += pickerView.layoutInSuperview(edges: .trailing, insets: insets) + contentStackView.addArrangedSubview(pickerView) } private func selectDefaultFont() { diff --git a/TestingApp/Settings/Cells/SettingsSwitchCell.swift b/TestingApp/Settings/Cells/SettingsSwitchCell.swift index bb2ec13fa..9884c4787 100644 --- a/TestingApp/Settings/Cells/SettingsSwitchCell.swift +++ b/TestingApp/Settings/Cells/SettingsSwitchCell.swift @@ -10,38 +10,7 @@ final class SettingsSwitchCell: SettingsCell { } private func layout() { - contentView.addSubview(switcher) - switcher.translatesAutoresizingMaskIntoConstraints = false - var constraints = [NSLayoutConstraint](); defer { constraints.activate() } - let insets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 20) - constraints += switcher.layoutInSuperview(edges: .vertical, insets: insets) - constraints += switcher.layoutInSuperview(edges: .trailing, insets: insets) - constraints += switcher.leadingAnchor.constraint( - equalTo: titleLabel.trailingAnchor, - constant: 10 - ) - } -} - -final class SettingsSegmentedCell: SettingsCell { - let segmentedControl: UISegmentedControl - - init(title: String, items: String...) { - self.segmentedControl = .init(items: items.map(NSString.init(string:))) - super.init(title: title) - layout() - } - - private func layout() { - contentView.addSubview(segmentedControl) - segmentedControl.translatesAutoresizingMaskIntoConstraints = false - var constraints = [NSLayoutConstraint](); defer { constraints.activate() } - let insets = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 20) - constraints += segmentedControl.layoutInSuperview(edges: .vertical, insets: insets) - constraints += segmentedControl.layoutInSuperview(edges: .trailing, insets: insets) - constraints += segmentedControl.leadingAnchor.constraint( - equalTo: titleLabel.trailingAnchor, - constant: 10 - ) + titleLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + contentStackView.addArrangedSubview(switcher) } } diff --git a/TestingApp/Settings/Cells/SettingsTextCell.swift b/TestingApp/Settings/Cells/SettingsTextCell.swift index 71cc3f92f..0de39ea50 100644 --- a/TestingApp/Settings/Cells/SettingsTextCell.swift +++ b/TestingApp/Settings/Cells/SettingsTextCell.swift @@ -2,31 +2,68 @@ import UIKit class SettingsTextCell: SettingsCell { let textField = UITextField() + var button: UIButton? - init(title: String, text: String) { + init( + title: String, + text: String, + isRequired: Bool = false, + extraButton: ExtraButton? = nil + ) { textField.text = text + if let extraButton { + self.button = .init(type: .system) + self.button?.setTitle(extraButton.title, for: .normal) + self.button?.addTarget(extraButton, action: #selector(extraButton.onTouchUpInside), for: .touchUpInside) + } + self.extraButton = extraButton + self.isRequired = isRequired + super.init(title: title) + + if isRequired { + let attributedString = NSMutableAttributedString(string: "\(title) *") + attributedString.setAttributes([.foregroundColor: UIColor.red.cgColor], range: .init(location: attributedString.length - 1, length: 1)) + titleLabel.attributedText = attributedString + } setup() layout() } + // MARK: - Private + + private let extraButton: ExtraButton? + private let isRequired: Bool + private func setup() { textField.borderStyle = .roundedRect textField.autocorrectionType = .no textField.autocapitalizationType = .none + if let button { + addSubview(button) + } } private func layout() { - contentView.addSubview(textField) - textField.translatesAutoresizingMaskIntoConstraints = false - var constraints = [NSLayoutConstraint](); defer { constraints.activate() } - constraints += textField.widthAnchor.constraint( - equalTo: contentView.widthAnchor, - multiplier: 0.7 - ) - constraints += textField.leadingAnchor.constraint(greaterThanOrEqualTo: titleLabel.trailingAnchor, constant: 10) - let insets = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 20) - constraints += textField.layoutInSuperview(edges: .vertical, insets: insets) - constraints += textField.layoutInSuperview(edges: .trailing, insets: insets) + contentStackView.addArrangedSubview(textField) + if let button { + contentStackView.addArrangedSubview(button) + } + } +} + +extension SettingsTextCell { + class ExtraButton { + let title: String + let tap: () -> Void + + init(title: String, tap: @escaping () -> Void) { + self.title = title + self.tap = tap + } + + @objc func onTouchUpInside() { + tap() + } } } diff --git a/TestingApp/Settings/SettingsViewController.swift b/TestingApp/Settings/SettingsViewController.swift index b240e0a3d..0cfdd1eaa 100644 --- a/TestingApp/Settings/SettingsViewController.swift +++ b/TestingApp/Settings/SettingsViewController.swift @@ -97,22 +97,48 @@ private extension SettingsViewController { private func createCells() { siteApiKeyIdCell = SettingsTextCell( title: "Identifier:", - text: props.config.siteApiKeyId + text: props.config.siteApiKeyId, + isRequired: true ) siteApiKeyIdCell.textField.accessibilityIdentifier = "settings_siteApiKeyId_textfield" siteApiKeySecretCell = SettingsTextCell( title: "Secret:", - text: props.config.siteApiKeySecret + text: props.config.siteApiKeySecret, + isRequired: true ) siteApiKeySecretCell.textField.accessibilityIdentifier = "settings_siteApiKeySecret_textfield" siteCell = SettingsTextCell( title: "Site:", - text: props.config.site + text: props.config.site, + isRequired: true ) siteCell.textField.accessibilityIdentifier = "settings_siteId_textfield" queueIDCell = SettingsTextCell( title: "Queue ID:", - text: props.queueId + text: props.queueId, + extraButton: .init(title: "List queues", tap: { [weak self] in + let alert = UIAlertController(title: "List queues", message: "Please choose queue", preferredStyle: .alert) + + Glia.sharedInstance.listQueues { [weak self] result in + switch result { + case .success(let queues): + queues.forEach { queue in + alert.addAction(.init(title: queue.name, style: .default) { _ in + self?.queueIDCell.textField.text = queue.id + self?.props.changeQueueId(queue.id) + alert.dismiss(animated: true) + }) + } + case .failure(let failure): + let action = UIAlertAction(title: "\(failure)", style: .default) + action.isEnabled = false + alert.addAction(action) + } + alert.addAction(.init(title: "Close", style: .cancel)) + } + + self?.present(alert, animated: true) + }) ) queueIDCell.textField.accessibilityIdentifier = "settings_queueId_textfield" environmentCell = EnvironmentSettingsTextCell( diff --git a/TestingApp/ViewController/ViewController.swift b/TestingApp/ViewController/ViewController.swift index c7c718fdb..93d364ed1 100644 --- a/TestingApp/ViewController/ViewController.swift +++ b/TestingApp/ViewController/ViewController.swift @@ -129,10 +129,7 @@ class ViewController: UIViewController { // only if such engagement exists, we need // to configure SDK, and only then attempt // to end engagement. - try Glia.sharedInstance.configure( - with: configuration, - queueId: queueId - ) { + try Glia.sharedInstance.configure(with: configuration) { Glia.sharedInstance.endEngagement { result in print("End engagement operation has been executed. Result='\(result)'.") } @@ -220,7 +217,6 @@ extension ViewController { do { try Glia.sharedInstance.configure( with: configuration, - queueId: queueId, uiConfig: uiConfig ) { completion("SDK has been configured") From eaf4ea1af5fcd18d5e77318629b842bb1e511942 Mon Sep 17 00:00:00 2001 From: Yurii Dukhovnyi Date: Wed, 13 Sep 2023 21:44:54 +0300 Subject: [PATCH 2/2] Introduce list queue interface Restore Swift Package Manager compatibility in a local package connectivity mode. MOB-2594 --- GliaWidgets.xcodeproj/project.pbxproj | 4 --- .../Component/Bubble/BubbleView.Mock.swift | 3 +++ .../Sources/Interactor/Interactor.swift | 6 +++-- .../Chat/ChatViewController.Mock.swift | 25 ++++++++++++++++++ GliaWidgetsTests/CoreSdk/CoreSdk.swift | 26 ------------------- 5 files changed, 32 insertions(+), 32 deletions(-) delete mode 100644 GliaWidgetsTests/CoreSdk/CoreSdk.swift diff --git a/GliaWidgets.xcodeproj/project.pbxproj b/GliaWidgets.xcodeproj/project.pbxproj index 7dd6c05aa..9c18d4548 100644 --- a/GliaWidgets.xcodeproj/project.pbxproj +++ b/GliaWidgets.xcodeproj/project.pbxproj @@ -299,7 +299,6 @@ 75CF8D9129C3A85C00CB1524 /* SecureConversationsWelcomeScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CF8D9029C3A85C00CB1524 /* SecureConversationsWelcomeScreenTests.swift */; }; 75CF8DAD29C8F2B500CB1524 /* SecureConversationsConfirmationScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75CF8DAC29C8F2B500CB1524 /* SecureConversationsConfirmationScreenTests.swift */; }; 75F58EE127E7D5300065BA2D /* Survey.ViewController.Props.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F58EE027E7D5300065BA2D /* Survey.ViewController.Props.swift */; }; - 75FD003F2A80E8C5002DC458 /* CoreSdk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552DFB32A6FBC7F0093519B /* CoreSdk.swift */; }; 75FF151427F3A2D600FE7BE2 /* Theme+Survey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FF151327F3A2D600FE7BE2 /* Theme+Survey.swift */; }; 75FF151727F4E13900FE7BE2 /* Theme.Survey.BooleanQuestion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FF151627F4E13900FE7BE2 /* Theme.Survey.BooleanQuestion.swift */; }; 75FF151B27F4F52D00FE7BE2 /* Theme.Survey.SingleQuestion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75FF151A27F4F52D00FE7BE2 /* Theme.Survey.SingleQuestion.swift */; }; @@ -953,7 +952,6 @@ 7543141728806AEB00C9C1C6 /* EnvironmentSettingsTextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentSettingsTextCell.swift; sourceTree = ""; }; 754CC61427E27C42005676E9 /* Survey.Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Survey.Checkbox.swift; sourceTree = ""; }; 7552DFB02A6FB7DF0093519B /* ChatMessageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageTests.swift; sourceTree = ""; }; - 7552DFB32A6FBC7F0093519B /* CoreSdk.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreSdk.swift; sourceTree = ""; }; 755D186429A6A4E20009F5E8 /* WelcomeStyle+TitleStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WelcomeStyle+TitleStyle.swift"; sourceTree = ""; }; 755D186629A6A4FA0009F5E8 /* WelcomeStyle+SubtitleStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WelcomeStyle+SubtitleStyle.swift"; sourceTree = ""; }; 755D186829A6A5270009F5E8 /* WelcomeStyle+CheckMessagesButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WelcomeStyle+CheckMessagesButtonStyle.swift"; sourceTree = ""; }; @@ -2656,7 +2654,6 @@ 7552DFB22A6FBC6E0093519B /* CoreSdk */ = { isa = PBXGroup; children = ( - 7552DFB32A6FBC7F0093519B /* CoreSdk.swift */, ); path = CoreSdk; sourceTree = ""; @@ -4658,7 +4655,6 @@ 754CC61227E2767A005676E9 /* Survey.BooleanQuestionView.swift in Sources */, 755D187529A6A6B70009F5E8 /* WelcomeStyle+SendButton.swift in Sources */, 6EA3516926E139DA00BF5941 /* GliaViewTransitionController.swift in Sources */, - 75FD003F2A80E8C5002DC458 /* CoreSdk.swift in Sources */, C0D2F07929A4E3DF00803B47 /* UserImageView.Mock.swift in Sources */, 84265E6B29912E2100D65842 /* RemoteConfiguration+CallVisualizer.swift in Sources */, 1A1E30C725F9FDAB00850E68 /* ChatImageFileContentView.swift in Sources */, diff --git a/GliaWidgets/Sources/Component/Bubble/BubbleView.Mock.swift b/GliaWidgets/Sources/Component/Bubble/BubbleView.Mock.swift index f39faad43..012a75053 100644 --- a/GliaWidgets/Sources/Component/Bubble/BubbleView.Mock.swift +++ b/GliaWidgets/Sources/Component/Bubble/BubbleView.Mock.swift @@ -1,4 +1,7 @@ #if DEBUG + +import Foundation + extension BubbleView { static func mock( with bubbleStyle: BubbleStyle = .mock(), diff --git a/GliaWidgets/Sources/Interactor/Interactor.swift b/GliaWidgets/Sources/Interactor/Interactor.swift index 5960e6b7c..95ab3e77e 100644 --- a/GliaWidgets/Sources/Interactor/Interactor.swift +++ b/GliaWidgets/Sources/Interactor/Interactor.swift @@ -385,10 +385,12 @@ extension InteractorState: Equatable { switch (lhs, rhs) { case (.none, .none), (.enqueueing, .enqueueing), - (.enqueued, .enqueued), - (.ended, .ended): + (.enqueued, .enqueued): return true + case (.ended(let lhsReason), .ended(let rhsReason)): + return lhsReason == rhsReason + case (.engaged(let lhsOperator), .engaged(let rhsOperator)): return lhsOperator == rhsOperator diff --git a/GliaWidgets/Sources/ViewController/Chat/ChatViewController.Mock.swift b/GliaWidgets/Sources/ViewController/Chat/ChatViewController.Mock.swift index c8f29234d..5b1c85064 100644 --- a/GliaWidgets/Sources/ViewController/Chat/ChatViewController.Mock.swift +++ b/GliaWidgets/Sources/ViewController/Chat/ChatViewController.Mock.swift @@ -641,5 +641,30 @@ extension ChatViewController { """.data(using: .utf8) } } + +/// Defines wrapper structure for getting decoding container. +/// This container can be used when message metadata is needed in +/// tests. +struct CoreSdkMessageMetadataContainer: Decodable { + let container: KeyedDecodingContainer + + init(from decoder: Decoder) throws { + self.container = try decoder.container( + keyedBy: GliaCoreSDK.Message.Metadata.CodingKeys.self + ) + } + + /// Creates instance with decoding container inside. + /// This initializer can be used for created mocked Metadata with passing + /// json-data inside of this initializer. + /// NB! Empty 'jsonData' will lead to decoding error. + init( + jsonData: Data, + jsonDecoder: JSONDecoder = .init() + ) throws { + self = try jsonDecoder.decode(CoreSdkMessageMetadataContainer.self, from: jsonData) + } +} + // swiftlint:enable function_body_length #endif diff --git a/GliaWidgetsTests/CoreSdk/CoreSdk.swift b/GliaWidgetsTests/CoreSdk/CoreSdk.swift deleted file mode 100644 index 089332b9c..000000000 --- a/GliaWidgetsTests/CoreSdk/CoreSdk.swift +++ /dev/null @@ -1,26 +0,0 @@ -import Foundation -import GliaCoreSDK - -/// Defines wrapper structure for getting decoding container. -/// This container can be used when message metadata is needed in -/// tests. -struct CoreSdkMessageMetadataContainer: Decodable { - let container: KeyedDecodingContainer - - init(from decoder: Decoder) throws { - self.container = try decoder.container( - keyedBy: GliaCoreSDK.Message.Metadata.CodingKeys.self - ) - } - - /// Creates instance with decoding container inside. - /// This initializer can be used for created mocked Metadata with passing - /// json-data inside of this initializer. - /// NB! Empty 'jsonData' will lead to decoding error. - init( - jsonData: Data, - jsonDecoder: JSONDecoder = .init() - ) throws { - self = try jsonDecoder.decode(CoreSdkMessageMetadataContainer.self, from: jsonData) - } -}