diff --git a/AliyunpanSDK.xcodeproj/project.pbxproj b/AliyunpanSDK.xcodeproj/project.pbxproj index 6cdc15f..917a8bc 100644 --- a/AliyunpanSDK.xcodeproj/project.pbxproj +++ b/AliyunpanSDK.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ F498215E2B188A6D006559CC /* GetVipFeatureTrial.swift in Sources */ = {isa = PBXBuildFile; fileRef = F498213F2B188A6D006559CC /* GetVipFeatureTrial.swift */; }; F49821602B188C4C006559CC /* AliyunpanSpaceInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = F498215F2B188C4C006559CC /* AliyunpanSpaceInfo.swift */; }; F4B3F7152B202CB500D9E122 /* DownloaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4B3F7142B202CB500D9E122 /* DownloaderTests.swift */; }; + F4B3F7332B29859100D9E122 /* CredentialTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4B3F7322B29859100D9E122 /* CredentialTests.swift */; }; F4C6F2312B060C4B003A06B3 /* AliyunpanSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4C6F2262B060C4B003A06B3 /* AliyunpanSDK.framework */; }; F4E9F9692B148ABA00DC8DBF /* Crypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4E9F9672B148ABA00DC8DBF /* Crypto.swift */; }; F4E9F96A2B148ABA00DC8DBF /* URL+AliyunpanSDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4E9F9682B148ABA00DC8DBF /* URL+AliyunpanSDK.swift */; }; @@ -137,6 +138,7 @@ F498213F2B188A6D006559CC /* GetVipFeatureTrial.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetVipFeatureTrial.swift; sourceTree = ""; }; F498215F2B188C4C006559CC /* AliyunpanSpaceInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AliyunpanSpaceInfo.swift; sourceTree = ""; }; F4B3F7142B202CB500D9E122 /* DownloaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloaderTests.swift; sourceTree = ""; }; + F4B3F7322B29859100D9E122 /* CredentialTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CredentialTests.swift; sourceTree = ""; }; F4C6F2262B060C4B003A06B3 /* AliyunpanSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AliyunpanSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F4C6F2302B060C4B003A06B3 /* AliyunpanSDKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AliyunpanSDKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F4E9F9672B148ABA00DC8DBF /* Crypto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Crypto.swift; sourceTree = ""; }; @@ -255,6 +257,7 @@ children = ( F47FADDC2B14767D00EC0D8D /* AliyunpanSDKTests.swift */, F49745FE2B1F100C0043A4D7 /* AliyunpanClientTests.swift */, + F4B3F7322B29859100D9E122 /* CredentialTests.swift */, F47FADDB2B14767D00EC0D8D /* CryptoTests.swift */, F47FADDD2B14767D00EC0D8D /* HTTPRequestTests.swift */, F4B3F7142B202CB500D9E122 /* DownloaderTests.swift */, @@ -552,6 +555,7 @@ F47FADFD2B14779200EC0D8D /* CryptoTests.swift in Sources */, F4EE794A2B1F06A80061DB13 /* JSONTest.swift in Sources */, F47FADFF2B14779900EC0D8D /* HTTPRequestTests.swift in Sources */, + F4B3F7332B29859100D9E122 /* CredentialTests.swift in Sources */, F4B3F7152B202CB500D9E122 /* DownloaderTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/AliyunpanSDK/AliyunpanClient.swift b/Sources/AliyunpanSDK/AliyunpanClient.swift index 48cef04..a487954 100644 --- a/Sources/AliyunpanSDK/AliyunpanClient.swift +++ b/Sources/AliyunpanSDK/AliyunpanClient.swift @@ -38,7 +38,7 @@ public class AliyunpanClient { } @MainActor - private var token: AliyunpanToken? { + var token: AliyunpanToken? { willSet { if token != newValue, let data = try? JSONParameterEncoder().encode(newValue) { diff --git a/Sources/AliyunpanSDK/AliyunpanScope/File/GetFileList.swift b/Sources/AliyunpanSDK/AliyunpanScope/File/GetFileList.swift index 5fb65e1..cbdd59c 100644 --- a/Sources/AliyunpanSDK/AliyunpanScope/File/GetFileList.swift +++ b/Sources/AliyunpanSDK/AliyunpanScope/File/GetFileList.swift @@ -24,13 +24,13 @@ extension AliyunpanFileScope { /// 分页标记 public var marker: String? /// created_at, updated_at, name, size, name_enhanced - public var order_by: String? + public var order_by: OrderBy? /// DESC ASC - public var order_direction: String? + public var order_direction: OrderDirection? /// 分类,目前有枚举:video | doc | audio | zip | others | image, 可任意组合,按照逗号分割,例如 video,doc,audio, image,doc - public var category: String? + public var category: AliyunpanFile.FileCategory? /// all | file | folder, 默认所有类型, type为folder时,category不做检查 - public var type: String? + public var type: AliyunpanFile.FileType? /// 生成的视频缩略图截帧时间,单位ms,默认120000ms public var video_thumbnail_time: Int? /// 生成的视频缩略图宽度,默认480px @@ -40,7 +40,7 @@ extension AliyunpanFileScope { /// 当填 * 时,返回文件所有字段 public var fields: String? - public init(drive_id: String, parent_file_id: String, limit: Int? = nil, marker: String? = nil, order_by: String? = nil, order_direction: String? = nil, category: String? = nil, type: String? = nil, video_thumbnail_time: Int? = nil, video_thumbnail_width: Int? = nil, image_thumbnail_width: Int? = nil, fields: String? = nil) { + public init(drive_id: String, parent_file_id: String, limit: Int? = nil, marker: String? = nil, order_by: OrderBy? = nil, order_direction: OrderDirection? = nil, category: AliyunpanFile.FileCategory? = nil, type: AliyunpanFile.FileType? = nil, video_thumbnail_time: Int? = nil, video_thumbnail_width: Int? = nil, image_thumbnail_width: Int? = nil, fields: String? = nil) { self.drive_id = drive_id self.parent_file_id = parent_file_id self.limit = limit diff --git a/Sources/AliyunpanSDK/AliyunpanScope/File/GetStarredList.swift b/Sources/AliyunpanSDK/AliyunpanScope/File/GetStarredList.swift index 4b4942f..d5f7cab 100644 --- a/Sources/AliyunpanSDK/AliyunpanScope/File/GetStarredList.swift +++ b/Sources/AliyunpanSDK/AliyunpanScope/File/GetStarredList.swift @@ -22,27 +22,27 @@ extension AliyunpanFileScope { /// 分页标记 public var marker: String? /// created_at, updated_at, name, size - public var order_by: String? + public var order_by: OrderBy? + /// DESC ASC + public var order_direction: OrderDirection? /// 生成的视频缩略图截帧时间,单位ms,默认120000ms public var video_thumbnail_time: Int? /// 生成的视频缩略图宽度,默认480px public var video_thumbnail_width: Int? /// 生成的图片缩略图宽度,默认480px public var image_thumbnail_width: Int? - /// DESC ASC - public var order_direction: String? /// file 或 folder , 默认所有类型 - public var type: String? + public var type: AliyunpanFile.FileType? - public init(drive_id: String, limit: Int? = nil, marker: String? = nil, order_by: String? = nil, video_thumbnail_time: Int? = nil, video_thumbnail_width: Int? = nil, image_thumbnail_width: Int? = nil, order_direction: String? = nil, type: String? = nil) { + public init(drive_id: String, limit: Int? = nil, marker: String? = nil, order_by: OrderBy? = nil, order_direction: OrderDirection? = nil, video_thumbnail_time: Int? = nil, video_thumbnail_width: Int? = nil, image_thumbnail_width: Int? = nil, type: AliyunpanFile.FileType? = nil) { self.drive_id = drive_id self.limit = limit self.marker = marker self.order_by = order_by + self.order_direction = order_direction self.video_thumbnail_time = video_thumbnail_time self.video_thumbnail_width = video_thumbnail_width self.image_thumbnail_width = image_thumbnail_width - self.order_direction = order_direction self.type = type } } diff --git a/Sources/AliyunpanSDK/AliyunpanScope/File/SearchFile.swift b/Sources/AliyunpanSDK/AliyunpanScope/File/SearchFile.swift index 2dec0d8..036d09a 100644 --- a/Sources/AliyunpanSDK/AliyunpanScope/File/SearchFile.swift +++ b/Sources/AliyunpanSDK/AliyunpanScope/File/SearchFile.swift @@ -24,7 +24,7 @@ extension AliyunpanFileScope { /// 查询语句,样例:固定目录搜索,只搜索一级 parent_file_id = '123' 精确查询 name = '123' 模糊匹配 name match '123' 搜索指定后缀文件 file_extension = 'apk' 范围查询 created_at < '2019-01-14T00:00:00' 复合查询: type = 'folder' or name = '123' parent_file_id = 'root' and name = '123' and category = 'video' public let query: String? /// created_at ASC | DESC updated_at ASC | DESC name ASC | DESC size ASC | DESC - public let order_by: String? + public let order_by: OrderBy? /// 生成的视频缩略图截帧时间,单位ms,默认120000ms public let video_thumbnail_time: Int? /// 生成的视频缩略图宽度,默认480px @@ -34,7 +34,7 @@ extension AliyunpanFileScope { /// 是否返回总数 public let return_total_count: Bool? - public init(drive_id: String, limit: Int? = nil, marker: String? = nil, query: String? = nil, order_by: String? = nil, video_thumbnail_time: Int? = nil, video_thumbnail_width: Int? = nil, image_thumbnail_width: Int? = nil, return_total_count: Bool? = nil) { + public init(drive_id: String, limit: Int?, marker: String?, query: String?, order_by: OrderBy?, video_thumbnail_time: Int?, video_thumbnail_width: Int?, image_thumbnail_width: Int?, return_total_count: Bool?) { self.drive_id = drive_id self.limit = limit self.marker = marker diff --git a/Tests/AliyunpanSDKTests/AliyunpanClientTests.swift b/Tests/AliyunpanSDKTests/AliyunpanClientTests.swift index a92f0ea..8fda086 100644 --- a/Tests/AliyunpanSDKTests/AliyunpanClientTests.swift +++ b/Tests/AliyunpanSDKTests/AliyunpanClientTests.swift @@ -8,4 +8,28 @@ import XCTest @testable import AliyunpanSDK -class AliyunpanClientTests: XCTestCase {} +class AliyunpanClientTests: XCTestCase { + @MainActor func testToken() { + let client1 = AliyunpanClient(.init(appId: "app", scope: "scope", identifier: "user1", credentials: .pkce)) + let client2 = AliyunpanClient(.init(appId: "app", scope: "scope", identifier: "user2", credentials: .pkce)) + let client3 = AliyunpanClient(.init(appId: "app", scope: "scope", credentials: .pkce)) + + let now = Date() + let token = AliyunpanToken( + token_type: "token_type1", + access_token: "access_token1", + refresh_token: "refresh_token1", + expires_in: now.timeIntervalSince1970) + client1.token = token + XCTAssertEqual(client1.accessToken, "access_token1") + XCTAssertEqual(client1.token?.token_type, "token_type1") + XCTAssertEqual(client1.token?.refresh_token, "refresh_token1") + XCTAssertEqual(client1.token?.expires_in, now.timeIntervalSince1970) + XCTAssertEqual(client2.accessToken, nil) + XCTAssertEqual(client3.accessToken, nil) + client1.cleanToken() + XCTAssertEqual(client1.accessToken, nil) + XCTAssertEqual(client2.accessToken, nil) + XCTAssertEqual(client3.accessToken, nil) + } +} diff --git a/Tests/AliyunpanSDKTests/CredentialTests.swift b/Tests/AliyunpanSDKTests/CredentialTests.swift new file mode 100644 index 0000000..54ff22a --- /dev/null +++ b/Tests/AliyunpanSDKTests/CredentialTests.swift @@ -0,0 +1,24 @@ +// +// CredentialTests.swift +// AliyunpanSDKTests +// +// Created by zhaixian on 2023/12/13. +// + +import Foundation + +import XCTest +@testable import AliyunpanSDK + +class TestBizServer: AliyunpanBizServer { + func requestToken(appId: String, authCode: String) async throws -> AliyunpanToken { + return .init(token_type: "", access_token: "", refresh_token: nil, expires_in: 0) + } +} + +class CredentialTests: XCTestCase { + func testCredential() throws { + XCTAssertTrue(AliyunpanCredentials.pkce.implement is AliyunpanPKCECredentials) + XCTAssertTrue(AliyunpanCredentials.server(TestBizServer()).implement is AliyunpanServerCredentials) + } +} diff --git a/Tests/AliyunpanSDKTests/HTTPRequestTests.swift b/Tests/AliyunpanSDKTests/HTTPRequestTests.swift index 215beb4..2310b0c 100644 --- a/Tests/AliyunpanSDKTests/HTTPRequestTests.swift +++ b/Tests/AliyunpanSDKTests/HTTPRequestTests.swift @@ -8,6 +8,13 @@ import XCTest @testable import AliyunpanSDK +extension Array where Element == URLQueryItem { + subscript(key: String) -> String? { + first(where: { $0.name == key })?.value + } + +} + class HTTPRequestTests: XCTestCase { func testURLExtension() throws { let url = URL(string: "https://alipan.com?a=1&b=2&c=3&d=4")! @@ -27,7 +34,7 @@ class HTTPRequestTests: XCTestCase { } func testHTTPHeader1() throws { - let request = HTTPRequest(command: AliyunpanScope.User.GetUsersInfo()) + let request = HTTPRequest(command: AliyunpanScope.User.GetDriveInfo()) let urlRequest = try request.asURLRequest() XCTAssertEqual(urlRequest.headers.count, HTTPHeaders.default.count) HTTPHeaders.default.forEach { @@ -36,7 +43,7 @@ class HTTPRequestTests: XCTestCase { } func testHTTPHeader2() throws { - let request = HTTPRequest(command: AliyunpanScope.User.GetUsersInfo()) + let request = HTTPRequest(command: AliyunpanScope.User.GetVipInfo()) .headers([ .acceptEncoding("other"), .authorization(bearerToken: "abc") @@ -45,4 +52,67 @@ class HTTPRequestTests: XCTestCase { XCTAssertEqual(urlRequest.allHTTPHeaderFields!["Accept-Encoding"], "other") XCTAssertEqual(urlRequest.allHTTPHeaderFields!["Authorization"], "Bearer abc") } + + func testHTTPBody1() throws { + let request = HTTPRequest( + command: AliyunpanScope.File.GetFileList( + .init(drive_id: "drive_id1", + parent_file_id: "parent_file_id1", + limit: 300, + marker: "next_marker", + order_by: .created_at, + order_direction: .desc))) + let urlRequest = try request.asURLRequest() + XCTAssertEqual(urlRequest.httpMethod?.lowercased(), "post") + + + let json = try JSONSerialization.jsonObject(with: urlRequest.httpBody!) as! [String: Any] + XCTAssertEqual(json["drive_id"] as! String, "drive_id1") + XCTAssertEqual(json["parent_file_id"] as! String, "parent_file_id1") + XCTAssertEqual(json["limit"] as! Int, 300) + XCTAssertEqual(json["marker"] as! String, "next_marker") + XCTAssertEqual(json["order_by"] as! String, "created_at") + XCTAssertEqual(json["order_direction"] as! String, "DESC") + } + + func testHTTPBody2() throws { + let request = HTTPRequest( + command: AliyunpanScope.File.GetStarredList( + .init( + drive_id: "drive_id1", + limit: 300, + marker: "next_marker", + order_by: .created_at, + order_direction: .desc))) + let urlRequest = try request.asURLRequest() + XCTAssertEqual(urlRequest.httpMethod?.lowercased(), "post") + + let json = try JSONSerialization.jsonObject(with: urlRequest.httpBody!) as! [String: Any] + XCTAssertEqual(json["drive_id"] as! String, "drive_id1") + XCTAssertEqual(json["limit"] as! Int, 300) + XCTAssertEqual(json["marker"] as! String, "next_marker") + XCTAssertEqual(json["order_by"] as! String, "created_at") + XCTAssertEqual(json["order_direction"] as! String, "DESC") + } + + func testHTTPParams() throws { + let request = HTTPRequest( + command: AliyunpanScope.Internal.Authorize( + .init( + client_id: "client_id1", + redirect_uri: "redirect_uri1", + scope: "scope1", + response_type: "response_type1", + relogin: true))) + let urlRequest = try request.asURLRequest() + XCTAssertEqual(urlRequest.httpMethod?.lowercased(), "get") + + let queryItem = urlRequest.url!.queryItems + + XCTAssertEqual(queryItem["client_id"], "client_id1") + XCTAssertEqual(queryItem["redirect_uri"], "redirect_uri1") + XCTAssertEqual(queryItem["scope"], "scope1") + XCTAssertEqual(queryItem["response_type"], "response_type1") + XCTAssertEqual(queryItem["relogin"], "1") + } }