diff --git a/Libraries/Sources/APIService/Endpoints/UploadFileEndpoint.swift b/Libraries/Sources/APIService/Endpoints/UploadFileEndpoint.swift new file mode 100644 index 0000000..75ecdc5 --- /dev/null +++ b/Libraries/Sources/APIService/Endpoints/UploadFileEndpoint.swift @@ -0,0 +1,47 @@ +// +// UploadFileEndpoint.swift +// APIService +// +// Created by Javier Cicchelli on 04/12/2022. +// Copyright © 2022 Röck+Cöde. All rights reserved. +// + +import Foundation + +struct UploadFileEndpoint: Endpoint { + let path: String + let method: RequestMethod + let credentials: BasicCredentials + let headers: [String : String] + let body: Data? +} + +// MARK: - Initialisers + +extension UploadFileEndpoint { + init( + itemId: String, + fileName: String, + fileData: Data, + username: String, + password: String + ) { + self.path = .init(format: .Formats.itemsWithId, itemId) + self.method = .post + self.credentials = .init( + username: username, + password: password + ) + self.headers = [ + .Header.Keys.contentType: .Header.Values.contentTypeOctet, + .Header.Keys.contentDisposition: .init(format: .Formats.attachment, fileName) + ] + self.body = fileData + } +} + +// MARK: - String+Formats + +private extension String.Formats { + static let attachment = "attachment;filename*=utf-8''%@" +} diff --git a/Libraries/Sources/APIService/Extensions/String+Headers.swift b/Libraries/Sources/APIService/Extensions/String+Headers.swift index f224c8a..cd4eefd 100644 --- a/Libraries/Sources/APIService/Extensions/String+Headers.swift +++ b/Libraries/Sources/APIService/Extensions/String+Headers.swift @@ -11,10 +11,12 @@ extension String { enum Keys { static let authorization = "Authorization" static let contentType = "Content-Type" + static let contentDisposition = "Content-Disposition" } enum Values { static let contentTypeJSON = "application/json" + static let contentTypeOctet = "application/octet-stream" } } } diff --git a/Libraries/Tests/APIServiceTests/Cases/Endpoints/UploadFileEndpoint+InitTests.swift b/Libraries/Tests/APIServiceTests/Cases/Endpoints/UploadFileEndpoint+InitTests.swift new file mode 100644 index 0000000..4aaf70d --- /dev/null +++ b/Libraries/Tests/APIServiceTests/Cases/Endpoints/UploadFileEndpoint+InitTests.swift @@ -0,0 +1,90 @@ +// +// UploadFileEndpoint+InitTests.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 UploadFileEndpoint_InitTests: XCTestCase { + + // MARK: Properties + + let itemId = UUID().uuidString + + var endpoint: UploadFileEndpoint! + var fileName: String! + var fileData: Data! + var username: String! + var password: String! + + // MARK: Test cases + + func test_withItemId_someFileNameAndData_andProperUsernameAndPassword() throws { + // GIVEN + fileName = "some-filename.txt" + fileData = "This is some raw text data for testing...".data(using: .utf8) + username = "username" + password = "password" + + // WHEN + endpoint = .init( + itemId: itemId, + fileName: fileName, + fileData: fileData, + username: username, + password: password + ) + + // THEN + XCTAssertEqual(endpoint.scheme, .Schemes.http) + XCTAssertEqual(endpoint.host, .Hosts.default) + XCTAssertEqual(endpoint.path, "/items/\(itemId)") + XCTAssertEqual(endpoint.method, .post) + XCTAssertEqual(endpoint.credentials.username, username) + XCTAssertEqual(endpoint.credentials.password, password) + XCTAssertEqual(endpoint.headers, [ + .Header.Keys.contentType: .Header.Values.contentTypeOctet, + .Header.Keys.contentDisposition: "attachment;filename*=utf-8''" + fileName + ]) + XCTAssertEqual(endpoint.authorizationHeader, [.Header.Keys.authorization: "Basic dXNlcm5hbWU6cGFzc3dvcmQ="]) + XCTAssertEqual(endpoint.body, fileData) + } + + func test_withItemId_someFileNameAndData_andEmptyUsernameOrPassword() throws { + // GIVEN + fileName = "some-filename.txt" + fileData = "This is some raw text data for testing...".data(using: .utf8) + username = "username" + password = "" + + // WHEN + endpoint = .init( + itemId: itemId, + fileName: fileName, + fileData: fileData, + username: username, + password: password + ) + + // THEN + XCTAssertEqual(endpoint.scheme, .Schemes.http) + XCTAssertEqual(endpoint.host, .Hosts.default) + XCTAssertEqual(endpoint.path, "/items/\(itemId)") + XCTAssertEqual(endpoint.method, .post) + XCTAssertEqual(endpoint.credentials.username, username) + XCTAssertEqual(endpoint.credentials.password, password) + XCTAssertEqual(endpoint.headers, [ + .Header.Keys.contentType: .Header.Values.contentTypeOctet, + .Header.Keys.contentDisposition: "attachment;filename*=utf-8''" + fileName + ]) + XCTAssertEqual(endpoint.authorizationHeader, [:]) + XCTAssertEqual(endpoint.body, fileData) + } + +}