// // 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) } } }