Implemented the APIService service.
This commit is contained in:
parent
f748c11886
commit
571724b012
112
Libraries/Sources/APIService/Actors/APIService.swift
Normal file
112
Libraries/Sources/APIService/Actors/APIService.swift
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
//
|
||||||
|
// APIService.swift
|
||||||
|
// APIService
|
||||||
|
//
|
||||||
|
// Created by Javier Cicchelli on 04/12/2022.
|
||||||
|
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public actor APIService {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
private let client: Client
|
||||||
|
|
||||||
|
// MARK: Initialisers
|
||||||
|
|
||||||
|
public init(configuration: URLSessionConfiguration = .default) {
|
||||||
|
self.client = APIClient(configuration: configuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Service
|
||||||
|
|
||||||
|
extension APIService: Service {
|
||||||
|
public func getUser(
|
||||||
|
credentials: Credentials
|
||||||
|
) async throws -> Me {
|
||||||
|
try await client.request(
|
||||||
|
endpoint: GetMeEndpoint(
|
||||||
|
username: credentials.username,
|
||||||
|
password: credentials.password
|
||||||
|
),
|
||||||
|
model: Me.self
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getItems(
|
||||||
|
id: String,
|
||||||
|
credentials: Credentials
|
||||||
|
) async throws -> [Item] {
|
||||||
|
try await client.request(
|
||||||
|
endpoint: GetItemsEndpoint(
|
||||||
|
itemId: id,
|
||||||
|
username: credentials.username,
|
||||||
|
password: credentials.password
|
||||||
|
),
|
||||||
|
model: [Item].self
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func getData(
|
||||||
|
id: String,
|
||||||
|
credentials: Credentials
|
||||||
|
) async throws -> Data {
|
||||||
|
try await client.request(
|
||||||
|
endpoint: GetDataEndpoint(
|
||||||
|
itemId: id,
|
||||||
|
username: credentials.username,
|
||||||
|
password: credentials.password
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func createFolder(
|
||||||
|
id: String,
|
||||||
|
name: String,
|
||||||
|
credentials: Credentials
|
||||||
|
) async throws -> Item {
|
||||||
|
try await client.request(
|
||||||
|
endpoint: CreateFolderEndpoint(
|
||||||
|
itemId: id,
|
||||||
|
folderName: name,
|
||||||
|
username: credentials.username,
|
||||||
|
password: credentials.password
|
||||||
|
),
|
||||||
|
model: Item.self
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func uploadFile(
|
||||||
|
id: String,
|
||||||
|
file: File,
|
||||||
|
credentials: Credentials
|
||||||
|
) async throws -> Item {
|
||||||
|
try await client.request(
|
||||||
|
endpoint: UploadFileEndpoint(
|
||||||
|
itemId: id,
|
||||||
|
fileName: file.name,
|
||||||
|
fileData: file.data,
|
||||||
|
username: credentials.username,
|
||||||
|
password: credentials.password
|
||||||
|
),
|
||||||
|
model: Item.self
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func deleteItem(
|
||||||
|
id: String,
|
||||||
|
credentials: Credentials
|
||||||
|
) async throws {
|
||||||
|
try await client.request(
|
||||||
|
endpoint: DeleteItemEndpoint(
|
||||||
|
itemId: id,
|
||||||
|
username: credentials.username,
|
||||||
|
password: credentials.password
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,228 @@
|
|||||||
|
//
|
||||||
|
// APIService+CreateFolderTests.swift
|
||||||
|
// APIServiceTests
|
||||||
|
//
|
||||||
|
// Created by Javier Cicchelli on 04/12/2022.
|
||||||
|
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import APIService
|
||||||
|
|
||||||
|
final class APIServiceCreateFolderTests: XCTestCase {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
private let dateFormatter = DateFormatter.isoZulu
|
||||||
|
private let sessionConfiguration = {
|
||||||
|
let configuration = URLSessionConfiguration.default
|
||||||
|
|
||||||
|
configuration.protocolClasses = [MockURLProtocol.self]
|
||||||
|
|
||||||
|
return configuration
|
||||||
|
}()
|
||||||
|
|
||||||
|
private let itemId = UUID().uuidString
|
||||||
|
private let url = URL(string: "http://163.172.147.216:8080/items/")!
|
||||||
|
|
||||||
|
private var service: APIService!
|
||||||
|
private var data: Data!
|
||||||
|
private var result: Item!
|
||||||
|
|
||||||
|
// MARK: Setup
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
service = .init(configuration: sessionConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() async throws {
|
||||||
|
service = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Test cases
|
||||||
|
|
||||||
|
func test_withExistingParentFolderId_someFolderName_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
data = "{\"id\":\"058c53609cac8d8388b96792cbc42bea31c73def\",\"parentId\":\"\(itemId)\",\"name\":\"Some new folder name\",\"isDir\":true,\"modificationDate\":\"2022-12-04T20:54:12.513214855Z\"}".data(using: .utf8)
|
||||||
|
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .created,
|
||||||
|
headers: [.Header.Keys.contentType: .Header.Values.contentTypeJSON],
|
||||||
|
data: data
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
result = try await service.createFolder(
|
||||||
|
id: itemId,
|
||||||
|
name: "Some new folder name",
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(result, Item(
|
||||||
|
idParent: itemId,
|
||||||
|
id: "058c53609cac8d8388b96792cbc42bea31c73def",
|
||||||
|
name: "Some new folder name",
|
||||||
|
isDirectory: true,
|
||||||
|
lastModifiedAt: dateFormatter.date(from: "2022-12-04T20:54:12.513214855Z")!,
|
||||||
|
size: nil,
|
||||||
|
contentType: nil
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingParentFolderId_someFolderName_andWrongCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .unauthorized,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.createFolder(
|
||||||
|
id: itemId,
|
||||||
|
name: "Some new folder name",
|
||||||
|
credentials: .init(
|
||||||
|
username: "usrname",
|
||||||
|
password: "passwrd"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.authenticationFailed {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withNonExistingParentFolderId_someFolderName_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .notFound,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.createFolder(
|
||||||
|
id: itemId,
|
||||||
|
name: "Some new folder name",
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemDoesNotExist {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withEmptyParentFolderId_someFolderName_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent("")] = MockURLResponse(
|
||||||
|
status: .notFound,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.createFolder(
|
||||||
|
id: "",
|
||||||
|
name: "Some new folder name",
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemDoesNotExist {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingParentFolderId_someInvalidFolderName_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .badRequest,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.createFolder(
|
||||||
|
id: itemId,
|
||||||
|
name: "./Some:new:folder:name\\",
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemNameInvalidOrDefined {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingParentFolderId_someExistingFolderName_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .badRequest,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.createFolder(
|
||||||
|
id: itemId,
|
||||||
|
name: "Some new folder name",
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemNameInvalidOrDefined {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingParentFolderId_someEmptyFolderName_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .badRequest,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.createFolder(
|
||||||
|
id: itemId,
|
||||||
|
name: "",
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemNameInvalidOrDefined {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
//
|
||||||
|
// APIService+DeleteItemTests.swift
|
||||||
|
// APIServiceTests
|
||||||
|
//
|
||||||
|
// Created by Javier Cicchelli on 04/12/2022.
|
||||||
|
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import APIService
|
||||||
|
|
||||||
|
final class APIServiceDeleteItemTests: XCTestCase {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
private let sessionConfiguration = {
|
||||||
|
let configuration = URLSessionConfiguration.default
|
||||||
|
|
||||||
|
configuration.protocolClasses = [MockURLProtocol.self]
|
||||||
|
|
||||||
|
return configuration
|
||||||
|
}()
|
||||||
|
|
||||||
|
private let itemId = UUID().uuidString
|
||||||
|
private let url = URL(string: "http://163.172.147.216:8080/items/")!
|
||||||
|
|
||||||
|
private var service: APIService!
|
||||||
|
|
||||||
|
// MARK: Setup
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
service = .init(configuration: sessionConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() async throws {
|
||||||
|
service = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Test cases
|
||||||
|
|
||||||
|
func test_withExistingId_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .noContent,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
try await service.deleteItem(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingId_andWrongCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .unauthorized,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
try await service.deleteItem(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "usrname",
|
||||||
|
password: "passwrd"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.authenticationFailed {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withNonExistingId_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .notFound,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
try await service.deleteItem(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemDoesNotExist {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withEmptyId_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent("")] = MockURLResponse(
|
||||||
|
status: .notFound,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
try await service.deleteItem(
|
||||||
|
id: "",
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemDoesNotExist {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,164 @@
|
|||||||
|
//
|
||||||
|
// APIService+GetDataTests.swift
|
||||||
|
// APIServiceTests
|
||||||
|
//
|
||||||
|
// Created by Javier Cicchelli on 04/12/2022.
|
||||||
|
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import APIService
|
||||||
|
|
||||||
|
final class APIServiceGetDataTests: XCTestCase {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
private let sessionConfiguration = {
|
||||||
|
let configuration = URLSessionConfiguration.default
|
||||||
|
|
||||||
|
configuration.protocolClasses = [MockURLProtocol.self]
|
||||||
|
|
||||||
|
return configuration
|
||||||
|
}()
|
||||||
|
|
||||||
|
private let itemId = UUID().uuidString
|
||||||
|
private let url = URL(string: "http://163.172.147.216:8080/items/")!
|
||||||
|
|
||||||
|
private var service: APIService!
|
||||||
|
private var data: Data!
|
||||||
|
private var result: Data!
|
||||||
|
|
||||||
|
// MARK: Setup
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
service = .init(configuration: sessionConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() async throws {
|
||||||
|
service = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Test cases
|
||||||
|
|
||||||
|
func test_withExistingFileId_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
data = "This is just a simple text for testing purposes.".data(using: .utf8)
|
||||||
|
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId + "/data")] = MockURLResponse(
|
||||||
|
status: .ok,
|
||||||
|
headers: [.Header.Keys.contentType: .Header.Values.contentTypeOctet],
|
||||||
|
data: data
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
result = try await service.getData(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(result, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingFileId_andWrongCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId + "/data")] = MockURLResponse(
|
||||||
|
status: .unauthorized,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.getData(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "usrname",
|
||||||
|
password: "passwrd"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.authenticationFailed {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withNonExistingFileId_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId + "/data")] = MockURLResponse(
|
||||||
|
status: .notFound,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.getData(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemDoesNotExist {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withEmptyFileId_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent("/data")] = MockURLResponse(
|
||||||
|
status: .badRequest,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.getData(
|
||||||
|
id: "",
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemIsNotFile {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withSomeFolderId_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId + "/data")] = MockURLResponse(
|
||||||
|
status: .badRequest,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.getData(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemIsNotFile {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
//
|
||||||
|
// APIService+GetItemsTests.swift
|
||||||
|
// APIServiceTests
|
||||||
|
//
|
||||||
|
// Created by Javier Cicchelli on 04/12/2022.
|
||||||
|
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import APIService
|
||||||
|
|
||||||
|
final class APIServiceGetItemsTests: XCTestCase {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
private let dateFormatter = DateFormatter.isoZulu
|
||||||
|
private let sessionConfiguration = {
|
||||||
|
let configuration = URLSessionConfiguration.default
|
||||||
|
|
||||||
|
configuration.protocolClasses = [MockURLProtocol.self]
|
||||||
|
|
||||||
|
return configuration
|
||||||
|
}()
|
||||||
|
|
||||||
|
private let itemId = UUID().uuidString
|
||||||
|
private let url = URL(string: "http://163.172.147.216:8080/items/")!
|
||||||
|
|
||||||
|
private var service: APIService!
|
||||||
|
private var data: Data!
|
||||||
|
private var result: [Item]!
|
||||||
|
|
||||||
|
// MARK: Setup
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
service = .init(configuration: sessionConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() async throws {
|
||||||
|
service = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Test cases
|
||||||
|
|
||||||
|
func test_withExistingId_andRightCredentials_whenDataArrayPopulated() async throws {
|
||||||
|
// GIVEN
|
||||||
|
data = "[{\"id\":\"a077432ceb69b4f2dcbd4932d3ec63c3a4f14784\",\"parentId\":\"4b8e41fd4a6a89712f15bbf102421b9338cfab11\",\"name\":\"Tokyo\",\"isDir\":true,\"modificationDate\":\"2022-11-25T17:33:57.095027128Z\"},{\"id\":\"f5d351f7e532cae7c7be28488564b567ffeb425a\",\"parentId\":\"4b8e41fd4a6a89712f15bbf102421b9338cfab11\",\"name\":\"Meme.jpg\",\"isDir\":false,\"size\":43144,\"contentType\":\"image/jpeg\",\"modificationDate\":\"2022-12-01T15:24:12.29816675Z\"}]\n".data(using: .utf8)
|
||||||
|
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .ok,
|
||||||
|
headers: [.Header.Keys.contentType: .Header.Values.contentTypeJSON],
|
||||||
|
data: data
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
result = try await service.getItems(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(result, [
|
||||||
|
.init(
|
||||||
|
idParent: "4b8e41fd4a6a89712f15bbf102421b9338cfab11",
|
||||||
|
id: "a077432ceb69b4f2dcbd4932d3ec63c3a4f14784",
|
||||||
|
name: "Tokyo",
|
||||||
|
isDirectory: true,
|
||||||
|
lastModifiedAt: dateFormatter.date(from: "2022-11-25T17:33:57.095027128Z")!,
|
||||||
|
size: nil,
|
||||||
|
contentType: nil
|
||||||
|
),
|
||||||
|
.init(
|
||||||
|
idParent: "4b8e41fd4a6a89712f15bbf102421b9338cfab11",
|
||||||
|
id: "f5d351f7e532cae7c7be28488564b567ffeb425a",
|
||||||
|
name: "Meme.jpg",
|
||||||
|
isDirectory: false,
|
||||||
|
lastModifiedAt: dateFormatter.date(from: "2022-12-01T15:24:12.29816675Z")!,
|
||||||
|
size: 43144,
|
||||||
|
contentType: "image/jpeg"
|
||||||
|
),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingId_andRightCredentials_whenDataArrayEmpty() async throws {
|
||||||
|
// GIVEN
|
||||||
|
data = "[]".data(using: .utf8)
|
||||||
|
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .ok,
|
||||||
|
headers: [.Header.Keys.contentType: .Header.Values.contentTypeJSON],
|
||||||
|
data: data
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
result = try await service.getItems(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(result, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingId_andWrongCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .unauthorized,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.getItems(
|
||||||
|
id: itemId,
|
||||||
|
credentials: .init(
|
||||||
|
username: "usrname",
|
||||||
|
password: "passwrd"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.authenticationFailed {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withNonExistingId_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent("xxx")] = MockURLResponse(
|
||||||
|
status: .notFound,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.getItems(
|
||||||
|
id: "xxx",
|
||||||
|
credentials: .init(
|
||||||
|
username: "usrname",
|
||||||
|
password: "passwrd"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemDoesNotExist {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withEmptyId_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent("")] = MockURLResponse(
|
||||||
|
status: .notFound,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.getItems(
|
||||||
|
id: "",
|
||||||
|
credentials: .init(
|
||||||
|
username: "usrname",
|
||||||
|
password: "passwrd"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemDoesNotExist {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
//
|
||||||
|
// APIService+GetUserTests.swift
|
||||||
|
// APIServiceTests
|
||||||
|
//
|
||||||
|
// Created by Javier Cicchelli on 04/12/2022.
|
||||||
|
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import APIService
|
||||||
|
|
||||||
|
final class APIServiceGetUserTests: XCTestCase {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
private let dateFormatter = DateFormatter.iso8601
|
||||||
|
private let sessionConfiguration = {
|
||||||
|
let configuration = URLSessionConfiguration.default
|
||||||
|
|
||||||
|
configuration.protocolClasses = [MockURLProtocol.self]
|
||||||
|
|
||||||
|
return configuration
|
||||||
|
}()
|
||||||
|
|
||||||
|
private let url = URL(string: "http://163.172.147.216:8080/me")!
|
||||||
|
|
||||||
|
private var service: APIService!
|
||||||
|
private var data: Data!
|
||||||
|
private var result: Me!
|
||||||
|
|
||||||
|
// MARK: Setup
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
service = .init(configuration: sessionConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() async throws {
|
||||||
|
service = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Test cases
|
||||||
|
|
||||||
|
func test_withRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
data = "{\"firstName\":\"Noel\",\"lastName\":\"Flantier\",\"rootItem\":{\"id\":\"4b8e41fd4a6a89712f15bbf102421b9338cfab11\",\"parentId\":\"\",\"name\":\"dossierTest\",\"isDir\":true,\"modificationDate\":\"2021-11-29T10:57:13Z\"}}\n".data(using: .utf8)
|
||||||
|
|
||||||
|
MockURLProtocol.mockData[url] = MockURLResponse(
|
||||||
|
status: .ok,
|
||||||
|
headers: [.Header.Keys.contentType: .Header.Values.contentTypeJSON],
|
||||||
|
data: data
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
result = try await service.getUser(credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
))
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(result, Me(
|
||||||
|
firstName: "Noel",
|
||||||
|
lastName: "Flantier",
|
||||||
|
rootItem: .init(
|
||||||
|
idParent: "",
|
||||||
|
id: "4b8e41fd4a6a89712f15bbf102421b9338cfab11",
|
||||||
|
name: "dossierTest",
|
||||||
|
isDirectory: true,
|
||||||
|
lastModifiedAt: dateFormatter.date(from: "2021-11-29T10:57:13Z")!,
|
||||||
|
size: nil,
|
||||||
|
contentType: nil
|
||||||
|
)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withWrongCredentials() async throws {
|
||||||
|
MockURLProtocol.mockData[url] = MockURLResponse(
|
||||||
|
status: .unauthorized,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.getUser(credentials: .init(
|
||||||
|
username: "usrname",
|
||||||
|
password: "passwrd"
|
||||||
|
))
|
||||||
|
} catch APIClientError.authenticationFailed {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withMalformedResponseData() async throws {
|
||||||
|
// GIVEN
|
||||||
|
data = "{\"firstName\":\"Noel\",\"rootItem\":{\"id\":\"4b8e41fd4a6a89712f15bbf102421b9338cfab11\"\"name\":\"dossierTest\",\"isDir\":true}}\n".data(using: .utf8)
|
||||||
|
|
||||||
|
MockURLProtocol.mockData[url] = MockURLResponse(
|
||||||
|
status: .ok,
|
||||||
|
headers: [.Header.Keys.contentType: .Header.Values.contentTypeJSON],
|
||||||
|
data: data
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.getUser(credentials: .init(
|
||||||
|
username: "usrname",
|
||||||
|
password: "passwrd"
|
||||||
|
))
|
||||||
|
} catch is DecodingError {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,247 @@
|
|||||||
|
//
|
||||||
|
// APIService+UploadFileTests.swift
|
||||||
|
// APIServiceTests
|
||||||
|
//
|
||||||
|
// Created by Javier Cicchelli on 04/12/2022.
|
||||||
|
// Copyright © 2022 Röck+Cöde. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@testable import APIService
|
||||||
|
|
||||||
|
final class APIServiceUploadFileTests: XCTestCase {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
private let dateFormatter = DateFormatter.isoZulu
|
||||||
|
private let sessionConfiguration = {
|
||||||
|
let configuration = URLSessionConfiguration.default
|
||||||
|
|
||||||
|
configuration.protocolClasses = [MockURLProtocol.self]
|
||||||
|
|
||||||
|
return configuration
|
||||||
|
}()
|
||||||
|
|
||||||
|
private let itemId = UUID().uuidString
|
||||||
|
private let url = URL(string: "http://163.172.147.216:8080/items/")!
|
||||||
|
|
||||||
|
private var service: APIService!
|
||||||
|
private var data: Data!
|
||||||
|
private var result: Item!
|
||||||
|
|
||||||
|
// MARK: Setup
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
service = .init(configuration: sessionConfiguration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() async throws {
|
||||||
|
service = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Test cases
|
||||||
|
|
||||||
|
func test_withExistingParentFolderId_someFileNameAndData_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
data = "{\"id\":\"eb34443b0f1cd1b0a53dc889aa7ccb5a63edb2f8\",\"parentId\":\"\(itemId)\",\"name\":\"some-text-file.txt\",\"isDir\":false,\"size\":43,\"contentType\":\"text/plain; charset=utf-8\",\"modificationDate\":\"2022-12-04T21:20:01.218032276Z\"}".data(using: .utf8)
|
||||||
|
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .created,
|
||||||
|
headers: [.Header.Keys.contentType: .Header.Values.contentTypeJSON],
|
||||||
|
data: data
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
result = try await service.uploadFile(
|
||||||
|
id: itemId,
|
||||||
|
file: .init(
|
||||||
|
name: "some-text-file.txt",
|
||||||
|
data: "This is just a dummy content in text format".data(using: .utf8)!
|
||||||
|
),
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
XCTAssertEqual(result, Item(
|
||||||
|
idParent: itemId,
|
||||||
|
id: "eb34443b0f1cd1b0a53dc889aa7ccb5a63edb2f8",
|
||||||
|
name: "some-text-file.txt",
|
||||||
|
isDirectory: false,
|
||||||
|
lastModifiedAt: dateFormatter.date(from: "2022-12-04T21:20:01.218032276Z")!,
|
||||||
|
size: 43,
|
||||||
|
contentType: "text/plain; charset=utf-8"
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingParentFolderId_someFileNameAndData_andWrongCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .unauthorized,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.uploadFile(
|
||||||
|
id: itemId,
|
||||||
|
file: .init(
|
||||||
|
name: "some-text-file.txt",
|
||||||
|
data: .init()
|
||||||
|
),
|
||||||
|
credentials: .init(
|
||||||
|
username: "usrname",
|
||||||
|
password: "passwrd"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.authenticationFailed {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withNonExistingParentFolderId_someFileNameAndData_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .notFound,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.uploadFile(
|
||||||
|
id: itemId,
|
||||||
|
file: .init(
|
||||||
|
name: "some-text-file.txt",
|
||||||
|
data: .init()
|
||||||
|
),
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemDoesNotExist {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withEmptyParentFolderId_someFileNameAndData_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent("")] = MockURLResponse(
|
||||||
|
status: .badRequest,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.uploadFile(
|
||||||
|
id: "",
|
||||||
|
file: .init(
|
||||||
|
name: "some-text-file.txt",
|
||||||
|
data: .init()
|
||||||
|
),
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemNameInvalidOrDefined {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withExistingParentFolderId_someInvalidFileNameAndData_andRightCredentials() async throws {
|
||||||
|
// GIVEN
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .badRequest,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.uploadFile(
|
||||||
|
id: itemId,
|
||||||
|
file: .init(
|
||||||
|
name: "some-text-file.txt",
|
||||||
|
data: .init()
|
||||||
|
),
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemNameInvalidOrDefined {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withEmptyParentFolderId_someExistingNameAndData_andRightCredentials() async throws {
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .badRequest,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.uploadFile(
|
||||||
|
id: itemId,
|
||||||
|
file: .init(
|
||||||
|
name: "some-text-file.txt",
|
||||||
|
data: .init()
|
||||||
|
),
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemNameInvalidOrDefined {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_withEmptyParentFolderId_someEmptyFileNameAndData_andRightCredentials() async throws {
|
||||||
|
MockURLProtocol.mockData[url.appendingPathComponent(itemId)] = MockURLResponse(
|
||||||
|
status: .badRequest,
|
||||||
|
headers: [:],
|
||||||
|
data: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
// WHEN & THEN
|
||||||
|
do {
|
||||||
|
_ = try await service.uploadFile(
|
||||||
|
id: itemId,
|
||||||
|
file: .init(
|
||||||
|
name: "",
|
||||||
|
data: .init()
|
||||||
|
),
|
||||||
|
credentials: .init(
|
||||||
|
username: "username",
|
||||||
|
password: "password"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} catch APIClientError.itemNameInvalidOrDefined {
|
||||||
|
XCTAssertTrue(true)
|
||||||
|
} catch {
|
||||||
|
XCTAssertTrue(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user