diff --git a/.gitignore b/.gitignore index 2cf10f33..f849ab14 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,7 @@ playground.xcworkspace # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. # Packages/ # Package.pins -# Package.resolved +Package.resolved .build/ .swiftpm/ diff --git a/AzureSDK.xcworkspace/xcshareddata/xcschemes/all.xcscheme b/AzureSDK.xcworkspace/xcshareddata/xcschemes/all.xcscheme index dc302d40..c2bb956e 100644 --- a/AzureSDK.xcworkspace/xcshareddata/xcschemes/all.xcscheme +++ b/AzureSDK.xcworkspace/xcshareddata/xcschemes/all.xcscheme @@ -42,10 +42,10 @@ buildForAnalyzing = "YES"> + BlueprintIdentifier = "0A3A5EB72316DB1E00473FDA" + BuildableName = "AzureCommunication.framework" + BlueprintName = "AzureCommunication" + ReferencedContainer = "container:sdk/communication/AzureCommunication/AzureCommunication.xcodeproj"> + BlueprintIdentifier = "0A686488233E834D004B7E17" + BuildableName = "AzureStorageBlob.framework" + BlueprintName = "AzureStorageBlob" + ReferencedContainer = "container:sdk/storage/AzureStorageBlob/AzureStorageBlob.xcodeproj"> + + + + + + + + + + + + + BlueprintIdentifier = "0A3A5EC02316DB1E00473FDA" + BuildableName = "AzureCommunicationTests.xctest" + BlueprintName = "AzureCommunicationTests" + ReferencedContainer = "container:sdk/communication/AzureCommunication/AzureCommunication.xcodeproj"> + BlueprintIdentifier = "D1B7EAEC257F02FC004F384A" + BuildableName = "AzureCommunicationChatTests.xctest" + BlueprintName = "AzureCommunicationChatTests" + ReferencedContainer = "container:sdk/communication/AzureCommunicationChat/AzureCommunicationChat.xcodeproj"> + + + + + + + + diff --git a/AzureSDK.xcworkspace/xcshareddata/xcschemes/sdk.xcscheme b/AzureSDK.xcworkspace/xcshareddata/xcschemes/sdk.xcscheme index dde77baf..4de420b4 100644 --- a/AzureSDK.xcworkspace/xcshareddata/xcschemes/sdk.xcscheme +++ b/AzureSDK.xcworkspace/xcshareddata/xcschemes/sdk.xcscheme @@ -157,6 +157,28 @@ ReferencedContainer = "container:sdk/communication/AzureCommunication/AzureCommunication.xcodeproj"> + + + + + + + + /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + DED08D1BF86630CC5BACF415 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-AzureCommunicationTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -305,9 +380,10 @@ 1DE4DB7724C0FE8300631921 /* AutoRefreshTokenCredential.swift in Sources */, F1540EBD25BF893C0056B087 /* CommunicationCloudEnvironment.swift in Sources */, 882F28D425A632CA009689E3 /* CommunicationTokenRefreshOptions.swift in Sources */, - F183A5FC24AFEF1400F0E0D5 /* CommunicationTokenCredential.swift in Sources */, - 7AAE2D17251444B600C9F897 /* CommunicationAuthenticationPolicy.swift in Sources */, + 7AAE2D17251444B600C9F897 /* CommunicationPolicyTokenCredential.swift in Sources */, F183A5FE24AFF1B100F0E0D5 /* JwtTokenParser.swift in Sources */, + D112634825B7969B00F437C6 /* (null) in Sources */, + D1A42CF825CCA1C100408C0F /* CommunicationTokenCredential.swift in Sources */, F183A5FA24AFB37900F0E0D5 /* StaticTokenCredential.swift in Sources */, F1540E9625BF83D80056B087 /* Enumerations.swift in Sources */, F1540E9725BF83D80056B087 /* CommunicationIdentifierModel.swift in Sources */, @@ -324,6 +400,7 @@ F1540EC125BFD6910056B087 /* CommunicationIdentifierTest.swift in Sources */, 1D07222D24C8FB0F00C2EF4E /* CommunicationTokenCredentialTests.swift in Sources */, 88CC8C35254750260028977C /* ObjCCommunicationTokenCredentialAsyncTests.m in Sources */, + 883AEDB825AF623000E21497 /* CommunicationPolicyTokenCredentialTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -464,6 +541,7 @@ }; 0A3A5ECD2316DB1E00473FDA /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 73DFF8D8D93685E64E46AD1B /* Pods-AzureCommunication.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; BUILD_LIBRARY_FOR_DISTRIBUTION = YES; @@ -493,6 +571,7 @@ }; 0A3A5ECE2316DB1E00473FDA /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 316382976240347BE77E907F /* Pods-AzureCommunication.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; BUILD_LIBRARY_FOR_DISTRIBUTION = YES; @@ -521,6 +600,7 @@ }; 0A3A5ED02316DB1E00473FDA /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = C7FEC671B55120C7AFDF3B62 /* Pods-AzureCommunicationTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; @@ -541,6 +621,7 @@ }; 0A3A5ED12316DB1E00473FDA /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E5E66C937B734ADA8532CFC3 /* Pods-AzureCommunicationTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; diff --git a/sdk/communication/AzureCommunication/README.md b/sdk/communication/AzureCommunication/README.md index 5093b31c..cd65a913 100644 --- a/sdk/communication/AzureCommunication/README.md +++ b/sdk/communication/AzureCommunication/README.md @@ -101,14 +101,14 @@ $ pod install ## Key concepts -### CommunicationUserCredential -A `CommunicationUserCredential` authenticates a user with Communication Services, such as Chat or Calling. It optionally +### CommunicationTokenCredential +A `CommunicationTokenCredential` authenticates a user with Communication Services, such as Chat or Calling. It optionally provides an auto-refresh mechanism to ensure a continuously stable authentication state during communications. User tokens are created by the application developer using the Communication Administration SDK - once created, they are -provided to the various Communication Services client libraries by way of a `CommunicationUserCredential` object. +provided to the various Communication Services client libraries by way of a `CommunicationTokenCredential` object. ## Examples -The following sections provide several code snippets showing different ways to use a `CommunicationUserCredential`: +The following sections provide several code snippets showing different ways to use a `CommunicationTokenCredential`: * [Creating a credential with a static token](#creating-a-credential-with-a-static-token) * [Creating a credential that refreshes synchronously](#creating-a-credential-that-refreshes-synchronously) @@ -117,7 +117,7 @@ The following sections provide several code snippets showing different ways to u ### Creating a credential with a static token ```swift let sampleToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjMyNTAzNjgwMDAwfQ.9i7FNNHHJT8cOzo-yrAUJyBSfJ-tPPk2emcHavOEpWc" -let userCredential = try CommunicationUserCredential(token: sampleToken) +let credential = try CommunicationTokenCredential(token: sampleToken) ``` ### Creating a credential that refreshes synchronously @@ -130,12 +130,12 @@ func fetchTokenSync(completionHandler: TokenRefreshOnCompletion) { completionHandler(newToken, nil) } -let userCredential = try CommunicationUserCredential(initialToken: sampleExpiredToken, +let credential = try CommunicationTokenCredential(initialToken: sampleExpiredToken, refreshProactively: false, tokenRefresher: fetchTokenSync) DispatchQueue.global(qos: .utility).async { - userCredential.token { (accessToken: AccessToken?, error: Error?) in + credential.token { (accessToken: AccessToken?, error: Error?) in ... } } @@ -156,12 +156,12 @@ func fetchTokenAsync(completionHandler: @escaping TokenRefreshOnCompletion) { } } -let userCredential = try CommunicationUserCredential(initialToken: sampleExpiredToken, +let credential = try CommunicationTokenCredential(initialToken: sampleExpiredToken, refreshProactively: false, tokenRefresher: fetchTokenAsync) DispatchQueue.global(qos: .utility).async { - userCredential.token { (accessToken: AccessToken?, error: Error?) in + credential.token { (accessToken: AccessToken?, error: Error?) in ... } } diff --git a/sdk/communication/AzureCommunication/Source/Authentication/CommunicationAuthenticationPolicy.swift b/sdk/communication/AzureCommunication/Source/Authentication/CommunicationPolicyTokenCredential.swift similarity index 52% rename from sdk/communication/AzureCommunication/Source/Authentication/CommunicationAuthenticationPolicy.swift rename to sdk/communication/AzureCommunication/Source/Authentication/CommunicationPolicyTokenCredential.swift index 2b80ebe5..a51ec1f1 100644 --- a/sdk/communication/AzureCommunication/Source/Authentication/CommunicationAuthenticationPolicy.swift +++ b/sdk/communication/AzureCommunication/Source/Authentication/CommunicationPolicyTokenCredential.swift @@ -29,44 +29,47 @@ import AzureCore #endif import Foundation /** - The Azure Communication Services authentication policy. + The Azure Communication Services token credential used to authenticate pipeline requests. */ -public class CommunicationTokenCredentialPolicy: Authenticating { - public var next: PipelineStage? - +public class CommunicationPolicyTokenCredential: TokenCredential { private let credential: CommunicationTokenCredential - + var error: AzureError? = nil /** - Creates a credential policy that authenticates requests using the provided `CommunicationTokenCredential`. + Creates a token credential that authenticates requests using the provided `CommunicationTokenCredential`. - - Parameter credential: The `CommunicationTokenCredential` that will be used to authenticate requests. - - - SeeAlso: `CommunicationTokenCredential.init(...)` + - Parameter credential: The token credential to authenticate with. */ - public init(credential: CommunicationTokenCredential) { + public init(_ credential: CommunicationTokenCredential) { self.credential = credential } - /** - Authenticates an HTTP `PipelineRequest` with a token retrieved from the credential. + Retrieve a token for the provided scope. + - Parameters: - - request:A `PipelineRequest` object. - - completionHandler: A completion handler that forwards the modified pipeline request. + - scopes: A list of a scope strings for which to retrieve the token. + - completionHandler: A completion handler which forwards the access token. */ - public func authenticate(request: PipelineRequest, completionHandler: @escaping OnRequestCompletionHandler) { - credential.token { token, error in - if let error = error { - completionHandler(request, AzureError.client("Error while retrieving access token", error)) + public func token(forScopes scopes: [String], completionHandler: @escaping TokenCompletionHandler) { + credential.token { (communicationAccessToken, error) in + guard let communicationAccessToken = communicationAccessToken else { + self.error = AzureError.client("Communication Token Failure", error) + completionHandler(nil, self.error) return } - - guard let token = token?.token else { - completionHandler(request, AzureError.client("Token cannot be empty")) - return - } - - request.httpRequest.headers[.authorization] = "Bearer \(token)" - completionHandler(request, nil) + + let accessToken = AccessToken(token: communicationAccessToken.token, + expiresOn: communicationAccessToken.expiresOn) + + completionHandler(accessToken, nil) + } + } + /** + Validates throws an error if token creating had any errors + - Throws: Azure error with the error from the get token call. + */ + public func validate() throws { + if let error = error { + throw error } } } diff --git a/sdk/communication/AzureCommunication/Source/Authentication/CommunicationTokenRefreshOptions.swift b/sdk/communication/AzureCommunication/Source/Authentication/CommunicationTokenRefreshOptions.swift index 64febb7f..2ccd15dc 100644 --- a/sdk/communication/AzureCommunication/Source/Authentication/CommunicationTokenRefreshOptions.swift +++ b/sdk/communication/AzureCommunication/Source/Authentication/CommunicationTokenRefreshOptions.swift @@ -28,8 +28,8 @@ import Foundation public typealias TokenRefresherClosure = (@escaping TokenRefreshOnCompletion) -> Void /** - The Communication Token Refresh Options. Used to initialize a `CommunicationUserCredential` - - SeeAlso: ` CommunicationUserCredential.init(...)` + The Communication Token Refresh Options. Used to initialize a `CommunicationTokenCredential` + - SeeAlso: ` CommunicationTokenCredential.token(...)` */ @objcMembers public class CommunicationTokenRefreshOptions: NSObject { var initialToken: String? diff --git a/sdk/communication/AzureCommunication/Tests/CommunicationPolicyTokenCredentialTests.swift b/sdk/communication/AzureCommunication/Tests/CommunicationPolicyTokenCredentialTests.swift new file mode 100644 index 00000000..5e29a8ea --- /dev/null +++ b/sdk/communication/AzureCommunication/Tests/CommunicationPolicyTokenCredentialTests.swift @@ -0,0 +1,148 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import XCTest + +#if canImport(AzureCommunication) +@testable import AzureCommunication +#endif +#if canImport(AzureCore) +@testable import AzureCore +#endif + +class CommunicationPolicyTokenCredentialTests: XCTestCase { + let sampleToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjMyNTAzNjgwMDAwfQ.9i7FNNHHJT8cOzo-yrAUJyBSfJ-tPPk2emcHavOEpWc" + let aampleTokenExpiry = 32503680000 + let expiredToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEwMH0.1h_scYkNp-G98-O4cW6KvfJZwiz54uJMyeDACE4nypg" + + func fetchTokenSync(completionHandler: TokenRefreshOnCompletion) { + let newToken = sampleToken + completionHandler(newToken, nil) + } + + func testCreateStaticToken() throws { + let expectation = self.expectation(description: "Create static token") + + let token = expiredToken + let userCredential = try CommunicationTokenCredential(token: token) + let communicationTokenPolicy = CommunicationPolicyTokenCredential(userCredential) + communicationTokenPolicy.token(forScopes: [""]) { (accessToken, error) in + XCTAssertNil(error) + XCTAssertNotNil(accessToken) + expectation.fulfill() + } + + waitForExpectations(timeout: 1000) { (error) in + if let error = error { + XCTFail("Create token timed out: \(error)") + } + } + } + + func testCreateRefreshableWithoutInitialToken() throws { + let expectation = self.expectation(description: "Create refreshable without initial token") + let options = CommunicationTokenRefreshOptions( + refreshProactively: true, + tokenRefresher: fetchTokenSync + ) + let userCredential = try CommunicationTokenCredential(with: options) + let communicationTokenPolicy = CommunicationPolicyTokenCredential(userCredential) + + communicationTokenPolicy.token(forScopes: [""]) { (accessToken, error) in + XCTAssertNil(error) + XCTAssertNotNil(accessToken) + expectation.fulfill() + } + + waitForExpectations(timeout: 1000) { (error) in + if let error = error { + XCTFail("Create token timed out: \(error)") + } + } + } + + func testCreateRefreshableWithInitialToken() throws { + let expectation = self.expectation(description: "Create refreshable with initial token") + let token = expiredToken + let options = CommunicationTokenRefreshOptions( + initialToken: token, + refreshProactively: true, + tokenRefresher: fetchTokenSync + ) + let userCredential = try CommunicationTokenCredential(with: options) + let communicationTokenPolicy = CommunicationPolicyTokenCredential(userCredential) + + communicationTokenPolicy.token(forScopes: [""]) { (accessToken, error) in + XCTAssertNil(error) + XCTAssertNotNil(accessToken) + expectation.fulfill() + } + + waitForExpectations(timeout: 1000) { (error) in + if let error = error { + XCTFail("Create token timed out: \(error)") + } + } + } + + func testDecodesToken() throws { + let expectation = self.expectation(description: "Decode access token") + let initialToken = sampleToken + let userCredential = try CommunicationTokenCredential(token: initialToken) + let communicationTokenPolicy = CommunicationPolicyTokenCredential(userCredential) + + communicationTokenPolicy.token(forScopes: [""]) { (accessToken, error) in + XCTAssertEqual(accessToken?.token, initialToken) + XCTAssertEqual(accessToken?.expiresOn, accessToken?.expiresOn) + expectation.fulfill() + } + + waitForExpectations(timeout: 1000) { (error) in + if let error = error { + XCTFail("Create token timed out: \(error)") + } + } + } + + func testStaticTokenReturnsExpiredToken() throws { + let expectation = self.expectation(description: "Static token is expired") + let initialToken = expiredToken + let userCredential = try CommunicationTokenCredential(token: initialToken) + let communicationTokenPolicy = CommunicationPolicyTokenCredential(userCredential) + + communicationTokenPolicy.token(forScopes: [""]) { [weak self] (accessToken, error) in + guard let self = self else { return } + XCTAssertEqual(self.expiredToken, accessToken?.token) + expectation.fulfill() + } + + waitForExpectations(timeout: 1000) { (error) in + if let error = error { + XCTFail("Create token timed out: \(error)") + } + } + } +} diff --git a/sdk/communication/AzureCommunicationChat/AzureCommunicationChat.xcodeproj/project.pbxproj b/sdk/communication/AzureCommunicationChat/AzureCommunicationChat.xcodeproj/project.pbxproj index a3dd3916..24b179e3 100644 --- a/sdk/communication/AzureCommunicationChat/AzureCommunicationChat.xcodeproj/project.pbxproj +++ b/sdk/communication/AzureCommunicationChat/AzureCommunicationChat.xcodeproj/project.pbxproj @@ -3,276 +3,441 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ - 0A47454A2583FDF600CA86E5 /* AzureCommunicationChatClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47451D2583FDF600CA86E5 /* AzureCommunicationChatClient.swift */; }; - 0A47454B2583FDF600CA86E5 /* AzureCommunicationChatService+CreateChatThreadOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47451F2583FDF600CA86E5 /* AzureCommunicationChatService+CreateChatThreadOptions.swift */; }; - 0A47454C2583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatMessageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745202583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatMessageOptions.swift */; }; - 0A47454D2583FDF600CA86E5 /* AzureCommunicationChatClientOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745212583FDF600CA86E5 /* AzureCommunicationChatClientOptions.swift */; }; - 0A47454E2583FDF600CA86E5 /* AzureCommunicationChatService+ListChatThreadsOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745222583FDF600CA86E5 /* AzureCommunicationChatService+ListChatThreadsOptions.swift */; }; - 0A47454F2583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatThreadOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745232583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatThreadOptions.swift */; }; - 0A4745502583FDF600CA86E5 /* AzureCommunicationChatService+SendChatMessageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745242583FDF600CA86E5 /* AzureCommunicationChatService+SendChatMessageOptions.swift */; }; - 0A4745512583FDF600CA86E5 /* AzureCommunicationChatService+GetChatThreadOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745252583FDF600CA86E5 /* AzureCommunicationChatService+GetChatThreadOptions.swift */; }; - 0A4745522583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatThreadOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745262583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatThreadOptions.swift */; }; - 0A4745532583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatMessageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745272583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatMessageOptions.swift */; }; - 0A4745542583FDF600CA86E5 /* AzureCommunicationChatService+ListChatMessagesOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745282583FDF600CA86E5 /* AzureCommunicationChatService+ListChatMessagesOptions.swift */; }; - 0A4745552583FDF600CA86E5 /* AzureCommunicationChatService+ListChatReadReceiptsOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745292583FDF600CA86E5 /* AzureCommunicationChatService+ListChatReadReceiptsOptions.swift */; }; - 0A4745562583FDF600CA86E5 /* AzureCommunicationChatService+AddChatThreadMembersOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47452A2583FDF600CA86E5 /* AzureCommunicationChatService+AddChatThreadMembersOptions.swift */; }; - 0A4745572583FDF600CA86E5 /* AzureCommunicationChatService+GetChatMessageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47452B2583FDF600CA86E5 /* AzureCommunicationChatService+GetChatMessageOptions.swift */; }; - 0A4745582583FDF700CA86E5 /* AzureCommunicationChatService+ListChatThreadMembersOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47452C2583FDF600CA86E5 /* AzureCommunicationChatService+ListChatThreadMembersOptions.swift */; }; - 0A4745592583FDF700CA86E5 /* AzureCommunicationChatService+SendChatReadReceiptOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47452D2583FDF600CA86E5 /* AzureCommunicationChatService+SendChatReadReceiptOptions.swift */; }; - 0A47455A2583FDF700CA86E5 /* AzureCommunicationChatService+SendTypingNotificationOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47452E2583FDF600CA86E5 /* AzureCommunicationChatService+SendTypingNotificationOptions.swift */; }; - 0A47455B2583FDF700CA86E5 /* AzureCommunicationChatService+RemoveChatThreadMemberOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47452F2583FDF600CA86E5 /* AzureCommunicationChatService+RemoveChatThreadMemberOptions.swift */; }; - 0A47455C2583FDF700CA86E5 /* PatchUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745312583FDF600CA86E5 /* PatchUtil.swift */; }; - 0A47455D2583FDF700CA86E5 /* SendChatMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745332583FDF600CA86E5 /* SendChatMessageRequest.swift */; }; - 0A47455E2583FDF700CA86E5 /* MultiStatusResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745342583FDF600CA86E5 /* MultiStatusResponse.swift */; }; - 0A47455F2583FDF700CA86E5 /* UpdateChatThreadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745352583FDF600CA86E5 /* UpdateChatThreadRequest.swift */; }; - 0A4745602583FDF700CA86E5 /* ChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745362583FDF600CA86E5 /* ChatMessage.swift */; }; - 0A4745612583FDF700CA86E5 /* ChatMessagesCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745372583FDF600CA86E5 /* ChatMessagesCollection.swift */; }; - 0A4745622583FDF700CA86E5 /* CreateChatThreadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745382583FDF600CA86E5 /* CreateChatThreadRequest.swift */; }; - 0A4745632583FDF700CA86E5 /* AddChatThreadMembersRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745392583FDF600CA86E5 /* AddChatThreadMembersRequest.swift */; }; - 0A4745642583FDF700CA86E5 /* ReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47453A2583FDF600CA86E5 /* ReadReceipt.swift */; }; - 0A4745652583FDF700CA86E5 /* Enumerations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47453B2583FDF600CA86E5 /* Enumerations.swift */; }; - 0A4745662583FDF700CA86E5 /* IndividualStatusResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47453C2583FDF600CA86E5 /* IndividualStatusResponse.swift */; }; - 0A4745672583FDF700CA86E5 /* ChatThreadsInfoCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47453D2583FDF600CA86E5 /* ChatThreadsInfoCollection.swift */; }; - 0A4745682583FDF700CA86E5 /* ChatThread.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47453E2583FDF600CA86E5 /* ChatThread.swift */; }; - 0A4745692583FDF700CA86E5 /* UpdateChatMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A47453F2583FDF600CA86E5 /* UpdateChatMessageRequest.swift */; }; - 0A47456A2583FDF700CA86E5 /* SendReadReceiptRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745402583FDF600CA86E5 /* SendReadReceiptRequest.swift */; }; - 0A47456B2583FDF700CA86E5 /* ChatThreadMember.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745412583FDF600CA86E5 /* ChatThreadMember.swift */; }; - 0A47456C2583FDF700CA86E5 /* ErrorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745422583FDF600CA86E5 /* ErrorType.swift */; }; - 0A47456D2583FDF700CA86E5 /* ChatThreadInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745432583FDF600CA86E5 /* ChatThreadInfo.swift */; }; - 0A47456E2583FDF700CA86E5 /* SendChatMessageResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745442583FDF600CA86E5 /* SendChatMessageResult.swift */; }; - 0A47456F2583FDF700CA86E5 /* ReadReceiptsCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745452583FDF600CA86E5 /* ReadReceiptsCollection.swift */; }; - 0A4745702583FDF700CA86E5 /* ChatThreadMembersCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745462583FDF600CA86E5 /* ChatThreadMembersCollection.swift */; }; - 0A4745712583FDF700CA86E5 /* AzureCommunicationChatService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745472583FDF600CA86E5 /* AzureCommunicationChatService.swift */; }; - 0A4745722583FDF700CA86E5 /* AzureCommuncationChatClient+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745482583FDF600CA86E5 /* AzureCommuncationChatClient+Convenience.swift */; }; - 0A4745732583FDF700CA86E5 /* Custom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4745492583FDF600CA86E5 /* Custom.swift */; }; - 0A74765C2522918900819FC9 /* AzureCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A74765B2522918900819FC9 /* AzureCore.framework */; }; + 9766BE9261FCB48436FA6682 /* Pods_AzureCommunicationChatTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F1FE3013E797A134E8A6C3B5 /* Pods_AzureCommunicationChatTests.framework */; }; + D10C3BCE25A63F7800A181E3 /* listParticipants.json in Resources */ = {isa = PBXBuildFile; fileRef = D10C3BCD25A63F7800A181E3 /* listParticipants.json */; }; + D10C3BD425A660AF00A181E3 /* listMessages.json in Resources */ = {isa = PBXBuildFile; fileRef = D10C3BD325A660AF00A181E3 /* listMessages.json */; }; + D10C3BDA25A66D4D00A181E3 /* listThreads.json in Resources */ = {isa = PBXBuildFile; fileRef = D10C3BD925A66D4D00A181E3 /* listThreads.json */; }; + D110F507258D603F001FA3CD /* AzureCommunication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D110F506258D603F001FA3CD /* AzureCommunication.framework */; }; + D110F50A258D604B001FA3CD /* AzureCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D110F509258D604B001FA3CD /* AzureCore.framework */; }; + D110F50C258D6053001FA3CD /* Pods_AzureCommunicationChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D110F50B258D6053001FA3CD /* Pods_AzureCommunicationChat.framework */; }; + D13CE65125BFB6D700415467 /* listReadReceipts.json in Resources */ = {isa = PBXBuildFile; fileRef = D13CE64E25BFB69100415467 /* listReadReceipts.json */; }; + D147E62D25CE242C001CFB5D /* AzureCommunicationChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "AzureCommunicationChat::AzureCommunicationChat::Product" /* AzureCommunicationChat.framework */; }; + D147E63925CE244A001CFB5D /* ChatClientUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECA8CD1258181A5006760F7 /* ChatClientUnitTests.swift */; }; + D147E64025CE244F001CFB5D /* ChatThreadClientUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ECA8D08258432DC006760F7 /* ChatThreadClientUnitTests.swift */; }; + D147E64725CE2459001CFB5D /* TestUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CD93B2258D6C3D00409613 /* TestUtil.swift */; }; + D147E65225CE246B001CFB5D /* ListReadReceiptResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8D2E25889619006760F7 /* ListReadReceiptResponse.json */; }; + D147E65925CE246E001CFB5D /* AddParticipantResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8D28258892CD006760F7 /* AddParticipantResponse.json */; }; + D147E66025CE2470001CFB5D /* ListParticipantsResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8D2225888DD8006760F7 /* ListParticipantsResponse.json */; }; + D147E66725CE2473001CFB5D /* ListMessagesResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8D1C258887D3006760F7 /* ListMessagesResponse.json */; }; + D147E66E25CE2476001CFB5D /* GetMessageResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8D1625888667006760F7 /* GetMessageResponse.json */; }; + D147E67525CE2478001CFB5D /* NoContent.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8D0E25888515006760F7 /* NoContent.json */; }; + D147E67C25CE247B001CFB5D /* SendMessageResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8D0F25888515006760F7 /* SendMessageResponse.json */; }; + D147E68325CE247D001CFB5D /* ListThreadsResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8CF02582A633006760F7 /* ListThreadsResponse.json */; }; + D147E68A25CE2480001CFB5D /* UnauthorizedError.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8CEA2582A52D006760F7 /* UnauthorizedError.json */; }; + D147E69125CE2482001CFB5D /* GetThreadResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = 0ECA8CDE258188D0006760F7 /* GetThreadResponse.json */; }; + D147E69825CE2485001CFB5D /* CreateThreadResponse.json in Resources */ = {isa = PBXBuildFile; fileRef = D1BA104525807B0B00CA7130 /* CreateThreadResponse.json */; }; + D1565C71256DB74900AF45F8 /* ChatClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1565C70256DB74900AF45F8 /* ChatClient.swift */; }; + D1565C74256DB76C00AF45F8 /* ChatThreadClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1565C73256DB76C00AF45F8 /* ChatThreadClient.swift */; }; + D15E98FA25B7C80C00E63DB2 /* AzureCommunicationChatClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98CA25B7C80C00E63DB2 /* AzureCommunicationChatClient.swift */; }; + D15E98FB25B7C80C00E63DB2 /* ChatThreadOperation+AddChatParticipantsOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98CC25B7C80C00E63DB2 /* ChatThreadOperation+AddChatParticipantsOptions.swift */; }; + D15E98FC25B7C80C00E63DB2 /* ChatThreadOperation+ListChatReadReceiptsOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98CD25B7C80C00E63DB2 /* ChatThreadOperation+ListChatReadReceiptsOptions.swift */; }; + D15E98FD25B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatMessageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98CE25B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatMessageOptions.swift */; }; + D15E98FE25B7C80C00E63DB2 /* Chat+ListChatThreadsOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98CF25B7C80C00E63DB2 /* Chat+ListChatThreadsOptions.swift */; }; + D15E98FF25B7C80C00E63DB2 /* Chat+DeleteChatThreadOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D025B7C80C00E63DB2 /* Chat+DeleteChatThreadOptions.swift */; }; + D15E990025B7C80C00E63DB2 /* AzureCommunicationChatClientOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D125B7C80C00E63DB2 /* AzureCommunicationChatClientOptions.swift */; }; + D15E990125B7C80C00E63DB2 /* ChatThreadOperation+SendChatMessageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D225B7C80C00E63DB2 /* ChatThreadOperation+SendChatMessageOptions.swift */; }; + D15E990225B7C80C00E63DB2 /* ChatThreadOperation+SendChatReadReceiptOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D325B7C80C00E63DB2 /* ChatThreadOperation+SendChatReadReceiptOptions.swift */; }; + D15E990325B7C80C00E63DB2 /* ChatThreadOperation+RemoveChatParticipantOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D425B7C80C00E63DB2 /* ChatThreadOperation+RemoveChatParticipantOptions.swift */; }; + D15E990425B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatThreadOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D525B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatThreadOptions.swift */; }; + D15E990525B7C80C00E63DB2 /* Chat+CreateChatThreadOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D625B7C80C00E63DB2 /* Chat+CreateChatThreadOptions.swift */; }; + D15E990625B7C80C00E63DB2 /* ChatThreadOperation+SendTypingNotificationOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D725B7C80C00E63DB2 /* ChatThreadOperation+SendTypingNotificationOptions.swift */; }; + D15E990725B7C80C00E63DB2 /* ChatThreadOperation+DeleteChatMessageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D825B7C80C00E63DB2 /* ChatThreadOperation+DeleteChatMessageOptions.swift */; }; + D15E990825B7C80C00E63DB2 /* ChatThreadOperation+ListChatMessagesOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98D925B7C80C00E63DB2 /* ChatThreadOperation+ListChatMessagesOptions.swift */; }; + D15E990925B7C80C00E63DB2 /* ChatThreadOperation+GetChatMessageOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98DA25B7C80C00E63DB2 /* ChatThreadOperation+GetChatMessageOptions.swift */; }; + D15E990A25B7C80C00E63DB2 /* Chat+GetChatThreadOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98DB25B7C80C00E63DB2 /* Chat+GetChatThreadOptions.swift */; }; + D15E990B25B7C80C00E63DB2 /* ChatThreadOperation+ListChatParticipantsOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98DC25B7C80C00E63DB2 /* ChatThreadOperation+ListChatParticipantsOptions.swift */; }; + D15E990C25B7C80C00E63DB2 /* PatchUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98DE25B7C80C00E63DB2 /* PatchUtil.swift */; }; + D15E990D25B7C80C00E63DB2 /* Chat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98DF25B7C80C00E63DB2 /* Chat.swift */; }; + D15E990E25B7C80C00E63DB2 /* AddChatParticipantsErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98E125B7C80C00E63DB2 /* AddChatParticipantsErrors.swift */; }; + D15E990F25B7C80C00E63DB2 /* CommunicationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98E225B7C80C00E63DB2 /* CommunicationError.swift */; }; + D15E991025B7C80C00E63DB2 /* SendChatMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98E325B7C80C00E63DB2 /* SendChatMessageRequest.swift */; }; + D15E991125B7C80C00E63DB2 /* ChatMessageContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98E425B7C80C00E63DB2 /* ChatMessageContent.swift */; }; + D15E991225B7C80C00E63DB2 /* UpdateChatThreadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98E525B7C80C00E63DB2 /* UpdateChatThreadRequest.swift */; }; + D15E991325B7C80C00E63DB2 /* ChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98E625B7C80C00E63DB2 /* ChatMessage.swift */; }; + D15E991425B7C80C00E63DB2 /* ChatMessagesCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98E725B7C80C00E63DB2 /* ChatMessagesCollection.swift */; }; + D15E991525B7C80C00E63DB2 /* CreateChatThreadErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98E825B7C80C00E63DB2 /* CreateChatThreadErrors.swift */; }; + D15E991625B7C80C00E63DB2 /* ChatMessageReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98E925B7C80C00E63DB2 /* ChatMessageReadReceipt.swift */; }; + D15E991725B7C80C00E63DB2 /* CreateChatThreadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98EA25B7C80C00E63DB2 /* CreateChatThreadRequest.swift */; }; + D15E991825B7C80C00E63DB2 /* CommunicationErrorResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98EB25B7C80C00E63DB2 /* CommunicationErrorResponse.swift */; }; + D15E991925B7C80C00E63DB2 /* Enumerations.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98EC25B7C80C00E63DB2 /* Enumerations.swift */; }; + D15E991A25B7C80C00E63DB2 /* AddChatParticipantsResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98ED25B7C80C00E63DB2 /* AddChatParticipantsResult.swift */; }; + D15E991B25B7C80C00E63DB2 /* ChatMessageReadReceiptsCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98EE25B7C80C00E63DB2 /* ChatMessageReadReceiptsCollection.swift */; }; + D15E991C25B7C80C00E63DB2 /* ChatThreadsInfoCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98EF25B7C80C00E63DB2 /* ChatThreadsInfoCollection.swift */; }; + D15E991D25B7C80C00E63DB2 /* ChatThread.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F025B7C80C00E63DB2 /* ChatThread.swift */; }; + D15E991E25B7C80C00E63DB2 /* UpdateChatMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F125B7C80C00E63DB2 /* UpdateChatMessageRequest.swift */; }; + D15E991F25B7C80C00E63DB2 /* CreateChatThreadResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F225B7C80C00E63DB2 /* CreateChatThreadResult.swift */; }; + D15E992025B7C80C00E63DB2 /* SendReadReceiptRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F325B7C80C00E63DB2 /* SendReadReceiptRequest.swift */; }; + D15E992125B7C80C00E63DB2 /* ChatThreadInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F425B7C80C00E63DB2 /* ChatThreadInfo.swift */; }; + D15E992225B7C80C00E63DB2 /* SendChatMessageResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F525B7C80C00E63DB2 /* SendChatMessageResult.swift */; }; + D15E992325B7C80C00E63DB2 /* AddChatParticipantsRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F625B7C80C00E63DB2 /* AddChatParticipantsRequest.swift */; }; + D15E992425B7C80C00E63DB2 /* ChatParticipant.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F725B7C80C00E63DB2 /* ChatParticipant.swift */; }; + D15E992525B7C80C00E63DB2 /* ChatParticipantsCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F825B7C80C00E63DB2 /* ChatParticipantsCollection.swift */; }; + D15E992625B7C80C00E63DB2 /* ChatThreadOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D15E98F925B7C80C00E63DB2 /* ChatThreadOperation.swift */; }; + D16C802D25BA0A2400C42803 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = D16C802C25BA0A2400C42803 /* Message.swift */; }; + D16C803325BA0AE400C42803 /* Thread.swift in Sources */ = {isa = PBXBuildFile; fileRef = D16C803225BA0AE400C42803 /* Thread.swift */; }; + D16C803725BA0AFE00C42803 /* Participant.swift in Sources */ = {isa = PBXBuildFile; fileRef = D16C803625BA0AFE00C42803 /* Participant.swift */; }; + D16C803B25BA0B0E00C42803 /* ReadReceipt.swift in Sources */ = {isa = PBXBuildFile; fileRef = D16C803A25BA0B0E00C42803 /* ReadReceipt.swift */; }; + D16C803F25BA0B5200C42803 /* MessageContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D16C803E25BA0B5200C42803 /* MessageContent.swift */; }; + D16C804325BA402100C42803 /* CreateThreadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D16C804225BA402100C42803 /* CreateThreadRequest.swift */; }; + D16C804725BA406D00C42803 /* CreateThreadResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = D16C804625BA406D00C42803 /* CreateThreadResult.swift */; }; + D193C45B25CE258F006F769C /* OHHTTPStubsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = D193C45A25CE258F006F769C /* OHHTTPStubsSwift */; }; + D1B7EB06257F0D20004F384A /* AzureCommunicationChat.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "AzureCommunicationChat::AzureCommunicationChat::Product" /* AzureCommunicationChat.framework */; }; + D1BA104D25807B7500CA7130 /* OHHTTPStubsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = D1BA104C25807B7500CA7130 /* OHHTTPStubsSwift */; }; + D1CD93A2258D6BC700409613 /* ChatClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CD93A1258D6BC700409613 /* ChatClientTests.swift */; }; + D1CD93A8258D6BDC00409613 /* ChatThreadClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CD93A7258D6BDC00409613 /* ChatThreadClientTests.swift */; }; + D1CD93AD258D6C2500409613 /* RecordingUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CD93AC258D6C2500409613 /* RecordingUtil.swift */; }; + D1CD93B3258D6C3D00409613 /* TestUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1CD93B2258D6C3D00409613 /* TestUtil.swift */; }; + D1CD93BE258D6E6200409613 /* addParticipants.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93BD258D6E6200409613 /* addParticipants.json */; }; + D1CD93C4258D6E7300409613 /* createThread.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93C3258D6E7300409613 /* createThread.json */; }; + D1CD93C8258D6E8F00409613 /* deleteMessage.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93C7258D6E8F00409613 /* deleteMessage.json */; }; + D1CD93CC258D6E9E00409613 /* deleteThread.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93CB258D6E9E00409613 /* deleteThread.json */; }; + D1CD93D0258D6EAB00409613 /* getThread.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93CF258D6EAB00409613 /* getThread.json */; }; + D1CD93D8258D6ECD00409613 /* removeParticipant.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93D7258D6ECD00409613 /* removeParticipant.json */; }; + D1CD93DC258D6EDA00409613 /* sendMessage.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93DB258D6EDA00409613 /* sendMessage.json */; }; + D1CD93E0258D6EEA00409613 /* sendReadReceipt.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93DF258D6EEA00409613 /* sendReadReceipt.json */; }; + D1CD93E4258D6EF700409613 /* sendTypingNotification.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93E3258D6EF700409613 /* sendTypingNotification.json */; }; + D1CD93E8258D6F0600409613 /* updateMessage.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93E7258D6F0600409613 /* updateMessage.json */; }; + D1CD93EC258D6F1300409613 /* updateTopic.json in Resources */ = {isa = PBXBuildFile; fileRef = D1CD93EB258D6F1300409613 /* updateTopic.json */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + D147E62E25CE242C001CFB5D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = OBJ_1 /* Project object */; + proxyType = 1; + remoteGlobalIDString = "AzureCommunicationChat::AzureCommunicationChat"; + remoteInfo = AzureCommunicationChat; + }; + D1CD936C258D688D00409613 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = OBJ_1 /* Project object */; + proxyType = 1; + remoteGlobalIDString = "AzureCommunicationChat::AzureCommunicationChat"; + remoteInfo = AzureCommunicationChat; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ - 0A4745032583F47600CA86E5 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - 0A47451D2583FDF600CA86E5 /* AzureCommunicationChatClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AzureCommunicationChatClient.swift; sourceTree = ""; }; - 0A47451F2583FDF600CA86E5 /* AzureCommunicationChatService+CreateChatThreadOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+CreateChatThreadOptions.swift"; sourceTree = ""; }; - 0A4745202583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatMessageOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+UpdateChatMessageOptions.swift"; sourceTree = ""; }; - 0A4745212583FDF600CA86E5 /* AzureCommunicationChatClientOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AzureCommunicationChatClientOptions.swift; sourceTree = ""; }; - 0A4745222583FDF600CA86E5 /* AzureCommunicationChatService+ListChatThreadsOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+ListChatThreadsOptions.swift"; sourceTree = ""; }; - 0A4745232583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatThreadOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+DeleteChatThreadOptions.swift"; sourceTree = ""; }; - 0A4745242583FDF600CA86E5 /* AzureCommunicationChatService+SendChatMessageOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+SendChatMessageOptions.swift"; sourceTree = ""; }; - 0A4745252583FDF600CA86E5 /* AzureCommunicationChatService+GetChatThreadOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+GetChatThreadOptions.swift"; sourceTree = ""; }; - 0A4745262583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatThreadOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+UpdateChatThreadOptions.swift"; sourceTree = ""; }; - 0A4745272583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatMessageOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+DeleteChatMessageOptions.swift"; sourceTree = ""; }; - 0A4745282583FDF600CA86E5 /* AzureCommunicationChatService+ListChatMessagesOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+ListChatMessagesOptions.swift"; sourceTree = ""; }; - 0A4745292583FDF600CA86E5 /* AzureCommunicationChatService+ListChatReadReceiptsOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+ListChatReadReceiptsOptions.swift"; sourceTree = ""; }; - 0A47452A2583FDF600CA86E5 /* AzureCommunicationChatService+AddChatThreadMembersOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+AddChatThreadMembersOptions.swift"; sourceTree = ""; }; - 0A47452B2583FDF600CA86E5 /* AzureCommunicationChatService+GetChatMessageOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+GetChatMessageOptions.swift"; sourceTree = ""; }; - 0A47452C2583FDF600CA86E5 /* AzureCommunicationChatService+ListChatThreadMembersOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+ListChatThreadMembersOptions.swift"; sourceTree = ""; }; - 0A47452D2583FDF600CA86E5 /* AzureCommunicationChatService+SendChatReadReceiptOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+SendChatReadReceiptOptions.swift"; sourceTree = ""; }; - 0A47452E2583FDF600CA86E5 /* AzureCommunicationChatService+SendTypingNotificationOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+SendTypingNotificationOptions.swift"; sourceTree = ""; }; - 0A47452F2583FDF600CA86E5 /* AzureCommunicationChatService+RemoveChatThreadMemberOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommunicationChatService+RemoveChatThreadMemberOptions.swift"; sourceTree = ""; }; - 0A4745312583FDF600CA86E5 /* PatchUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PatchUtil.swift; sourceTree = ""; }; - 0A4745332583FDF600CA86E5 /* SendChatMessageRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendChatMessageRequest.swift; sourceTree = ""; }; - 0A4745342583FDF600CA86E5 /* MultiStatusResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultiStatusResponse.swift; sourceTree = ""; }; - 0A4745352583FDF600CA86E5 /* UpdateChatThreadRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateChatThreadRequest.swift; sourceTree = ""; }; - 0A4745362583FDF600CA86E5 /* ChatMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessage.swift; sourceTree = ""; }; - 0A4745372583FDF600CA86E5 /* ChatMessagesCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessagesCollection.swift; sourceTree = ""; }; - 0A4745382583FDF600CA86E5 /* CreateChatThreadRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateChatThreadRequest.swift; sourceTree = ""; }; - 0A4745392583FDF600CA86E5 /* AddChatThreadMembersRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddChatThreadMembersRequest.swift; sourceTree = ""; }; - 0A47453A2583FDF600CA86E5 /* ReadReceipt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadReceipt.swift; sourceTree = ""; }; - 0A47453B2583FDF600CA86E5 /* Enumerations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enumerations.swift; sourceTree = ""; }; - 0A47453C2583FDF600CA86E5 /* IndividualStatusResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndividualStatusResponse.swift; sourceTree = ""; }; - 0A47453D2583FDF600CA86E5 /* ChatThreadsInfoCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThreadsInfoCollection.swift; sourceTree = ""; }; - 0A47453E2583FDF600CA86E5 /* ChatThread.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThread.swift; sourceTree = ""; }; - 0A47453F2583FDF600CA86E5 /* UpdateChatMessageRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateChatMessageRequest.swift; sourceTree = ""; }; - 0A4745402583FDF600CA86E5 /* SendReadReceiptRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendReadReceiptRequest.swift; sourceTree = ""; }; - 0A4745412583FDF600CA86E5 /* ChatThreadMember.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThreadMember.swift; sourceTree = ""; }; - 0A4745422583FDF600CA86E5 /* ErrorType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorType.swift; sourceTree = ""; }; - 0A4745432583FDF600CA86E5 /* ChatThreadInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThreadInfo.swift; sourceTree = ""; }; - 0A4745442583FDF600CA86E5 /* SendChatMessageResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendChatMessageResult.swift; sourceTree = ""; }; - 0A4745452583FDF600CA86E5 /* ReadReceiptsCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadReceiptsCollection.swift; sourceTree = ""; }; - 0A4745462583FDF600CA86E5 /* ChatThreadMembersCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThreadMembersCollection.swift; sourceTree = ""; }; - 0A4745472583FDF600CA86E5 /* AzureCommunicationChatService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AzureCommunicationChatService.swift; sourceTree = ""; }; - 0A4745482583FDF600CA86E5 /* AzureCommuncationChatClient+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AzureCommuncationChatClient+Convenience.swift"; sourceTree = ""; }; - 0A4745492583FDF600CA86E5 /* Custom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Custom.swift; sourceTree = ""; }; - 0A74765B2522918900819FC9 /* AzureCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AzureCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 04B336EEF1E42CCE389E4935 /* Pods-AzureCommunicationChat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AzureCommunicationChat.release.xcconfig"; path = "Target Support Files/Pods-AzureCommunicationChat/Pods-AzureCommunicationChat.release.xcconfig"; sourceTree = ""; }; + 0ECA8CD1258181A5006760F7 /* ChatClientUnitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatClientUnitTests.swift; sourceTree = ""; }; + 0ECA8CDE258188D0006760F7 /* GetThreadResponse.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = GetThreadResponse.json; sourceTree = ""; }; + 0ECA8CEA2582A52D006760F7 /* UnauthorizedError.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = UnauthorizedError.json; sourceTree = ""; }; + 0ECA8CF02582A633006760F7 /* ListThreadsResponse.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ListThreadsResponse.json; sourceTree = ""; }; + 0ECA8D08258432DC006760F7 /* ChatThreadClientUnitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThreadClientUnitTests.swift; sourceTree = ""; }; + 0ECA8D0E25888515006760F7 /* NoContent.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = NoContent.json; sourceTree = ""; }; + 0ECA8D0F25888515006760F7 /* SendMessageResponse.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = SendMessageResponse.json; sourceTree = ""; }; + 0ECA8D1625888667006760F7 /* GetMessageResponse.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = GetMessageResponse.json; sourceTree = ""; }; + 0ECA8D1C258887D3006760F7 /* ListMessagesResponse.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ListMessagesResponse.json; sourceTree = ""; }; + 0ECA8D2225888DD8006760F7 /* ListParticipantsResponse.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ListParticipantsResponse.json; sourceTree = ""; }; + 0ECA8D28258892CD006760F7 /* AddParticipantResponse.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = AddParticipantResponse.json; sourceTree = ""; }; + 0ECA8D2E25889619006760F7 /* ListReadReceiptResponse.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ListReadReceiptResponse.json; sourceTree = ""; }; + 2CB55B558C70B4045A54487D /* Pods-AzureCommunicationChatTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AzureCommunicationChatTests.debug.xcconfig"; path = "Target Support Files/Pods-AzureCommunicationChatTests/Pods-AzureCommunicationChatTests.debug.xcconfig"; sourceTree = ""; }; + 8E5206D2E09378DA0F9FD0E4 /* Pods-AzureCommunicationChatTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AzureCommunicationChatTests.release.xcconfig"; path = "Target Support Files/Pods-AzureCommunicationChatTests/Pods-AzureCommunicationChatTests.release.xcconfig"; sourceTree = ""; }; + 9FE998BEC9685C476F2AFD1C /* Pods-AzureCommunicationChat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AzureCommunicationChat.debug.xcconfig"; path = "Target Support Files/Pods-AzureCommunicationChat/Pods-AzureCommunicationChat.debug.xcconfig"; sourceTree = ""; }; "AzureCommunicationChat::AzureCommunicationChat::Product" /* AzureCommunicationChat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AzureCommunicationChat.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - OBJ_101 /* ApplicationUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationUtil.swift; sourceTree = ""; }; - OBJ_102 /* AzureCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AzureCodable.swift; sourceTree = ""; }; - OBJ_103 /* ConvertingInitializers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConvertingInitializers.swift; sourceTree = ""; }; - OBJ_104 /* Copyable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Copyable.swift; sourceTree = ""; }; - OBJ_105 /* CryptoUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoUtil.swift; sourceTree = ""; }; - OBJ_106 /* KeychainUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainUtil.swift; sourceTree = ""; }; - OBJ_107 /* ReachabilityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReachabilityManager.swift; sourceTree = ""; }; - OBJ_108 /* ReachabilityManagerType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReachabilityManagerType.swift; sourceTree = ""; }; - OBJ_109 /* RegexUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegexUtil.swift; sourceTree = ""; }; - OBJ_110 /* StringUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringUtil.swift; sourceTree = ""; }; - OBJ_111 /* URLUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLUtil.swift; sourceTree = ""; }; - OBJ_112 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; name = Package.swift; path = "/Users/travisprescott/Documents/generated/sdk/AzureCommunicationChat/.build/checkouts/azure-sdk-for-ios/Package.swift"; sourceTree = ""; }; - OBJ_57 /* AzureTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AzureTask.swift; sourceTree = ""; }; - OBJ_58 /* ClientLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientLogger.swift; sourceTree = ""; }; - OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; - OBJ_60 /* CancellationToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancellationToken.swift; sourceTree = ""; }; - OBJ_61 /* Collections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Collections.swift; sourceTree = ""; }; - OBJ_63 /* XMLMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XMLMap.swift; sourceTree = ""; }; - OBJ_64 /* XMLModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XMLModel.swift; sourceTree = ""; }; - OBJ_65 /* XMLTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XMLTree.swift; sourceTree = ""; }; - OBJ_66 /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; - OBJ_68 /* Pipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pipeline.swift; sourceTree = ""; }; - OBJ_69 /* PipelineClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PipelineClient.swift; sourceTree = ""; }; - OBJ_70 /* PipelineContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PipelineContext.swift; sourceTree = ""; }; - OBJ_71 /* PipelineRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PipelineRequest.swift; sourceTree = ""; }; - OBJ_72 /* PipelineResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PipelineResponse.swift; sourceTree = ""; }; - OBJ_73 /* PipelineStage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PipelineStage.swift; sourceTree = ""; }; - OBJ_75 /* AddDatePolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddDatePolicy.swift; sourceTree = ""; }; - OBJ_76 /* AuthenticationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationPolicy.swift; sourceTree = ""; }; - OBJ_77 /* ContentDecodePolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentDecodePolicy.swift; sourceTree = ""; }; - OBJ_78 /* HeadersPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersPolicy.swift; sourceTree = ""; }; - OBJ_79 /* HeadersValidationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersValidationPolicy.swift; sourceTree = ""; }; - OBJ_80 /* LoggingPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingPolicy.swift; sourceTree = ""; }; - OBJ_81 /* NormalizeETagPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NormalizeETagPolicy.swift; sourceTree = ""; }; - OBJ_82 /* RequestIdPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestIdPolicy.swift; sourceTree = ""; }; - OBJ_83 /* UserAgentPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgentPolicy.swift; sourceTree = ""; }; - OBJ_85 /* DataStringConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStringConvertible.swift; sourceTree = ""; }; - OBJ_86 /* HTTPHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPHeader.swift; sourceTree = ""; }; - OBJ_87 /* HTTPMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPMethod.swift; sourceTree = ""; }; - OBJ_88 /* HTTPRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPRequest.swift; sourceTree = ""; }; - OBJ_89 /* HTTPResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPResponse.swift; sourceTree = ""; }; - OBJ_90 /* HTTPTransportStage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPTransportStage.swift; sourceTree = ""; }; - OBJ_91 /* TelemetryOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryOptions.swift; sourceTree = ""; }; - OBJ_92 /* TransportOptions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransportOptions.swift; sourceTree = ""; }; - OBJ_93 /* URLHTTPResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLHTTPResponse.swift; sourceTree = ""; }; - OBJ_94 /* URLSessionTransport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionTransport.swift; sourceTree = ""; }; - OBJ_96 /* BundleInfoProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleInfoProvider.swift; sourceTree = ""; }; - OBJ_97 /* DeviceProviders.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceProviders.swift; sourceTree = ""; }; - OBJ_98 /* LocaleInfoProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocaleInfoProvider.swift; sourceTree = ""; }; - OBJ_99 /* PlatformInfoProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformInfoProvider.swift; sourceTree = ""; }; + D10C3BCD25A63F7800A181E3 /* listParticipants.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = listParticipants.json; sourceTree = ""; }; + D10C3BD325A660AF00A181E3 /* listMessages.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = listMessages.json; sourceTree = ""; }; + D10C3BD925A66D4D00A181E3 /* listThreads.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = listThreads.json; sourceTree = ""; }; + D110F506258D603F001FA3CD /* AzureCommunication.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AzureCommunication.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D110F509258D604B001FA3CD /* AzureCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AzureCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D110F50B258D6053001FA3CD /* Pods_AzureCommunicationChat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Pods_AzureCommunicationChat.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D13CE64E25BFB69100415467 /* listReadReceipts.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = listReadReceipts.json; sourceTree = ""; }; + D147E62825CE242C001CFB5D /* AzureCommunicationChatUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AzureCommunicationChatUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + D1565C70256DB74900AF45F8 /* ChatClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatClient.swift; sourceTree = ""; }; + D1565C73256DB76C00AF45F8 /* ChatThreadClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatThreadClient.swift; sourceTree = ""; }; + D15E98CA25B7C80C00E63DB2 /* AzureCommunicationChatClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AzureCommunicationChatClient.swift; sourceTree = ""; }; + D15E98CC25B7C80C00E63DB2 /* ChatThreadOperation+AddChatParticipantsOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+AddChatParticipantsOptions.swift"; sourceTree = ""; }; + D15E98CD25B7C80C00E63DB2 /* ChatThreadOperation+ListChatReadReceiptsOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+ListChatReadReceiptsOptions.swift"; sourceTree = ""; }; + D15E98CE25B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatMessageOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+UpdateChatMessageOptions.swift"; sourceTree = ""; }; + D15E98CF25B7C80C00E63DB2 /* Chat+ListChatThreadsOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Chat+ListChatThreadsOptions.swift"; sourceTree = ""; }; + D15E98D025B7C80C00E63DB2 /* Chat+DeleteChatThreadOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Chat+DeleteChatThreadOptions.swift"; sourceTree = ""; }; + D15E98D125B7C80C00E63DB2 /* AzureCommunicationChatClientOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AzureCommunicationChatClientOptions.swift; sourceTree = ""; }; + D15E98D225B7C80C00E63DB2 /* ChatThreadOperation+SendChatMessageOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+SendChatMessageOptions.swift"; sourceTree = ""; }; + D15E98D325B7C80C00E63DB2 /* ChatThreadOperation+SendChatReadReceiptOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+SendChatReadReceiptOptions.swift"; sourceTree = ""; }; + D15E98D425B7C80C00E63DB2 /* ChatThreadOperation+RemoveChatParticipantOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+RemoveChatParticipantOptions.swift"; sourceTree = ""; }; + D15E98D525B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatThreadOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+UpdateChatThreadOptions.swift"; sourceTree = ""; }; + D15E98D625B7C80C00E63DB2 /* Chat+CreateChatThreadOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Chat+CreateChatThreadOptions.swift"; sourceTree = ""; }; + D15E98D725B7C80C00E63DB2 /* ChatThreadOperation+SendTypingNotificationOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+SendTypingNotificationOptions.swift"; sourceTree = ""; }; + D15E98D825B7C80C00E63DB2 /* ChatThreadOperation+DeleteChatMessageOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+DeleteChatMessageOptions.swift"; sourceTree = ""; }; + D15E98D925B7C80C00E63DB2 /* ChatThreadOperation+ListChatMessagesOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+ListChatMessagesOptions.swift"; sourceTree = ""; }; + D15E98DA25B7C80C00E63DB2 /* ChatThreadOperation+GetChatMessageOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+GetChatMessageOptions.swift"; sourceTree = ""; }; + D15E98DB25B7C80C00E63DB2 /* Chat+GetChatThreadOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Chat+GetChatThreadOptions.swift"; sourceTree = ""; }; + D15E98DC25B7C80C00E63DB2 /* ChatThreadOperation+ListChatParticipantsOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadOperation+ListChatParticipantsOptions.swift"; sourceTree = ""; }; + D15E98DE25B7C80C00E63DB2 /* PatchUtil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PatchUtil.swift; sourceTree = ""; }; + D15E98DF25B7C80C00E63DB2 /* Chat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Chat.swift; sourceTree = ""; }; + D15E98E125B7C80C00E63DB2 /* AddChatParticipantsErrors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddChatParticipantsErrors.swift; sourceTree = ""; }; + D15E98E225B7C80C00E63DB2 /* CommunicationError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommunicationError.swift; sourceTree = ""; }; + D15E98E325B7C80C00E63DB2 /* SendChatMessageRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendChatMessageRequest.swift; sourceTree = ""; }; + D15E98E425B7C80C00E63DB2 /* ChatMessageContent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageContent.swift; sourceTree = ""; }; + D15E98E525B7C80C00E63DB2 /* UpdateChatThreadRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateChatThreadRequest.swift; sourceTree = ""; }; + D15E98E625B7C80C00E63DB2 /* ChatMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessage.swift; sourceTree = ""; }; + D15E98E725B7C80C00E63DB2 /* ChatMessagesCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessagesCollection.swift; sourceTree = ""; }; + D15E98E825B7C80C00E63DB2 /* CreateChatThreadErrors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateChatThreadErrors.swift; sourceTree = ""; }; + D15E98E925B7C80C00E63DB2 /* ChatMessageReadReceipt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageReadReceipt.swift; sourceTree = ""; }; + D15E98EA25B7C80C00E63DB2 /* CreateChatThreadRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateChatThreadRequest.swift; sourceTree = ""; }; + D15E98EB25B7C80C00E63DB2 /* CommunicationErrorResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommunicationErrorResponse.swift; sourceTree = ""; }; + D15E98EC25B7C80C00E63DB2 /* Enumerations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Enumerations.swift; sourceTree = ""; }; + D15E98ED25B7C80C00E63DB2 /* AddChatParticipantsResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddChatParticipantsResult.swift; sourceTree = ""; }; + D15E98EE25B7C80C00E63DB2 /* ChatMessageReadReceiptsCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatMessageReadReceiptsCollection.swift; sourceTree = ""; }; + D15E98EF25B7C80C00E63DB2 /* ChatThreadsInfoCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThreadsInfoCollection.swift; sourceTree = ""; }; + D15E98F025B7C80C00E63DB2 /* ChatThread.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThread.swift; sourceTree = ""; }; + D15E98F125B7C80C00E63DB2 /* UpdateChatMessageRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdateChatMessageRequest.swift; sourceTree = ""; }; + D15E98F225B7C80C00E63DB2 /* CreateChatThreadResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateChatThreadResult.swift; sourceTree = ""; }; + D15E98F325B7C80C00E63DB2 /* SendReadReceiptRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendReadReceiptRequest.swift; sourceTree = ""; }; + D15E98F425B7C80C00E63DB2 /* ChatThreadInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThreadInfo.swift; sourceTree = ""; }; + D15E98F525B7C80C00E63DB2 /* SendChatMessageResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendChatMessageResult.swift; sourceTree = ""; }; + D15E98F625B7C80C00E63DB2 /* AddChatParticipantsRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddChatParticipantsRequest.swift; sourceTree = ""; }; + D15E98F725B7C80C00E63DB2 /* ChatParticipant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatParticipant.swift; sourceTree = ""; }; + D15E98F825B7C80C00E63DB2 /* ChatParticipantsCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatParticipantsCollection.swift; sourceTree = ""; }; + D15E98F925B7C80C00E63DB2 /* ChatThreadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThreadOperation.swift; sourceTree = ""; }; + D16C802C25BA0A2400C42803 /* Message.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = ""; }; + D16C803225BA0AE400C42803 /* Thread.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Thread.swift; sourceTree = ""; }; + D16C803625BA0AFE00C42803 /* Participant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Participant.swift; sourceTree = ""; }; + D16C803A25BA0B0E00C42803 /* ReadReceipt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadReceipt.swift; sourceTree = ""; }; + D16C803E25BA0B5200C42803 /* MessageContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageContent.swift; sourceTree = ""; }; + D16C804225BA402100C42803 /* CreateThreadRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateThreadRequest.swift; sourceTree = ""; }; + D16C804625BA406D00C42803 /* CreateThreadResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateThreadResult.swift; sourceTree = ""; }; + D1B7EAED257F02FC004F384A /* AzureCommunicationChatTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AzureCommunicationChatTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + D1B7EAFC257F03A1004F384A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D1BA104525807B0B00CA7130 /* CreateThreadResponse.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = CreateThreadResponse.json; sourceTree = ""; }; + D1CD93A1258D6BC700409613 /* ChatClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatClientTests.swift; sourceTree = ""; }; + D1CD93A7258D6BDC00409613 /* ChatThreadClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatThreadClientTests.swift; sourceTree = ""; }; + D1CD93AC258D6C2500409613 /* RecordingUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingUtil.swift; sourceTree = ""; }; + D1CD93B2258D6C3D00409613 /* TestUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestUtil.swift; sourceTree = ""; }; + D1CD93BD258D6E6200409613 /* addParticipants.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = addParticipants.json; sourceTree = ""; }; + D1CD93C3258D6E7300409613 /* createThread.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = createThread.json; sourceTree = ""; }; + D1CD93C7258D6E8F00409613 /* deleteMessage.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = deleteMessage.json; sourceTree = ""; }; + D1CD93CB258D6E9E00409613 /* deleteThread.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = deleteThread.json; sourceTree = ""; }; + D1CD93CF258D6EAB00409613 /* getThread.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = getThread.json; sourceTree = ""; }; + D1CD93D7258D6ECD00409613 /* removeParticipant.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = removeParticipant.json; sourceTree = ""; }; + D1CD93DB258D6EDA00409613 /* sendMessage.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = sendMessage.json; sourceTree = ""; }; + D1CD93DF258D6EEA00409613 /* sendReadReceipt.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = sendReadReceipt.json; sourceTree = ""; }; + D1CD93E3258D6EF700409613 /* sendTypingNotification.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = sendTypingNotification.json; sourceTree = ""; }; + D1CD93E7258D6F0600409613 /* updateMessage.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = updateMessage.json; sourceTree = ""; }; + D1CD93EB258D6F1300409613 /* updateTopic.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = updateTopic.json; sourceTree = ""; }; + F1FE3013E797A134E8A6C3B5 /* Pods_AzureCommunicationChatTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AzureCommunicationChatTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + D147E62525CE242C001CFB5D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D147E62D25CE242C001CFB5D /* AzureCommunicationChat.framework in Frameworks */, + D193C45B25CE258F006F769C /* OHHTTPStubsSwift in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D1B7EAEA257F02FC004F384A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D1B7EB06257F0D20004F384A /* AzureCommunicationChat.framework in Frameworks */, + D1BA104D25807B7500CA7130 /* OHHTTPStubsSwift in Frameworks */, + 9766BE9261FCB48436FA6682 /* Pods_AzureCommunicationChatTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; OBJ_161 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 0; files = ( - 0A74765C2522918900819FC9 /* AzureCore.framework in Frameworks */, + D110F50C258D6053001FA3CD /* Pods_AzureCommunicationChat.framework in Frameworks */, + D110F50A258D604B001FA3CD /* AzureCore.framework in Frameworks */, + D110F507258D603F001FA3CD /* AzureCommunication.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0A47451B2583FDF600CA86E5 /* Source */ = { - isa = PBXGroup; - children = ( - 0A47451C2583FDF600CA86E5 /* Generated */, - 0A4745482583FDF600CA86E5 /* AzureCommuncationChatClient+Convenience.swift */, - 0A4745492583FDF600CA86E5 /* Custom.swift */, - ); - path = Source; - sourceTree = ""; - }; - 0A47451C2583FDF600CA86E5 /* Generated */ = { - isa = PBXGroup; - children = ( - 0A47451D2583FDF600CA86E5 /* AzureCommunicationChatClient.swift */, - 0A47451E2583FDF600CA86E5 /* Options */, - 0A4745302583FDF600CA86E5 /* Util */, - 0A4745322583FDF600CA86E5 /* Models */, - 0A4745472583FDF600CA86E5 /* AzureCommunicationChatService.swift */, - ); - path = Generated; - sourceTree = ""; - }; - 0A47451E2583FDF600CA86E5 /* Options */ = { - isa = PBXGroup; - children = ( - 0A47451F2583FDF600CA86E5 /* AzureCommunicationChatService+CreateChatThreadOptions.swift */, - 0A4745202583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatMessageOptions.swift */, - 0A4745212583FDF600CA86E5 /* AzureCommunicationChatClientOptions.swift */, - 0A4745222583FDF600CA86E5 /* AzureCommunicationChatService+ListChatThreadsOptions.swift */, - 0A4745232583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatThreadOptions.swift */, - 0A4745242583FDF600CA86E5 /* AzureCommunicationChatService+SendChatMessageOptions.swift */, - 0A4745252583FDF600CA86E5 /* AzureCommunicationChatService+GetChatThreadOptions.swift */, - 0A4745262583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatThreadOptions.swift */, - 0A4745272583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatMessageOptions.swift */, - 0A4745282583FDF600CA86E5 /* AzureCommunicationChatService+ListChatMessagesOptions.swift */, - 0A4745292583FDF600CA86E5 /* AzureCommunicationChatService+ListChatReadReceiptsOptions.swift */, - 0A47452A2583FDF600CA86E5 /* AzureCommunicationChatService+AddChatThreadMembersOptions.swift */, - 0A47452B2583FDF600CA86E5 /* AzureCommunicationChatService+GetChatMessageOptions.swift */, - 0A47452C2583FDF600CA86E5 /* AzureCommunicationChatService+ListChatThreadMembersOptions.swift */, - 0A47452D2583FDF600CA86E5 /* AzureCommunicationChatService+SendChatReadReceiptOptions.swift */, - 0A47452E2583FDF600CA86E5 /* AzureCommunicationChatService+SendTypingNotificationOptions.swift */, - 0A47452F2583FDF600CA86E5 /* AzureCommunicationChatService+RemoveChatThreadMemberOptions.swift */, - ); - path = Options; - sourceTree = ""; - }; - 0A4745302583FDF600CA86E5 /* Util */ = { - isa = PBXGroup; - children = ( - 0A4745312583FDF600CA86E5 /* PatchUtil.swift */, - ); - path = Util; - sourceTree = ""; - }; - 0A4745322583FDF600CA86E5 /* Models */ = { - isa = PBXGroup; - children = ( - 0A4745332583FDF600CA86E5 /* SendChatMessageRequest.swift */, - 0A4745342583FDF600CA86E5 /* MultiStatusResponse.swift */, - 0A4745352583FDF600CA86E5 /* UpdateChatThreadRequest.swift */, - 0A4745362583FDF600CA86E5 /* ChatMessage.swift */, - 0A4745372583FDF600CA86E5 /* ChatMessagesCollection.swift */, - 0A4745382583FDF600CA86E5 /* CreateChatThreadRequest.swift */, - 0A4745392583FDF600CA86E5 /* AddChatThreadMembersRequest.swift */, - 0A47453A2583FDF600CA86E5 /* ReadReceipt.swift */, - 0A47453B2583FDF600CA86E5 /* Enumerations.swift */, - 0A47453C2583FDF600CA86E5 /* IndividualStatusResponse.swift */, - 0A47453D2583FDF600CA86E5 /* ChatThreadsInfoCollection.swift */, - 0A47453E2583FDF600CA86E5 /* ChatThread.swift */, - 0A47453F2583FDF600CA86E5 /* UpdateChatMessageRequest.swift */, - 0A4745402583FDF600CA86E5 /* SendReadReceiptRequest.swift */, - 0A4745412583FDF600CA86E5 /* ChatThreadMember.swift */, - 0A4745422583FDF600CA86E5 /* ErrorType.swift */, - 0A4745432583FDF600CA86E5 /* ChatThreadInfo.swift */, - 0A4745442583FDF600CA86E5 /* SendChatMessageResult.swift */, - 0A4745452583FDF600CA86E5 /* ReadReceiptsCollection.swift */, - 0A4745462583FDF600CA86E5 /* ChatThreadMembersCollection.swift */, - ); - path = Models; - sourceTree = ""; - }; 0A74765A2522918800819FC9 /* Frameworks */ = { isa = PBXGroup; children = ( - 0A74765B2522918900819FC9 /* AzureCore.framework */, + D110F50B258D6053001FA3CD /* Pods_AzureCommunicationChat.framework */, + D110F509258D604B001FA3CD /* AzureCore.framework */, + D110F506258D603F001FA3CD /* AzureCommunication.framework */, + F1FE3013E797A134E8A6C3B5 /* Pods_AzureCommunicationChatTests.framework */, ); name = Frameworks; sourceTree = ""; }; - OBJ_100 /* Util */ = { + 0ECA8CD52581838E006760F7 /* Mocks */ = { isa = PBXGroup; children = ( - OBJ_101 /* ApplicationUtil.swift */, - OBJ_102 /* AzureCodable.swift */, - OBJ_103 /* ConvertingInitializers.swift */, - OBJ_104 /* Copyable.swift */, - OBJ_105 /* CryptoUtil.swift */, - OBJ_106 /* KeychainUtil.swift */, - OBJ_107 /* ReachabilityManager.swift */, - OBJ_108 /* ReachabilityManagerType.swift */, - OBJ_109 /* RegexUtil.swift */, - OBJ_110 /* StringUtil.swift */, - OBJ_111 /* URLUtil.swift */, + 0ECA8D2E25889619006760F7 /* ListReadReceiptResponse.json */, + 0ECA8D28258892CD006760F7 /* AddParticipantResponse.json */, + 0ECA8D2225888DD8006760F7 /* ListParticipantsResponse.json */, + 0ECA8D1C258887D3006760F7 /* ListMessagesResponse.json */, + 0ECA8D1625888667006760F7 /* GetMessageResponse.json */, + 0ECA8D0E25888515006760F7 /* NoContent.json */, + 0ECA8D0F25888515006760F7 /* SendMessageResponse.json */, + 0ECA8CF02582A633006760F7 /* ListThreadsResponse.json */, + 0ECA8CEA2582A52D006760F7 /* UnauthorizedError.json */, + 0ECA8CDE258188D0006760F7 /* GetThreadResponse.json */, + D1BA104525807B0B00CA7130 /* CreateThreadResponse.json */, + ); + path = Mocks; + sourceTree = ""; + }; + A4D0748296D3AEEA8C0DAB94 /* Pods */ = { + isa = PBXGroup; + children = ( + 9FE998BEC9685C476F2AFD1C /* Pods-AzureCommunicationChat.debug.xcconfig */, + 04B336EEF1E42CCE389E4935 /* Pods-AzureCommunicationChat.release.xcconfig */, + 2CB55B558C70B4045A54487D /* Pods-AzureCommunicationChatTests.debug.xcconfig */, + 8E5206D2E09378DA0F9FD0E4 /* Pods-AzureCommunicationChatTests.release.xcconfig */, + ); + name = Pods; + path = ../../../Pods; + sourceTree = ""; + }; + D15E98C925B7C80C00E63DB2 /* Generated */ = { + isa = PBXGroup; + children = ( + D15E98CA25B7C80C00E63DB2 /* AzureCommunicationChatClient.swift */, + D15E98CB25B7C80C00E63DB2 /* Options */, + D15E98DD25B7C80C00E63DB2 /* Util */, + D15E98DF25B7C80C00E63DB2 /* Chat.swift */, + D15E98E025B7C80C00E63DB2 /* Models */, + D15E98F925B7C80C00E63DB2 /* ChatThreadOperation.swift */, + ); + path = Generated; + sourceTree = ""; + }; + D15E98CB25B7C80C00E63DB2 /* Options */ = { + isa = PBXGroup; + children = ( + D15E98CC25B7C80C00E63DB2 /* ChatThreadOperation+AddChatParticipantsOptions.swift */, + D15E98CD25B7C80C00E63DB2 /* ChatThreadOperation+ListChatReadReceiptsOptions.swift */, + D15E98CE25B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatMessageOptions.swift */, + D15E98CF25B7C80C00E63DB2 /* Chat+ListChatThreadsOptions.swift */, + D15E98D025B7C80C00E63DB2 /* Chat+DeleteChatThreadOptions.swift */, + D15E98D125B7C80C00E63DB2 /* AzureCommunicationChatClientOptions.swift */, + D15E98D225B7C80C00E63DB2 /* ChatThreadOperation+SendChatMessageOptions.swift */, + D15E98D325B7C80C00E63DB2 /* ChatThreadOperation+SendChatReadReceiptOptions.swift */, + D15E98D425B7C80C00E63DB2 /* ChatThreadOperation+RemoveChatParticipantOptions.swift */, + D15E98D525B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatThreadOptions.swift */, + D15E98D625B7C80C00E63DB2 /* Chat+CreateChatThreadOptions.swift */, + D15E98D725B7C80C00E63DB2 /* ChatThreadOperation+SendTypingNotificationOptions.swift */, + D15E98D825B7C80C00E63DB2 /* ChatThreadOperation+DeleteChatMessageOptions.swift */, + D15E98D925B7C80C00E63DB2 /* ChatThreadOperation+ListChatMessagesOptions.swift */, + D15E98DA25B7C80C00E63DB2 /* ChatThreadOperation+GetChatMessageOptions.swift */, + D15E98DB25B7C80C00E63DB2 /* Chat+GetChatThreadOptions.swift */, + D15E98DC25B7C80C00E63DB2 /* ChatThreadOperation+ListChatParticipantsOptions.swift */, + ); + path = Options; + sourceTree = ""; + }; + D15E98DD25B7C80C00E63DB2 /* Util */ = { + isa = PBXGroup; + children = ( + D15E98DE25B7C80C00E63DB2 /* PatchUtil.swift */, ); path = Util; sourceTree = ""; }; + D15E98E025B7C80C00E63DB2 /* Models */ = { + isa = PBXGroup; + children = ( + D15E98E125B7C80C00E63DB2 /* AddChatParticipantsErrors.swift */, + D15E98E225B7C80C00E63DB2 /* CommunicationError.swift */, + D15E98E325B7C80C00E63DB2 /* SendChatMessageRequest.swift */, + D15E98E425B7C80C00E63DB2 /* ChatMessageContent.swift */, + D15E98E525B7C80C00E63DB2 /* UpdateChatThreadRequest.swift */, + D15E98E625B7C80C00E63DB2 /* ChatMessage.swift */, + D15E98E725B7C80C00E63DB2 /* ChatMessagesCollection.swift */, + D15E98E825B7C80C00E63DB2 /* CreateChatThreadErrors.swift */, + D15E98E925B7C80C00E63DB2 /* ChatMessageReadReceipt.swift */, + D15E98EA25B7C80C00E63DB2 /* CreateChatThreadRequest.swift */, + D15E98EB25B7C80C00E63DB2 /* CommunicationErrorResponse.swift */, + D15E98EC25B7C80C00E63DB2 /* Enumerations.swift */, + D15E98ED25B7C80C00E63DB2 /* AddChatParticipantsResult.swift */, + D15E98EE25B7C80C00E63DB2 /* ChatMessageReadReceiptsCollection.swift */, + D15E98EF25B7C80C00E63DB2 /* ChatThreadsInfoCollection.swift */, + D15E98F025B7C80C00E63DB2 /* ChatThread.swift */, + D15E98F125B7C80C00E63DB2 /* UpdateChatMessageRequest.swift */, + D15E98F225B7C80C00E63DB2 /* CreateChatThreadResult.swift */, + D15E98F325B7C80C00E63DB2 /* SendReadReceiptRequest.swift */, + D15E98F425B7C80C00E63DB2 /* ChatThreadInfo.swift */, + D15E98F525B7C80C00E63DB2 /* SendChatMessageResult.swift */, + D15E98F625B7C80C00E63DB2 /* AddChatParticipantsRequest.swift */, + D15E98F725B7C80C00E63DB2 /* ChatParticipant.swift */, + D15E98F825B7C80C00E63DB2 /* ChatParticipantsCollection.swift */, + ); + path = Models; + sourceTree = ""; + }; + D16C802B25BA0A0F00C42803 /* Models */ = { + isa = PBXGroup; + children = ( + D16C802C25BA0A2400C42803 /* Message.swift */, + D16C803225BA0AE400C42803 /* Thread.swift */, + D16C803625BA0AFE00C42803 /* Participant.swift */, + D16C803A25BA0B0E00C42803 /* ReadReceipt.swift */, + D16C803E25BA0B5200C42803 /* MessageContent.swift */, + D16C804225BA402100C42803 /* CreateThreadRequest.swift */, + D16C804625BA406D00C42803 /* CreateThreadResult.swift */, + ); + path = Models; + sourceTree = ""; + }; + D1B7EAFA257F03A1004F384A /* Tests */ = { + isa = PBXGroup; + children = ( + D1CD93AB258D6C0300409613 /* Util */, + D1B7EAFC257F03A1004F384A /* Info.plist */, + 0ECA8CD1258181A5006760F7 /* ChatClientUnitTests.swift */, + 0ECA8D08258432DC006760F7 /* ChatThreadClientUnitTests.swift */, + D1CD93A1258D6BC700409613 /* ChatClientTests.swift */, + D1CD93A7258D6BDC00409613 /* ChatThreadClientTests.swift */, + ); + path = Tests; + sourceTree = ""; + }; + D1CD93AB258D6C0300409613 /* Util */ = { + isa = PBXGroup; + children = ( + D1CD93BC258D6E3500409613 /* Recordings */, + 0ECA8CD52581838E006760F7 /* Mocks */, + D1CD93AC258D6C2500409613 /* RecordingUtil.swift */, + D1CD93B2258D6C3D00409613 /* TestUtil.swift */, + ); + path = Util; + sourceTree = ""; + }; + D1CD93BC258D6E3500409613 /* Recordings */ = { + isa = PBXGroup; + children = ( + D13CE64E25BFB69100415467 /* listReadReceipts.json */, + D10C3BD925A66D4D00A181E3 /* listThreads.json */, + D10C3BD325A660AF00A181E3 /* listMessages.json */, + D10C3BCD25A63F7800A181E3 /* listParticipants.json */, + D1CD93BD258D6E6200409613 /* addParticipants.json */, + D1CD93C3258D6E7300409613 /* createThread.json */, + D1CD93C7258D6E8F00409613 /* deleteMessage.json */, + D1CD93CB258D6E9E00409613 /* deleteThread.json */, + D1CD93CF258D6EAB00409613 /* getThread.json */, + D1CD93D7258D6ECD00409613 /* removeParticipant.json */, + D1CD93DB258D6EDA00409613 /* sendMessage.json */, + D1CD93DF258D6EEA00409613 /* sendReadReceipt.json */, + D1CD93E3258D6EF700409613 /* sendTypingNotification.json */, + D1CD93E7258D6F0600409613 /* updateMessage.json */, + D1CD93EB258D6F1300409613 /* updateTopic.json */, + ); + path = Recordings; + sourceTree = ""; + }; OBJ_113 /* Products */ = { isa = PBXGroup; children = ( "AzureCommunicationChat::AzureCommunicationChat::Product" /* AzureCommunicationChat.framework */, + D1B7EAED257F02FC004F384A /* AzureCommunicationChatTests.xctest */, + D147E62825CE242C001CFB5D /* AzureCommunicationChatUnitTests.xctest */, ); name = Products; sourceTree = BUILT_PRODUCTS_DIR; @@ -280,142 +445,25 @@ OBJ_5 = { isa = PBXGroup; children = ( - 0A47451B2583FDF600CA86E5 /* Source */, - OBJ_51 /* Tests */, - OBJ_52 /* Dependencies */, + OBJ_7 /* Sources */, + D1B7EAFA257F03A1004F384A /* Tests */, OBJ_113 /* Products */, 0A74765A2522918800819FC9 /* Frameworks */, - OBJ_6 /* Package.swift */, - 0A4745032583F47600CA86E5 /* README.md */, + A4D0748296D3AEEA8C0DAB94 /* Pods */, ); sourceTree = ""; }; - OBJ_51 /* Tests */ = { + OBJ_7 /* Sources */ = { isa = PBXGroup; children = ( + D1565C70256DB74900AF45F8 /* ChatClient.swift */, + D1565C73256DB76C00AF45F8 /* ChatThreadClient.swift */, + D16C802B25BA0A0F00C42803 /* Models */, + D15E98C925B7C80C00E63DB2 /* Generated */, ); - name = Tests; - sourceTree = SOURCE_ROOT; - }; - OBJ_52 /* Dependencies */ = { - isa = PBXGroup; - children = ( - OBJ_53 /* AzureSDK */, - ); - name = Dependencies; - sourceTree = ""; - }; - OBJ_53 /* AzureSDK */ = { - isa = PBXGroup; - children = ( - OBJ_54 /* AzureCommunication */, - OBJ_55 /* AzureCore */, - OBJ_112 /* Package.swift */, - ); - name = AzureSDK; - sourceTree = SOURCE_ROOT; - }; - OBJ_54 /* AzureCommunication */ = { - isa = PBXGroup; - children = ( - ); - name = AzureCommunication; - path = ".build/checkouts/azure-sdk-for-ios/sdk/communication/AzureCommunication"; - sourceTree = SOURCE_ROOT; - }; - OBJ_55 /* AzureCore */ = { - isa = PBXGroup; - children = ( - OBJ_56 /* Source */, - ); - name = AzureCore; - path = ".build/checkouts/azure-sdk-for-ios/sdk/core/AzureCore"; - sourceTree = SOURCE_ROOT; - }; - OBJ_56 /* Source */ = { - isa = PBXGroup; - children = ( - OBJ_57 /* AzureTask.swift */, - OBJ_58 /* ClientLogger.swift */, - OBJ_59 /* DataStructures */, - OBJ_66 /* Errors.swift */, - OBJ_67 /* Pipeline */, - OBJ_95 /* Providers */, - OBJ_100 /* Util */, - ); + name = Sources; path = Source; - sourceTree = ""; - }; - OBJ_59 /* DataStructures */ = { - isa = PBXGroup; - children = ( - OBJ_60 /* CancellationToken.swift */, - OBJ_61 /* Collections.swift */, - OBJ_63 /* XMLMap.swift */, - OBJ_64 /* XMLModel.swift */, - OBJ_65 /* XMLTree.swift */, - ); - path = DataStructures; - sourceTree = ""; - }; - OBJ_67 /* Pipeline */ = { - isa = PBXGroup; - children = ( - OBJ_68 /* Pipeline.swift */, - OBJ_69 /* PipelineClient.swift */, - OBJ_70 /* PipelineContext.swift */, - OBJ_71 /* PipelineRequest.swift */, - OBJ_72 /* PipelineResponse.swift */, - OBJ_73 /* PipelineStage.swift */, - OBJ_74 /* Policies */, - OBJ_84 /* Transport */, - ); - path = Pipeline; - sourceTree = ""; - }; - OBJ_74 /* Policies */ = { - isa = PBXGroup; - children = ( - OBJ_75 /* AddDatePolicy.swift */, - OBJ_76 /* AuthenticationPolicy.swift */, - OBJ_77 /* ContentDecodePolicy.swift */, - OBJ_78 /* HeadersPolicy.swift */, - OBJ_79 /* HeadersValidationPolicy.swift */, - OBJ_80 /* LoggingPolicy.swift */, - OBJ_81 /* NormalizeETagPolicy.swift */, - OBJ_82 /* RequestIdPolicy.swift */, - OBJ_83 /* UserAgentPolicy.swift */, - ); - path = Policies; - sourceTree = ""; - }; - OBJ_84 /* Transport */ = { - isa = PBXGroup; - children = ( - OBJ_85 /* DataStringConvertible.swift */, - OBJ_86 /* HTTPHeader.swift */, - OBJ_87 /* HTTPMethod.swift */, - OBJ_88 /* HTTPRequest.swift */, - OBJ_89 /* HTTPResponse.swift */, - OBJ_90 /* HTTPTransportStage.swift */, - OBJ_91 /* TelemetryOptions.swift */, - OBJ_92 /* TransportOptions.swift */, - OBJ_93 /* URLHTTPResponse.swift */, - OBJ_94 /* URLSessionTransport.swift */, - ); - path = Transport; - sourceTree = ""; - }; - OBJ_95 /* Providers */ = { - isa = PBXGroup; - children = ( - OBJ_96 /* BundleInfoProvider.swift */, - OBJ_97 /* DeviceProviders.swift */, - OBJ_98 /* LocaleInfoProvider.swift */, - OBJ_99 /* PlatformInfoProvider.swift */, - ); - path = Providers; - sourceTree = ""; + sourceTree = SOURCE_ROOT; }; /* End PBXGroup section */ @@ -424,9 +472,10 @@ isa = PBXNativeTarget; buildConfigurationList = OBJ_117 /* Build configuration list for PBXNativeTarget "AzureCommunicationChat" */; buildPhases = ( + F533BDB375922B2AE143D56C /* [CP] Check Pods Manifest.lock */, OBJ_120 /* Sources */, OBJ_161 /* Frameworks */, - 0A4745B325840B3700CA86E5 /* Format and Lint */, + 0ADDCFDA258D2AA900BD5E58 /* Format and Lint */, ); buildRules = ( ); @@ -437,6 +486,50 @@ productReference = "AzureCommunicationChat::AzureCommunicationChat::Product" /* AzureCommunicationChat.framework */; productType = "com.apple.product-type.framework"; }; + D147E62725CE242C001CFB5D /* AzureCommunicationChatUnitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D147E63225CE242C001CFB5D /* Build configuration list for PBXNativeTarget "AzureCommunicationChatUnitTests" */; + buildPhases = ( + D147E62425CE242C001CFB5D /* Sources */, + D147E62525CE242C001CFB5D /* Frameworks */, + D147E62625CE242C001CFB5D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + D147E62F25CE242C001CFB5D /* PBXTargetDependency */, + ); + name = AzureCommunicationChatUnitTests; + packageProductDependencies = ( + D193C45A25CE258F006F769C /* OHHTTPStubsSwift */, + ); + productName = AzureCommunicationChatUnitTests; + productReference = D147E62825CE242C001CFB5D /* AzureCommunicationChatUnitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + D1B7EAEC257F02FC004F384A /* AzureCommunicationChatTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D1B7EAF2257F02FC004F384A /* Build configuration list for PBXNativeTarget "AzureCommunicationChatTests" */; + buildPhases = ( + 54BA66082A36E067F3B5A4A1 /* [CP] Check Pods Manifest.lock */, + D1B7EAE9257F02FC004F384A /* Sources */, + D1B7EAEA257F02FC004F384A /* Frameworks */, + D1B7EAEB257F02FC004F384A /* Resources */, + 445ADB16537FA45018DDA5D2 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + D1CD936D258D688D00409613 /* PBXTargetDependency */, + ); + name = AzureCommunicationChatTests; + packageProductDependencies = ( + D1BA104C25807B7500CA7130 /* OHHTTPStubsSwift */, + ); + productName = AzureCommunicationChatTests; + productReference = D1B7EAED257F02FC004F384A /* AzureCommunicationChatTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -444,27 +537,86 @@ isa = PBXProject; attributes = { LastSwiftMigration = 9999; + LastSwiftUpdateCheck = 1240; LastUpgradeCheck = 9999; + ORGANIZATIONNAME = "Azure SDK Team"; + TargetAttributes = { + D147E62725CE242C001CFB5D = { + CreatedOnToolsVersion = 12.4; + }; + D1B7EAEC257F02FC004F384A = { + CreatedOnToolsVersion = 12.2; + ProvisioningStyle = Automatic; + }; + }; }; buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "AzureCommunicationChat" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = OBJ_5; + packageReferences = ( + D1BA104B25807B7500CA7130 /* XCRemoteSwiftPackageReference "OHHTTPStubs" */, + ); productRefGroup = OBJ_113 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( "AzureCommunicationChat::AzureCommunicationChat" /* AzureCommunicationChat */, + D1B7EAEC257F02FC004F384A /* AzureCommunicationChatTests */, + D147E62725CE242C001CFB5D /* AzureCommunicationChatUnitTests */, ); }; /* End PBXProject section */ +/* Begin PBXResourcesBuildPhase section */ + D147E62625CE242C001CFB5D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D147E68A25CE2480001CFB5D /* UnauthorizedError.json in Resources */, + D147E66725CE2473001CFB5D /* ListMessagesResponse.json in Resources */, + D147E66025CE2470001CFB5D /* ListParticipantsResponse.json in Resources */, + D147E65925CE246E001CFB5D /* AddParticipantResponse.json in Resources */, + D147E65225CE246B001CFB5D /* ListReadReceiptResponse.json in Resources */, + D147E67525CE2478001CFB5D /* NoContent.json in Resources */, + D147E66E25CE2476001CFB5D /* GetMessageResponse.json in Resources */, + D147E69125CE2482001CFB5D /* GetThreadResponse.json in Resources */, + D147E68325CE247D001CFB5D /* ListThreadsResponse.json in Resources */, + D147E67C25CE247B001CFB5D /* SendMessageResponse.json in Resources */, + D147E69825CE2485001CFB5D /* CreateThreadResponse.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D1B7EAEB257F02FC004F384A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D1CD93CC258D6E9E00409613 /* deleteThread.json in Resources */, + D1CD93EC258D6F1300409613 /* updateTopic.json in Resources */, + D1CD93C4258D6E7300409613 /* createThread.json in Resources */, + D1CD93D8258D6ECD00409613 /* removeParticipant.json in Resources */, + D1CD93DC258D6EDA00409613 /* sendMessage.json in Resources */, + D13CE65125BFB6D700415467 /* listReadReceipts.json in Resources */, + D1CD93C8258D6E8F00409613 /* deleteMessage.json in Resources */, + D10C3BDA25A66D4D00A181E3 /* listThreads.json in Resources */, + D1CD93D0258D6EAB00409613 /* getThread.json in Resources */, + D10C3BCE25A63F7800A181E3 /* listParticipants.json in Resources */, + D1CD93E4258D6EF700409613 /* sendTypingNotification.json in Resources */, + D1CD93E0258D6EEA00409613 /* sendReadReceipt.json in Resources */, + D1CD93E8258D6F0600409613 /* updateMessage.json in Resources */, + D1CD93BE258D6E6200409613 /* addParticipants.json in Resources */, + D10C3BD425A660AF00A181E3 /* listMessages.json in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + /* Begin PBXShellScriptBuildPhase section */ - 0A4745B325840B3700CA86E5 /* Format and Lint */ = { + 0ADDCFDA258D2AA900BD5E58 /* Format and Lint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -482,132 +634,320 @@ shellPath = /bin/sh; shellScript = "BUILD_PATH=$(pwd)\nROOT_PATH=$(pwd | rev | cut -d'/' -f4- | rev) \n$ROOT_PATH/Scripts/swiftlint.sh $BUILD_PATH\n"; }; + 445ADB16537FA45018DDA5D2 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-AzureCommunicationChatTests/Pods-AzureCommunicationChatTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-AzureCommunicationChatTests/Pods-AzureCommunicationChatTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AzureCommunicationChatTests/Pods-AzureCommunicationChatTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 54BA66082A36E067F3B5A4A1 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-AzureCommunicationChatTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + F533BDB375922B2AE143D56C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-AzureCommunicationChat-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + D147E62425CE242C001CFB5D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D147E64025CE244F001CFB5D /* ChatThreadClientUnitTests.swift in Sources */, + D147E64725CE2459001CFB5D /* TestUtil.swift in Sources */, + D147E63925CE244A001CFB5D /* ChatClientUnitTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D1B7EAE9257F02FC004F384A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D1CD93A8258D6BDC00409613 /* ChatThreadClientTests.swift in Sources */, + D1CD93AD258D6C2500409613 /* RecordingUtil.swift in Sources */, + D1CD93A2258D6BC700409613 /* ChatClientTests.swift in Sources */, + D1CD93B3258D6C3D00409613 /* TestUtil.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; OBJ_120 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( - 0A4745592583FDF700CA86E5 /* AzureCommunicationChatService+SendChatReadReceiptOptions.swift in Sources */, - 0A47456C2583FDF700CA86E5 /* ErrorType.swift in Sources */, - 0A47455B2583FDF700CA86E5 /* AzureCommunicationChatService+RemoveChatThreadMemberOptions.swift in Sources */, - 0A4745512583FDF600CA86E5 /* AzureCommunicationChatService+GetChatThreadOptions.swift in Sources */, - 0A4745522583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatThreadOptions.swift in Sources */, - 0A47455C2583FDF700CA86E5 /* PatchUtil.swift in Sources */, - 0A47454D2583FDF600CA86E5 /* AzureCommunicationChatClientOptions.swift in Sources */, - 0A4745502583FDF600CA86E5 /* AzureCommunicationChatService+SendChatMessageOptions.swift in Sources */, - 0A4745652583FDF700CA86E5 /* Enumerations.swift in Sources */, - 0A4745602583FDF700CA86E5 /* ChatMessage.swift in Sources */, - 0A4745532583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatMessageOptions.swift in Sources */, - 0A4745702583FDF700CA86E5 /* ChatThreadMembersCollection.swift in Sources */, - 0A4745692583FDF700CA86E5 /* UpdateChatMessageRequest.swift in Sources */, - 0A4745562583FDF600CA86E5 /* AzureCommunicationChatService+AddChatThreadMembersOptions.swift in Sources */, - 0A4745732583FDF700CA86E5 /* Custom.swift in Sources */, - 0A4745642583FDF700CA86E5 /* ReadReceipt.swift in Sources */, - 0A4745572583FDF600CA86E5 /* AzureCommunicationChatService+GetChatMessageOptions.swift in Sources */, - 0A4745662583FDF700CA86E5 /* IndividualStatusResponse.swift in Sources */, - 0A47455F2583FDF700CA86E5 /* UpdateChatThreadRequest.swift in Sources */, - 0A4745542583FDF600CA86E5 /* AzureCommunicationChatService+ListChatMessagesOptions.swift in Sources */, - 0A4745552583FDF600CA86E5 /* AzureCommunicationChatService+ListChatReadReceiptsOptions.swift in Sources */, - 0A47456E2583FDF700CA86E5 /* SendChatMessageResult.swift in Sources */, - 0A4745672583FDF700CA86E5 /* ChatThreadsInfoCollection.swift in Sources */, - 0A4745722583FDF700CA86E5 /* AzureCommuncationChatClient+Convenience.swift in Sources */, - 0A47454A2583FDF600CA86E5 /* AzureCommunicationChatClient.swift in Sources */, - 0A47454F2583FDF600CA86E5 /* AzureCommunicationChatService+DeleteChatThreadOptions.swift in Sources */, - 0A47454B2583FDF600CA86E5 /* AzureCommunicationChatService+CreateChatThreadOptions.swift in Sources */, - 0A47456D2583FDF700CA86E5 /* ChatThreadInfo.swift in Sources */, - 0A4745622583FDF700CA86E5 /* CreateChatThreadRequest.swift in Sources */, - 0A4745582583FDF700CA86E5 /* AzureCommunicationChatService+ListChatThreadMembersOptions.swift in Sources */, - 0A4745712583FDF700CA86E5 /* AzureCommunicationChatService.swift in Sources */, - 0A47454E2583FDF600CA86E5 /* AzureCommunicationChatService+ListChatThreadsOptions.swift in Sources */, - 0A47456F2583FDF700CA86E5 /* ReadReceiptsCollection.swift in Sources */, - 0A47456B2583FDF700CA86E5 /* ChatThreadMember.swift in Sources */, - 0A4745612583FDF700CA86E5 /* ChatMessagesCollection.swift in Sources */, - 0A47455A2583FDF700CA86E5 /* AzureCommunicationChatService+SendTypingNotificationOptions.swift in Sources */, - 0A47454C2583FDF600CA86E5 /* AzureCommunicationChatService+UpdateChatMessageOptions.swift in Sources */, - 0A4745682583FDF700CA86E5 /* ChatThread.swift in Sources */, - 0A47455D2583FDF700CA86E5 /* SendChatMessageRequest.swift in Sources */, - 0A47456A2583FDF700CA86E5 /* SendReadReceiptRequest.swift in Sources */, - 0A47455E2583FDF700CA86E5 /* MultiStatusResponse.swift in Sources */, - 0A4745632583FDF700CA86E5 /* AddChatThreadMembersRequest.swift in Sources */, + D1565C71256DB74900AF45F8 /* ChatClient.swift in Sources */, + D1565C74256DB76C00AF45F8 /* ChatThreadClient.swift in Sources */, + D15E990525B7C80C00E63DB2 /* Chat+CreateChatThreadOptions.swift in Sources */, + D15E991925B7C80C00E63DB2 /* Enumerations.swift in Sources */, + D15E990F25B7C80C00E63DB2 /* CommunicationError.swift in Sources */, + D16C803325BA0AE400C42803 /* Thread.swift in Sources */, + D16C804725BA406D00C42803 /* CreateThreadResult.swift in Sources */, + D15E990425B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatThreadOptions.swift in Sources */, + D15E992225B7C80C00E63DB2 /* SendChatMessageResult.swift in Sources */, + D15E990A25B7C80C00E63DB2 /* Chat+GetChatThreadOptions.swift in Sources */, + D15E98FB25B7C80C00E63DB2 /* ChatThreadOperation+AddChatParticipantsOptions.swift in Sources */, + D15E990725B7C80C00E63DB2 /* ChatThreadOperation+DeleteChatMessageOptions.swift in Sources */, + D15E992325B7C80C00E63DB2 /* AddChatParticipantsRequest.swift in Sources */, + D15E990C25B7C80C00E63DB2 /* PatchUtil.swift in Sources */, + D15E991825B7C80C00E63DB2 /* CommunicationErrorResponse.swift in Sources */, + D15E991D25B7C80C00E63DB2 /* ChatThread.swift in Sources */, + D15E991225B7C80C00E63DB2 /* UpdateChatThreadRequest.swift in Sources */, + D15E991525B7C80C00E63DB2 /* CreateChatThreadErrors.swift in Sources */, + D15E990225B7C80C00E63DB2 /* ChatThreadOperation+SendChatReadReceiptOptions.swift in Sources */, + D15E991A25B7C80C00E63DB2 /* AddChatParticipantsResult.swift in Sources */, + D15E991E25B7C80C00E63DB2 /* UpdateChatMessageRequest.swift in Sources */, + D15E991625B7C80C00E63DB2 /* ChatMessageReadReceipt.swift in Sources */, + D15E991725B7C80C00E63DB2 /* CreateChatThreadRequest.swift in Sources */, + D15E990625B7C80C00E63DB2 /* ChatThreadOperation+SendTypingNotificationOptions.swift in Sources */, + D16C803F25BA0B5200C42803 /* MessageContent.swift in Sources */, + D15E98FF25B7C80C00E63DB2 /* Chat+DeleteChatThreadOptions.swift in Sources */, + D15E990025B7C80C00E63DB2 /* AzureCommunicationChatClientOptions.swift in Sources */, + D15E990325B7C80C00E63DB2 /* ChatThreadOperation+RemoveChatParticipantOptions.swift in Sources */, + D15E992425B7C80C00E63DB2 /* ChatParticipant.swift in Sources */, + D15E991025B7C80C00E63DB2 /* SendChatMessageRequest.swift in Sources */, + D15E990825B7C80C00E63DB2 /* ChatThreadOperation+ListChatMessagesOptions.swift in Sources */, + D16C804325BA402100C42803 /* CreateThreadRequest.swift in Sources */, + D15E98FE25B7C80C00E63DB2 /* Chat+ListChatThreadsOptions.swift in Sources */, + D15E991C25B7C80C00E63DB2 /* ChatThreadsInfoCollection.swift in Sources */, + D15E98FA25B7C80C00E63DB2 /* AzureCommunicationChatClient.swift in Sources */, + D15E98FC25B7C80C00E63DB2 /* ChatThreadOperation+ListChatReadReceiptsOptions.swift in Sources */, + D15E992125B7C80C00E63DB2 /* ChatThreadInfo.swift in Sources */, + D15E991425B7C80C00E63DB2 /* ChatMessagesCollection.swift in Sources */, + D15E990D25B7C80C00E63DB2 /* Chat.swift in Sources */, + D15E991325B7C80C00E63DB2 /* ChatMessage.swift in Sources */, + D15E990125B7C80C00E63DB2 /* ChatThreadOperation+SendChatMessageOptions.swift in Sources */, + D15E98FD25B7C80C00E63DB2 /* ChatThreadOperation+UpdateChatMessageOptions.swift in Sources */, + D15E991F25B7C80C00E63DB2 /* CreateChatThreadResult.swift in Sources */, + D15E990B25B7C80C00E63DB2 /* ChatThreadOperation+ListChatParticipantsOptions.swift in Sources */, + D15E992525B7C80C00E63DB2 /* ChatParticipantsCollection.swift in Sources */, + D15E992025B7C80C00E63DB2 /* SendReadReceiptRequest.swift in Sources */, + D15E991125B7C80C00E63DB2 /* ChatMessageContent.swift in Sources */, + D15E990E25B7C80C00E63DB2 /* AddChatParticipantsErrors.swift in Sources */, + D15E991B25B7C80C00E63DB2 /* ChatMessageReadReceiptsCollection.swift in Sources */, + D16C802D25BA0A2400C42803 /* Message.swift in Sources */, + D16C803725BA0AFE00C42803 /* Participant.swift in Sources */, + D15E990925B7C80C00E63DB2 /* ChatThreadOperation+GetChatMessageOptions.swift in Sources */, + D16C803B25BA0B0E00C42803 /* ReadReceipt.swift in Sources */, + D15E992625B7C80C00E63DB2 /* ChatThreadOperation.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + D147E62F25CE242C001CFB5D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = "AzureCommunicationChat::AzureCommunicationChat" /* AzureCommunicationChat */; + targetProxy = D147E62E25CE242C001CFB5D /* PBXContainerItemProxy */; + }; + D1CD936D258D688D00409613 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = "AzureCommunicationChat::AzureCommunicationChat" /* AzureCommunicationChat */; + targetProxy = D1CD936C258D688D00409613 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ - OBJ_118 /* Debug */ = { + D147E63025CE242C001CFB5D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CODE_SIGN_STYLE = Automatic; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.azure.communication.AzureCommunicationChatUnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + D147E63125CE242C001CFB5D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CODE_SIGN_STYLE = Automatic; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = Tests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.azure.communication.AzureCommunicationChatUnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + D1B7EAF3257F02FC004F384A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2CB55B558C70B4045A54487D /* Pods-AzureCommunicationChatTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = "$(inherited)"; + INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.azure.communication.AzureCommunicationChatTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + D1B7EAF4257F02FC004F384A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8E5206D2E09378DA0F9FD0E4 /* Pods-AzureCommunicationChatTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = "$(inherited)"; + INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.azure.communication.AzureCommunicationChatTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + OBJ_118 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9FE998BEC9685C476F2AFD1C /* Pods-AzureCommunicationChat.debug.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = NO; BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = AzureCommunicationChat.xcodeproj/AzureCommunicationChat_Info.plist; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = "1.0.0-beta.7"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + NEW_SETTING = ""; PRODUCT_BUNDLE_IDENTIFIER = com.azure.communication.AzureCommunicationChat; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; - TARGET_NAME = AzureCommunicationChat; - TVOS_DEPLOYMENT_TARGET = 12.0; - USE_HEADERMAP = YES; - WATCHOS_DEPLOYMENT_TARGET = 2.0; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; OBJ_119 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 04B336EEF1E42CCE389E4935 /* Pods-AzureCommunicationChat.release.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; + APPLICATION_EXTENSION_API_ONLY = NO; BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PLATFORM_DIR)/Developer/Library/Frameworks", - ); - HEADER_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = AzureCommunicationChat.xcodeproj/AzureCommunicationChat_Info.plist; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; - MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = "1.0.0-beta.7"; - OTHER_CFLAGS = "$(inherited)"; - OTHER_LDFLAGS = "$(inherited)"; - OTHER_SWIFT_FLAGS = "$(inherited)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + NEW_SETTING = ""; PRODUCT_BUNDLE_IDENTIFIER = com.azure.communication.AzureCommunicationChat; - PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)"; SWIFT_VERSION = 5.0; - TARGET_NAME = AzureCommunicationChat; - TVOS_DEPLOYMENT_TARGET = 12.0; - USE_HEADERMAP = YES; - WATCHOS_DEPLOYMENT_TARGET = 2.0; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; @@ -739,6 +1079,24 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + D147E63225CE242C001CFB5D /* Build configuration list for PBXNativeTarget "AzureCommunicationChatUnitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D147E63025CE242C001CFB5D /* Debug */, + D147E63125CE242C001CFB5D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D1B7EAF2257F02FC004F384A /* Build configuration list for PBXNativeTarget "AzureCommunicationChatTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D1B7EAF3257F02FC004F384A /* Debug */, + D1B7EAF4257F02FC004F384A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; OBJ_117 /* Build configuration list for PBXNativeTarget "AzureCommunicationChat" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -758,6 +1116,30 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + D1BA104B25807B7500CA7130 /* XCRemoteSwiftPackageReference "OHHTTPStubs" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/AliSoftware/OHHTTPStubs.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 9.1.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + D193C45A25CE258F006F769C /* OHHTTPStubsSwift */ = { + isa = XCSwiftPackageProductDependency; + package = D1BA104B25807B7500CA7130 /* XCRemoteSwiftPackageReference "OHHTTPStubs" */; + productName = OHHTTPStubsSwift; + }; + D1BA104C25807B7500CA7130 /* OHHTTPStubsSwift */ = { + isa = XCSwiftPackageProductDependency; + package = D1BA104B25807B7500CA7130 /* XCRemoteSwiftPackageReference "OHHTTPStubs" */; + productName = OHHTTPStubsSwift; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = OBJ_1 /* Project object */; } diff --git a/sdk/communication/AzureCommunicationChat/AzureCommunicationChat.xcodeproj/xcshareddata/xcschemes/AzureCommunicationChat.xcscheme b/sdk/communication/AzureCommunicationChat/AzureCommunicationChat.xcodeproj/xcshareddata/xcschemes/AzureCommunicationChat.xcscheme index 659e420f..97191499 100644 --- a/sdk/communication/AzureCommunicationChat/AzureCommunicationChat.xcodeproj/xcshareddata/xcschemes/AzureCommunicationChat.xcscheme +++ b/sdk/communication/AzureCommunicationChat/AzureCommunicationChat.xcodeproj/xcshareddata/xcschemes/AzureCommunicationChat.xcscheme @@ -28,6 +28,26 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + .communication.azure.com") else { - // Display error message -} - -let authPolicy = try CommunicationTokenCredentialPolicy( - credential: credential ?? CommunicationTokenCredential(token: "") -) -let options = AzureCommunicationChatClientOptions( - logger: ClientLoggers.default, - dispatchQueue: self.queue -) -let client = AzureCommunicationChatClient(baseUrl: baseUrl, authPolicy: authPolicy, withOptions: options) -``` - ## Key concepts ### User and User Access Tokens User access tokens enable you to build client applications that directly authenticate to Azure Communication Services. Refer [here](https://docs.microsoft.com/azure/communication-services/quickstarts/access-tokens) to learn how to create a user and issue a User Access Token. -The id for the user created above will be necessary later to add said user as a member of a new chat thread. The initiator of the create request must be in the list of members of the chat thread. +The id for the user created above will be necessary later to add said user as a participant of a new chat thread. The initiator of the create request must be in the list of participants of the chat thread. ### Chat Thread -A chat conversation is represented by a chat thread. Each user in the thread is called a thread member. Thread members can chat with one another privately in a 1:1 chat or huddle up in a 1:N group chat. +A chat conversation is represented by a chat thread. Each user in the thread is called a thread participant. Thread participants can chat with one another privately in a 1:1 chat or huddle up in a 1:N group chat. Using the APIs, users can also send typing indicators when typing a message and read receipts for the messages they have read in a chat thread. To learn more, read about chat concepts [here](https://docs.microsoft.com/azure/communication-services/concepts/chat/concepts). -### Chat Operations +### ChatClient -Once you initialize an `AzureCommunicationChatClient` class, you can perform the following chat operations: +`ChatClient` is used for performing chat thread operations, listed below. + +#### Initialization + +To instantiate ChatClient you will need the CommunicationServices resource endpoint, a CommunicationUserCredential created from a User Access Token, and optional options to create the client with. + +```swift +import AzureCommunication +import AzureCommunicationChat +import AzureCore + +let endpoint = "" + +let credential = try CommunicationTokenCredential(<"user_access_token>") + +let options = AzureCommunicationChatClientOptions( + logger: ClientLoggers.default, + dispatchQueue: self.queue +) + +let chatClient = ChatClient(endpoint: endpoint, credential: credential, withOptions: options) + +``` #### Thread Operations +ChatClient supports the following methods, see the links below for examples. + - [Create a thread](#create-a-thread) - [Get a thread](#get-a-thread) - [List threads](#list-threads) -- [Update a thread](#update-a-thread) - [Delete a thread](#delete-a-thread) +- [Get a thread client](#get-a-thread-client) + +### ChatThreadClient + +`ChatThreadClient` provides methods for operations within a chat thread, such as messaging and managing participants. + +#### Initialization + +ChatThreadClients should be created through the ChatClient. A ChatThreadClient is associated with a specific chat thread and is used to perform operations within the thread. See the list below for examples of each operation that ChatThreadClient supports. #### Message Operations @@ -150,11 +159,11 @@ Once you initialize an `AzureCommunicationChatClient` class, you can perform the - [Update a message](#update-a-message) - [Delete a message](#delete-a-message) -#### Thread Member Operations +#### Thread Participant Operations -- [Get thread members](#get-thread-members) -- [Add thread members](#add-thread-members) -- [Remove a thread member](#remove-a-thread-member) +- [Get thread participants](#get-thread-participants) +- [Add thread participants](#add-thread-participants) +- [Remove a thread participant](#remove-a-thread-participant) #### Events Operations @@ -162,43 +171,36 @@ Once you initialize an `AzureCommunicationChatClient` class, you can perform the - [Send read receipt](#send-read-receipt) - [Get read receipts](#get-read-receipts) +#### Thread Update Operations +- [Update the thread topic](#update-thread-topic) + ## Examples ### Thread Operations #### Create a thread -Use the `create` method to create a thread. +Use the `create` method of `ChatClient` to create a new thread. -- `CreateChatThreadRequest` is the model to pass to this method. -- `topic` is used to provide a topic for the thread. -- `members` is used to list the `ChatThreadMember` to be added to the thread. -- `id`, required, is the `CommunicationUser.identifier` you created before. Refer to [User and User Access Tokens](#user-and-user-access-tokens). -- `displayName`, optional, is the display name for the thread member. -- `shareHistoryTime`, optional, is the time from which the chat history is shared with the member. +- `CreateThreadRequest` is the model to pass to this method. It contains the participants to add to the thread as well as the topic of the thread. -`MultiStatusResponse` is the result returned from creating a thread. It has a 'multipleStatus' property which represents a list of `IndividualStatusResponse`. +- `CreateThreadResult` is the result returned from creating a thread. +- `thread` is the chat Thread that was created +- `errors` contains an array of errors for any invalid participants that failed to be added to the chat thread. ```swift -let thread = CreateChatThreadRequest( +let thread = CreateThreadRequest( topic: "General", - members: [ChatThreadMember( + participants: [Participant( id: , // Id of this needs to match with the Auth token - displayName: "initial member" + displayName: "initial participant" )] ) -client.create(chatThread: thread) { result, _ in +chatClient.create(thread: thread) { result, _ in switch result { - case let .success(createThreadResponse): - var threadId: String? = nil - for response in createThreadResponse.multipleStatus ?? [] { - if response.id?.hasSuffix("@thread.v2") ?? false, - response.type ?? "" == "Thread" { - threadId = response.id - } - } + case let .success(chatThreadResult): // Take further action case let .failure(error): @@ -209,14 +211,14 @@ client.create(chatThread: thread) { result, _ in #### Get a thread -Use the `getChatThread` method to retrieve a thread. +Use the `get` method of `ChatClient` to retrieve a thread. -- `chatThreadId` is the unique ID of the thread. +- `thread` is the unique ID of the thread. ```swift -client.getChatThread(chatThreadId: threadId) { result, _ in +chatClient.get(thread: threadId) { result, _ in switch result { - case let .success(thread): + case let .success(chatThread): // Take further action case let .failure(error): @@ -227,7 +229,7 @@ client.getChatThread(chatThreadId: threadId) { result, _ in #### List threads -Use the `listChatThreads` method to retrieve a list of threads. +Use the `listThreads` method to retrieve a list of threads. - `ListChatThreadsOptions` is the object representing the options to pass. - `maxPageSize`, optional, is the maximum number of messages to be returned per page. @@ -238,7 +240,7 @@ Use the `listChatThreads` method to retrieve a list of threads. ```swift import AzureCore let options = ListChatThreadsOptions(maxPageSize: 1) -client.listChatThreads(withOptions: options) { result, _ in +chatClient.listThreads(withOptions: options) { result, _ in switch result { case let .success(listThreadsResponse): var iterator = listThreadsResponse.syncIterator @@ -252,38 +254,15 @@ client.listChatThreads(withOptions: options) { result, _ in } ``` -#### Update a thread - -Use the `update` method to update a thread's properties. - -- `UpdateChatThreadRequest` is the model to pass to this method. -- `topic` is used to give a thread a new topic. -- `chatThreadId` is the unique ID of the thread. - -```swift - let thread = UpdateChatThreadRequest( - topic: "A new topic update with update()" -) - -client.update(chatThread: thread, chatThreadId: threadId) { result, _ in - switch result { - case .success: - // Take further action - - case let .failure(error): - // Display error message - } -} -``` #### Delete a thread -Use `deleteChatThread` method to delete a thread. +Use the `delete` method of `ChatClient` to delete a thread. -- `chatThreadId` is the unique ID of the thread. +- `thread` is the unique ID of the thread. ```swift -client.deleteChatThread(chatThreadId: threadId) { result, httpResponse in +chatClient.delete(thread: threadId) { result, httpResponse in switch result { case .success: // Take further action @@ -298,24 +277,22 @@ client.deleteChatThread(chatThreadId: threadId) { result, httpResponse in #### Send a message -Use the `send` method to send a message to a thread. +Use the `send` method of `ChatThreadClient` to send a message to a thread. - `SendChatMessageRequest` is the model to pass to this method. -- `priority` is used to specify the message priority level, such as 'normal' or 'high', if not specified, 'normal' will be set. - `content`, required, is used to provide the chat message content. - `senderDisplayName` is used to specify the display name of the sender, if not specified, an empty name will be set. -- `chatThreadId` is the unique ID of the thread. +- `type` is the type of message being sent, the supported types are text and html. `SendChatMessageResult` is the response returned from sending a message, it contains an id, which is the unique ID of the message. ```swift let message = SendChatMessageRequest( - priority: ChatMessagePriority.high, content: "Test message 1", senderDisplayName: "An Important person" ) -getClient().send(chatMessage: message, chatThreadId: threadId) { result, _ in +chatThreadClient.send(message: message) { result, _ in switch result { case let .success(createMessageResponse): // Take further action @@ -328,15 +305,14 @@ getClient().send(chatMessage: message, chatThreadId: threadId) { result, _ in #### Get a message -Use the `getChatMessage` method to retrieve a message in a thread. +Use the `get` method of `ChatThreadClient` to retrieve a message in a thread. -- `chatThreadId` is the unique ID of the thread. -- `chatMessageId` is the unique ID of the message. +- `message` is the unique ID of the message. -`ChatMessage` is the response returned from getting a message. +`Message` is the response returned from getting a message. ```swift -client.getChatMessage(chatThreadId: threadId, chatMessageId: messageId) { result, _ in +chatThreadClient.get(message: messageId) { result, _ in switch result { case let .success(message): // Take further action @@ -349,14 +325,13 @@ client.getChatMessage(chatThreadId: threadId, chatMessageId: messageId) { result #### List messages -Use the `listChatMessages` method to retrieve messages in a thread. +Use the `listMessages` method of `ChatThreadClient` to retrieve messages in a thread. -- `ListChatMessagesOptions` is the object representing the options to pass. +- `ListChatMessagesOptions` is the optional object representing the options to pass. - `maxPageSize`, optional, is the maximum number of messages to be returned per page. - `startTime`, optional, is the thread start time to consider in the query. -- `chatThreadId` is the unique ID of the thread. -`` is the response returned from listing messages +`` is the response returned from listing messages ```swift let dateFormatter = DateFormatter() @@ -369,7 +344,7 @@ if let date = dateFormatter.date(from: "2020-08-27T17:55:50Z") { ) } -client.listChatMessages(chatThreadId: threadId, withOptions: options) { result, _ in +client.listMessages(withOptions: options) { result, _ in switch result { case let .success(listMessagesResponse): var iterator = listMessagesResponse.syncIterator @@ -385,20 +360,20 @@ client.listChatMessages(chatThreadId: threadId, withOptions: options) { result, #### Update a message -Use the `update` method to update a message in a thread. +Use the `update` method of `ChatThreadClient` to update a message in a thread. - `UpdateChatMessageRequest` is the model to pass to this method. -- `priority` is the chat message priority `ChatMessagePriority`, such as 'Normal' or 'High', if not specified, 'Normal' will be set. - `content` is the message content to be updated. -- `chatThreadId` is the unique ID of the thread. - `chatMessageId` is the unique ID of the message. +-`messageId` is the unique id of the message. + ```swift let message = UpdateChatMessageRequest( content: "A message content with update()" ) -getClient().update(chatMessage: message, chatThreadId: threadId, chatMessageId: messageId) { result, _ in +chatThreadClient.update(message: message, messageId: messageId) { result, _ in switch result { case .success(_): // Take further action @@ -411,13 +386,12 @@ getClient().update(chatMessage: message, chatThreadId: threadId, chatMessageId: #### Delete a message -Use the `deleteChatMessage` method to delete a message in a thread. +Use the `delete` method of `ChatThreadClient` to delete a message in a thread. -- `chatThreadId` is the unique ID of the thread. -- `chatMessageId` is the unique ID of the message. +- `message` is the unique ID of the message. ```swift -getClient().deleteChatMessage(chatThreadId: threadId, chatMessageId: messageId) { result, _ in +chatThreadClient.delete(message: messageId) { result, _ in switch result { case .success: // Take further action @@ -428,22 +402,21 @@ getClient().deleteChatMessage(chatThreadId: threadId, chatMessageId: messageId) } ``` -### Thread Member Operations +### Thread Participant Operations -#### Get thread members +#### Get thread participants -Use the `listChatThreadMembers` method to retrieve the members participating in a thread. +Use the `listParticipants` of `ChatThreadClient` method to retrieve the participants of the thread. -- `chatThreadId` is the unique ID of the thread. -`PagedCollection` is the response returned from listing members. +`PagedCollection` is the response returned from listing participants. ```swift -client.listChatThreadMembers(chatThreadId: threadId) { result, _ in +chatThreadClient.listParticipants() { result, _ in switch result { - case let .success(threadmembers): - var iterator = threadmembers.syncIterator - while let threadMember = iterator.next() { + case let .success(threadParticipants): + var iterator = threadParticipants.syncIterator + while let threadParticipants = iterator.next() { // Take further action } @@ -453,27 +426,23 @@ client.listChatThreadMembers(chatThreadId: threadId) { result, _ in } ``` -#### Add thread members +#### Add thread participants -Use the `add` method to add members to a thread. +Use the `add` method to add participants to a thread. -- `AddChatThreadMembersRequest` is used to list the `ChatThreadMember`s to be added to the thread. -- `id`, required, is the `CommunicationUser.identifier` you created before. Refer to [User and User Access Tokens](#user-and-user-access-tokens). -- `displayName`, optional, is the display name for the thread member. -- `shareHistoryTime`, optional, is the time from which the chat history is shared with the member. -- `chatThreadId` is the unique ID of the thread. +- `participants` is an array of `Participant`'s to add +- `AddChatParticipantsResult` is the model returned, it contains an errors property that has an array of any invalid participants that failed to be added to the chat. ```swift -let threadMembers = AddChatThreadMembersRequest( - members: [ChatThreadMember( +let threadParticipants = [Participant( id: userId, - displayName: "a new member" + displayName: "a new participant" )] -) -client.add(chatThreadMembers: threadMembers, chatThreadId: threadId) { result, _ in + +chatThreadClient.add(participants: threadParticipants) { result, _ in switch result { - case .success: - // Take further action + case let .success(result): + // Check for invalid participants case let .failure(error): // Display error message @@ -481,15 +450,14 @@ client.add(chatThreadMembers: threadMembers, chatThreadId: threadId) { result, _ } ``` -#### Remove a thread member +#### Remove a thread participant -Use the `removeChatThreadMember` method to remove a member from a thread. +Use the `remove` method of `ChatThreadClient` to remove a participant from a thread. -- `chatThreadId` is the unique ID of the thread. -- `chatMemberId` is the user ID in the chat thread's member list. +- `participant` is id of the participant to remove. ```swift -client.removeChatThreadMember(chatThreadId: threadId, chatMemberId: memberId) { result, _ in +chatThreadClient.remove(participant: participantId) { result, _ in switch result { case .success: // Take further action @@ -504,10 +472,10 @@ client.removeChatThreadMember(chatThreadId: threadId, chatMemberId: memberId) { #### Send a typing notification -Use the `sendTypingNotification` method to post a typing notification event to a thread, on behalf of a user. +Use the `sendTypingNotification` method of `ChatThreadClient` to post a typing notification event to a thread, on behalf of a user. ```swift -client.sendTypingNotification(chatThreadId: threadId) { result, _ in +chatThreadClient.sendTypingNotification() { result, _ in switch result { case .success: // Take further action @@ -520,16 +488,13 @@ client.sendTypingNotification(chatThreadId: threadId) { result, _ in #### Send read receipt -Use the `send` method to post a read receipt event to a thread, on behalf of a user. +Use the `sendReadReceipt` method of `ChatThreadClient` to post a read receipt event to a thread, on behalf of a user. -- `SendReadReceiptRequest` is the model to be passed to this method. -- `chatMessageId` is the unique ID of the message. -- `chatThreadId` is the unique ID of the thread. +-`forMessage` refers to the unique ID of the message that the read receipt is for. ```swift -let readReceipt = SendReadReceiptRequest(chatMessageId: messageId) -client.send(chatReadReceipt: readReceipt, chatThreadId: threadId) { result, _ in +chatThreadClient.sendReadReceipt(forMessage: messageId) { result, _ in switch result { case .success: // Take further action @@ -542,14 +507,12 @@ client.send(chatReadReceipt: readReceipt, chatThreadId: threadId) { result, _ in #### Get read receipts -Use the `listChatReadReceipts` method to retrieve read receipts for a thread. - -- `chatThreadId` is the unique ID of the thread. +Use the `listReadReceipts` method of `ChatThreadClient` to retrieve read receipts for a thread. `PagedCollection` is the response returned from listing read receipts. ```swift -client.listChatReadReceipts(chatThreadId: threadId) { result, _ in +chatThreadClient.listReadReceipts() { result, _ in switch result { case let .success(readReceipts): var iterator = readReceipts.syncIterator @@ -563,12 +526,34 @@ client.listChatReadReceipts(chatThreadId: threadId) { result, _ in } ``` +### Thread Update Operations + +#### Update the thread's topic + +Use the `update` method of `ChatThreadClient` to update a thread's topic. + +- `topic` is the thread's new topic. + +```swift +let newTopic = "My new thread topic" + +chatThreadClient.update(topic: newTopic) { result, _ in + switch result { + case .success: + // Take further action + + case let .failure(error): + // Display error message + } +} +``` + ## Troubleshooting When an error occurs, the client calls the callback, passing in a `failure` result. You can use the provided error to act upon the failure. ```swift -client.create(chatThread: thread) { result, _ in +client.create(thread: thread) { result, _ in switch result { case let .failure(error): // Display error message @@ -594,4 +579,4 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. -![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-ios%2Fsdk%communication%2FAzureCommunicationChat%2FREADME.png) +![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-ios%2Fsdk%communication%2FAzureCommunicationChat%2FREADME.png) \ No newline at end of file diff --git a/sdk/communication/AzureCommunicationChat/Source/AzureCommuncationChatClient+Convenience.swift b/sdk/communication/AzureCommunicationChat/Source/AzureCommuncationChatClient+Convenience.swift deleted file mode 100644 index ba194798..00000000 --- a/sdk/communication/AzureCommunicationChat/Source/AzureCommuncationChatClient+Convenience.swift +++ /dev/null @@ -1,340 +0,0 @@ -// -------------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// The MIT License (MIT) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the ""Software""), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -// -// -------------------------------------------------------------------------- - -import AzureCore -import Foundation - -public extension AzureCommunicationChatClient { - /// Gets read receipts for a thread. - /// - Parameters: - /// - chatThreadId : Thread id to get the read receipts for. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func listChatReadReceipts( - chatThreadId: String, - withOptions options: AzureCommunicationChatService.ListChatReadReceiptsOptions? = nil, - completionHandler: @escaping HTTPResultHandler> - ) { - return azureCommunicationChatService.listChatReadReceipts( - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Sends a read receipt event to a thread, on behalf of a user. - /// - Parameters: - /// - chatReadReceipt : Read receipt details. - /// - chatThreadId : Thread id to send the read receipt event to. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func send( - chatReadReceipt: SendReadReceiptRequest, - chatThreadId: String, - withOptions options: AzureCommunicationChatService.SendChatReadReceiptOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.send( - chatReadReceipt: chatReadReceipt, - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Sends a message to a thread. - /// - Parameters: - /// - chatMessage : Details of the message to send. - /// - chatThreadId : The thread id to send the message to. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func send( - chatMessage: SendChatMessageRequest, - chatThreadId: String, - withOptions options: AzureCommunicationChatService.SendChatMessageOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.send( - chatMessage: chatMessage, - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Gets a list of messages from a thread. - /// - Parameters: - /// - chatThreadId : The thread id of the message. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func listChatMessages( - chatThreadId: String, - withOptions options: AzureCommunicationChatService.ListChatMessagesOptions? = nil, - completionHandler: @escaping HTTPResultHandler> - ) { - return azureCommunicationChatService.listChatMessages( - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Gets a message by id. - /// - Parameters: - /// - chatThreadId : The thread id to which the message was sent. - /// - chatMessageId : The message id. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func getChatMessage( - chatThreadId: String, - chatMessageId: String, - withOptions options: AzureCommunicationChatService.GetChatMessageOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.getChatMessage( - chatThreadId: chatThreadId, - chatMessageId: chatMessageId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Updates a message. - /// - Parameters: - /// - chatMessage : Details of the request to update the message. - /// - chatThreadId : The thread id to which the message was sent. - /// - chatMessageId : The message id. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func update( - chatMessage: UpdateChatMessageRequest, - chatThreadId: String, - chatMessageId: String, - withOptions options: AzureCommunicationChatService.UpdateChatMessageOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.update( - chatMessage: chatMessage, - chatThreadId: chatThreadId, - chatMessageId: chatMessageId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Deletes a message. - /// - Parameters: - /// - chatThreadId : The thread id to which the message was sent. - /// - chatMessageId : The message id. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func deleteChatMessage( - chatThreadId: String, - chatMessageId: String, - withOptions options: AzureCommunicationChatService.DeleteChatMessageOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.deleteChatMessage( - chatThreadId: chatThreadId, - chatMessageId: chatMessageId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Posts a typing event to a thread, on behalf of a user. - /// - Parameters: - /// - chatThreadId : Id of the thread. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func sendTypingNotification( - chatThreadId: String, - withOptions options: AzureCommunicationChatService.SendTypingNotificationOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.sendTypingNotification( - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Gets the members of a thread. - /// - Parameters: - /// - chatThreadId : Thread id to get members for. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func listChatThreadMembers( - chatThreadId: String, - withOptions options: AzureCommunicationChatService.ListChatThreadMembersOptions? = nil, - completionHandler: @escaping HTTPResultHandler> - ) { - return azureCommunicationChatService.listChatThreadMembers( - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Adds thread members to a thread. If members already exist, no change occurs. - /// - Parameters: - /// - chatThreadMembers : Thread members to be added to the thread. - /// - chatThreadId : Id of the thread to add members to. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func add( - chatThreadMembers: AddChatThreadMembersRequest, - chatThreadId: String, - withOptions options: AzureCommunicationChatService.AddChatThreadMembersOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.add( - chatThreadMembers: chatThreadMembers, - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Remove a member from a thread. - /// - Parameters: - /// - chatThreadId : Thread id to remove the member from. - /// - chatMemberId : Id of the thread member to remove from the thread. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func removeChatThreadMember( - chatThreadId: String, - chatMemberId: String, - withOptions options: AzureCommunicationChatService.RemoveChatThreadMemberOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.removeChatThreadMember( - chatThreadId: chatThreadId, - chatMemberId: chatMemberId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Creates a chat thread. - /// - Parameters: - /// - chatThread : Request payload for creating a chat thread. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func create( - chatThread: CreateChatThreadRequest, - withOptions options: AzureCommunicationChatService.CreateChatThreadOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.create( - chatThread: chatThread, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Gets the list of chat threads of a user. - /// - Parameters: - - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func listChatThreads( - withOptions options: AzureCommunicationChatService.ListChatThreadsOptions? = nil, - completionHandler: @escaping HTTPResultHandler> - ) { - return azureCommunicationChatService.listChatThreads(withOptions: options, completionHandler: completionHandler) - } - - /// Updates a thread's properties. - /// - Parameters: - /// - chatThread : Request payload for updating a chat thread. - /// - chatThreadId : The id of the thread to update. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func update( - chatThread: UpdateChatThreadRequest, - chatThreadId: String, - withOptions options: AzureCommunicationChatService.UpdateChatThreadOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.update( - chatThread: chatThread, - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Gets a chat thread. - /// - Parameters: - /// - chatThreadId : Thread id to get. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func getChatThread( - chatThreadId: String, - withOptions options: AzureCommunicationChatService.GetChatThreadOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.getChatThread( - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } - - /// Deletes a thread. - /// - Parameters: - /// - chatThreadId : Thread id to delete. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - func deleteChatThread( - chatThreadId: String, - withOptions options: AzureCommunicationChatService.DeleteChatThreadOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - return azureCommunicationChatService.deleteChatThread( - chatThreadId: chatThreadId, - withOptions: options, - completionHandler: completionHandler - ) - } -} diff --git a/sdk/communication/AzureCommunicationChat/Source/ChatClient.swift b/sdk/communication/AzureCommunicationChat/Source/ChatClient.swift new file mode 100644 index 00000000..d99bb378 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/ChatClient.swift @@ -0,0 +1,190 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCore +import Foundation + +public class ChatClient { + // MARK: Properties + + private let endpoint: String + private let credential: CommunicationTokenCredential + private let options: AzureCommunicationChatClientOptions + private let service: Chat + + // MARK: Initializers + + /// Create a ChatClient. + /// - Parameters: + /// - endpoint: The Communication Services endpoint. + /// - credential: The user credential. + /// - options: Options used to configure the client. + public init( + endpoint: String, + credential: CommunicationTokenCredential, + withOptions options: AzureCommunicationChatClientOptions + ) throws { + self.endpoint = endpoint + self.credential = credential + self.options = options + + guard let endpointUrl = URL(string: endpoint) else { + throw AzureError.client("Unable to form base URL.") + } + + let communicationCredential = CommunicationPolicyTokenCredential(credential) + let authPolicy = BearerTokenCredentialPolicy(credential: communicationCredential, scopes: []) + + let client = try AzureCommunicationChatClient( + endpoint: endpointUrl, + authPolicy: authPolicy, + withOptions: options + ) + + self.service = client.chat + } + + // MARK: Public Methods + + /// Create a ChatThreadClient for the ChatThread with id threadId. + /// - Parameters: + /// - threadId: The threadId. + public func createClient(forThread threadId: String) throws -> ChatThreadClient { + return try ChatThreadClient( + endpoint: endpoint, + credential: credential, + threadId: threadId, + withOptions: options + ) + } + + /// Create a new ChatThread. + /// - Parameters: + /// - thread: Request for creating a chat thread with the topic and members to add. + /// - options: Create chat thread options. + /// - completionHandler: A completion handler that receives a ChatThreadClient on success. + public func create( + thread: CreateThreadRequest, + withOptions options: Chat.CreateChatThreadOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + // Set the repeatabilityRequestID if it is not provided + let requestOptions = ((options?.repeatabilityRequestID) != nil) ? options : Chat.CreateChatThreadOptions( + repeatabilityRequestID: UUID().uuidString, + clientRequestId: options?.clientRequestId, + cancellationToken: options?.cancellationToken, + dispatchQueue: options?.dispatchQueue, + context: options?.context + ) + + // Convert Participants to ChatParticipants + let participants = thread.participants.map { + ChatParticipant( + id: $0.user.identifier, + displayName: $0.displayName, + shareHistoryTime: $0.shareHistoryTime + ) + } + + // Convert to CreateChatThreadRequest for generated code + let request = CreateChatThreadRequest( + topic: thread.topic, + participants: participants + ) + + service.create(chatThread: request, withOptions: requestOptions) { result, httpResponse in + switch result { + case let .success(chatThreadResult): + completionHandler(.success(CreateThreadResult(from: chatThreadResult)), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Get the Thread with given id. + /// - Parameters: + /// - threadId: The chat thread id. + /// - options: Get chat thread options. + /// - completionHandler: A completion handler that receives the chat thread on success. + public func get( + thread threadId: String, + withOptions options: Chat.GetChatThreadOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + service.getChatThread(chatThreadId: threadId, withOptions: options) { result, httpResponse in + switch result { + case let .success(chatThread): + completionHandler(.success(Thread(from: chatThread)), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Gets the list of ChatThreads for the user. + /// - Parameters: + /// - options: List chat threads options. + /// - completionHandler: A completion handler that receives the list of chat thread info on success. + public func listThreads( + withOptions options: Chat.ListChatThreadsOptions? = nil, + completionHandler: @escaping HTTPResultHandler> + ) { + service.listChatThreads(withOptions: options) { result, httpResponse in + switch result { + case let .success(chatThreads): + completionHandler(.success(chatThreads), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Delete the ChatThread with id chatThreadId. + /// - Parameters: + /// - threadId: The chat thread id. + /// - options: Delete chat thread options. + /// - completionHandler: A completion handler. + public func delete( + thread threadId: String, + withOptions options: Chat.DeleteChatThreadOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + service.deleteChatThread(chatThreadId: threadId, withOptions: options) { result, httpResponse in + switch result { + case .success: + completionHandler(.success(()), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/ChatThreadClient.swift b/sdk/communication/AzureCommunicationChat/Source/ChatThreadClient.swift new file mode 100644 index 00000000..262c2a7e --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/ChatThreadClient.swift @@ -0,0 +1,455 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCore +import Foundation + +public class ChatThreadClient { + // MARK: Properties + + public let threadId: String + private let endpoint: String + private let credential: CommunicationTokenCredential + private let options: AzureCommunicationChatClientOptions + private let service: ChatThreadOperation + + // MARK: Initializers + + /// Create a ChatThreadClient. + /// - Parameters: + /// - endpoint: The Communication Services endpoint. + /// - credential: The user credential. + /// - threadId: The chat thread id. + /// - options: Options used to configure the client. + public init( + endpoint: String, + credential: CommunicationTokenCredential, + threadId: String, + withOptions options: AzureCommunicationChatClientOptions + ) throws { + self.threadId = threadId + self.endpoint = endpoint + self.credential = credential + self.options = options + + guard let endpointUrl = URL(string: endpoint) else { + throw AzureError.client("Unable to form base URL") + } + + let communicationCredential = CommunicationPolicyTokenCredential(credential) + let authPolicy = BearerTokenCredentialPolicy(credential: communicationCredential, scopes: []) + + let client = try AzureCommunicationChatClient( + endpoint: endpointUrl, + authPolicy: authPolicy, + withOptions: options + ) + + self.service = client.chatThreadOperation + } + + // MARK: Private Methods + + /// Creates a PagedCollection from the given data and request. + /// - Parameters: + /// - data: The data to initialize the PagedCollection with. + /// - request: The HTTPRequest used to make the call. + /// - type: The type of the elements in the PagedCollection. + private func createPagedCollection( + from data: Data?, + withRequest request: HTTPRequest?, + of _: T.Type + ) throws -> PagedCollection { + guard let request = request else { + throw AzureError.client("HTTPResponse does not contain httpRequest.") + } + + guard let data = data else { + throw AzureError.client("HTTPResponse does not contain data.") + } + + let decoder = JSONDecoder() + + let codingKeys = PagedCodingKeys( + items: "value", + continuationToken: "nextLink" + ) + + let context = PipelineContext.of(keyValues: [ + ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject + ]) + + return try PagedCollection( + client: service.client, + request: request, + context: context, + data: data, + codingKeys: codingKeys, + decoder: decoder + ) + } + + // MARK: Public Methods + + /// Updates the ChatThread's topic. + /// - Parameters: + /// - topic: The topic. + /// - options: Update chat thread options. + /// - completionHandler: A completion handler that receives a status code on success. + public func update( + topic: String, + withOptions options: ChatThreadOperation.UpdateChatThreadOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + let updateChatThreadRequest = UpdateChatThreadRequest(topic: topic) + + service + .update( + chatThread: updateChatThreadRequest, + chatThreadId: threadId, + withOptions: options + ) { result, httpResponse in + switch result { + case .success: + completionHandler(.success(()), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Sends a read receipt. + /// - Parameters: + /// - messageId: The id of the message to send a read receipt for. + /// - options: Send read receipt options. + /// - completionHandler: A completion handler that receives a status code on success. + public func sendReadReceipt( + forMessage messageId: String, + withOptions options: ChatThreadOperation.SendChatReadReceiptOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + let sendReadReceiptRequest = SendReadReceiptRequest(chatMessageId: messageId) + + service + .send( + chatReadReceipt: sendReadReceiptRequest, + chatThreadId: threadId, + withOptions: options + ) { result, httpResponse in + switch result { + case .success: + completionHandler(.success(()), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Lists read receipts for the ChatThread. + /// - Parameters: + /// - options: List chat read receipts options. + /// - completionHandler: A completion handler that receives the list of read receipts on success. + public func listReadReceipts( + withOptions options: ChatThreadOperation.ListChatReadReceiptsOptions? = nil, + completionHandler: @escaping HTTPResultHandler> + ) { + service.listChatReadReceipts(chatThreadId: threadId, withOptions: options) { result, httpResponse in + switch result { + case .success: + // TODO: https://github.com/Azure/azure-sdk-for-ios/issues/644 + // Construct a new PagedCollection of type ReadReceipt + do { + let readReceipts = try self.createPagedCollection( + from: httpResponse?.data, + withRequest: httpResponse?.httpRequest, + of: ReadReceipt.self + ) + + completionHandler(.success(readReceipts), httpResponse) + } catch { + let azureError = AzureError.client(error.localizedDescription, error) + completionHandler(.failure(azureError), httpResponse) + } + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Sends a typing notification. + /// - Parameters: + /// - options: Send typing notification options + /// - completionHandler: A completion handler that receives a status code on success. + public func sendTypingNotification( + withOptions options: ChatThreadOperation.SendTypingNotificationOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + service.sendTypingNotification(chatThreadId: threadId, withOptions: options) { result, httpResponse in + switch result { + case .success: + completionHandler(.success(()), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Sends a message to a ChatThread. + /// - Parameters: + /// - message : Request that contains the message properties. + /// - options: A list of options for the operation. + /// - completionHandler: A completion handler that receives a status code on success. + public func send( + message: SendChatMessageRequest, + withOptions options: ChatThreadOperation.SendChatMessageOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + service.send(chatMessage: message, chatThreadId: threadId, withOptions: options) { result, httpResponse in + switch result { + case let .success(sendMessageResult): + completionHandler(.success(sendMessageResult), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Gets a message by id. + /// - Parameters: + /// - messageId : The id of the message to get. + /// - options: Get chat message options + /// - completionHandler: A completion handler that receives the chat message on success. + public func get( + message messageId: String, + withOptions options: ChatThreadOperation.GetChatMessageOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + service + .getChatMessage( + chatThreadId: threadId, + chatMessageId: messageId, + withOptions: options + ) { result, httpResponse in + switch result { + case let .success(chatMessage): + completionHandler(.success(Message(from: chatMessage)), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Updates a message. + /// - Parameters: + /// - message: Request that contains the message properties to update. + /// - messageId: The message id. + /// - options: Update chat message options + /// - completionHandler: A completion handler that receives a status code on success. + public func update( + message: UpdateChatMessageRequest, + messageId: String, + withOptions options: ChatThreadOperation.UpdateChatMessageOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + service + .update( + chatMessage: message, + chatThreadId: threadId, + chatMessageId: messageId, + withOptions: options + ) { result, httpResponse in + switch result { + case .success: + completionHandler(.success(()), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Deletes a message. + /// - Parameters: + /// - messageId : The message id. + /// - options: Delete chat message options + /// - completionHandler: A completion handler that receives a status code on success. + public func delete( + message messageId: String, + options: ChatThreadOperation.DeleteChatMessageOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + service + .deleteChatMessage( + chatThreadId: threadId, + chatMessageId: messageId, + withOptions: options + ) { result, httpResponse in + switch result { + case .success: + completionHandler(.success(()), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Gets a list of messages from a ChatThread. + /// - Parameters: + /// - options: List messages options. + /// - completionHandler: A completion handler that receives the list of messages on success. + public func listMessages( + withOptions options: ChatThreadOperation.ListChatMessagesOptions? = nil, + completionHandler: @escaping HTTPResultHandler> + ) { + service.listChatMessages(chatThreadId: threadId, withOptions: options) { result, httpResponse in + switch result { + case .success: + // TODO: github.com/Azure/azure-sdk-for-ios/issues/644 + // Construct a new PagedCollection of type Message + do { + let messages = try self.createPagedCollection( + from: httpResponse?.data, + withRequest: httpResponse?.httpRequest, + of: Message.self + ) + + completionHandler(.success(messages), httpResponse) + } catch { + let azureError = AzureError.client(error.localizedDescription, error) + completionHandler(.failure(azureError), httpResponse) + } + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Adds thread participants to a Thread. If the participants already exist, no change occurs. + /// - Parameters: + /// - participants : An array of participants to add. + /// - options: Add chat participants options. + /// - completionHandler: A completion handler that receives a status code on success. + public func add( + participants: [Participant], + withOptions options: ChatThreadOperation.AddChatParticipantsOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + // Convert Participants to ChatParticipants + let chatParticipants = participants.map { + ChatParticipant( + id: $0.user.identifier, + displayName: $0.displayName, + shareHistoryTime: $0.shareHistoryTime + ) + } + // Convert to AddChatParticipantsRequest for generated code + let addParticipantsRequest = AddChatParticipantsRequest( + participants: chatParticipants + ) + + service + .add( + chatParticipants: addParticipantsRequest, + chatThreadId: threadId, + withOptions: options + ) { result, httpResponse in + switch result { + case let .success(addParticipantsResult): + completionHandler(.success(addParticipantsResult), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Removes a participant from the thread. + /// - Parameters: + /// - participantId : Id of the participant to remove. + /// - options: Remove participant options + /// - completionHandler: A completion handler that receives a status code on success. + public func remove( + participant participantId: String, + withOptions options: ChatThreadOperation.RemoveChatParticipantOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + service + .removeChatParticipant( + chatThreadId: threadId, + chatParticipantId: participantId, + withOptions: options + ) { result, httpResponse in + switch result { + case .success: + completionHandler(.success(()), httpResponse) + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } + + /// Gets the participants of the thread. + /// - Parameters: + /// - options: List chat participants options. + /// - completionHandler: A completion handler that receives the list of members on success. + public func listParticipants( + withOptions options: ChatThreadOperation.ListChatParticipantsOptions? = nil, + completionHandler: @escaping HTTPResultHandler> + ) { + service.listChatParticipants(chatThreadId: threadId, withOptions: options) { result, httpResponse in + switch result { + case .success: + // TODO: https://github.com/Azure/azure-sdk-for-ios/issues/644 + // Construct a new PagedCollection of type Participant + do { + let participants = try self.createPagedCollection( + from: httpResponse?.data, + withRequest: httpResponse?.httpRequest, + of: Participant.self + ) + + completionHandler(.success(participants), httpResponse) + } catch { + let azureError = AzureError.client(error.localizedDescription, error) + completionHandler(.failure(azureError), httpResponse) + } + + case let .failure(error): + completionHandler(.failure(error), httpResponse) + } + } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/AzureCommunicationChatClient.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/AzureCommunicationChatClient.swift index 63485096..8f1a9837 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/AzureCommunicationChatClient.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/AzureCommunicationChatClient.swift @@ -25,27 +25,27 @@ public final class AzureCommunicationChatClient: PipelineClient, PageableClient public enum ApiVersion: RequestStringConvertible { /// Custom value for unrecognized enum values case custom(String) - /// API version "2020-09-21-preview2" - case v20200921preview2 + /// API version "2020-11-01-preview3" + case v20201101preview3 /// The most recent API version of the public static var latest: ApiVersion { - return .v20200921preview2 + return .v20201101preview3 } public var requestString: String { switch self { case let .custom(val): return val - case .v20200921preview2: - return "2020-09-21-preview2" + case .v20201101preview3: + return "2020-11-01-preview3" } } public init(_ val: String) { switch val.lowercased() { - case "2020-09-21-preview2": - self = .v20200921preview2 + case "2020-11-01-preview3": + self = .v20201101preview3 default: self = .custom(val) } @@ -85,7 +85,8 @@ public final class AzureCommunicationChatClient: PipelineClient, PageableClient ) } - public lazy var azureCommunicationChatService = AzureCommunicationChatService(client: self) + public lazy var chat = Chat(client: self) + public lazy var chatThreadOperation = ChatThreadOperation(client: self) // MARK: Public Client Methods } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Chat.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Chat.swift new file mode 100644 index 00000000..35d448c2 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Chat.swift @@ -0,0 +1,563 @@ +// -------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation +// swiftlint:disable superfluous_disable_command +// swiftlint:disable file_length +// swiftlint:disable cyclomatic_complexity +// swiftlint:disable function_body_length +// swiftlint:disable type_body_length + +public final class Chat { + public let client: AzureCommunicationChatClient + + init(client: AzureCommunicationChatClient) { + self.client = client + } + + /// Creates a chat thread. + /// - Parameters: + /// - chatThread : Request payload for creating a chat thread. + /// - options: A list of options for the operation + /// - completionHandler: A completion handler that receives a status code on + /// success. + public func create( + chatThread: CreateChatThreadRequest, + withOptions options: CreateChatThreadOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main + + // Create request parameters + let params = RequestParameters( + (.header, "repeatability-Request-ID", options?.repeatabilityRequestID, .encode), ( + .uri, + "endpoint", + client.endpoint.absoluteString, + .skipEncoding + ), (.query, "api-version", client.options.apiVersion, .encode), + (.header, "Content-Type", "application/json", .encode), + (.header, "Accept", "application/json", .encode) + ) + + // Construct request + guard let requestBody = try? JSONEncoder().encode(chatThread) else { + client.options.logger.error("Failed to encode request body as json.") + return + } + let urlTemplate = "/chat/threads" + guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), + let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) + else { + client.options.logger.error("Failed to construct HTTP request.") + return + } + + // Send request + let context = PipelineContext.of(keyValues: [ + ContextKey.allowedStatusCodes.rawValue: [201, 401, 403, 429, 503] as AnyObject + ]) + context.add(cancellationToken: options?.cancellationToken, applying: client.options) + context.merge(with: options?.context) + client.request(request, context: context) { result, httpResponse in + guard let data = httpResponse?.data else { + let noDataError = AzureError.client("Response data expected but not found.") + dispatchQueue.async { + completionHandler(.failure(noDataError), httpResponse) + } + return + } + switch result { + case .success: + guard let statusCode = httpResponse?.statusCode else { + let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") + dispatchQueue.async { + completionHandler(.failure(noStatusCodeError), httpResponse) + } + return + } + if [ + 201 + ].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CreateChatThreadResult.self, from: data) + dispatchQueue.async { + completionHandler(.success(decoded), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [401].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [403].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [429].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [503].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler( + .failure(AzureError.service("Service unavailable.", decoded)), + httpResponse + ) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + case let .failure(error): + dispatchQueue.async { + completionHandler(.failure(error), httpResponse) + } + } + } + } + + /// Gets the list of chat threads of a user. + /// - Parameters: + + /// - options: A list of options for the operation + /// - completionHandler: A completion handler that receives a status code on + /// success. + public func listChatThreads( + withOptions options: ListChatThreadsOptions? = nil, + completionHandler: @escaping HTTPResultHandler> + ) { + let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main + + // Create request parameters + let params = RequestParameters( + (.query, "maxPageSize", options?.maxPageSize, .encode), (.query, "startTime", options?.startTime, .encode), + (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), + (.query, "api-version", client.options.apiVersion, .encode), + (.header, "Accept", "application/json", .encode) + ) + + // Construct request + let urlTemplate = "/chat/threads" + guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), + let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) + else { + client.options.logger.error("Failed to construct HTTP request.") + return + } + + // Send request + let context = PipelineContext.of(keyValues: [ + ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject + ]) + context.add(cancellationToken: options?.cancellationToken, applying: client.options) + context.merge(with: options?.context) + client.request(request, context: context) { result, httpResponse in + guard let data = httpResponse?.data else { + let noDataError = AzureError.client("Response data expected but not found.") + dispatchQueue.async { + completionHandler(.failure(noDataError), httpResponse) + } + return + } + switch result { + case .success: + guard let statusCode = httpResponse?.statusCode else { + let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") + dispatchQueue.async { + completionHandler(.failure(noStatusCodeError), httpResponse) + } + return + } + if [ + 200 + ].contains(statusCode) { + do { + let decoder = JSONDecoder() + let codingKeys = PagedCodingKeys( + items: "value", + continuationToken: "nextLink" + ) + let paged = try PagedCollection( + client: self.client, + request: request, + context: context, + data: data, + codingKeys: codingKeys, + decoder: decoder + ) + dispatchQueue.async { + completionHandler(.success(paged), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + + if [401].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [403].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [429].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [503].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler( + .failure(AzureError.service("Service unavailable.", decoded)), + httpResponse + ) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + case let .failure(error): + dispatchQueue.async { + completionHandler(.failure(error), httpResponse) + } + } + } + } + + /// Gets a chat thread. + /// - Parameters: + /// - chatThreadId : Id of the thread. + /// - options: A list of options for the operation + /// - completionHandler: A completion handler that receives a status code on + /// success. + public func getChatThread( + chatThreadId: String, + withOptions options: GetChatThreadOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main + + // Create request parameters + let params = RequestParameters( + (.path, "chatThreadId", chatThreadId, .encode), + (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), + (.query, "api-version", client.options.apiVersion, .encode), + (.header, "Accept", "application/json", .encode) + ) + + // Construct request + let urlTemplate = "/chat/threads/{chatThreadId}" + guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), + let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) + else { + client.options.logger.error("Failed to construct HTTP request.") + return + } + + // Send request + let context = PipelineContext.of(keyValues: [ + ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject + ]) + context.add(cancellationToken: options?.cancellationToken, applying: client.options) + context.merge(with: options?.context) + client.request(request, context: context) { result, httpResponse in + guard let data = httpResponse?.data else { + let noDataError = AzureError.client("Response data expected but not found.") + dispatchQueue.async { + completionHandler(.failure(noDataError), httpResponse) + } + return + } + switch result { + case .success: + guard let statusCode = httpResponse?.statusCode else { + let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") + dispatchQueue.async { + completionHandler(.failure(noStatusCodeError), httpResponse) + } + return + } + if [ + 200 + ].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(ChatThread.self, from: data) + dispatchQueue.async { + completionHandler(.success(decoded), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [401].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [403].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [429].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [503].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler( + .failure(AzureError.service("Service unavailable.", decoded)), + httpResponse + ) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + case let .failure(error): + dispatchQueue.async { + completionHandler(.failure(error), httpResponse) + } + } + } + } + + /// Deletes a thread. + /// - Parameters: + /// - chatThreadId : Id of the thread to be deleted. + /// - options: A list of options for the operation + /// - completionHandler: A completion handler that receives a status code on + /// success. + public func deleteChatThread( + chatThreadId: String, + withOptions options: DeleteChatThreadOptions? = nil, + completionHandler: @escaping HTTPResultHandler + ) { + let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main + + // Create request parameters + let params = RequestParameters( + (.path, "chatThreadId", chatThreadId, .encode), + (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), + (.query, "api-version", client.options.apiVersion, .encode), + (.header, "Accept", "application/json", .encode) + ) + + // Construct request + let urlTemplate = "/chat/threads/{chatThreadId}" + guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), + let request = try? HTTPRequest(method: .delete, url: requestUrl, headers: params.headers) + else { + client.options.logger.error("Failed to construct HTTP request.") + return + } + + // Send request + let context = PipelineContext.of(keyValues: [ + ContextKey.allowedStatusCodes.rawValue: [204, 401, 403, 429, 503] as AnyObject + ]) + context.add(cancellationToken: options?.cancellationToken, applying: client.options) + context.merge(with: options?.context) + client.request(request, context: context) { result, httpResponse in + guard let data = httpResponse?.data else { + let noDataError = AzureError.client("Response data expected but not found.") + dispatchQueue.async { + completionHandler(.failure(noDataError), httpResponse) + } + return + } + switch result { + case .success: + guard let statusCode = httpResponse?.statusCode else { + let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") + dispatchQueue.async { + completionHandler(.failure(noStatusCodeError), httpResponse) + } + return + } + if [ + 204 + ].contains(statusCode) { + dispatchQueue.async { + completionHandler( + .success(()), + httpResponse + ) + } + } + if [401].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [403].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [429].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + if [503].contains(statusCode) { + do { + let decoder = JSONDecoder() + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) + dispatchQueue.async { + completionHandler( + .failure(AzureError.service("Service unavailable.", decoded)), + httpResponse + ) + } + } catch { + dispatchQueue.async { + completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) + } + } + } + case let .failure(error): + dispatchQueue.async { + completionHandler(.failure(error), httpResponse) + } + } + } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/AzureCommunicationChatService.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/ChatThreadOperation.swift similarity index 66% rename from sdk/communication/AzureCommunicationChat/Source/Generated/AzureCommunicationChatService.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/ChatThreadOperation.swift index 930b8a7f..9a5ad436 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/AzureCommunicationChatService.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/ChatThreadOperation.swift @@ -16,38 +16,40 @@ import Foundation // swiftlint:disable function_body_length // swiftlint:disable type_body_length -public final class AzureCommunicationChatService { +public final class ChatThreadOperation { public let client: AzureCommunicationChatClient init(client: AzureCommunicationChatClient) { self.client = client } - /// Gets read receipts for a thread. + /// Gets chat message read receipts for a thread. /// - Parameters: - /// - chatThreadId : Thread id to get the read receipts for. + /// - chatThreadId : Thread id to get the chat message read receipts for. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. public func listChatReadReceipts( chatThreadId: String, withOptions options: ListChatReadReceiptsOptions? = nil, - completionHandler: @escaping HTTPResultHandler> + completionHandler: @escaping HTTPResultHandler> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( - (.path, "chatThreadId", chatThreadId, .encode), + (.path, "chatThreadId", chatThreadId, .encode), (.query, "maxPageSize", options?.maxPageSize, .encode), + (.query, "skip", options?.skip, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Accept", "application/json", .encode) ) // Construct request - let urlTemplate = "/chat/threads/{chatThreadId}/readreceipts" + let urlTemplate = "/chat/threads/{chatThreadId}/readReceipts" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { + let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) + else { client.options.logger.error("Failed to construct HTTP request.") return } @@ -84,7 +86,7 @@ public final class AzureCommunicationChatService { items: "value", continuationToken: "nextLink" ) - let paged = try PagedCollection( + let paged = try PagedCollection( client: self.client, request: request, context: context, @@ -105,9 +107,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -118,9 +120,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -131,9 +133,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -144,10 +146,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -194,9 +196,9 @@ public final class AzureCommunicationChatService { client.options.logger.error("Failed to encode request body as json.") return } - let urlTemplate = "/chat/threads/{chatThreadId}/readreceipts" + let urlTemplate = "/chat/threads/{chatThreadId}/readReceipts" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) + let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) else { client.options.logger.error("Failed to construct HTTP request.") return @@ -204,7 +206,7 @@ public final class AzureCommunicationChatService { // Send request let context = PipelineContext.of(keyValues: [ - ContextKey.allowedStatusCodes.rawValue: [201, 401, 403, 429, 503] as AnyObject + ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) @@ -226,7 +228,7 @@ public final class AzureCommunicationChatService { return } if [ - 201 + 200 ].contains(statusCode) { dispatchQueue.async { completionHandler( @@ -238,9 +240,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -251,9 +253,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -264,9 +266,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -277,10 +279,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -329,7 +331,7 @@ public final class AzureCommunicationChatService { } let urlTemplate = "/chat/threads/{chatThreadId}/messages" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) + let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) else { client.options.logger.error("Failed to construct HTTP request.") return @@ -376,9 +378,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -389,9 +391,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -402,9 +404,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -415,10 +417,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -461,7 +463,8 @@ public final class AzureCommunicationChatService { // Construct request let urlTemplate = "/chat/threads/{chatThreadId}/messages" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { + let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) + else { client.options.logger.error("Failed to construct HTTP request.") return } @@ -519,9 +522,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -532,9 +535,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -545,9 +548,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -558,10 +561,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -605,7 +608,8 @@ public final class AzureCommunicationChatService { // Construct request let urlTemplate = "/chat/threads/{chatThreadId}/messages/{chatMessageId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { + let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) + else { client.options.logger.error("Failed to construct HTTP request.") return } @@ -651,9 +655,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -664,9 +668,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -677,9 +681,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -690,10 +694,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -733,7 +737,7 @@ public final class AzureCommunicationChatService { (.path, "chatThreadId", chatThreadId, .encode), (.path, "chatMessageId", chatMessageId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), - (.header, "Content-Type", "application/json", .encode), + (.header, "Content-Type", "application/merge-patch+json", .encode), (.header, "Accept", "application/json", .encode) ) @@ -744,7 +748,12 @@ public final class AzureCommunicationChatService { } let urlTemplate = "/chat/threads/{chatThreadId}/messages/{chatMessageId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .patch, url: requestUrl, headers: params.headers, data: requestBody) + let request = try? HTTPRequest( + method: .patch, + url: requestUrl, + headers: params.headers, + data: requestBody + ) else { client.options.logger.error("Failed to construct HTTP request.") return @@ -752,7 +761,7 @@ public final class AzureCommunicationChatService { // Send request let context = PipelineContext.of(keyValues: [ - ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject + ContextKey.allowedStatusCodes.rawValue: [204, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) @@ -774,7 +783,7 @@ public final class AzureCommunicationChatService { return } if [ - 200 + 204 ].contains(statusCode) { dispatchQueue.async { completionHandler( @@ -786,9 +795,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -799,9 +808,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -812,9 +821,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -825,10 +834,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -872,7 +881,8 @@ public final class AzureCommunicationChatService { // Construct request let urlTemplate = "/chat/threads/{chatThreadId}/messages/{chatMessageId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .delete, url: requestUrl, headers: params.headers) else { + let request = try? HTTPRequest(method: .delete, url: requestUrl, headers: params.headers) + else { client.options.logger.error("Failed to construct HTTP request.") return } @@ -913,9 +923,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -926,9 +936,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -939,9 +949,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -952,10 +962,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -997,7 +1007,8 @@ public final class AzureCommunicationChatService { // Construct request let urlTemplate = "/chat/threads/{chatThreadId}/typing" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers) else { + let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers) + else { client.options.logger.error("Failed to construct HTTP request.") return } @@ -1038,9 +1049,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1051,9 +1062,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1064,9 +1075,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1077,10 +1088,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -1098,31 +1109,33 @@ public final class AzureCommunicationChatService { } } - /// Gets the members of a thread. + /// Gets the participants of a thread. /// - Parameters: - /// - chatThreadId : Thread id to get members for. + /// - chatThreadId : Thread id to get participants for. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. - public func listChatThreadMembers( + public func listChatParticipants( chatThreadId: String, - withOptions options: ListChatThreadMembersOptions? = nil, - completionHandler: @escaping HTTPResultHandler> + withOptions options: ListChatParticipantsOptions? = nil, + completionHandler: @escaping HTTPResultHandler> ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( - (.path, "chatThreadId", chatThreadId, .encode), + (.path, "chatThreadId", chatThreadId, .encode), (.query, "maxPageSize", options?.maxPageSize, .encode), + (.query, "skip", options?.skip, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Accept", "application/json", .encode) ) // Construct request - let urlTemplate = "/chat/threads/{chatThreadId}/members" + let urlTemplate = "/chat/threads/{chatThreadId}/participants" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { + let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) + else { client.options.logger.error("Failed to construct HTTP request.") return } @@ -1159,7 +1172,7 @@ public final class AzureCommunicationChatService { items: "value", continuationToken: "nextLink" ) - let paged = try PagedCollection( + let paged = try PagedCollection( client: self.client, request: request, context: context, @@ -1180,9 +1193,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1193,9 +1206,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1206,9 +1219,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1219,10 +1232,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -1240,170 +1253,38 @@ public final class AzureCommunicationChatService { } } - /// Adds thread members to a thread. If members already exist, no change occurs. + /// Remove a participant from a thread. /// - Parameters: - /// - chatThreadMembers : Thread members to be added to the thread. - /// - chatThreadId : Id of the thread to add members to. + /// - chatThreadId : Thread id to remove the participant from. + /// - chatParticipantId : Id of the thread participant to remove from the thread. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. - public func add( - chatThreadMembers: AddChatThreadMembersRequest, + public func removeChatParticipant( chatThreadId: String, - withOptions options: AddChatThreadMembersOptions? = nil, + chatParticipantId: String, + withOptions options: RemoveChatParticipantOptions? = nil, completionHandler: @escaping HTTPResultHandler ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( - (.path, "chatThreadId", chatThreadId, .encode), + (.path, "chatThreadId", chatThreadId, .encode), (.path, "chatParticipantId", chatParticipantId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), - (.header, "Content-Type", "application/json", .encode), (.header, "Accept", "application/json", .encode) ) // Construct request - guard let requestBody = try? JSONEncoder().encode(chatThreadMembers) else { - client.options.logger.error("Failed to encode request body as json.") - return - } - let urlTemplate = "/chat/threads/{chatThreadId}/members" + let urlTemplate = "/chat/threads/{chatThreadId}/participants/{chatParticipantId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) + let request = try? HTTPRequest(method: .delete, url: requestUrl, headers: params.headers) else { client.options.logger.error("Failed to construct HTTP request.") return } - // Send request - let context = PipelineContext.of(keyValues: [ - ContextKey.allowedStatusCodes.rawValue: [207, 401, 403, 429, 503] as AnyObject - ]) - context.add(cancellationToken: options?.cancellationToken, applying: client.options) - context.merge(with: options?.context) - client.request(request, context: context) { result, httpResponse in - guard let data = httpResponse?.data else { - let noDataError = AzureError.client("Response data expected but not found.") - dispatchQueue.async { - completionHandler(.failure(noDataError), httpResponse) - } - return - } - switch result { - case .success: - guard let statusCode = httpResponse?.statusCode else { - let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") - dispatchQueue.async { - completionHandler(.failure(noStatusCodeError), httpResponse) - } - return - } - if [ - 207 - ].contains(statusCode) { - dispatchQueue.async { - completionHandler( - .success(()), - httpResponse - ) - } - } - if [401].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [403].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [429].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [503].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), - httpResponse - ) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - case let .failure(error): - dispatchQueue.async { - completionHandler(.failure(error), httpResponse) - } - } - } - } - - /// Remove a member from a thread. - /// - Parameters: - /// - chatThreadId : Thread id to remove the member from. - /// - chatMemberId : Id of the thread member to remove from the thread. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - public func removeChatThreadMember( - chatThreadId: String, - chatMemberId: String, - withOptions options: RemoveChatThreadMemberOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main - - // Create request parameters - let params = RequestParameters( - (.path, "chatThreadId", chatThreadId, .encode), (.path, "chatMemberId", chatMemberId, .encode), - (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), - (.query, "api-version", client.options.apiVersion, .encode), - (.header, "Accept", "application/json", .encode) - ) - - // Construct request - let urlTemplate = "/chat/threads/{chatThreadId}/members/{chatMemberId}" - guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .delete, url: requestUrl, headers: params.headers) else { - client.options.logger.error("Failed to construct HTTP request.") - return - } - // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [204, 401, 403, 429, 503] as AnyObject @@ -1440,9 +1321,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1453,9 +1334,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1466,9 +1347,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1479,10 +1360,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -1500,21 +1381,24 @@ public final class AzureCommunicationChatService { } } - /// Creates a chat thread. + /// Adds thread participants to a thread. If participants already exist, no change occurs. /// - Parameters: - /// - chatThread : Request payload for creating a chat thread. + /// - chatParticipants : Thread participants to be added to the thread. + /// - chatThreadId : Id of the thread to add participants to. /// - options: A list of options for the operation /// - completionHandler: A completion handler that receives a status code on /// success. - public func create( - chatThread: CreateChatThreadRequest, - withOptions options: CreateChatThreadOptions? = nil, - completionHandler: @escaping HTTPResultHandler + public func add( + chatParticipants: AddChatParticipantsRequest, + chatThreadId: String, + withOptions options: AddChatParticipantsOptions? = nil, + completionHandler: @escaping HTTPResultHandler ) { let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main // Create request parameters let params = RequestParameters( + (.path, "chatThreadId", chatThreadId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), (.header, "Content-Type", "application/json", .encode), @@ -1522,13 +1406,13 @@ public final class AzureCommunicationChatService { ) // Construct request - guard let requestBody = try? JSONEncoder().encode(chatThread) else { + guard let requestBody = try? JSONEncoder().encode(chatParticipants) else { client.options.logger.error("Failed to encode request body as json.") return } - let urlTemplate = "/chat/threads" + let urlTemplate = "/chat/threads/{chatThreadId}/participants/:add" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) + let request = try? HTTPRequest(method: .post, url: requestUrl, headers: params.headers, data: requestBody) else { client.options.logger.error("Failed to construct HTTP request.") return @@ -1536,7 +1420,7 @@ public final class AzureCommunicationChatService { // Send request let context = PipelineContext.of(keyValues: [ - ContextKey.allowedStatusCodes.rawValue: [207, 401, 403, 429, 503] as AnyObject + ContextKey.allowedStatusCodes.rawValue: [201, 401, 403, 429, 503] as AnyObject ]) context.add(cancellationToken: options?.cancellationToken, applying: client.options) context.merge(with: options?.context) @@ -1558,11 +1442,11 @@ public final class AzureCommunicationChatService { return } if [ - 207 + 201 ].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(MultiStatusResponse.self, from: data) + let decoded = try decoder.decode(AddChatParticipantsResult.self, from: data) dispatchQueue.async { completionHandler(.success(decoded), httpResponse) } @@ -1575,9 +1459,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1588,9 +1472,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1601,9 +1485,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -1614,151 +1498,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), - httpResponse - ) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - case let .failure(error): - dispatchQueue.async { - completionHandler(.failure(error), httpResponse) - } - } - } - } - - /// Gets the list of chat threads of a user. - /// - Parameters: - - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - public func listChatThreads( - withOptions options: ListChatThreadsOptions? = nil, - completionHandler: @escaping HTTPResultHandler> - ) { - let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main - - // Create request parameters - let params = RequestParameters( - (.query, "maxPageSize", options?.maxPageSize, .encode), (.query, "startTime", options?.startTime, .encode), - (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), - (.query, "api-version", client.options.apiVersion, .encode), - (.header, "Accept", "application/json", .encode) - ) - - // Construct request - let urlTemplate = "/chat/threads" - guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { - client.options.logger.error("Failed to construct HTTP request.") - return - } - - // Send request - let context = PipelineContext.of(keyValues: [ - ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject - ]) - context.add(cancellationToken: options?.cancellationToken, applying: client.options) - context.merge(with: options?.context) - client.request(request, context: context) { result, httpResponse in - guard let data = httpResponse?.data else { - let noDataError = AzureError.client("Response data expected but not found.") - dispatchQueue.async { - completionHandler(.failure(noDataError), httpResponse) - } - return - } - switch result { - case .success: - guard let statusCode = httpResponse?.statusCode else { - let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") - dispatchQueue.async { - completionHandler(.failure(noStatusCodeError), httpResponse) - } - return - } - if [ - 200 - ].contains(statusCode) { - do { - let decoder = JSONDecoder() - let codingKeys = PagedCodingKeys( - items: "value", - continuationToken: "nextLink" - ) - let paged = try PagedCollection( - client: self.client, - request: request, - context: context, - data: data, - codingKeys: codingKeys, - decoder: decoder - ) - dispatchQueue.async { - completionHandler(.success(paged), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - - if [401].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [403].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [429].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [503].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } @@ -1796,7 +1539,7 @@ public final class AzureCommunicationChatService { (.path, "chatThreadId", chatThreadId, .encode), (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), (.query, "api-version", client.options.apiVersion, .encode), - (.header, "Content-Type", "application/json", .encode), + (.header, "Content-Type", "application/merge-patch+json", .encode), (.header, "Accept", "application/json", .encode) ) @@ -1807,267 +1550,17 @@ public final class AzureCommunicationChatService { } let urlTemplate = "/chat/threads/{chatThreadId}" guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .patch, url: requestUrl, headers: params.headers, data: requestBody) + let request = try? HTTPRequest( + method: .patch, + url: requestUrl, + headers: params.headers, + data: requestBody + ) else { client.options.logger.error("Failed to construct HTTP request.") return } - // Send request - let context = PipelineContext.of(keyValues: [ - ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject - ]) - context.add(cancellationToken: options?.cancellationToken, applying: client.options) - context.merge(with: options?.context) - client.request(request, context: context) { result, httpResponse in - guard let data = httpResponse?.data else { - let noDataError = AzureError.client("Response data expected but not found.") - dispatchQueue.async { - completionHandler(.failure(noDataError), httpResponse) - } - return - } - switch result { - case .success: - guard let statusCode = httpResponse?.statusCode else { - let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") - dispatchQueue.async { - completionHandler(.failure(noStatusCodeError), httpResponse) - } - return - } - if [ - 200 - ].contains(statusCode) { - dispatchQueue.async { - completionHandler( - .success(()), - httpResponse - ) - } - } - if [401].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [403].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [429].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [503].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), - httpResponse - ) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - case let .failure(error): - dispatchQueue.async { - completionHandler(.failure(error), httpResponse) - } - } - } - } - - /// Gets a chat thread. - /// - Parameters: - /// - chatThreadId : Thread id to get. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - public func getChatThread( - chatThreadId: String, - withOptions options: GetChatThreadOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main - - // Create request parameters - let params = RequestParameters( - (.path, "chatThreadId", chatThreadId, .encode), - (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), - (.query, "api-version", client.options.apiVersion, .encode), - (.header, "Accept", "application/json", .encode) - ) - - // Construct request - let urlTemplate = "/chat/threads/{chatThreadId}" - guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .get, url: requestUrl, headers: params.headers) else { - client.options.logger.error("Failed to construct HTTP request.") - return - } - - // Send request - let context = PipelineContext.of(keyValues: [ - ContextKey.allowedStatusCodes.rawValue: [200, 401, 403, 429, 503] as AnyObject - ]) - context.add(cancellationToken: options?.cancellationToken, applying: client.options) - context.merge(with: options?.context) - client.request(request, context: context) { result, httpResponse in - guard let data = httpResponse?.data else { - let noDataError = AzureError.client("Response data expected but not found.") - dispatchQueue.async { - completionHandler(.failure(noDataError), httpResponse) - } - return - } - switch result { - case .success: - guard let statusCode = httpResponse?.statusCode else { - let noStatusCodeError = AzureError.client("Expected a status code in response but didn't find one.") - dispatchQueue.async { - completionHandler(.failure(noStatusCodeError), httpResponse) - } - return - } - if [ - 200 - ].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ChatThread.self, from: data) - dispatchQueue.async { - completionHandler(.success(decoded), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [401].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [403].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [429].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - if [503].contains(statusCode) { - do { - let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) - dispatchQueue.async { - completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), - httpResponse - ) - } - } catch { - dispatchQueue.async { - completionHandler(.failure(AzureError.client("Decoding error.", error)), httpResponse) - } - } - } - case let .failure(error): - dispatchQueue.async { - completionHandler(.failure(error), httpResponse) - } - } - } - } - - /// Deletes a thread. - /// - Parameters: - /// - chatThreadId : Thread id to delete. - /// - options: A list of options for the operation - /// - completionHandler: A completion handler that receives a status code on - /// success. - public func deleteChatThread( - chatThreadId: String, - withOptions options: DeleteChatThreadOptions? = nil, - completionHandler: @escaping HTTPResultHandler - ) { - let dispatchQueue = options?.dispatchQueue ?? client.commonOptions.dispatchQueue ?? DispatchQueue.main - - // Create request parameters - let params = RequestParameters( - (.path, "chatThreadId", chatThreadId, .encode), - (.uri, "endpoint", client.endpoint.absoluteString, .skipEncoding), - (.query, "api-version", client.options.apiVersion, .encode), - (.header, "Accept", "application/json", .encode) - ) - - // Construct request - let urlTemplate = "/chat/threads/{chatThreadId}" - guard let requestUrl = client.url(host: "{endpoint}", template: urlTemplate, params: params), - let request = try? HTTPRequest(method: .delete, url: requestUrl, headers: params.headers) else { - client.options.logger.error("Failed to construct HTTP request.") - return - } - // Send request let context = PipelineContext.of(keyValues: [ ContextKey.allowedStatusCodes.rawValue: [204, 401, 403, 429, 503] as AnyObject @@ -2104,9 +1597,9 @@ public final class AzureCommunicationChatService { if [401].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Unauthorized", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Unauthorized.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -2117,9 +1610,9 @@ public final class AzureCommunicationChatService { if [403].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Forbidden", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Forbidden.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -2130,9 +1623,9 @@ public final class AzureCommunicationChatService { if [429].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { - completionHandler(.failure(AzureError.service("Too many requests", decoded)), httpResponse) + completionHandler(.failure(AzureError.service("Too many requests.", decoded)), httpResponse) } } catch { dispatchQueue.async { @@ -2143,10 +1636,10 @@ public final class AzureCommunicationChatService { if [503].contains(statusCode) { do { let decoder = JSONDecoder() - let decoded = try decoder.decode(ErrorType.self, from: data) + let decoded = try decoder.decode(CommunicationErrorResponse.self, from: data) dispatchQueue.async { completionHandler( - .failure(AzureError.service("Service unavailable", decoded)), + .failure(AzureError.service("Service unavailable.", decoded)), httpResponse ) } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatParticipantsErrors.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatParticipantsErrors.swift new file mode 100644 index 00000000..6f92e86c --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatParticipantsErrors.swift @@ -0,0 +1,53 @@ +// -------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation +// swiftlint:disable superfluous_disable_command +// swiftlint:disable identifier_name +// swiftlint:disable line_length +// swiftlint:disable cyclomatic_complexity + +/// Errors encountered during the addition of the chat participant to the chat thread. +public struct AddChatParticipantsErrors: Codable { + // MARK: Properties + + /// The participants that failed to be added to the chat thread. + public let invalidParticipants: [CommunicationError?] + + // MARK: Initializers + + /// Initialize a `AddChatParticipantsErrors` structure. + /// - Parameters: + /// - invalidParticipants: The participants that failed to be added to the chat thread. + public init( + invalidParticipants: [CommunicationError?] + ) { + self.invalidParticipants = invalidParticipants + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case invalidParticipants = "invalidParticipants" + } + + /// Initialize a `AddChatParticipantsErrors` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.invalidParticipants = try container.decode([CommunicationError?].self, forKey: .invalidParticipants) + } + + /// Encode a `AddChatParticipantsErrors` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(invalidParticipants, forKey: .invalidParticipants) + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/MultiStatusResponse.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatParticipantsRequest.swift similarity index 57% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Models/MultiStatusResponse.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatParticipantsRequest.swift index 77e5f5a3..b7d6ab4a 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/MultiStatusResponse.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatParticipantsRequest.swift @@ -15,38 +15,39 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -public struct MultiStatusResponse: Codable, Equatable { +/// Participants to be added to the thread. +public struct AddChatParticipantsRequest: Codable { // MARK: Properties - /// The list of status information for each resource in the request. - public let multipleStatus: [IndividualStatusResponse]? + /// Participants to add to a chat thread. + public let participants: [ChatParticipant] // MARK: Initializers - /// Initialize a `MultiStatusResponse` structure. + /// Initialize a `AddChatParticipantsRequest` structure. /// - Parameters: - /// - multipleStatus: The list of status information for each resource in the request. + /// - participants: Participants to add to a chat thread. public init( - multipleStatus: [IndividualStatusResponse]? = nil + participants: [ChatParticipant] ) { - self.multipleStatus = multipleStatus + self.participants = participants } // MARK: Codable enum CodingKeys: String, CodingKey { - case multipleStatus = "multipleStatus" + case participants = "participants" } - /// Initialize a `MultiStatusResponse` structure from decoder + /// Initialize a `AddChatParticipantsRequest` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.multipleStatus = try? container.decode([IndividualStatusResponse].self, forKey: .multipleStatus) + self.participants = try container.decode([ChatParticipant].self, forKey: .participants) } - /// Encode a `MultiStatusResponse` structure + /// Encode a `AddChatParticipantsRequest` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if multipleStatus != nil { try? container.encode(multipleStatus, forKey: .multipleStatus) } + try container.encode(participants, forKey: .participants) } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatParticipantsResult.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatParticipantsResult.swift new file mode 100644 index 00000000..56ba69be --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatParticipantsResult.swift @@ -0,0 +1,53 @@ +// -------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation +// swiftlint:disable superfluous_disable_command +// swiftlint:disable identifier_name +// swiftlint:disable line_length +// swiftlint:disable cyclomatic_complexity + +/// Result of the add chat participants operation. +public struct AddChatParticipantsResult: Codable { + // MARK: Properties + + /// Errors encountered during the addition of the chat participant to the chat thread. + public let errors: AddChatParticipantsErrors? + + // MARK: Initializers + + /// Initialize a `AddChatParticipantsResult` structure. + /// - Parameters: + /// - errors: Errors encountered during the addition of the chat participant to the chat thread. + public init( + errors: AddChatParticipantsErrors? = nil + ) { + self.errors = errors + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case errors = "errors" + } + + /// Initialize a `AddChatParticipantsResult` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.errors = try? container.decode(AddChatParticipantsErrors.self, forKey: .errors) + } + + /// Encode a `AddChatParticipantsResult` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + if errors != nil { try? container.encode(errors, forKey: .errors) } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessage.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessage.swift index 217fa772..b5f20b3d 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessage.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessage.swift @@ -15,34 +15,29 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -public struct ChatMessage: Codable, Equatable { +/// Chat message. +public struct ChatMessage: Codable { // MARK: Properties /// The id of the chat message. This id is server generated. - public let id: String? - /// Type of the chat message. - /// - /// Possible values: - /// - Text - /// - ThreadActivity/TopicUpdate - /// - ThreadActivity/AddMember - /// - ThreadActivity/DeleteMember - public let type: String? - /// The chat message priority. - public let priority: ChatMessagePriority? + public let id: String + /// The chat message type. + public let type: ChatMessageType + /// Sequence of the chat message in the conversation. + public let sequenceId: String /// Version of the chat message. - public let version: String? - /// Content of the chat message. - public let content: String? + public let version: String + /// Content of a chat message. + public let content: ChatMessageContent? /// The display name of the chat message sender. This property is used to populate sender name for push notifications. public let senderDisplayName: String? - /// The timestamp when the chat message arrived at the server. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. - public let createdOn: Iso8601Date? + /// The timestamp when the chat message arrived at the server. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let createdOn: Iso8601Date /// The id of the chat message sender. public let senderId: String? - /// The timestamp when the chat message was deleted. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// The timestamp (if applicable) when the message was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public let deletedOn: Iso8601Date? - /// The timestamp when the chat message was edited. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// The last timestamp (if applicable) when the message was edited. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public let editedOn: Iso8601Date? // MARK: Initializers @@ -50,29 +45,23 @@ public struct ChatMessage: Codable, Equatable { /// Initialize a `ChatMessage` structure. /// - Parameters: /// - id: The id of the chat message. This id is server generated. - /// - type: Type of the chat message. - /// - /// Possible values: - /// - Text - /// - ThreadActivity/TopicUpdate - /// - ThreadActivity/AddMember - /// - ThreadActivity/DeleteMember - /// - priority: The chat message priority. + /// - type: The chat message type. + /// - sequenceId: Sequence of the chat message in the conversation. /// - version: Version of the chat message. - /// - content: Content of the chat message. + /// - content: Content of a chat message. /// - senderDisplayName: The display name of the chat message sender. This property is used to populate sender name for push notifications. - /// - createdOn: The timestamp when the chat message arrived at the server. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - createdOn: The timestamp when the chat message arrived at the server. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. /// - senderId: The id of the chat message sender. - /// - deletedOn: The timestamp when the chat message was deleted. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. - /// - editedOn: The timestamp when the chat message was edited. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - deletedOn: The timestamp (if applicable) when the message was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - editedOn: The last timestamp (if applicable) when the message was edited. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public init( - id: String? = nil, type: String? = nil, priority: ChatMessagePriority? = nil, version: String? = nil, - content: String? = nil, senderDisplayName: String? = nil, createdOn: Iso8601Date? = nil, - senderId: String? = nil, deletedOn: Iso8601Date? = nil, editedOn: Iso8601Date? = nil + id: String, type: ChatMessageType, sequenceId: String, version: String, content: ChatMessageContent? = nil, + senderDisplayName: String? = nil, createdOn: Iso8601Date, senderId: String? = nil, + deletedOn: Iso8601Date? = nil, editedOn: Iso8601Date? = nil ) { self.id = id self.type = type - self.priority = priority + self.sequenceId = sequenceId self.version = version self.content = content self.senderDisplayName = senderDisplayName @@ -87,7 +76,7 @@ public struct ChatMessage: Codable, Equatable { enum CodingKeys: String, CodingKey { case id = "id" case type = "type" - case priority = "priority" + case sequenceId = "sequenceId" case version = "version" case content = "content" case senderDisplayName = "senderDisplayName" @@ -100,13 +89,13 @@ public struct ChatMessage: Codable, Equatable { /// Initialize a `ChatMessage` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.id = try? container.decode(String.self, forKey: .id) - self.type = try? container.decode(String.self, forKey: .type) - self.priority = try? container.decode(ChatMessagePriority.self, forKey: .priority) - self.version = try? container.decode(String.self, forKey: .version) - self.content = try? container.decode(String.self, forKey: .content) + self.id = try container.decode(String.self, forKey: .id) + self.type = try container.decode(ChatMessageType.self, forKey: .type) + self.sequenceId = try container.decode(String.self, forKey: .sequenceId) + self.version = try container.decode(String.self, forKey: .version) + self.content = try? container.decode(ChatMessageContent.self, forKey: .content) self.senderDisplayName = try? container.decode(String.self, forKey: .senderDisplayName) - self.createdOn = try? container.decode(Iso8601Date.self, forKey: .createdOn) + self.createdOn = try container.decode(Iso8601Date.self, forKey: .createdOn) self.senderId = try? container.decode(String.self, forKey: .senderId) self.deletedOn = try? container.decode(Iso8601Date.self, forKey: .deletedOn) self.editedOn = try? container.decode(Iso8601Date.self, forKey: .editedOn) @@ -115,13 +104,13 @@ public struct ChatMessage: Codable, Equatable { /// Encode a `ChatMessage` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if id != nil { try? container.encode(id, forKey: .id) } - if type != nil { try? container.encode(type, forKey: .type) } - if priority != nil { try? container.encode(priority, forKey: .priority) } - if version != nil { try? container.encode(version, forKey: .version) } + try container.encode(id, forKey: .id) + try container.encode(type, forKey: .type) + try container.encode(sequenceId, forKey: .sequenceId) + try container.encode(version, forKey: .version) if content != nil { try? container.encode(content, forKey: .content) } if senderDisplayName != nil { try? container.encode(senderDisplayName, forKey: .senderDisplayName) } - if createdOn != nil { try? container.encode(createdOn, forKey: .createdOn) } + try container.encode(createdOn, forKey: .createdOn) if senderId != nil { try? container.encode(senderId, forKey: .senderId) } if deletedOn != nil { try? container.encode(deletedOn, forKey: .deletedOn) } if editedOn != nil { try? container.encode(editedOn, forKey: .editedOn) } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessageContent.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessageContent.swift new file mode 100644 index 00000000..a87e27b9 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessageContent.swift @@ -0,0 +1,75 @@ +// -------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation +// swiftlint:disable superfluous_disable_command +// swiftlint:disable identifier_name +// swiftlint:disable line_length +// swiftlint:disable cyclomatic_complexity + +/// Content of a chat message. +public struct ChatMessageContent: Codable { + // MARK: Properties + + /// Chat message content for messages of types text or html. + public let message: String? + /// Chat message content for messages of type topicUpdated. + public let topic: String? + /// Chat message content for messages of types participantAdded or participantRemoved. + public let participants: [ChatParticipant]? + /// Chat message initiator. + public let initiator: String? + + // MARK: Initializers + + /// Initialize a `ChatMessageContent` structure. + /// - Parameters: + /// - message: Chat message content for messages of types text or html. + /// - topic: Chat message content for messages of type topicUpdated. + /// - participants: Chat message content for messages of types participantAdded or participantRemoved. + /// - initiator: Chat message initiator. + public init( + message: String? = nil, topic: String? = nil, participants: [ChatParticipant]? = nil, + initiator: String? = nil + ) { + self.message = message + self.topic = topic + self.participants = participants + self.initiator = initiator + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case message = "message" + case topic = "topic" + case participants = "participants" + case initiator = "initiator" + } + + /// Initialize a `ChatMessageContent` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.message = try? container.decode(String.self, forKey: .message) + self.topic = try? container.decode(String.self, forKey: .topic) + self.participants = try? container.decode([ChatParticipant].self, forKey: .participants) + self.initiator = try? container.decode(String.self, forKey: .initiator) + } + + /// Encode a `ChatMessageContent` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + if message != nil { try? container.encode(message, forKey: .message) } + if topic != nil { try? container.encode(topic, forKey: .topic) } + if participants != nil { try? container.encode(participants, forKey: .participants) } + if initiator != nil { try? container.encode(initiator, forKey: .initiator) } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessageReadReceipt.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessageReadReceipt.swift new file mode 100644 index 00000000..66828b6a --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessageReadReceipt.swift @@ -0,0 +1,67 @@ +// -------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation +// swiftlint:disable superfluous_disable_command +// swiftlint:disable identifier_name +// swiftlint:disable line_length +// swiftlint:disable cyclomatic_complexity + +/// A chat message read receipt indicates the time a chat message was read by a recipient. +public struct ChatMessageReadReceipt: Codable { + // MARK: Properties + + /// Id of the participant who read the message. + public let senderId: String + /// Id of the chat message that has been read. This id is generated by the server. + public let chatMessageId: String + /// The time at which the message was read. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let readOn: Iso8601Date + + // MARK: Initializers + + /// Initialize a `ChatMessageReadReceipt` structure. + /// - Parameters: + /// - senderId: Id of the participant who read the message. + /// - chatMessageId: Id of the chat message that has been read. This id is generated by the server. + /// - readOn: The time at which the message was read. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public init( + senderId: String, chatMessageId: String, readOn: Iso8601Date + ) { + self.senderId = senderId + self.chatMessageId = chatMessageId + self.readOn = readOn + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case senderId = "senderId" + case chatMessageId = "chatMessageId" + case readOn = "readOn" + } + + /// Initialize a `ChatMessageReadReceipt` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.senderId = try container.decode(String.self, forKey: .senderId) + self.chatMessageId = try container.decode(String.self, forKey: .chatMessageId) + self.readOn = try container.decode(Iso8601Date.self, forKey: .readOn) + } + + /// Encode a `ChatMessageReadReceipt` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(senderId, forKey: .senderId) + try container.encode(chatMessageId, forKey: .chatMessageId) + try container.encode(readOn, forKey: .readOn) + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadMembersCollection.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessageReadReceiptsCollection.swift similarity index 62% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadMembersCollection.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessageReadReceiptsCollection.swift index 6599ce39..ee51bcf9 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadMembersCollection.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessageReadReceiptsCollection.swift @@ -15,23 +15,23 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -/// Collection of thread members belong to a particular thread. -public struct ChatThreadMembersCollection: Codable, Equatable { +/// A paged collection of chat message read receipts. +public struct ChatMessageReadReceiptsCollection: Codable { // MARK: Properties - /// Chat thread members. - public let value: [ChatThreadMember]? - /// If there are more chat threads that can be retrieved, the next link will be populated. + /// Collection of chat message read receipts. + public let value: [ChatMessageReadReceipt] + /// If there are more chat message read receipts that can be retrieved, the next link will be populated. public let nextLink: String? // MARK: Initializers - /// Initialize a `ChatThreadMembersCollection` structure. + /// Initialize a `ChatMessageReadReceiptsCollection` structure. /// - Parameters: - /// - value: Chat thread members. - /// - nextLink: If there are more chat threads that can be retrieved, the next link will be populated. + /// - value: Collection of chat message read receipts. + /// - nextLink: If there are more chat message read receipts that can be retrieved, the next link will be populated. public init( - value: [ChatThreadMember]? = nil, nextLink: String? = nil + value: [ChatMessageReadReceipt], nextLink: String? = nil ) { self.value = value self.nextLink = nextLink @@ -44,17 +44,17 @@ public struct ChatThreadMembersCollection: Codable, Equatable { case nextLink = "nextLink" } - /// Initialize a `ChatThreadMembersCollection` structure from decoder + /// Initialize a `ChatMessageReadReceiptsCollection` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try? container.decode([ChatThreadMember].self, forKey: .value) + self.value = try container.decode([ChatMessageReadReceipt].self, forKey: .value) self.nextLink = try? container.decode(String.self, forKey: .nextLink) } - /// Encode a `ChatThreadMembersCollection` structure + /// Encode a `ChatMessageReadReceiptsCollection` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if value != nil { try? container.encode(value, forKey: .value) } + try container.encode(value, forKey: .value) if nextLink != nil { try? container.encode(nextLink, forKey: .nextLink) } } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessagesCollection.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessagesCollection.swift index 0d8a4ea9..81e80174 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessagesCollection.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatMessagesCollection.swift @@ -16,11 +16,11 @@ import Foundation // swiftlint:disable cyclomatic_complexity /// Collection of chat messages for a particular chat thread. -public struct ChatMessagesCollection: Codable, Equatable { +public struct ChatMessagesCollection: Codable { // MARK: Properties /// Collection of chat messages. - public let value: [ChatMessage]? + public let value: [ChatMessage] /// If there are more chat messages that can be retrieved, the next link will be populated. public let nextLink: String? @@ -31,7 +31,7 @@ public struct ChatMessagesCollection: Codable, Equatable { /// - value: Collection of chat messages. /// - nextLink: If there are more chat messages that can be retrieved, the next link will be populated. public init( - value: [ChatMessage]? = nil, nextLink: String? = nil + value: [ChatMessage], nextLink: String? = nil ) { self.value = value self.nextLink = nextLink @@ -47,14 +47,14 @@ public struct ChatMessagesCollection: Codable, Equatable { /// Initialize a `ChatMessagesCollection` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try? container.decode([ChatMessage].self, forKey: .value) + self.value = try container.decode([ChatMessage].self, forKey: .value) self.nextLink = try? container.decode(String.self, forKey: .nextLink) } /// Encode a `ChatMessagesCollection` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if value != nil { try? container.encode(value, forKey: .value) } + try container.encode(value, forKey: .value) if nextLink != nil { try? container.encode(nextLink, forKey: .nextLink) } } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadMember.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatParticipant.swift similarity index 73% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadMember.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatParticipant.swift index 69dfc4e4..f2359237 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadMember.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatParticipant.swift @@ -15,24 +15,24 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -/// A member of the chat thread. -public struct ChatThreadMember: Codable, Equatable { +/// A participant of the chat thread. +public struct ChatParticipant: Codable { // MARK: Properties - /// The id of the chat thread member in the format `8:acs:ResourceId_AcsUserId`. + /// The id of the chat participant. public let id: String - /// Display name for the chat thread member. + /// Display name for the chat participant. public let displayName: String? - /// Time from which the chat history is shared with the member. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// Time from which the chat history is shared with the participant. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public let shareHistoryTime: Iso8601Date? // MARK: Initializers - /// Initialize a `ChatThreadMember` structure. + /// Initialize a `ChatParticipant` structure. /// - Parameters: - /// - id: The id of the chat thread member in the format `8:acs:ResourceId_AcsUserId`. - /// - displayName: Display name for the chat thread member. - /// - shareHistoryTime: Time from which the chat history is shared with the member. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - id: The id of the chat participant. + /// - displayName: Display name for the chat participant. + /// - shareHistoryTime: Time from which the chat history is shared with the participant. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public init( id: String, displayName: String? = nil, shareHistoryTime: Iso8601Date? = nil ) { @@ -49,7 +49,7 @@ public struct ChatThreadMember: Codable, Equatable { case shareHistoryTime = "shareHistoryTime" } - /// Initialize a `ChatThreadMember` structure from decoder + /// Initialize a `ChatParticipant` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.id = try container.decode(String.self, forKey: .id) @@ -57,7 +57,7 @@ public struct ChatThreadMember: Codable, Equatable { self.shareHistoryTime = try? container.decode(Iso8601Date.self, forKey: .shareHistoryTime) } - /// Encode a `ChatThreadMember` structure + /// Encode a `ChatParticipant` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(id, forKey: .id) diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ReadReceiptsCollection.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatParticipantsCollection.swift similarity index 63% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Models/ReadReceiptsCollection.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatParticipantsCollection.swift index 02ac3aeb..a8d7c653 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ReadReceiptsCollection.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatParticipantsCollection.swift @@ -15,22 +15,23 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -public struct ReadReceiptsCollection: Codable, Equatable { +/// Collection of participants belong to a particular thread. +public struct ChatParticipantsCollection: Codable { // MARK: Properties - /// Collection of read receipts. - public let value: [ReadReceipt]? - /// If there are more read receipts that can be retrieved, the next link will be populated. + /// Chat participants. + public let value: [ChatParticipant] + /// If there are more chat participants that can be retrieved, the next link will be populated. public let nextLink: String? // MARK: Initializers - /// Initialize a `ReadReceiptsCollection` structure. + /// Initialize a `ChatParticipantsCollection` structure. /// - Parameters: - /// - value: Collection of read receipts. - /// - nextLink: If there are more read receipts that can be retrieved, the next link will be populated. + /// - value: Chat participants. + /// - nextLink: If there are more chat participants that can be retrieved, the next link will be populated. public init( - value: [ReadReceipt]? = nil, nextLink: String? = nil + value: [ChatParticipant], nextLink: String? = nil ) { self.value = value self.nextLink = nextLink @@ -43,17 +44,17 @@ public struct ReadReceiptsCollection: Codable, Equatable { case nextLink = "nextLink" } - /// Initialize a `ReadReceiptsCollection` structure from decoder + /// Initialize a `ChatParticipantsCollection` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try? container.decode([ReadReceipt].self, forKey: .value) + self.value = try container.decode([ChatParticipant].self, forKey: .value) self.nextLink = try? container.decode(String.self, forKey: .nextLink) } - /// Encode a `ReadReceiptsCollection` structure + /// Encode a `ChatParticipantsCollection` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if value != nil { try? container.encode(value, forKey: .value) } + try container.encode(value, forKey: .value) if nextLink != nil { try? container.encode(nextLink, forKey: .nextLink) } } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThread.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThread.swift index 29dd362f..f9c7534d 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThread.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThread.swift @@ -15,19 +15,20 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -public struct ChatThread: Codable, Equatable { +/// Chat thread. +public struct ChatThread: Codable { // MARK: Properties /// Chat thread id. - public let id: String? + public let id: String /// Chat thread topic. - public let topic: String? - /// The timestamp when the chat thread was created. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. - public let createdOn: Iso8601Date? + public let topic: String + /// The timestamp when the chat thread was created. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let createdOn: Iso8601Date /// Id of the chat thread owner. - public let createdBy: String? - /// Chat thread members. - public let members: [ChatThreadMember]? + public let createdBy: String + /// The timestamp when the chat thread was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let deletedOn: Iso8601Date? // MARK: Initializers @@ -35,18 +36,17 @@ public struct ChatThread: Codable, Equatable { /// - Parameters: /// - id: Chat thread id. /// - topic: Chat thread topic. - /// - createdOn: The timestamp when the chat thread was created. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - createdOn: The timestamp when the chat thread was created. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. /// - createdBy: Id of the chat thread owner. - /// - members: Chat thread members. + /// - deletedOn: The timestamp when the chat thread was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public init( - id: String? = nil, topic: String? = nil, createdOn: Iso8601Date? = nil, createdBy: String? = nil, - members: [ChatThreadMember]? = nil + id: String, topic: String, createdOn: Iso8601Date, createdBy: String, deletedOn: Iso8601Date? = nil ) { self.id = id self.topic = topic self.createdOn = createdOn self.createdBy = createdBy - self.members = members + self.deletedOn = deletedOn } // MARK: Codable @@ -56,26 +56,26 @@ public struct ChatThread: Codable, Equatable { case topic = "topic" case createdOn = "createdOn" case createdBy = "createdBy" - case members = "members" + case deletedOn = "deletedOn" } /// Initialize a `ChatThread` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.id = try? container.decode(String.self, forKey: .id) - self.topic = try? container.decode(String.self, forKey: .topic) - self.createdOn = try? container.decode(Iso8601Date.self, forKey: .createdOn) - self.createdBy = try? container.decode(String.self, forKey: .createdBy) - self.members = try? container.decode([ChatThreadMember].self, forKey: .members) + self.id = try container.decode(String.self, forKey: .id) + self.topic = try container.decode(String.self, forKey: .topic) + self.createdOn = try container.decode(Iso8601Date.self, forKey: .createdOn) + self.createdBy = try container.decode(String.self, forKey: .createdBy) + self.deletedOn = try? container.decode(Iso8601Date.self, forKey: .deletedOn) } /// Encode a `ChatThread` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if id != nil { try? container.encode(id, forKey: .id) } - if topic != nil { try? container.encode(topic, forKey: .topic) } - if createdOn != nil { try? container.encode(createdOn, forKey: .createdOn) } - if createdBy != nil { try? container.encode(createdBy, forKey: .createdBy) } - if members != nil { try? container.encode(members, forKey: .members) } + try container.encode(id, forKey: .id) + try container.encode(topic, forKey: .topic) + try container.encode(createdOn, forKey: .createdOn) + try container.encode(createdBy, forKey: .createdBy) + if deletedOn != nil { try? container.encode(deletedOn, forKey: .deletedOn) } } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadInfo.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadInfo.swift index ff8165ff..7613e944 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadInfo.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadInfo.swift @@ -15,16 +15,17 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -public struct ChatThreadInfo: Codable, Equatable { +/// Summary information of a chat thread. +public struct ChatThreadInfo: Codable { // MARK: Properties /// Chat thread id. - public let id: String? + public let id: String /// Chat thread topic. - public let topic: String? - /// Flag if a chat thread is soft deleted. - public let isDeleted: Bool? - /// The timestamp when the last message arrived at the server. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let topic: String + /// The timestamp when the chat thread was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let deletedOn: Iso8601Date? + /// The timestamp when the last message arrived at the server. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public let lastMessageReceivedOn: Iso8601Date? // MARK: Initializers @@ -33,14 +34,14 @@ public struct ChatThreadInfo: Codable, Equatable { /// - Parameters: /// - id: Chat thread id. /// - topic: Chat thread topic. - /// - isDeleted: Flag if a chat thread is soft deleted. - /// - lastMessageReceivedOn: The timestamp when the last message arrived at the server. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - deletedOn: The timestamp when the chat thread was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - lastMessageReceivedOn: The timestamp when the last message arrived at the server. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public init( - id: String? = nil, topic: String? = nil, isDeleted: Bool? = nil, lastMessageReceivedOn: Iso8601Date? = nil + id: String, topic: String, deletedOn: Iso8601Date? = nil, lastMessageReceivedOn: Iso8601Date? = nil ) { self.id = id self.topic = topic - self.isDeleted = isDeleted + self.deletedOn = deletedOn self.lastMessageReceivedOn = lastMessageReceivedOn } @@ -49,25 +50,25 @@ public struct ChatThreadInfo: Codable, Equatable { enum CodingKeys: String, CodingKey { case id = "id" case topic = "topic" - case isDeleted = "isDeleted" + case deletedOn = "deletedOn" case lastMessageReceivedOn = "lastMessageReceivedOn" } /// Initialize a `ChatThreadInfo` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.id = try? container.decode(String.self, forKey: .id) - self.topic = try? container.decode(String.self, forKey: .topic) - self.isDeleted = try? container.decode(Bool.self, forKey: .isDeleted) + self.id = try container.decode(String.self, forKey: .id) + self.topic = try container.decode(String.self, forKey: .topic) + self.deletedOn = try? container.decode(Iso8601Date.self, forKey: .deletedOn) self.lastMessageReceivedOn = try? container.decode(Iso8601Date.self, forKey: .lastMessageReceivedOn) } /// Encode a `ChatThreadInfo` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if id != nil { try? container.encode(id, forKey: .id) } - if topic != nil { try? container.encode(topic, forKey: .topic) } - if isDeleted != nil { try? container.encode(isDeleted, forKey: .isDeleted) } + try container.encode(id, forKey: .id) + try container.encode(topic, forKey: .topic) + if deletedOn != nil { try? container.encode(deletedOn, forKey: .deletedOn) } if lastMessageReceivedOn != nil { try? container.encode(lastMessageReceivedOn, forKey: .lastMessageReceivedOn) } } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadsInfoCollection.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadsInfoCollection.swift index 266a612a..91331584 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadsInfoCollection.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ChatThreadsInfoCollection.swift @@ -16,11 +16,11 @@ import Foundation // swiftlint:disable cyclomatic_complexity /// Collection of chat threads. -public struct ChatThreadsInfoCollection: Codable, Equatable { +public struct ChatThreadsInfoCollection: Codable { // MARK: Properties /// Collection of chat threads. - public let value: [ChatThreadInfo]? + public let value: [ChatThreadInfo] /// If there are more chat threads that can be retrieved, the next link will be populated. public let nextLink: String? @@ -31,7 +31,7 @@ public struct ChatThreadsInfoCollection: Codable, Equatable { /// - value: Collection of chat threads. /// - nextLink: If there are more chat threads that can be retrieved, the next link will be populated. public init( - value: [ChatThreadInfo]? = nil, nextLink: String? = nil + value: [ChatThreadInfo], nextLink: String? = nil ) { self.value = value self.nextLink = nextLink @@ -47,14 +47,14 @@ public struct ChatThreadsInfoCollection: Codable, Equatable { /// Initialize a `ChatThreadsInfoCollection` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.value = try? container.decode([ChatThreadInfo].self, forKey: .value) + self.value = try container.decode([ChatThreadInfo].self, forKey: .value) self.nextLink = try? container.decode(String.self, forKey: .nextLink) } /// Encode a `ChatThreadsInfoCollection` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if value != nil { try? container.encode(value, forKey: .value) } + try container.encode(value, forKey: .value) if nextLink != nil { try? container.encode(nextLink, forKey: .nextLink) } } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CommunicationError.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CommunicationError.swift new file mode 100644 index 00000000..8f0faae3 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CommunicationError.swift @@ -0,0 +1,82 @@ +// -------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation +// swiftlint:disable superfluous_disable_command +// swiftlint:disable identifier_name +// swiftlint:disable line_length +// swiftlint:disable cyclomatic_complexity + +/// The Communication Services error. +public final class CommunicationError: Codable, Swift.Error { + // MARK: Properties + + /// The error code. + public let code: String + /// The error message. + public let message: String + /// The error target. + public let target: String? + /// Further details about specific errors that led to this error. + public let details: [CommunicationError?]? + /// The inner error if any. + public let innerError: CommunicationError? + + // MARK: Initializers + + /// Initialize a `CommunicationError` structure. + /// - Parameters: + /// - code: The error code. + /// - message: The error message. + /// - target: The error target. + /// - details: Further details about specific errors that led to this error. + /// - innerError: The inner error if any. + public init( + code: String, message: String, target: String? = nil, details: [CommunicationError?]? = nil, + innerError: CommunicationError? = nil + ) { + self.code = code + self.message = message + self.target = target + self.details = details + self.innerError = innerError + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case code = "code" + case message = "message" + case target = "target" + case details = "details" + case innerError = "innererror" + } + + /// Initialize a `CommunicationError` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.code = try container.decode(String.self, forKey: .code) + self.message = try container.decode(String.self, forKey: .message) + self.target = try? container.decode(String.self, forKey: .target) + self.details = try? container.decode([CommunicationError?].self, forKey: .details) + self.innerError = try? container.decode(CommunicationError.self, forKey: .innerError) + } + + /// Encode a `CommunicationError` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(code, forKey: .code) + try container.encode(message, forKey: .message) + if target != nil { try? container.encode(target, forKey: .target) } + if details != nil { try? container.encode(details, forKey: .details) } + if innerError != nil { try? container.encode(innerError, forKey: .innerError) } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatThreadMembersRequest.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CommunicationErrorResponse.swift similarity index 61% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatThreadMembersRequest.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Models/CommunicationErrorResponse.swift index b244dcbb..886e7387 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/AddChatThreadMembersRequest.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CommunicationErrorResponse.swift @@ -15,39 +15,39 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -/// Thread members to be added to the thread. -public struct AddChatThreadMembersRequest: Codable, Equatable { +/// The Communication Services error. +public struct CommunicationErrorResponse: Codable, Swift.Error { // MARK: Properties - /// Members to add to a chat thread. - public let members: [ChatThreadMember] + /// The Communication Services error. + public let error: CommunicationError // MARK: Initializers - /// Initialize a `AddChatThreadMembersRequest` structure. + /// Initialize a `CommunicationErrorResponse` structure. /// - Parameters: - /// - members: Members to add to a chat thread. + /// - error: The Communication Services error. public init( - members: [ChatThreadMember] + error: CommunicationError ) { - self.members = members + self.error = error } // MARK: Codable enum CodingKeys: String, CodingKey { - case members = "members" + case error = "error" } - /// Initialize a `AddChatThreadMembersRequest` structure from decoder + /// Initialize a `CommunicationErrorResponse` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.members = try container.decode([ChatThreadMember].self, forKey: .members) + self.error = try container.decode(CommunicationError.self, forKey: .error) } - /// Encode a `AddChatThreadMembersRequest` structure + /// Encode a `CommunicationErrorResponse` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(members, forKey: .members) + try container.encode(error, forKey: .error) } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadErrors.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadErrors.swift new file mode 100644 index 00000000..66d2e77d --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadErrors.swift @@ -0,0 +1,53 @@ +// -------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation +// swiftlint:disable superfluous_disable_command +// swiftlint:disable identifier_name +// swiftlint:disable line_length +// swiftlint:disable cyclomatic_complexity + +/// Errors encountered during the creation of the chat thread. +public struct CreateChatThreadErrors: Codable { + // MARK: Properties + + /// The participants that failed to be added to the chat thread. + public let invalidParticipants: [CommunicationError?]? + + // MARK: Initializers + + /// Initialize a `CreateChatThreadErrors` structure. + /// - Parameters: + /// - invalidParticipants: The participants that failed to be added to the chat thread. + public init( + invalidParticipants: [CommunicationError?]? = nil + ) { + self.invalidParticipants = invalidParticipants + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case invalidParticipants = "invalidParticipants" + } + + /// Initialize a `CreateChatThreadErrors` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.invalidParticipants = try? container.decode([CommunicationError?].self, forKey: .invalidParticipants) + } + + /// Encode a `CreateChatThreadErrors` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + if invalidParticipants != nil { try? container.encode(invalidParticipants, forKey: .invalidParticipants) } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadRequest.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadRequest.swift index 9eb01ed3..1b183ca1 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadRequest.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadRequest.swift @@ -16,45 +16,45 @@ import Foundation // swiftlint:disable cyclomatic_complexity /// Request payload for creating a chat thread. -public struct CreateChatThreadRequest: Codable, Equatable { +public struct CreateChatThreadRequest: Codable { // MARK: Properties /// The chat thread topic. public let topic: String - /// Members to be added to the chat thread. - public let members: [ChatThreadMember] + /// Participants to be added to the chat thread. + public let participants: [ChatParticipant] // MARK: Initializers /// Initialize a `CreateChatThreadRequest` structure. /// - Parameters: /// - topic: The chat thread topic. - /// - members: Members to be added to the chat thread. + /// - participants: Participants to be added to the chat thread. public init( - topic: String, members: [ChatThreadMember] + topic: String, participants: [ChatParticipant] ) { self.topic = topic - self.members = members + self.participants = participants } // MARK: Codable enum CodingKeys: String, CodingKey { case topic = "topic" - case members = "members" + case participants = "participants" } /// Initialize a `CreateChatThreadRequest` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.topic = try container.decode(String.self, forKey: .topic) - self.members = try container.decode([ChatThreadMember].self, forKey: .members) + self.participants = try container.decode([ChatParticipant].self, forKey: .participants) } /// Encode a `CreateChatThreadRequest` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(topic, forKey: .topic) - try container.encode(members, forKey: .members) + try container.encode(participants, forKey: .participants) } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadResult.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadResult.swift new file mode 100644 index 00000000..8a651f29 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/CreateChatThreadResult.swift @@ -0,0 +1,60 @@ +// -------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation +// swiftlint:disable superfluous_disable_command +// swiftlint:disable identifier_name +// swiftlint:disable line_length +// swiftlint:disable cyclomatic_complexity + +/// Result of the create chat thread operation. +public struct CreateChatThreadResult: Codable { + // MARK: Properties + + /// Chat thread. + public let chatThread: ChatThread? + /// Errors encountered during the creation of the chat thread. + public let errors: CreateChatThreadErrors? + + // MARK: Initializers + + /// Initialize a `CreateChatThreadResult` structure. + /// - Parameters: + /// - chatThread: Chat thread. + /// - errors: Errors encountered during the creation of the chat thread. + public init( + chatThread: ChatThread? = nil, errors: CreateChatThreadErrors? = nil + ) { + self.chatThread = chatThread + self.errors = errors + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case chatThread = "chatThread" + case errors = "errors" + } + + /// Initialize a `CreateChatThreadResult` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.chatThread = try? container.decode(ChatThread.self, forKey: .chatThread) + self.errors = try? container.decode(CreateChatThreadErrors.self, forKey: .errors) + } + + /// Encode a `CreateChatThreadResult` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + if chatThread != nil { try? container.encode(chatThread, forKey: .chatThread) } + if errors != nil { try? container.encode(errors, forKey: .errors) } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/Enumerations.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/Enumerations.swift index b6634ded..dd7e2c60 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/Enumerations.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/Enumerations.swift @@ -11,32 +11,50 @@ import AzureCore import Foundation -/// The chat message priority. -public enum ChatMessagePriority: RequestStringConvertible, Codable, Equatable { +/// The chat message type. +public enum ChatMessageType: RequestStringConvertible, Codable, Equatable { /// Custom value for unrecognized enum values case custom(String) - case normal + case text - case high + case html + + case topicUpdated + + case participantAdded + + case participantRemoved public var requestString: String { switch self { case let .custom(val): return val - case .normal: - return "Normal" - case .high: - return "High" + case .text: + return "text" + case .html: + return "html" + case .topicUpdated: + return "topicUpdated" + case .participantAdded: + return "participantAdded" + case .participantRemoved: + return "participantRemoved" } } public init(_ val: String) { switch val.lowercased() { - case "normal": - self = .normal - case "high": - self = .high + case "text": + self = .text + case "html": + self = .html + case "topicupdated": + self = .topicUpdated + case "participantadded": + self = .participantAdded + case "participantremoved": + self = .participantRemoved default: self = .custom(val) } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ErrorType.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ErrorType.swift deleted file mode 100644 index 82a41fd3..00000000 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ErrorType.swift +++ /dev/null @@ -1,72 +0,0 @@ -// -------------------------------------------------------------------------- -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for -// license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is -// regenerated. -// -------------------------------------------------------------------------- - -import AzureCore -import Foundation -// swiftlint:disable superfluous_disable_command -// swiftlint:disable identifier_name -// swiftlint:disable line_length -// swiftlint:disable cyclomatic_complexity - -public struct ErrorType: Codable, Swift.Error { - // MARK: Properties - - public let code: String? - - public let message: String? - - public let target: String? - - public let innerErrors: [ErrorType]? - - // MARK: Initializers - - /// Initialize a `ErrorType` structure. - /// - Parameters: - /// - code: - /// - message: - /// - target: - /// - innerErrors: - public init( - code: String? = nil, message: String? = nil, target: String? = nil, innerErrors: [ErrorType]? = nil - ) { - self.code = code - self.message = message - self.target = target - self.innerErrors = innerErrors - } - - // MARK: Codable - - enum CodingKeys: String, CodingKey { - case code = "code" - case message = "message" - case target = "target" - case innerErrors = "innerErrors" - } - - /// Initialize a `ErrorType` structure from decoder - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.code = try? container.decode(String.self, forKey: .code) - self.message = try? container.decode(String.self, forKey: .message) - self.target = try? container.decode(String.self, forKey: .target) - self.innerErrors = try? container.decode([ErrorType].self, forKey: .innerErrors) - } - - /// Encode a `ErrorType` structure - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - if code != nil { try? container.encode(code, forKey: .code) } - if message != nil { try? container.encode(message, forKey: .message) } - if target != nil { try? container.encode(target, forKey: .target) } - if innerErrors != nil { try? container.encode(innerErrors, forKey: .innerErrors) } - } -} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/IndividualStatusResponse.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/IndividualStatusResponse.swift deleted file mode 100644 index 8c7051ef..00000000 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/IndividualStatusResponse.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -------------------------------------------------------------------------- -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for -// license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is -// regenerated. -// -------------------------------------------------------------------------- - -import AzureCore -import Foundation -// swiftlint:disable superfluous_disable_command -// swiftlint:disable identifier_name -// swiftlint:disable line_length -// swiftlint:disable cyclomatic_complexity - -public struct IndividualStatusResponse: Codable, Equatable { - // MARK: Properties - - /// Identifies the resource to which the individual status corresponds. - public let id: String? - /// The status code of the resource operation. - /// - /// Possible values include: - /// 200 for a successful update or delete, - /// 201 for successful creation, - /// 400 for a malformed input, - /// 403 for lacking permission to execute the operation, - /// 404 for resource not found. - public let statusCode: Int32? - /// The message explaining why the operation failed for the resource identified by the key; null if the operation succeeded. - public let message: String? - /// Identifies the type of the resource to which the individual status corresponds. - public let type: String? - - // MARK: Initializers - - /// Initialize a `IndividualStatusResponse` structure. - /// - Parameters: - /// - id: Identifies the resource to which the individual status corresponds. - /// - statusCode: The status code of the resource operation. - /// - /// Possible values include: - /// 200 for a successful update or delete, - /// 201 for successful creation, - /// 400 for a malformed input, - /// 403 for lacking permission to execute the operation, - /// 404 for resource not found. - /// - message: The message explaining why the operation failed for the resource identified by the key; null if the operation succeeded. - /// - type: Identifies the type of the resource to which the individual status corresponds. - public init( - id: String? = nil, statusCode: Int32? = nil, message: String? = nil, type: String? = nil - ) { - self.id = id - self.statusCode = statusCode - self.message = message - self.type = type - } - - // MARK: Codable - - enum CodingKeys: String, CodingKey { - case id = "id" - case statusCode = "statusCode" - case message = "message" - case type = "type" - } - - /// Initialize a `IndividualStatusResponse` structure from decoder - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.id = try? container.decode(String.self, forKey: .id) - self.statusCode = try? container.decode(Int32.self, forKey: .statusCode) - self.message = try? container.decode(String.self, forKey: .message) - self.type = try? container.decode(String.self, forKey: .type) - } - - /// Encode a `IndividualStatusResponse` structure - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - if id != nil { try? container.encode(id, forKey: .id) } - if statusCode != nil { try? container.encode(statusCode, forKey: .statusCode) } - if message != nil { try? container.encode(message, forKey: .message) } - if type != nil { try? container.encode(type, forKey: .type) } - } -} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ReadReceipt.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ReadReceipt.swift deleted file mode 100644 index cceb8bb6..00000000 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/ReadReceipt.swift +++ /dev/null @@ -1,67 +0,0 @@ -// -------------------------------------------------------------------------- -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for -// license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is -// regenerated. -// -------------------------------------------------------------------------- - -import AzureCore -import Foundation -// swiftlint:disable superfluous_disable_command -// swiftlint:disable identifier_name -// swiftlint:disable line_length -// swiftlint:disable cyclomatic_complexity - -/// A read receipt indicates the time a chat message was read by a recipient. -public struct ReadReceipt: Codable, Equatable { - // MARK: Properties - - /// Read receipt sender id. - public let senderId: String? - /// Id for the chat message that has been read. This id is generated by the server. - public let chatMessageId: String? - /// Read receipt timestamp. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. - public let readOn: Iso8601Date? - - // MARK: Initializers - - /// Initialize a `ReadReceipt` structure. - /// - Parameters: - /// - senderId: Read receipt sender id. - /// - chatMessageId: Id for the chat message that has been read. This id is generated by the server. - /// - readOn: Read receipt timestamp. The timestamp is in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. - public init( - senderId: String? = nil, chatMessageId: String? = nil, readOn: Iso8601Date? = nil - ) { - self.senderId = senderId - self.chatMessageId = chatMessageId - self.readOn = readOn - } - - // MARK: Codable - - enum CodingKeys: String, CodingKey { - case senderId = "senderId" - case chatMessageId = "chatMessageId" - case readOn = "readOn" - } - - /// Initialize a `ReadReceipt` structure from decoder - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.senderId = try? container.decode(String.self, forKey: .senderId) - self.chatMessageId = try? container.decode(String.self, forKey: .chatMessageId) - self.readOn = try? container.decode(Iso8601Date.self, forKey: .readOn) - } - - /// Encode a `ReadReceipt` structure - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - if senderId != nil { try? container.encode(senderId, forKey: .senderId) } - if chatMessageId != nil { try? container.encode(chatMessageId, forKey: .chatMessageId) } - if readOn != nil { try? container.encode(readOn, forKey: .readOn) } - } -} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendChatMessageRequest.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendChatMessageRequest.swift index 2f3e1b03..90140632 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendChatMessageRequest.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendChatMessageRequest.swift @@ -16,52 +16,52 @@ import Foundation // swiftlint:disable cyclomatic_complexity /// Details of the message to send. -public struct SendChatMessageRequest: Codable, Equatable { +public struct SendChatMessageRequest: Codable { // MARK: Properties - /// The chat message priority. - public let priority: ChatMessagePriority? /// Chat message content. public let content: String /// The display name of the chat message sender. This property is used to populate sender name for push notifications. public let senderDisplayName: String? + /// The chat message type. + public let type: ChatMessageType? // MARK: Initializers /// Initialize a `SendChatMessageRequest` structure. /// - Parameters: - /// - priority: The chat message priority. /// - content: Chat message content. /// - senderDisplayName: The display name of the chat message sender. This property is used to populate sender name for push notifications. + /// - type: The chat message type. public init( - priority: ChatMessagePriority? = nil, content: String, senderDisplayName: String? = nil + content: String, senderDisplayName: String? = nil, type: ChatMessageType? = nil ) { - self.priority = priority self.content = content self.senderDisplayName = senderDisplayName + self.type = type } // MARK: Codable enum CodingKeys: String, CodingKey { - case priority = "priority" case content = "content" case senderDisplayName = "senderDisplayName" + case type = "type" } /// Initialize a `SendChatMessageRequest` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.priority = try? container.decode(ChatMessagePriority.self, forKey: .priority) self.content = try container.decode(String.self, forKey: .content) self.senderDisplayName = try? container.decode(String.self, forKey: .senderDisplayName) + self.type = try? container.decode(ChatMessageType.self, forKey: .type) } /// Encode a `SendChatMessageRequest` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if priority != nil { try? container.encode(priority, forKey: .priority) } try container.encode(content, forKey: .content) if senderDisplayName != nil { try? container.encode(senderDisplayName, forKey: .senderDisplayName) } + if type != nil { try? container.encode(type, forKey: .type) } } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendChatMessageResult.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendChatMessageResult.swift index 9aaa073a..9c9791d0 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendChatMessageResult.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendChatMessageResult.swift @@ -16,11 +16,11 @@ import Foundation // swiftlint:disable cyclomatic_complexity /// Result of the send message operation. -public struct SendChatMessageResult: Codable, Equatable { +public struct SendChatMessageResult: Codable { // MARK: Properties /// A server-generated message id. - public let id: String? + public let id: String // MARK: Initializers @@ -28,7 +28,7 @@ public struct SendChatMessageResult: Codable, Equatable { /// - Parameters: /// - id: A server-generated message id. public init( - id: String? = nil + id: String ) { self.id = id } @@ -42,12 +42,12 @@ public struct SendChatMessageResult: Codable, Equatable { /// Initialize a `SendChatMessageResult` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - self.id = try? container.decode(String.self, forKey: .id) + self.id = try container.decode(String.self, forKey: .id) } /// Encode a `SendChatMessageResult` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if id != nil { try? container.encode(id, forKey: .id) } + try container.encode(id, forKey: .id) } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendReadReceiptRequest.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendReadReceiptRequest.swift index a9a08426..e22dd6fb 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendReadReceiptRequest.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/SendReadReceiptRequest.swift @@ -16,7 +16,7 @@ import Foundation // swiftlint:disable cyclomatic_complexity /// Request payload for sending a read receipt. -public struct SendReadReceiptRequest: Codable, Equatable { +public struct SendReadReceiptRequest: Codable { // MARK: Properties /// Id of the latest chat message read by the user. diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/UpdateChatMessageRequest.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/UpdateChatMessageRequest.swift index 4c65bb45..d93047dd 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/UpdateChatMessageRequest.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/UpdateChatMessageRequest.swift @@ -15,45 +15,39 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -public struct UpdateChatMessageRequest: Codable, Equatable { +/// Request payload for updating a chat message. +public struct UpdateChatMessageRequest: Codable { // MARK: Properties /// Chat message content. public let content: String? - /// The chat message priority. - public let priority: ChatMessagePriority? // MARK: Initializers /// Initialize a `UpdateChatMessageRequest` structure. /// - Parameters: /// - content: Chat message content. - /// - priority: The chat message priority. public init( - content: String? = nil, priority: ChatMessagePriority? = nil + content: String? = nil ) { self.content = content - self.priority = priority } // MARK: Codable enum CodingKeys: String, CodingKey { case content = "content" - case priority = "priority" } /// Initialize a `UpdateChatMessageRequest` structure from decoder public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.content = try? container.decode(String.self, forKey: .content) - self.priority = try? container.decode(ChatMessagePriority.self, forKey: .priority) } /// Encode a `UpdateChatMessageRequest` structure public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) if content != nil { try? container.encode(content, forKey: .content) } - if priority != nil { try? container.encode(priority, forKey: .priority) } } } diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/UpdateChatThreadRequest.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/UpdateChatThreadRequest.swift index ad8704b5..563451e9 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Models/UpdateChatThreadRequest.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Models/UpdateChatThreadRequest.swift @@ -15,7 +15,8 @@ import Foundation // swiftlint:disable line_length // swiftlint:disable cyclomatic_complexity -public struct UpdateChatThreadRequest: Codable, Equatable { +/// Request payload for updating a chat thread. +public struct UpdateChatThreadRequest: Codable { // MARK: Properties /// Chat thread topic. diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+RemoveChatThreadMemberOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+RemoveChatThreadMemberOptions.swift deleted file mode 100644 index dad3c754..00000000 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+RemoveChatThreadMemberOptions.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -------------------------------------------------------------------------- -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for -// license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is -// regenerated. -// -------------------------------------------------------------------------- - -import AzureCore -import Foundation - -// swiftlint:disable superfluous_disable_command -// swiftlint:disable identifier_name -// swiftlint:disable line_length - -extension AzureCommunicationChatService { - /// User-configurable options for the `AzureCommunicationChatService.RemoveChatThreadMember` operation. - public struct RemoveChatThreadMemberOptions: RequestOptions { - /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. - /// Highly recommended for correlating client-side activites with requests received by the server. - public let clientRequestId: String? - - /// A token used to make a best-effort attempt at canceling a request. - public let cancellationToken: CancellationToken? - - /// A dispatch queue on which to call the completion handler. Defaults to `DispatchQueue.main`. - public var dispatchQueue: DispatchQueue? - - /// A `PipelineContext` object to associate with the request. - public var context: PipelineContext? - - /// Initialize a `RemoveChatThreadMemberOptions` structure. - /// - Parameters: - /// - clientRequestId: A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. - /// - cancellationToken: A token used to make a best-effort attempt at canceling a request. - /// - dispatchQueue: A dispatch queue on which to call the completion handler. Defaults to `DispatchQueue.main`. - /// - context: A `PipelineContext` object to associate with the request. - public init( - clientRequestId: String? = nil, - cancellationToken: CancellationToken? = nil, - dispatchQueue: DispatchQueue? = nil, - context: PipelineContext? = nil - ) { - self.clientRequestId = clientRequestId - self.cancellationToken = cancellationToken - self.dispatchQueue = dispatchQueue - self.context = context - } - } -} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatThreadMembersOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+CreateChatThreadOptions.swift similarity index 62% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatThreadMembersOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+CreateChatThreadOptions.swift index 39d05d81..6d5e3e5d 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatThreadMembersOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+CreateChatThreadOptions.swift @@ -15,9 +15,12 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { - /// User-configurable options for the `AzureCommunicationChatService.ListChatThreadMembers` operation. - public struct ListChatThreadMembersOptions: RequestOptions { +public extension Chat { + /// User-configurable options for the `AzureCommunicationChatService.CreateChatThread` operation. + struct CreateChatThreadOptions: RequestOptions { + /// If specified, the client directs that the request is repeatable; that is, that the client can make the request multiple times with the same Repeatability-Request-ID and get back an appropriate response without the server executing the request multiple times. The value of the Repeatability-Request-ID is an opaque string representing a client-generated, globally unique for all time, identifier for the request. It is recommended to use version 4 (random) UUIDs. + public let repeatabilityRequestID: String? + /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? @@ -31,18 +34,21 @@ extension AzureCommunicationChatService { /// A `PipelineContext` object to associate with the request. public var context: PipelineContext? - /// Initialize a `ListChatThreadMembersOptions` structure. + /// Initialize a `CreateChatThreadOptions` structure. /// - Parameters: + /// - repeatabilityRequestID: If specified, the client directs that the request is repeatable; that is, that the client can make the request multiple times with the same Repeatability-Request-ID and get back an appropriate response without the server executing the request multiple times. The value of the Repeatability-Request-ID is an opaque string representing a client-generated, globally unique for all time, identifier for the request. It is recommended to use version 4 (random) UUIDs. /// - clientRequestId: A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// - cancellationToken: A token used to make a best-effort attempt at canceling a request. /// - dispatchQueue: A dispatch queue on which to call the completion handler. Defaults to `DispatchQueue.main`. /// - context: A `PipelineContext` object to associate with the request. public init( + repeatabilityRequestID: String? = nil, clientRequestId: String? = nil, cancellationToken: CancellationToken? = nil, dispatchQueue: DispatchQueue? = nil, context: PipelineContext? = nil ) { + self.repeatabilityRequestID = repeatabilityRequestID self.clientRequestId = clientRequestId self.cancellationToken = cancellationToken self.dispatchQueue = dispatchQueue diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+DeleteChatThreadOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+DeleteChatThreadOptions.swift similarity index 95% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+DeleteChatThreadOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+DeleteChatThreadOptions.swift index 68c5612a..7c02d68b 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+DeleteChatThreadOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+DeleteChatThreadOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension Chat { /// User-configurable options for the `AzureCommunicationChatService.DeleteChatThread` operation. - public struct DeleteChatThreadOptions: RequestOptions { + struct DeleteChatThreadOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+GetChatThreadOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+GetChatThreadOptions.swift similarity index 95% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+GetChatThreadOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+GetChatThreadOptions.swift index 795da55f..d7b935fa 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+GetChatThreadOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+GetChatThreadOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension Chat { /// User-configurable options for the `AzureCommunicationChatService.GetChatThread` operation. - public struct GetChatThreadOptions: RequestOptions { + struct GetChatThreadOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatThreadsOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+ListChatThreadsOptions.swift similarity index 92% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatThreadsOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+ListChatThreadsOptions.swift index 791e80bb..b3160421 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatThreadsOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/Chat+ListChatThreadsOptions.swift @@ -15,12 +15,12 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension Chat { /// User-configurable options for the `AzureCommunicationChatService.ListChatThreads` operation. - public struct ListChatThreadsOptions: RequestOptions { + struct ListChatThreadsOptions: RequestOptions { /// The maximum number of chat threads returned per page. public let maxPageSize: Int32? - /// The earliest point in time to get chat threads up to. The timestamp should be in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// The earliest point in time to get chat threads up to. The timestamp should be in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public let startTime: Iso8601Date? /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. @@ -39,7 +39,7 @@ extension AzureCommunicationChatService { /// Initialize a `ListChatThreadsOptions` structure. /// - Parameters: /// - maxPageSize: The maximum number of chat threads returned per page. - /// - startTime: The earliest point in time to get chat threads up to. The timestamp should be in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - startTime: The earliest point in time to get chat threads up to. The timestamp should be in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. /// - clientRequestId: A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// - cancellationToken: A token used to make a best-effort attempt at canceling a request. /// - dispatchQueue: A dispatch queue on which to call the completion handler. Defaults to `DispatchQueue.main`. diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+AddChatParticipantsOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+AddChatParticipantsOptions.swift new file mode 100644 index 00000000..a919c55f --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+AddChatParticipantsOptions.swift @@ -0,0 +1,52 @@ +// -------------------------------------------------------------------------- +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for +// license information. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation + +// swiftlint:disable superfluous_disable_command +// swiftlint:disable identifier_name +// swiftlint:disable line_length + +public extension ChatThreadOperation { + /// User-configurable options for the `AzureCommunicationChatService.AddChatParticipants` operation. + struct AddChatParticipantsOptions: RequestOptions { + /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. + /// Highly recommended for correlating client-side activites with requests received by the server. + public let clientRequestId: String? + + /// A token used to make a best-effort attempt at canceling a request. + public let cancellationToken: CancellationToken? + + /// A dispatch queue on which to call the completion handler. Defaults to `DispatchQueue.main`. + public var dispatchQueue: DispatchQueue? + + /// A `PipelineContext` object to associate with the request. + public var context: PipelineContext? + + /// Initialize a `AddChatParticipantsOptions` structure. + /// - Parameters: + /// - clientRequestId: A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. + /// - cancellationToken: A token used to make a best-effort attempt at canceling a request. + /// - dispatchQueue: A dispatch queue on which to call the completion handler. Defaults to `DispatchQueue.main`. + /// - context: A `PipelineContext` object to associate with the request. + public init( + clientRequestId: String? = nil, + cancellationToken: CancellationToken? = nil, + dispatchQueue: DispatchQueue? = nil, + context: PipelineContext? = nil + ) { + self.clientRequestId = clientRequestId + self.cancellationToken = cancellationToken + self.dispatchQueue = dispatchQueue + self.context = context + } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+DeleteChatMessageOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+DeleteChatMessageOptions.swift similarity index 95% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+DeleteChatMessageOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+DeleteChatMessageOptions.swift index 221a0ae4..846deee4 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+DeleteChatMessageOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+DeleteChatMessageOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension ChatThreadOperation { /// User-configurable options for the `AzureCommunicationChatService.DeleteChatMessage` operation. - public struct DeleteChatMessageOptions: RequestOptions { + struct DeleteChatMessageOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+GetChatMessageOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+GetChatMessageOptions.swift similarity index 95% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+GetChatMessageOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+GetChatMessageOptions.swift index e1334c23..5adcc21d 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+GetChatMessageOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+GetChatMessageOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension ChatThreadOperation { /// User-configurable options for the `AzureCommunicationChatService.GetChatMessage` operation. - public struct GetChatMessageOptions: RequestOptions { + struct GetChatMessageOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatMessagesOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+ListChatMessagesOptions.swift similarity index 92% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatMessagesOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+ListChatMessagesOptions.swift index 9da8fdae..cc458faf 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatMessagesOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+ListChatMessagesOptions.swift @@ -15,12 +15,12 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension ChatThreadOperation { /// User-configurable options for the `AzureCommunicationChatService.ListChatMessages` operation. - public struct ListChatMessagesOptions: RequestOptions { + struct ListChatMessagesOptions: RequestOptions { /// The maximum number of messages to be returned per page. public let maxPageSize: Int32? - /// The earliest point in time to get messages up to. The timestamp should be in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// The earliest point in time to get messages up to. The timestamp should be in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. public let startTime: Iso8601Date? /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. @@ -39,7 +39,7 @@ extension AzureCommunicationChatService { /// Initialize a `ListChatMessagesOptions` structure. /// - Parameters: /// - maxPageSize: The maximum number of messages to be returned per page. - /// - startTime: The earliest point in time to get messages up to. The timestamp should be in ISO8601 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - startTime: The earliest point in time to get messages up to. The timestamp should be in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. /// - clientRequestId: A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// - cancellationToken: A token used to make a best-effort attempt at canceling a request. /// - dispatchQueue: A dispatch queue on which to call the completion handler. Defaults to `DispatchQueue.main`. diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+AddChatThreadMembersOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+ListChatParticipantsOptions.swift similarity index 75% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+AddChatThreadMembersOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+ListChatParticipantsOptions.swift index 3c78beec..9eb35c18 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+AddChatThreadMembersOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+ListChatParticipantsOptions.swift @@ -15,9 +15,14 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { - /// User-configurable options for the `AzureCommunicationChatService.AddChatThreadMembers` operation. - public struct AddChatThreadMembersOptions: RequestOptions { +public extension ChatThreadOperation { + /// User-configurable options for the `AzureCommunicationChatService.ListChatParticipants` operation. + struct ListChatParticipantsOptions: RequestOptions { + /// The maximum number of participants to be returned per page. + public let maxPageSize: Int32? + /// Skips participants up to a specified position in response. + public let skip: Int32? + /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? @@ -31,18 +36,24 @@ extension AzureCommunicationChatService { /// A `PipelineContext` object to associate with the request. public var context: PipelineContext? - /// Initialize a `AddChatThreadMembersOptions` structure. + /// Initialize a `ListChatParticipantsOptions` structure. /// - Parameters: + /// - maxPageSize: The maximum number of participants to be returned per page. + /// - skip: Skips participants up to a specified position in response. /// - clientRequestId: A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// - cancellationToken: A token used to make a best-effort attempt at canceling a request. /// - dispatchQueue: A dispatch queue on which to call the completion handler. Defaults to `DispatchQueue.main`. /// - context: A `PipelineContext` object to associate with the request. public init( + maxPageSize: Int32? = nil, + skip: Int32? = nil, clientRequestId: String? = nil, cancellationToken: CancellationToken? = nil, dispatchQueue: DispatchQueue? = nil, context: PipelineContext? = nil ) { + self.maxPageSize = maxPageSize + self.skip = skip self.clientRequestId = clientRequestId self.cancellationToken = cancellationToken self.dispatchQueue = dispatchQueue diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatReadReceiptsOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+ListChatReadReceiptsOptions.swift similarity index 77% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatReadReceiptsOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+ListChatReadReceiptsOptions.swift index 4cd5ce84..e781d3e5 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+ListChatReadReceiptsOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+ListChatReadReceiptsOptions.swift @@ -15,9 +15,14 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension ChatThreadOperation { /// User-configurable options for the `AzureCommunicationChatService.ListChatReadReceipts` operation. - public struct ListChatReadReceiptsOptions: RequestOptions { + struct ListChatReadReceiptsOptions: RequestOptions { + /// The maximum number of chat message read receipts to be returned per page. + public let maxPageSize: Int32? + /// Skips chat message read receipts up to a specified position in response. + public let skip: Int32? + /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? @@ -33,16 +38,22 @@ extension AzureCommunicationChatService { /// Initialize a `ListChatReadReceiptsOptions` structure. /// - Parameters: + /// - maxPageSize: The maximum number of chat message read receipts to be returned per page. + /// - skip: Skips chat message read receipts up to a specified position in response. /// - clientRequestId: A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// - cancellationToken: A token used to make a best-effort attempt at canceling a request. /// - dispatchQueue: A dispatch queue on which to call the completion handler. Defaults to `DispatchQueue.main`. /// - context: A `PipelineContext` object to associate with the request. public init( + maxPageSize: Int32? = nil, + skip: Int32? = nil, clientRequestId: String? = nil, cancellationToken: CancellationToken? = nil, dispatchQueue: DispatchQueue? = nil, context: PipelineContext? = nil ) { + self.maxPageSize = maxPageSize + self.skip = skip self.clientRequestId = clientRequestId self.cancellationToken = cancellationToken self.dispatchQueue = dispatchQueue diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+CreateChatThreadOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+RemoveChatParticipantOptions.swift similarity index 91% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+CreateChatThreadOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+RemoveChatParticipantOptions.swift index c54a7826..c22f4478 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+CreateChatThreadOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+RemoveChatParticipantOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { - /// User-configurable options for the `AzureCommunicationChatService.CreateChatThread` operation. - public struct CreateChatThreadOptions: RequestOptions { +public extension ChatThreadOperation { + /// User-configurable options for the `AzureCommunicationChatService.RemoveChatParticipant` operation. + struct RemoveChatParticipantOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? @@ -31,7 +31,7 @@ extension AzureCommunicationChatService { /// A `PipelineContext` object to associate with the request. public var context: PipelineContext? - /// Initialize a `CreateChatThreadOptions` structure. + /// Initialize a `RemoveChatParticipantOptions` structure. /// - Parameters: /// - clientRequestId: A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// - cancellationToken: A token used to make a best-effort attempt at canceling a request. diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+SendChatMessageOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+SendChatMessageOptions.swift similarity index 95% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+SendChatMessageOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+SendChatMessageOptions.swift index d482279c..461b2aa3 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+SendChatMessageOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+SendChatMessageOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension ChatThreadOperation { /// User-configurable options for the `AzureCommunicationChatService.SendChatMessage` operation. - public struct SendChatMessageOptions: RequestOptions { + struct SendChatMessageOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+SendChatReadReceiptOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+SendChatReadReceiptOptions.swift similarity index 95% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+SendChatReadReceiptOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+SendChatReadReceiptOptions.swift index 33d16a6a..003a66ec 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+SendChatReadReceiptOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+SendChatReadReceiptOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension ChatThreadOperation { /// User-configurable options for the `AzureCommunicationChatService.SendChatReadReceipt` operation. - public struct SendChatReadReceiptOptions: RequestOptions { + struct SendChatReadReceiptOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+SendTypingNotificationOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+SendTypingNotificationOptions.swift similarity index 95% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+SendTypingNotificationOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+SendTypingNotificationOptions.swift index 31d4771d..c03f682c 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+SendTypingNotificationOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+SendTypingNotificationOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension ChatThreadOperation { /// User-configurable options for the `AzureCommunicationChatService.SendTypingNotification` operation. - public struct SendTypingNotificationOptions: RequestOptions { + struct SendTypingNotificationOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+UpdateChatMessageOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+UpdateChatMessageOptions.swift similarity index 95% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+UpdateChatMessageOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+UpdateChatMessageOptions.swift index 98cf84aa..a06c9cb6 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+UpdateChatMessageOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+UpdateChatMessageOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension ChatThreadOperation { /// User-configurable options for the `AzureCommunicationChatService.UpdateChatMessage` operation. - public struct UpdateChatMessageOptions: RequestOptions { + struct UpdateChatMessageOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? diff --git a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+UpdateChatThreadOptions.swift b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+UpdateChatThreadOptions.swift similarity index 95% rename from sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+UpdateChatThreadOptions.swift rename to sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+UpdateChatThreadOptions.swift index da571031..2a0a5242 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Generated/Options/AzureCommunicationChatService+UpdateChatThreadOptions.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Generated/Options/ChatThreadOperation+UpdateChatThreadOptions.swift @@ -15,9 +15,9 @@ import Foundation // swiftlint:disable identifier_name // swiftlint:disable line_length -extension AzureCommunicationChatService { +public extension ChatThreadOperation { /// User-configurable options for the `AzureCommunicationChatService.UpdateChatThread` operation. - public struct UpdateChatThreadOptions: RequestOptions { + struct UpdateChatThreadOptions: RequestOptions { /// A client-generated, opaque value with 1KB character limit that is recorded in analytics logs. /// Highly recommended for correlating client-side activites with requests received by the server. public let clientRequestId: String? diff --git a/sdk/communication/AzureCommunicationChat/Source/Custom.swift b/sdk/communication/AzureCommunicationChat/Source/Models/CreateThreadRequest.swift similarity index 67% rename from sdk/communication/AzureCommunicationChat/Source/Custom.swift rename to sdk/communication/AzureCommunicationChat/Source/Models/CreateThreadRequest.swift index 2d84e9ed..2c35e574 100644 --- a/sdk/communication/AzureCommunicationChat/Source/Custom.swift +++ b/sdk/communication/AzureCommunicationChat/Source/Models/CreateThreadRequest.swift @@ -1,4 +1,3 @@ - // -------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. @@ -25,6 +24,29 @@ // // -------------------------------------------------------------------------- +import AzureCore import Foundation -// TODO: Custom Code Here +/// Request payload for creating a chat thread. +public struct CreateThreadRequest: Codable { + // MARK: Properties + + /// The thread topic. + public let topic: String + /// Participants to be added to the thread. + public let participants: [Participant] + + // MARK: Initializers + + /// Initialize a `CreateThreadRequest` structure. + /// - Parameters: + /// - topic: The thread topic. + /// - participants: Participants to be added to the chat thread. + public init( + topic: String, + participants: [Participant] + ) { + self.topic = topic + self.participants = participants + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Models/CreateThreadResult.swift b/sdk/communication/AzureCommunicationChat/Source/Models/CreateThreadResult.swift new file mode 100644 index 00000000..c04ab8c1 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Models/CreateThreadResult.swift @@ -0,0 +1,59 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation + +/// Result of the create thread operation. +public struct CreateThreadResult: Codable { + // MARK: Properties + + /// Chat thread. + public let thread: Thread? + /// Errors encountered during the creation of the chat thread. + public let errors: CreateChatThreadErrors? + + // MARK: Initializers + + public init( + from createChatThreadResult: CreateChatThreadResult + ) { + self.thread = (createChatThreadResult.chatThread != nil) ? Thread(from: createChatThreadResult.chatThread!) : nil + self.errors = createChatThreadResult.errors + } + + /// Initialize a `ChatThreadResult` structure. + /// - Parameters: + /// - thread: Chat thread. + /// - errors: Errors encountered during the creation of the chat thread. + public init( + thread: Thread? = nil, + errors: CreateChatThreadErrors? = nil + ) { + self.thread = thread + self.errors = errors + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Models/Message.swift b/sdk/communication/AzureCommunicationChat/Source/Models/Message.swift new file mode 100644 index 00000000..abba5273 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Models/Message.swift @@ -0,0 +1,169 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCore +import Foundation + +/// Message. +public struct Message: Codable { + // MARK: Properties + + /// The id of the message. This id is server generated. + public let id: String + /// The message type. + public let type: ChatMessageType + /// Sequence of the message in the conversation. + public let sequenceId: String + /// Version of the message. + public let version: String + /// Content of the message. + public let content: MessageContent? + /// The display name of the message sender. This property is used to populate sender name for push notifications. + public let senderDisplayName: String? + /// The timestamp when the message arrived at the server. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let createdOn: Iso8601Date + /// The sender of the message. + public let sender: CommunicationUserIdentifier? + /// The timestamp (if applicable) when the message was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let deletedOn: Iso8601Date? + /// The last timestamp (if applicable) when the message was edited. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let editedOn: Iso8601Date? + + // MARK: Initializers + + /// Initialize a `Message` structure from a ChatMessage. + /// - Parameters: + /// - chatMessage: The ChatMessage to initialize from. + public init( + from chatMessage: ChatMessage + ) { + self.id = chatMessage.id + self.type = chatMessage.type + self.sequenceId = chatMessage.sequenceId + self.version = chatMessage.version + self.content = (chatMessage.content != nil) ? MessageContent(from: chatMessage.content!) : nil + self.senderDisplayName = chatMessage.senderDisplayName + self.createdOn = chatMessage.createdOn + self.sender = (chatMessage.senderId != nil) ? CommunicationUserIdentifier(identifier: chatMessage.senderId!) : nil + self.deletedOn = chatMessage.deletedOn + self.editedOn = chatMessage.editedOn + } + + /// Initialize a `Message` structure. + /// - Parameters: + /// - id: The id of the message. This id is server generated. + /// - type: The chat message type. + /// - sequenceId: Sequence of the message in the conversation. + /// - version: Version of the message. + /// - content: Content of a message. + /// - senderDisplayName: The display name of the message sender. This property is used to populate sender name for push notifications. + /// - createdOn: The timestamp when the message arrived at the server. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - sender: The id of the sender of the message. + /// - deletedOn: The timestamp (if applicable) when the message was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - editedOn: The last timestamp (if applicable) when the message was edited. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public init( + id: String, + type: ChatMessageType, + sequenceId: String, + version: String, + content: MessageContent? = nil, + senderDisplayName: String? = nil, + createdOn: Iso8601Date, + senderId: String? = nil, + deletedOn: Iso8601Date? = nil, + editedOn: Iso8601Date? = nil + ) { + self.id = id + self.type = type + self.sequenceId = sequenceId + self.version = version + self.content = content + self.senderDisplayName = senderDisplayName + self.createdOn = createdOn + self.sender = (senderId != nil) ? CommunicationUserIdentifier(identifier: senderId!) : nil + self.deletedOn = deletedOn + self.editedOn = editedOn + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case id + case type + case sequenceId + case version + case content + case senderDisplayName + case createdOn + case sender = "senderId" + case deletedOn + case editedOn + } + + /// Initialize a `Message` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + self.id = try container.decode(String.self, forKey: .id) + self.type = try container.decode(ChatMessageType.self, forKey: .type) + self.sequenceId = try container.decode(String.self, forKey: .sequenceId) + self.version = try container.decode(String.self, forKey: .version) + + // Convert ChatMessageContent to MessageContent + let content = try? container.decode(ChatMessageContent.self, forKey: .content) + self.content = MessageContent(from: content!) + + self.senderDisplayName = try? container.decode(String.self, forKey: .senderDisplayName) + self.createdOn = try container.decode(Iso8601Date.self, forKey: .createdOn) + + // Convert senderId to CommunicationUserIdentifier + let senderId = try? container.decode(String.self, forKey: .sender) + self.sender = (senderId != nil) ? CommunicationUserIdentifier(identifier: senderId!) : nil + + self.deletedOn = try? container.decode(Iso8601Date.self, forKey: .deletedOn) + self.editedOn = try? container.decode(Iso8601Date.self, forKey: .editedOn) + } + + /// Encode a `Message` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(id, forKey: .id) + try container.encode(type, forKey: .type) + try container.encode(sequenceId, forKey: .sequenceId) + try container.encode(version, forKey: .version) + if content != nil { try? container.encode(content, forKey: .content) } + if senderDisplayName != nil { try? container.encode(senderDisplayName, forKey: .senderDisplayName) } + try container.encode(createdOn, forKey: .createdOn) + + // Encode user object to senderId string + if sender != nil { try? container.encode(sender?.identifier, forKey: .sender) } + + if deletedOn != nil { try? container.encode(deletedOn, forKey: .deletedOn) } + if editedOn != nil { try? container.encode(editedOn, forKey: .editedOn) } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Models/MessageContent.swift b/sdk/communication/AzureCommunicationChat/Source/Models/MessageContent.swift new file mode 100644 index 00000000..92bd930d --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Models/MessageContent.swift @@ -0,0 +1,118 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation + +/// Content of a message. +public struct MessageContent: Codable { + // MARK: Properties + + /// Chat message content for messages of types text or html. + public let message: String? + /// Chat message content for messages of type topicUpdated. + public let topic: String? + /// Chat message content for messages of types participantAdded or participantRemoved. + public let participants: [Participant]? + /// Chat message content for messages of types participantAdded or participantRemoved. + public let initiator: String? + + // MARK: Initializers + + /// Initializes a `MessageContent` structure from a ChatMessageContent. + /// - Parameters: + /// - chatMessageContent: ChatMessageContent to initialize from. + public init( + from chatMessageContent: ChatMessageContent + ) { + self.message = chatMessageContent.message + self.topic = chatMessageContent.topic + self.participants = (chatMessageContent.participants != nil) ? + chatMessageContent.participants!.map { Participant(from: $0) } : nil + self.initiator = chatMessageContent.initiator + } + + /// Initialize a `MessageContent` structure. + /// - Parameters: + /// - message: Message content for messages of types text or html. + /// - topic: Message content for messages of type topicUpdated. + /// - participants: Message content for messages of types participantAdded or participantRemoved. + /// - initiator: Message content for messages of types participantAdded or participantRemoved. + public init( + message: String? = nil, + topic: String? = nil, + participants: [Participant]? = nil, + initiator: String? = nil + ) { + self.message = message + self.topic = topic + self.participants = participants + self.initiator = initiator + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case message + case topic + case participants + case initiator + } + + /// Initialize a `MessageContent` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.message = try? container.decode(String.self, forKey: .message) + self.topic = try? container.decode(String.self, forKey: .topic) + + // Convert ChatParticipants to Participants + let chatParticipants = try? container.decode([ChatParticipant].self, forKey: .participants) + self.participants = (chatParticipants != nil) ? chatParticipants!.map { Participant(from: $0) } : nil + + self.initiator = try? container.decode(String.self, forKey: .initiator) + } + + /// Encode a `MessageContent` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + if message != nil { try? container.encode(message, forKey: .message) } + if topic != nil { try? container.encode(topic, forKey: .topic) } + + // Encode Participant to ChatParticipant format + if participants != nil { + let test = participants!.map { + ChatParticipant( + id: $0.user.identifier, + displayName: $0.displayName, + shareHistoryTime: $0.shareHistoryTime + ) + } + try? container.encode(test, forKey: .participants) + } + + if initiator != nil { try? container.encode(initiator, forKey: .initiator) } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Models/Participant.swift b/sdk/communication/AzureCommunicationChat/Source/Models/Participant.swift new file mode 100644 index 00000000..8bace678 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Models/Participant.swift @@ -0,0 +1,100 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCore +import Foundation + +/// A participant of the chat thread. +public struct Participant: Codable { + // MARK: Properties + + /// The CommunicationUserIdentifier for the participant. + public let user: CommunicationUserIdentifier + /// Display name for the participant. + public let displayName: String? + /// Time from which the chat history is shared with the participant. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let shareHistoryTime: Iso8601Date? + + // MARK: Initializers + + /// Initialize a `Participant` structure from a ChatParticipant. + /// - Parameters: + /// - chatParticipant: The ChatParticipant to initialize from. + public init( + from chatParticipant: ChatParticipant + ) { + self.user = CommunicationUserIdentifier(identifier: chatParticipant.id) + self.displayName = chatParticipant.displayName + self.shareHistoryTime = chatParticipant.shareHistoryTime + } + + /// Initialize a `Participant` structure. + /// - Parameters: + /// - id: The id of the participant. + /// - displayName: Display name for the participant. + /// - shareHistoryTime: Time from which the chat history is shared with the participant. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public init( + id: String, + displayName: String? = nil, + shareHistoryTime: Iso8601Date? = nil + ) { + self.user = CommunicationUserIdentifier(identifier: id) + self.displayName = displayName + self.shareHistoryTime = shareHistoryTime + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case user = "id" + case displayName + case shareHistoryTime + } + + /// Initialize a `Participant` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + // Convert id to CommunicationUserIdentifier + let identifier = try? container.decode(String.self, forKey: .user) + self.user = CommunicationUserIdentifier(identifier: identifier!) + + self.displayName = try? container.decode(String.self, forKey: .displayName) + self.shareHistoryTime = try? container.decode(Iso8601Date.self, forKey: .shareHistoryTime) + } + + /// Encode a `Participant` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + // Encode user object to id string + try container.encode(user.identifier, forKey: .user) + + if displayName != nil { try? container.encode(displayName, forKey: .displayName) } + if shareHistoryTime != nil { try? container.encode(shareHistoryTime, forKey: .shareHistoryTime) } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Models/ReadReceipt.swift b/sdk/communication/AzureCommunicationChat/Source/Models/ReadReceipt.swift new file mode 100644 index 00000000..9df56451 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Models/ReadReceipt.swift @@ -0,0 +1,100 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCore +import Foundation + +/// A read receipt indicates the time a message was read by a recipient. +public struct ReadReceipt: Codable { + // MARK: Properties + + /// The user who read the message. + public let sender: CommunicationUserIdentifier + /// Id of the message that has been read. This id is generated by the server. + public let chatMessageId: String + /// The time at which the message was read. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let readOn: Iso8601Date + + // MARK: Initializers + + /// Initialize a `ReadReceipt` structure from a ChatMessageReadReceipt. + /// - Parameters: + /// - chatMessageReadReceipt: The ChatMessageReadReceipt to initialize from. + public init( + from chatMessageReadReceipt: ChatMessageReadReceipt + ) { + self.sender = CommunicationUserIdentifier(identifier: chatMessageReadReceipt.senderId) + self.chatMessageId = chatMessageReadReceipt.chatMessageId + self.readOn = chatMessageReadReceipt.readOn + } + + /// Initialize a `ReadReceipt` structure. + /// - Parameters: + /// - senderId: Id of the participant who read the message. + /// - chatMessageId: Id of the chat message that has been read. This id is generated by the server. + /// - readOn: The time at which the message was read. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public init( + senderId: String, + chatMessageId: String, + readOn: Iso8601Date + ) { + self.sender = CommunicationUserIdentifier(identifier: senderId) + self.chatMessageId = chatMessageId + self.readOn = readOn + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case sender = "senderId" + case chatMessageId + case readOn + } + + /// Initialize a `ReadReceipt` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + // Convert senderId to CommunicationUserIdentifier + let senderId = try container.decode(String.self, forKey: .sender) + self.sender = CommunicationUserIdentifier(identifier: senderId) + + self.chatMessageId = try container.decode(String.self, forKey: .chatMessageId) + self.readOn = try container.decode(Iso8601Date.self, forKey: .readOn) + } + + /// Encode a `ReadReceipt` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + // Encode user object to senderId string + try container.encode(sender.identifier, forKey: .sender) + + try container.encode(chatMessageId, forKey: .chatMessageId) + try container.encode(readOn, forKey: .readOn) + } +} diff --git a/sdk/communication/AzureCommunicationChat/Source/Models/Thread.swift b/sdk/communication/AzureCommunicationChat/Source/Models/Thread.swift new file mode 100644 index 00000000..1803c89a --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Source/Models/Thread.swift @@ -0,0 +1,119 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCore +import Foundation + +/// Chat thread. +public struct Thread: Codable { + // MARK: Properties + + /// Thread id. + public let id: String + /// Thread topic. + public let topic: String + /// The timestamp when the thread was created. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let createdOn: Iso8601Date + /// CommunicationUserIdentifier of the thread owner. + public let createdBy: CommunicationUserIdentifier + /// The timestamp when the thread was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public let deletedOn: Iso8601Date? + + // MARK: Initializers + + /// Initialize a `ChatThread` structure from a ChatThread. + /// - Parameters: + /// - chatThread: The ChatThread to initialize from. + public init( + from chatThread: ChatThread + ) { + self.id = chatThread.id + self.topic = chatThread.topic + self.createdOn = chatThread.createdOn + self.createdBy = CommunicationUserIdentifier(identifier: chatThread.createdBy) + self.deletedOn = chatThread.deletedOn + } + + /// Initialize a `ChatThread` structure. + /// - Parameters: + /// - id: Thread id. + /// - topic: Thread topic. + /// - createdOn: The timestamp when the thread was created. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + /// - createdBy: Id of the thread owner. + /// - deletedOn: The timestamp when the thread was deleted. The timestamp is in RFC3339 format: `yyyy-MM-ddTHH:mm:ssZ`. + public init( + id: String, + topic: String, + createdOn: Iso8601Date, + createdBy: String, + deletedOn: Iso8601Date? = nil + ) { + self.id = id + self.topic = topic + self.createdOn = createdOn + self.createdBy = CommunicationUserIdentifier(identifier: createdBy) + self.deletedOn = deletedOn + } + + // MARK: Codable + + enum CodingKeys: String, CodingKey { + case id + case topic + case createdOn + case createdBy + case deletedOn + } + + /// Initialize a `Thread` structure from decoder + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + self.id = try container.decode(String.self, forKey: .id) + self.topic = try container.decode(String.self, forKey: .topic) + self.createdOn = try container.decode(Iso8601Date.self, forKey: .createdOn) + + // Convert createdBy to CommunicationUserIdentifier + let createdBy = try container.decode(String.self, forKey: .createdBy) + self.createdBy = CommunicationUserIdentifier(identifier: createdBy) + + self.deletedOn = try? container.decode(Iso8601Date.self, forKey: .deletedOn) + } + + /// Encode a `Thread` structure + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) + try container.encode(topic, forKey: .topic) + try container.encode(createdOn, forKey: .createdOn) + + // Encode user object to createdBy string + try container.encode(createdBy.identifier, forKey: .createdBy) + + if deletedOn != nil { try? container.encode(deletedOn, forKey: .deletedOn) } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/ChatClientTests.swift b/sdk/communication/AzureCommunicationChat/Tests/ChatClientTests.swift new file mode 100644 index 00000000..f795a7da --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/ChatClientTests.swift @@ -0,0 +1,276 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCommunicationChat +import AzureCore +import XCTest + +class ChatClientTests: XCTestCase { + /// ChatClient initialized in setup. + private var chatClient: ChatClient! + /// An ACS user id. + private var user: String = TestUtil.user1 + /// Thread topic. + private let topic: String = "General" + + override class func setUp() { + if TestUtil.mode == "playback" { + // Register stubs for playback mode + Recorder.registerStubs() + } + } + + override func setUpWithError() throws { + chatClient = try TestUtil.getChatClient() + } + + /// Helper to create a thread for tests that act on an existing thread. + /// - Parameters: + /// - id: The user id. + /// - topic: The thread topic. + /// - completionHandler: Completion handler that receives the thread id of the created thread. + func createThread( + withUser id: String, + withTopic topic: String, + completionHandler: @escaping (String) -> Void + ) { + let participant = Participant( + id: id, + displayName: "User", + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + let thread = CreateThreadRequest( + topic: topic, + participants: [ + participant + ] + ) + + chatClient.create(thread: thread) { result, _ in + switch result { + case let .success(chatThreadResult): + guard let threadId = chatThreadResult.thread?.id else { + XCTFail("Failed to get thread id") + return + } + + completionHandler(threadId) + case let .failure(error): + XCTFail("Error creating thread: \(error)") + } + } + } + + func test_CreateThread_ResultContainsChatThread() { + let participant = Participant( + id: user, + displayName: "User", + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + let thread = CreateThreadRequest( + topic: topic, + participants: [ + participant + ] + ) + + let expectation = self.expectation(description: "Create thread") + + chatClient.create(thread: thread) { result, httpResponse in + switch result { + case let .success(response): + let chatThread = response.thread + XCTAssertNotNil(response.thread) + XCTAssertEqual(chatThread?.topic, thread.topic) + XCTAssertNotNil(httpResponse?.httpRequest?.headers["repeatability-Request-ID"]) + + if TestUtil.mode == "record" { + Recorder.record(name: Recording.createThread, httpResponse: httpResponse) + } + + case let .failure(error): + XCTFail("Create thread failed with error: \(error)") + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Create thread timed out: \(error)") + } + } + } + + func test_CreateThread_WithOptions_SetsRepeatabilityRequestID() { + let participant = Participant( + id: user, + displayName: "User", + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + let thread = CreateThreadRequest( + topic: topic, + participants: [ + participant + ] + ) + + // Create options without repeatabilityRequestID + let options = Chat.CreateChatThreadOptions(clientRequestId: "test_id") + + let expectation = self.expectation(description: "Create thread") + + chatClient.create(thread: thread, withOptions: options) { result, httpResponse in + switch result { + case .success: + XCTAssertNotNil(httpResponse?.httpRequest?.headers["repeatability-Request-ID"]) + + case let .failure(error): + XCTFail("Create thread failed with error: \(error)") + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Create thread timed out: \(error)") + } + } + } + + func test_GetThread_ReturnsChatThread() { + let expectation = self.expectation(description: "Get thread") + + // Create a thread + createThread(withUser: user, withTopic: topic) { threadId in + // Get the thread + self.chatClient.get(thread: threadId) { result, httpResponse in + switch result { + case let .success(thread): + XCTAssert(thread.topic == self.topic) + XCTAssertNotNil(thread.createdBy) + + if TestUtil.mode == "record" { + Recorder.record(name: Recording.getThread, httpResponse: httpResponse) + } + + case let .failure(error): + XCTFail("Get thread failed with error: \(error)") + } + + expectation.fulfill() + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Get thread timed out: \(error)") + } + } + } + + func test_DeleteThread() { + let expectation = self.expectation(description: "Delete thread") + + // Create a thread + createThread(withUser: user, withTopic: topic) { threadId in + // Delete the thread + self.chatClient.delete(thread: threadId) { result, httpResponse in + switch result { + case .success: + if TestUtil.mode == "record" { + Recorder.record(name: Recording.deleteThread, httpResponse: httpResponse) + } + + // Get the thread and verify deleted + if TestUtil.mode != "playback" { + self.chatClient.get(thread: threadId) { result, _ in + switch result { + case let .success(thread): + XCTAssertNotNil(thread.deletedOn) + + case let .failure(error): + XCTFail("Deleted thread failed with error: \(error)") + } + + expectation.fulfill() + } + } else { + expectation.fulfill() + } + + case let .failure(error): + XCTFail("Delete thread failed: \(error)") + expectation.fulfill() + } + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Delete thread timed out: \(error)") + } + } + } + + func test_ListThreads_ReturnsThreads() { + let expectation = self.expectation(description: "List threads") + + // Create a thread + createThread(withUser: user, withTopic: "Hello World") { _ in + // List threads + self.chatClient.listThreads { result, httpResponse in + switch result { + case let .success(listThreadsResult): + if TestUtil.mode == "record" { + Recorder.record(name: Recording.listThreads, httpResponse: httpResponse) + } + + let threads = listThreadsResult.items + XCTAssertNotNil(threads) + XCTAssertNotNil(threads?.count) + XCTAssertNotEqual(threads?.count, 0) + + case let .failure(error): + XCTFail("List threads failed: \(error)") + } + + expectation.fulfill() + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List threads timed out: \(error)") + } + } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/ChatClientUnitTests.swift b/sdk/communication/AzureCommunicationChat/Tests/ChatClientUnitTests.swift new file mode 100644 index 00000000..4bb883d9 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/ChatClientUnitTests.swift @@ -0,0 +1,318 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCommunicationChat +import AzureCore +import OHHTTPStubsSwift +import XCTest + +class ChatClientUnitTests: XCTestCase { + private var chatClient: ChatClient! + + private let participantId = "test_participant_id" + private let threadId = "test_thread_id" + private let topic = "test topic" + + override func setUpWithError() throws { + chatClient = try TestUtil.getChatClient() + } + + func test_CreateChatThreadClient_ReturnChatThreadClient() { + do { + let threadClient = try chatClient.createClient(forThread: threadId) + XCTAssertEqual(threadClient.threadId, threadId) + } catch _ { + XCTFail("Failed in creating chat thread client") + } + } + + func test_CreateChatThread_ReturnChatThread() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "CreateThreadResponse", ofType: "json") ?? "" + stub(condition: isMethodPOST() && isPath("/chat/threads")) { _ in + fixture(filePath: path, status: 201, headers: nil) + } + + let participant = Participant( + id: "test_participant_id", + displayName: "test name", + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + let request = CreateThreadRequest( + topic: "test topic", + participants: [ + participant + ] + ) + + let expectation = self.expectation(description: "Create chat thread") + + chatClient.create(thread: request) { result, _ in + switch result { + case let .success(response): + guard let thread = response.thread else { + XCTFail("Failed to extract chatThread from response") + return + } + XCTAssert(thread.id == self.threadId) + XCTAssert(thread.topic == request.topic) + XCTAssert(thread.createdBy.identifier == participant.user.identifier) + + case .failure: + XCTFail("Unexpected failure happened in create chat thread") + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Create chat thread timed out: \(error)") + } + } + } + + func test_CreateChatThread_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodPOST() && isPath("/chat/threads")) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let participant = Participant( + id: "test id", + displayName: "test name", + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + let request = CreateThreadRequest( + topic: "test topic", + participants: [ + participant + ] + ) + + let expectation = self.expectation(description: "Create chat thread") + + chatClient.create(thread: request) { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in create chat thread") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Create chat thread timed out: \(error)") + } + } + } + + func test_GetChatThread_ReturnChatThread() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "GetThreadResponse", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + let expectation = self.expectation(description: "Get thread") + + chatClient.get(thread: threadId) { result, _ in + switch result { + case let .success(chatThread): + XCTAssertEqual(chatThread.id, self.threadId) + XCTAssertEqual(chatThread.topic, self.topic) + XCTAssertEqual(chatThread.createdBy.identifier, self.participantId) + + case .failure: + XCTFail() + } + + expectation.fulfill() + } + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Get thread timed out: \(error)") + } + } + } + + func test_GetChatThread_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Get thread") + + chatClient.get(thread: threadId) { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in get thread") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Get thread timed out: \(error)") + } + } + } + + func test_ListChatThreads_ReturnChatThreads() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "ListThreadsResponse", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + let expectation = self.expectation(description: "List threads") + + chatClient.listThreads { result, _ in + switch result { + case let .success(threads): + threads.nextItem { result in + switch result { + case let .success(item): + XCTAssert(item.topic == self.topic) + XCTAssert(item.id == self.threadId) + + case .failure: + XCTFail("Unexpected failure happened in list chat threads") + } + + expectation.fulfill() + } + + case .failure: + XCTFail("Unexpected failure happened in list chat threads") + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List threads timed out: \(error)") + } + } + } + + func test_ListChatThreads_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "List chat threads") + + chatClient.listThreads { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in list chat threads") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List chat threads timed out: \(error)") + } + } + } + + func test_DeleteChatThread_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "NoContent", ofType: "json") ?? "" + stub(condition: isMethodDELETE()) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + let expectation = self.expectation(description: "Delete chat thread") + + chatClient.delete(thread: threadId, completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + + case .failure: + XCTFail("Unexpected failure happened in delete chat thread") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Delete chat thread timed out: \(error)") + } + } + } + + func test_DeleteChatThread_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodDELETE()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Delete chat thread") + + chatClient.delete(thread: threadId, completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in delete chat thread") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Delete chat thread timed out: \(error)") + } + } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/ChatThreadClientTests.swift b/sdk/communication/AzureCommunicationChat/Tests/ChatThreadClientTests.swift new file mode 100644 index 00000000..127687ca --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/ChatThreadClientTests.swift @@ -0,0 +1,592 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCommunicationChat +import AzureCore +import XCTest + +// swiftlint:disable type_body_length +// swiftlint:disable file_length + +class ChatThreadClientTests: XCTestCase { + /// An ACS user id. + private var user1: String = TestUtil.user1 + /// An ACS user id. + private var user2: String = TestUtil.user2 + /// Id of the thread created in setup. + private var threadId: String = "testThreadId" + /// ChatClient initialized in setup. + private var chatClient: ChatClient! + /// ChatThreadClient initialized in setup. + private var chatThreadClient: ChatThreadClient! + /// Initial thread topic. + private let topic: String = "General" + + override class func setUp() { + if TestUtil.mode == "playback" { + // Register stubs for playback mode + Recorder.registerStubs() + } + } + + override func setUpWithError() throws { + // Initialize the chatClient + chatClient = try TestUtil.getChatClient() + + let participant = Participant( + id: user1, + displayName: "User 1", + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + let thread = CreateThreadRequest( + topic: topic, + participants: [ + participant + ] + ) + + let expectation = self.expectation(description: "Create thread") + + // Create a thread for the test + chatClient.create(thread: thread) { result, httpResponse in + switch result { + case let .success(createThreadResult): + // Initialize threadId + self.threadId = (createThreadResult.thread?.id)! + + if TestUtil.mode == "record" { + Recorder.record(name: Recording.createThread, httpResponse: httpResponse) + } + + case let .failure(error): + print("Failed to create thread with error: \(error)") + } + + expectation.fulfill() + } + + wait(for: [expectation], timeout: TestUtil.timeout) + + // Initialize the ChatThreadClient + chatThreadClient = try chatClient.createClient(forThread: threadId) + } + + func test_UpdateTopic() { + let newTopic = "New topic" + let expectation = self.expectation(description: "Update topic") + + // Update topic + chatThreadClient.update(topic: newTopic) { result, httpResponse in + switch result { + case .success: + if TestUtil.mode == "record" { + Recorder.record(name: Recording.updateTopic, httpResponse: httpResponse) + } + + // Get thread and verify topic updated + if TestUtil.mode != "playback" { + self.chatClient.get(thread: self.threadId) { result, _ in + switch result { + case let .success(chatThread): + XCTAssertEqual(chatThread.topic, newTopic) + + case let .failure(error): + XCTFail("Failed to update topic: \(error)") + } + + expectation.fulfill() + } + } else { + expectation.fulfill() + } + + case let .failure(error): + XCTFail("Failed to update topic: \(error)") + expectation.fulfill() + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Update topic timed out: \(error)") + } + } + } + + func test_SendMessage_ReturnsMessageId() { + let testMessage = SendChatMessageRequest( + content: "Hello World!", + senderDisplayName: "User 1", + type: .text + ) + + let expectation = self.expectation(description: "Send message") + + chatThreadClient.send(message: testMessage) { result, httpResponse in + switch result { + case let .success(sendMessageResult): + if TestUtil.mode == "record" { + Recorder.record(name: Recording.sendMessage, httpResponse: httpResponse) + } + XCTAssertNotNil(sendMessageResult.id) + + case let .failure(error): + XCTFail("Send message failed: \(error)") + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send message timed out: \(error)") + } + } + } + + func test_SendMessage_SendsHTML() { + let testMessage = SendChatMessageRequest( + content: "
Hello
", + senderDisplayName: "User 1", + type: .html + ) + + let expectation = self.expectation(description: "Send message") + + chatThreadClient.send(message: testMessage) { result, _ in + switch result { + case let .success(sendMessageResult): + XCTAssertNotNil(sendMessageResult.id) + + case let .failure(error): + XCTFail("Send message failed to send HTML: \(error)") + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send message timed out: \(error)") + } + } + } + + func test_ListMessages_ReturnsMessages() { + let testMessage = SendChatMessageRequest( + content: "Hello World!", + senderDisplayName: "User 1", + type: .text + ) + + let expectation = self.expectation(description: "List messages") + + // Send a couple messages + chatThreadClient.send(message: testMessage) { _, _ in + self.chatThreadClient.send(message: testMessage) { _, _ in + // List messages + self.chatThreadClient.listMessages { result, httpResponse in + switch result { + case let .success(listMessagesResult): + if TestUtil.mode == "record" { + Recorder.record(name: Recording.listMessages, httpResponse: httpResponse) + } + + let messages = listMessagesResult.items + messages?.forEach { message in + if message.type == ChatMessageType.text { + XCTAssertEqual(message.content?.message, testMessage.content) + XCTAssertEqual(message.senderDisplayName, testMessage.senderDisplayName) + } + } + + XCTAssertNotNil(messages) + + case let .failure(error): + XCTFail("List messages failed: \(error)") + } + + expectation.fulfill() + } + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List messages timed out: \(error)") + } + } + } + + func test_SendTypingNotification() { + let expectation = self.expectation(description: "Send typing notification") + + chatThreadClient.sendTypingNotification { result, httpResponse in + switch result { + case .success: + if TestUtil.mode == "record" { + Recorder.record(name: Recording.sendTypingNotification, httpResponse: httpResponse) + } + + case let .failure(error): + XCTFail("Send typing notification failed: \(error)") + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send typing notification timed out: \(error)") + } + } + } + + func test_SendReadReceipt() { + let testMessage = SendChatMessageRequest( + content: "Hello World!", + senderDisplayName: "User 1", + type: .text + ) + + let expectation = self.expectation(description: "Send read receipt") + + // Send message + chatThreadClient.send(message: testMessage) { result, _ in + switch result { + case let .success(sendMessageResult): + // Send read receipt + self.chatThreadClient.sendReadReceipt(forMessage: sendMessageResult.id) { result, httpResponse in + switch result { + case .success: + if TestUtil.mode == "record" { + Recorder.record(name: Recording.sendReadReceipt, httpResponse: httpResponse) + } + + case let .failure(error): + XCTFail("Send read receipt failed: \(error)") + } + + expectation.fulfill() + } + + case let .failure(error): + XCTFail("Send message failed: \(error)") + expectation.fulfill() + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send message timed out: \(error)") + } + } + } + + func test_ListReadReceipts_ReturnsReadReceipts() { + let testMessage = SendChatMessageRequest( + content: "Hello World!", + senderDisplayName: "User 1", + type: .text + ) + + let expectation = self.expectation(description: "Send read receipt") + + // Send message + chatThreadClient.send(message: testMessage) { result, _ in + switch result { + case let .success(sendMessageResult): + // Send read receipt + self.chatThreadClient.sendReadReceipt(forMessage: sendMessageResult.id) { result, _ in + switch result { + case .success: + // List read receipts + self.chatThreadClient.listReadReceipts { result, httpResponse in + switch result { + case let .success(readReceipts): + if TestUtil.mode == "record" { + Recorder.record(name: Recording.listReadReceipts, httpResponse: httpResponse) + } + + readReceipts.items?.forEach { readReceipt in + XCTAssertNotNil(readReceipt.sender) + XCTAssertEqual(readReceipt.chatMessageId, sendMessageResult.id) + } + + XCTAssertNotNil(readReceipts.items) + case let .failure(error): + XCTFail("List read receipts failed: \(error)") + } + + expectation.fulfill() + } + + case let .failure(error): + XCTFail("Send read receipt failed: \(error)") + expectation.fulfill() + } + } + + case let .failure(error): + XCTFail("Send message failed: \(error)") + expectation.fulfill() + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send message timed out: \(error)") + } + } + } + + func test_UpdateChatMessage() { + let testMessage = SendChatMessageRequest( + content: "Hello World!", + senderDisplayName: "User 1", + type: .text + ) + + let expectation = self.expectation(description: "Update message") + + // Send message + chatThreadClient.send(message: testMessage) { result, _ in + switch result { + case let .success(sendMessageResult): + let updatedMessage = UpdateChatMessageRequest( + content: "Some new content" + ) + + // Update message + self.chatThreadClient + .update(message: updatedMessage, messageId: sendMessageResult.id) { result, httpResponse in + switch result { + case .success: + if TestUtil.mode == "record" { + Recorder.record(name: Recording.updateMessage, httpResponse: httpResponse) + } + + // Get message and verify updated + if TestUtil.mode != "playback" { + self.chatThreadClient.get(message: sendMessageResult.id) { result, _ in + switch result { + case let .success(message): + XCTAssertEqual(message.content?.message, updatedMessage.content) + + case let .failure(error): + XCTFail("Get message failed: \(error)") + } + + expectation.fulfill() + } + } else { + expectation.fulfill() + } + + case let .failure(error): + XCTFail("Update message failed: \(error)") + expectation.fulfill() + } + } + + case let .failure(error): + XCTFail("Send message failed: \(error)") + expectation.fulfill() + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send message timed out: \(error)") + } + } + } + + func test_DeleteMessage() { + let testMessage = SendChatMessageRequest( + content: "Hello World!", + senderDisplayName: "User 1", + type: .text + ) + + let expectation = self.expectation(description: "Delete message") + + // Send message + chatThreadClient.send(message: testMessage) { result, _ in + switch result { + case let .success(sendMessageResult): + // Delete message + self.chatThreadClient.delete(message: sendMessageResult.id) { result, httpResponse in + switch result { + case .success: + if TestUtil.mode == "record" { + Recorder.record(name: Recording.deleteMessage, httpResponse: httpResponse) + } + + case let .failure(error): + XCTFail("Delete message failed: \(error)") + } + + expectation.fulfill() + } + + case let .failure(error): + XCTFail("Send message failed: \(error)") + expectation.fulfill() + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Delete message timed out: \(error)") + } + } + } + + func test_AddValidParticipant_ReturnsWithoutErrors() { + let newParticipant = Participant( + id: user2, + displayName: "User 2", + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + let expectation = self.expectation(description: "Add participant") + + // Add a participant + chatThreadClient.add(participants: [newParticipant]) { result, httpResponse in + switch result { + case let .success(addParticipantsResult): + XCTAssertNil(addParticipantsResult.errors) + if TestUtil.mode == "record" { + Recorder.record(name: Recording.addParticipants, httpResponse: httpResponse) + } + + case let .failure(error): + XCTFail("Add participants failed: \(error)") + } + + expectation.fulfill() + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Add participant timed out: \(error)") + } + } + } + + func test_RemoveParticipant() { + let removedParticipant = Participant( + id: user2, + displayName: "User 2", + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + let expectation = self.expectation(description: "Remove participant") + + // Add a participant + chatThreadClient.add(participants: [removedParticipant]) { result, _ in + switch result { + case .success: + // Remove the participant + self.chatThreadClient.remove(participant: removedParticipant.user.identifier) { result, httpResponse in + switch result { + case .success: + if TestUtil.mode == "record" { + Recorder.record(name: Recording.removeParticipant, httpResponse: httpResponse) + } + + case let .failure(error): + XCTFail("Remove participant failed: \(error)") + } + + expectation.fulfill() + } + + case let .failure(error): + XCTFail("Remove participants failed: \(error)") + expectation.fulfill() + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Remove participant timed out: \(error)") + } + } + } + + func test_ListParticipants_ReturnsParticipants() { + let anotherParticipant = Participant( + id: user2, + displayName: "User 2", + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + let expectation = self.expectation(description: "List participants") + + // Add a participant + chatThreadClient.add(participants: [anotherParticipant]) { result, httpResponse in + switch result { + case .success: + // List participants + self.chatThreadClient.listParticipants { result, httpResponse in + if TestUtil.mode == "record" { + Recorder.record(name: Recording.listParticipants, httpResponse: httpResponse) + } + + switch result { + case let .success(participantsResult): + let participants = participantsResult.pageItems + participants?.forEach { participant in + XCTAssertNotNil(participant.user.identifier) + XCTAssertNotNil(participant.displayName) + } + + XCTAssertEqual(participants?.count, 2) + + case let .failure(error): + XCTFail("List participants failed: \(error)") + } + + expectation.fulfill() + } + + case let .failure(error): + XCTFail("Add participants failed: \(error)") + expectation.fulfill() + } + } + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List participants timed out: \(error)") + } + } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/ChatThreadClientUnitTests.swift b/sdk/communication/AzureCommunicationChat/Tests/ChatThreadClientUnitTests.swift new file mode 100644 index 00000000..f9046bdb --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/ChatThreadClientUnitTests.swift @@ -0,0 +1,788 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCommunication +import AzureCommunicationChat +import AzureCore +import OHHTTPStubsSwift +import XCTest + +// swiftlint:disable all +class ChatThreadClientUnitTests: XCTestCase { + private var chatClient: ChatClient! + private var chatThreadClient: ChatThreadClient! + + private let participantId = "test_participant_id" + private let participantName = "test_participant_name" + private let threadId = "test_thread_id" + private let topic = "test topic" + private let messageId = "test_message_id" + + override func setUpWithError() throws { + chatClient = try TestUtil.getChatClient() + chatThreadClient = try chatClient.createClient(forThread: threadId) + } + + func test_UpdateThreadTopic_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "NoContent", ofType: "json") ?? "" + stub(condition: isMethodPATCH()) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + let expectation = self.expectation(description: "Update thread topic") + + chatThreadClient.update(topic: topic, completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + + case .failure: + XCTFail("Unexpected failure happened in update thread topic") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Update thread topic timed out: \(error)") + } + } + } + + func test_UpdateThreadTopic_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodPATCH()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Update thread topic") + + chatThreadClient.update(topic: topic, completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in update thread topic") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Update thread topic timed out: \(error)") + } + } + } + + func test_SendMessage_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "SendMessageResponse", ofType: "json") ?? "" + stub(condition: isMethodPOST()) { _ in + fixture(filePath: path, status: 201, headers: nil) + } + + let messageRequest = SendChatMessageRequest( + content: "Hello world!", + senderDisplayName: "Leo" + ) + + let expectation = self.expectation(description: "Send message") + + chatThreadClient.send(message: messageRequest, completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + XCTAssertEqual(response.id, self.messageId) + + case .failure: + XCTFail("Unexpected failure happened in send message") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send message timed out: \(error)") + } + } + } + + func test_SendMessage_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodPOST()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let messageRequest = SendChatMessageRequest( + content: "Hello world!", + senderDisplayName: "Leo" + ) + + let expectation = self.expectation(description: "Send message") + + chatThreadClient.send(message: messageRequest, completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in send message") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send message timed out: \(error)") + } + } + } + + func test_GetMessage_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "GetMessageResponse", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + let expectation = self.expectation(description: "Get message") + + chatThreadClient.get(message: messageId, completionHandler: { result, _ in + switch result { + case let .success(response): + guard let content = response.content else { + XCTFail("Failed to extract message content from response") + return + } + XCTAssertNotNil(response) + XCTAssertEqual(response.id, self.messageId) + XCTAssertEqual(content.message, "Hello World!") + + case .failure: + XCTFail("Unexpected failure happened in get message") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Get message timed out: \(error)") + } + } + } + + func test_GetMessage_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Get message") + + chatThreadClient.get(message: messageId, completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in get message") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Get message timed out: \(error)") + } + } + } + + func test_ListMessages_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "ListMessagesResponse", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + let expectation = self.expectation(description: "List messages") + + chatThreadClient.listMessages(completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + response.nextItem { result in + switch result { + case let .success(message): + guard let content = message.content else { + XCTFail("Failed to extract message content from response") + return + } + XCTAssertEqual(message.id, self.messageId) + XCTAssertEqual(content.message, "Hello world!") + XCTAssertEqual(message.sender?.identifier, self.participantId) + + case .failure: + XCTFail("Unexpected failure happened in list messages") + } + } + + case .failure: + XCTFail("Unexpected failure happened in list messages") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List messages timed out: \(error)") + } + } + } + + func test_ListMessages_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "List messages") + + chatThreadClient.listMessages(completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in list messages") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List messages timed out: \(error)") + } + } + } + + func test_UpdateMessage_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "NoContent", ofType: "json") ?? "" + stub(condition: isMethodPATCH()) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + let expectation = self.expectation(description: "Update message") + + let message = UpdateChatMessageRequest(content: "update message") + chatThreadClient.update(message: message, messageId: messageId, completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + + case .failure: + XCTFail("Unexpected failure happened in update message") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Update message timed out: \(error)") + } + } + } + + func test_UpdateMessage_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodPATCH()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Update message") + + chatThreadClient.update(topic: topic, completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in update message") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Update message timed out: \(error)") + } + } + } + + func test_DeleteMessage_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "NoContent", ofType: "json") ?? "" + stub(condition: isMethodDELETE()) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + let expectation = self.expectation(description: "Delete message") + + chatThreadClient.delete(message: messageId, completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + + case .failure: + XCTFail("Unexpected failure happened in delete message") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Delete message timed out: \(error)") + } + } + } + + func test_DeleteMessage_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodDELETE()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Delete message") + + chatThreadClient.delete(message: messageId, completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in delete message") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Delete message timed out: \(error)") + } + } + } + + func test_ListParticipants_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "ListParticipantsResponse", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + let expectation = self.expectation(description: "List participants") + + chatThreadClient.listParticipants(completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + response.nextItem { result in + switch result { + case let .success(participant): + guard let displayName = participant.displayName else { + XCTFail("Failed to extract senderDisplayName from response") + return + } + XCTAssertEqual(participant.user.identifier, self.participantId) + XCTAssertEqual(displayName, self.participantName) + + case .failure: + XCTFail("Unexpected failure happened in list participants") + } + } + + case .failure: + XCTFail("Unexpected failure happened in list participants") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List participants timed out: \(error)") + } + } + } + + func test_ListParticipants_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "List participants") + + chatThreadClient.listParticipants(completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in list participants") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List participants timed out: \(error)") + } + } + } + + func test_AddParticipant_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "AddParticipantResponse", ofType: "json") ?? "" + stub(condition: isMethodPOST()) { _ in + fixture(filePath: path, status: 201, headers: nil) + } + + let expectation = self.expectation(description: "Add participant") + + let participant = Participant( + id: participantId, + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + chatThreadClient.add(participants: [participant], completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + + case .failure: + XCTFail("Unexpected failure happened in Add participant") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Add participant timed out: \(error)") + } + } + } + + func test_AddParticipant_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodPOST()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Add participant") + + let participant = Participant( + id: participantId, + shareHistoryTime: Iso8601Date(string: "2016-04-13T00:00:00Z")! + ) + + chatThreadClient.add(participants: [participant], completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in add participant") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Add participant timed out: \(error)") + } + } + } + + func test_RemoveParticipant_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "NoContent", ofType: "json") ?? "" + stub(condition: isMethodDELETE()) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + let expectation = self.expectation(description: "Remove Participant") + + chatThreadClient.remove(participant: participantId, completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + + case .failure: + XCTFail("Unexpected failure happened in remove participant") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Remove participant timed out: \(error)") + } + } + } + + func test_RemoveParticipant_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodDELETE()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Remove Participant") + + chatThreadClient.remove(participant: participantId, completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in remove participant") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Remove participant timed out: \(error)") + } + } + } + + func test_SendTypingNotification_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "NoContent", ofType: "json") ?? "" + stub(condition: isMethodPOST()) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + let expectation = self.expectation(description: "Send typing notification") + + chatThreadClient.sendTypingNotification(completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + + case .failure: + XCTFail("Unexpected failure happened in send typing notification") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send typing notification timed out: \(error)") + } + } + } + + func test_SendTypingNotification_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodPOST()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Send typing notification") + + chatThreadClient.sendTypingNotification(completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in send typing notification") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send typing notification timed out: \(error)") + } + } + } + + func test_SendReadReceipt_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "NoContent", ofType: "json") ?? "" + stub(condition: isMethodPOST()) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + let expectation = self.expectation(description: "Send read receipt") + + chatThreadClient.sendReadReceipt(forMessage: messageId, completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + + case .failure: + XCTFail("Unexpected failure happened in send read receipt") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send read receipt timed out: \(error)") + } + } + } + + func test_SendReadReceipt_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodPOST()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "Send read receipt") + + chatThreadClient.sendReadReceipt(forMessage: messageId, completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in send read receipt") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("Send read receipt timed out: \(error)") + } + } + } + + func test_ListReadReceipts_ReturnSuccess() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "ListReadReceiptResponse", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + let expectation = self.expectation(description: "List read receipts") + + chatThreadClient.listReadReceipts(completionHandler: { result, _ in + switch result { + case let .success(response): + XCTAssertNotNil(response) + response.nextItem { result in + switch result { + case let .success(readReceipt): + XCTAssertEqual(readReceipt.sender.identifier, self.participantId) + XCTAssertEqual(readReceipt.chatMessageId, self.messageId) + XCTAssertNotNil(readReceipt.readOn) + + case .failure: + XCTFail("Unexpected failure happened in list read receipts") + } + } + + case .failure: + XCTFail("Unexpected failure happened in list read receipts") + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List read receipts timed out: \(error)") + } + } + } + + func test_ListReadReceipts_ReturnError() { + let bundle = Bundle(for: type(of: self)) + let path = bundle.path(forResource: "UnauthorizedError", ofType: "json") ?? "" + stub(condition: isMethodGET()) { _ in + fixture(filePath: path, status: 401, headers: nil) + } + + let expectation = self.expectation(description: "List read receipts") + + chatThreadClient.listReadReceipts(completionHandler: { result, _ in + switch result { + case .success: + XCTFail("Unexpected failure happened in list read receipt") + + case let .failure(error): + XCTAssertNotNil(error) + } + + expectation.fulfill() + }) + + waitForExpectations(timeout: TestUtil.timeout) { error in + if let error = error { + XCTFail("List read receipts timed out: \(error)") + } + } + } +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Info.plist b/sdk/communication/AzureCommunicationChat/Tests/Info.plist new file mode 100644 index 00000000..64d65ca4 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/AddParticipantResponse.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/AddParticipantResponse.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/AddParticipantResponse.json @@ -0,0 +1 @@ +{} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/CreateThreadResponse.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/CreateThreadResponse.json new file mode 100644 index 00000000..08a71559 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/CreateThreadResponse.json @@ -0,0 +1,8 @@ +{ + "chatThread": { + "id": "test_thread_id", + "topic": "test topic", + "createdOn": "2021-01-08T01:49:05Z", + "createdBy": "test_participant_id" + } +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/GetMessageResponse.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/GetMessageResponse.json new file mode 100644 index 00000000..9d131314 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/GetMessageResponse.json @@ -0,0 +1,12 @@ +{ + "id": "test_message_id", + "type": "text", + "sequenceId": "3", + "version": "1610070518313", + "content": { + "message": "Hello World!" + }, + "senderDisplayName": "User 1", + "createdOn": "2021-01-08T01:48:38Z", + "senderId": "test_sender_id" +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/GetThreadResponse.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/GetThreadResponse.json new file mode 100644 index 00000000..39951178 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/GetThreadResponse.json @@ -0,0 +1,7 @@ +{ + "id": "test_thread_id", + "topic": "test topic", + "createdOn": "2020-10-30T10:50:50Z", + "createdBy": "test_participant_id", + "deletedOn": "2020-10-30T10:50:50Z" +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListMessagesResponse.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListMessagesResponse.json new file mode 100644 index 00000000..8ef06819 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListMessagesResponse.json @@ -0,0 +1,20 @@ +{ + "value": [ + { + "id": "test_message_id", + "type": "text", + "sequenceId": "4", + "version": "string", + "content": { + "message": "Hello world!" + }, + "senderDisplayName": "Jane", + "createdOn": "2020-10-30T10:50:50Z", + "senderId": "test_participant_id", + "deletedOn": "2020-10-30T10:50:50Z", + "editedOn": "2020-10-30T10:50:50Z" + } + ], + "nextLink": "string" +} + diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListParticipantsResponse.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListParticipantsResponse.json new file mode 100644 index 00000000..2aeed0e5 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListParticipantsResponse.json @@ -0,0 +1,10 @@ +{ + "value": [ + { + "id": "test_participant_id", + "displayName": "test_participant_name", + "shareHistoryTime": "2020-10-30T10:50:50Z" + } + ], + "nextLink": "string" +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListReadReceiptResponse.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListReadReceiptResponse.json new file mode 100644 index 00000000..2fe04700 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListReadReceiptResponse.json @@ -0,0 +1,10 @@ +{ + "value": [ + { + "senderId": "test_participant_id", + "chatMessageId": "test_message_id", + "readOn": "2020-10-30T10:50:50Z" + } + ], + "nextLink": "string" +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListThreadsResponse.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListThreadsResponse.json new file mode 100644 index 00000000..4b28afc4 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/ListThreadsResponse.json @@ -0,0 +1,11 @@ +{ + "value": [ + { + "id": "test_thread_id", + "topic": "test topic", + "deletedOn": "2020-10-30T10:50:50Z", + "lastMessageReceivedOn": "2020-10-30T10:50:50Z" + } + ], + "nextLink": "string" +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/NoContent.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/NoContent.json new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/NoContent.json @@ -0,0 +1 @@ + diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/SendMessageResponse.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/SendMessageResponse.json new file mode 100644 index 00000000..39e93523 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/SendMessageResponse.json @@ -0,0 +1,3 @@ +{ + "id": "test_message_id" +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/UnauthorizedError.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/UnauthorizedError.json new file mode 100644 index 00000000..dc934477 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Mocks/UnauthorizedError.json @@ -0,0 +1,5 @@ +{ + "code": "401", + "message": "Unauthorized", + "target": "test_participant_id" +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/RecordingUtil.swift b/sdk/communication/AzureCommunicationChat/Tests/Util/RecordingUtil.swift new file mode 100644 index 00000000..e1f4042b --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/RecordingUtil.swift @@ -0,0 +1,206 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- + +import AzureCore +import Foundation +import OHHTTPStubsSwift + +class Recorder { + /// Remove ids from response data + /// - Parameter data: The string to sanitize. + private static func sanitize(data: String) throws -> String { + let patterns = [ + ("\\\"id\\\":\\\".*?\\\"", "\\\"id\\\":\\\"sanitized\\\""), + ("\\\"createdBy\\\":\\\".*?\\\"", "\\\"createdBy\\\":\\\"sanitized\\\""), + ("\\\"senderId\\\":\\\".*?\\\"", "\\\"senderId\\\":\\\"sanitized\\\""), + ("\\\"initiator\\\":\\\".*?\\\"", "\\\"initator\\\":\\\"sanitized\\\""), + ("\\\"chatMessageId\\\":\\\".*?\\\"", "\\\"chatMessageId\\\":\\\"sanitized\\\"") + ] + var sanitized = data + for (pattern, template) in patterns { + sanitized = try sanitize(data: sanitized, pattern: pattern, template: template) + } + return sanitized + } + + private static func sanitize(data: String, pattern: String, template: String) throws -> String { + let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive) + return regex.stringByReplacingMatches( + in: data, + range: NSRange(0 ..< data.utf16.count), + withTemplate: template + ) + } + + /// Writes an HTTPResponse to a file for playback. + /// - Parameters: + /// - name: The name of the recording, used as the filename. + /// - httpResponse: The HTTPResponse returned by the request. + public static func record( + name: Recording, + httpResponse: HTTPResponse? + ) { + guard let response = httpResponse else { + return + } + + do { + // Get filepath + var url = URL(fileURLWithPath: #filePath) + url.deleteLastPathComponent() + var path = url.path + path.append("/Recordings/\(name).json") + + // Create recording file, will overwrite existing + FileManager.default.createFile(atPath: path, contents: nil) + + // Get response body from data + guard let responseData = String(data: response.data!, encoding: .utf8) else { + return + } + + // Remove ids from the response + let sanitized = try sanitize(data: responseData) + + // Write response to file + try sanitized.write(toFile: path, atomically: true, encoding: .utf8) + } catch { + print(error.localizedDescription) + } + } + + /// Register a stub for each ACS call + public static func registerStubs() { + for recording in Recording.allCases { + register(stub: recording) + } + } + + /// Registers a stub for the given recording. + /// - Parameter recording: The recording to stub + private static func register(stub recording: Recording) { + let bundle = Bundle(for: Self.self) + let path = bundle.path(forResource: recording.rawValue, ofType: "json")! + + switch recording { + case Recording.addParticipants: + stub(condition: isMethodPOST() && pathEndsWith("/participants/:add")) { _ in + fixture(filePath: path, status: 201, headers: nil) + } + + case Recording.createThread: + stub(condition: isMethodPOST() && pathEndsWith("/chat/threads")) { _ in + fixture(filePath: path, status: 201, headers: nil) + } + + case Recording.deleteMessage: + stub(condition: isMethodDELETE() && pathMatches("//messages//")) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + case Recording.deleteThread: + stub(condition: isMethodDELETE() && pathStartsWith("/chat/threads/")) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + case Recording.getThread: + stub(condition: isMethodGET() && pathStartsWith("/chat/threads/")) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + case Recording.removeParticipant: + stub(condition: isMethodDELETE() && pathMatches("//participants//")) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + case Recording.sendMessage: + stub(condition: isMethodPOST() && pathEndsWith("/messages")) { _ in + fixture(filePath: path, status: 201, headers: nil) + } + + case Recording.sendReadReceipt: + stub(condition: isMethodPOST() && pathEndsWith("/readReceipts")) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + case Recording.sendTypingNotification: + stub(condition: isMethodPOST() && pathEndsWith("/typing")) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + case Recording.updateMessage: + stub(condition: isMethodPATCH() && pathMatches("/messages/")) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + case Recording.updateTopic: + stub(condition: isMethodPATCH() && pathStartsWith("/chat/threads")) { _ in + fixture(filePath: path, status: 204, headers: nil) + } + + case Recording.listParticipants: + stub(condition: isMethodGET() && pathEndsWith("/participants")) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + case Recording.listMessages: + stub(condition: isMethodGET() && pathEndsWith("/messages")) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + case Recording.listThreads: + stub(condition: isMethodGET() && pathEndsWith("/threads")) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + + case Recording.listReadReceipts: + stub(condition: isMethodGET() && pathEndsWith("/readReceipts")) { _ in + fixture(filePath: path, status: 200, headers: nil) + } + } + } +} + +/// Names for stubbing network calls +enum Recording: String, CaseIterable { + // ChatClient + case createThread + case getThread + case deleteThread + // ChatThreadClient + case updateTopic + case sendReadReceipt + case sendTypingNotification + case sendMessage + case updateMessage + case deleteMessage + case addParticipants + case removeParticipant + case listParticipants + case listMessages + case listThreads + case listReadReceipts +} diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/addParticipants.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/addParticipants.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/addParticipants.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/createThread.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/createThread.json new file mode 100644 index 00000000..7e81ad4d --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/createThread.json @@ -0,0 +1 @@ +{"chatThread":{"id":"sanitized","topic":"General","createdOn":"2021-01-26T02:42:15Z","createdBy":"sanitized"}} \ No newline at end of file diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/deleteMessage.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/deleteMessage.json new file mode 100644 index 00000000..e69de29b diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/deleteThread.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/deleteThread.json new file mode 100644 index 00000000..e69de29b diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/getThread.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/getThread.json new file mode 100644 index 00000000..c0e88027 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/getThread.json @@ -0,0 +1 @@ +{"id":"sanitized","topic":"General","createdOn":"2021-01-26T02:41:36Z","createdBy":"sanitized"} \ No newline at end of file diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listMessages.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listMessages.json new file mode 100644 index 00000000..0a50668a --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listMessages.json @@ -0,0 +1 @@ +{"value":[{"id":"sanitized","type":"text","sequenceId":"4","version":"1611628909524","content":{"message":"Hello World!"},"senderDisplayName":"User 1","createdOn":"2021-01-26T02:41:49Z","senderId":"sanitized"},{"id":"sanitized","type":"text","sequenceId":"3","version":"1611628908993","content":{"message":"Hello World!"},"senderDisplayName":"User 1","createdOn":"2021-01-26T02:41:48Z","senderId":"sanitized"},{"id":"sanitized","type":"topicUpdated","sequenceId":"2","version":"1611628907883","content":{"topic":"General","initator":"sanitized"},"createdOn":"2021-01-26T02:41:47Z","senderId":"sanitized"},{"id":"sanitized","type":"participantAdded","sequenceId":"1","version":"1611628907852","content":{"participants":[{"id":"sanitized","displayName":"User 1","shareHistoryTime":"1970-01-01T00:00:00Z"}],"initator":"sanitized"},"createdOn":"2021-01-26T02:41:47Z","senderId":"sanitized"}]} \ No newline at end of file diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listParticipants.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listParticipants.json new file mode 100644 index 00000000..d403cf1f --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listParticipants.json @@ -0,0 +1 @@ +{"value":[{"id":"sanitized","displayName":"User 1","shareHistoryTime":"1970-01-01T00:00:00Z"},{"id":"sanitized","displayName":"User 2","shareHistoryTime":"2016-04-13T00:00:00Z"}]} \ No newline at end of file diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listReadReceipts.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listReadReceipts.json new file mode 100644 index 00000000..1fb62017 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listReadReceipts.json @@ -0,0 +1 @@ +{"value":[{"senderId":"sanitized","chatMessageId":"sanitized","readOn":"2021-01-26T02:41:57Z"}]} \ No newline at end of file diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listThreads.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listThreads.json new file mode 100644 index 00000000..adf13018 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/listThreads.json @@ -0,0 +1 @@ +{"value":[{"id":"sanitized","topic":"Hello World","lastMessageReceivedOn":"2021-01-26T02:41:39Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:41:37Z"},{"id":"sanitized","topic":"General","deletedOn":"2021-01-26T02:41:35Z","lastMessageReceivedOn":"2021-01-26T02:41:34Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:41:32Z"},{"id":"sanitized","topic":"New topic","lastMessageReceivedOn":"2021-01-26T02:36:14Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:36:10Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:36:08Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:36:05Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:36:02Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:36:01Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:35:55Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:35:53Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:35:48Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:35:44Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:35:43Z"},{"id":"sanitized","topic":"Hello World","lastMessageReceivedOn":"2021-01-26T02:35:39Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:35:37Z"},{"id":"sanitized","topic":"General","deletedOn":"2021-01-26T02:35:35Z","lastMessageReceivedOn":"2021-01-26T02:35:34Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:35:33Z"},{"id":"sanitized","topic":"New topic","lastMessageReceivedOn":"2021-01-26T02:31:27Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:31:23Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:31:20Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:31:17Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:31:14Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:31:13Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:31:07Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:31:05Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:31:00Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:30:57Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:30:56Z"},{"id":"sanitized","topic":"Hello World","lastMessageReceivedOn":"2021-01-26T02:30:52Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:30:50Z"},{"id":"sanitized","topic":"General","deletedOn":"2021-01-26T02:30:48Z","lastMessageReceivedOn":"2021-01-26T02:30:47Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:30:45Z"},{"id":"sanitized","topic":"New topic","lastMessageReceivedOn":"2021-01-26T02:12:44Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:41Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:38Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:34Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:32Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:30Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:24Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:22Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:17Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:14Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:13Z"},{"id":"sanitized","topic":"Hello World","lastMessageReceivedOn":"2021-01-26T02:12:09Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:07Z"},{"id":"sanitized","topic":"General","deletedOn":"2021-01-26T02:12:05Z","lastMessageReceivedOn":"2021-01-26T02:12:04Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:12:03Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:09:54Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:08:54Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T02:04:31Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:57:08Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:54:28Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:52:20Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:52:05Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:46:05Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:32:33Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:14:51Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:13:14Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:10:14Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:05:16Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T01:04:16Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T00:59:46Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T00:57:15Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T00:53:40Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T00:52:24Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T00:48:32Z"},{"id":"sanitized","topic":"General","lastMessageReceivedOn":"2021-01-26T00:46:08Z"}]} \ No newline at end of file diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/removeParticipant.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/removeParticipant.json new file mode 100644 index 00000000..e69de29b diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/sendMessage.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/sendMessage.json new file mode 100644 index 00000000..31360023 --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/sendMessage.json @@ -0,0 +1 @@ +{"id":"sanitized"} \ No newline at end of file diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/sendReadReceipt.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/sendReadReceipt.json new file mode 100644 index 00000000..e69de29b diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/sendTypingNotification.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/sendTypingNotification.json new file mode 100644 index 00000000..e69de29b diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/updateMessage.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/updateMessage.json new file mode 100644 index 00000000..e69de29b diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/updateTopic.json b/sdk/communication/AzureCommunicationChat/Tests/Util/Recordings/updateTopic.json new file mode 100644 index 00000000..e69de29b diff --git a/sdk/communication/AzureCommunicationChat/Tests/Util/TestUtil.swift b/sdk/communication/AzureCommunicationChat/Tests/Util/TestUtil.swift new file mode 100644 index 00000000..1dc27bac --- /dev/null +++ b/sdk/communication/AzureCommunicationChat/Tests/Util/TestUtil.swift @@ -0,0 +1,51 @@ +// -------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// The MIT License (MIT) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the ""Software""), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// -------------------------------------------------------------------------- +import AzureCommunication +import AzureCommunicationChat +import Foundation + +class TestUtil { + public static let mode: String = "playback" + public static let user1: String = "id:1" + public static let user2: String = "id:2" + public static let timeout: TimeInterval = 10.0 + + /// Creates and returns a ChatClient + public static func getChatClient() throws -> ChatClient { + let endpoint = "https://endpoint" + let token = generateToken() + let credential = try CommunicationTokenCredential(token: token) + let options = AzureCommunicationChatClientOptions() + + return try ChatClient(endpoint: endpoint, credential: credential, withOptions: options) + } +} + +func generateToken() -> String { + let fakeValue = "{\"iss\":\"ACS\",\"iat\": 1608152725,\"exp\": 1739688725,\"aud\": \"\",\"sub\": \"\"}" + .base64EncodedString() + return "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9." + fakeValue + ".EMS0ExXqRuobm34WKJE8mAfZ7KppU5kEHl0OFdyree8" +}