diff --git a/Example/Modules/MockServer/MockServer/FakeChainBuilder.swift b/Example/Modules/MockServer/MockServer/FakeChainBuilder.swift new file mode 100644 index 000000000..46b69fd20 --- /dev/null +++ b/Example/Modules/MockServer/MockServer/FakeChainBuilder.swift @@ -0,0 +1,18 @@ +// +// FakeChainBuilder.swift +// +// +// Created by Andrei Frolov on 02.05.24. +// + +import NodeKit +import NodeKitMock + +public final class FakeChainBuilder: URLChainBuilder { + + public init() { + super.init( + serviceChainProvider: URLServiceChainProvider(session: NetworkMock().urlSession) + ) + } +} diff --git a/Example/Modules/Services/Services/AuthService/AuthService.swift b/Example/Modules/Services/Services/AuthService/AuthService.swift index bb0aab57f..653780a24 100644 --- a/Example/Modules/Services/Services/AuthService/AuthService.swift +++ b/Example/Modules/Services/Services/AuthService/AuthService.swift @@ -7,7 +7,7 @@ import Foundation import Models import NodeKit -import NodeKitMock +import MockServer public protocol AuthServiceProtocol { func auth(by email: String, and passwod: String) async -> NodeResult @@ -18,8 +18,7 @@ public struct AuthService: AuthServiceProtocol { public init() { } public func auth(by email: String, and passwod: String) async -> NodeResult { - return await UrlChainsBuilder() - .set(session: NetworkMock().urlSession) + return await FakeChainBuilder() .encode(as: .urlQuery) .route(.post, .login) .build() diff --git a/Example/Modules/Services/Services/AuthService/AuthURLProvider.swift b/Example/Modules/Services/Services/AuthService/AuthURLProvider.swift index bfd63dc61..69fc60e24 100644 --- a/Example/Modules/Services/Services/AuthService/AuthURLProvider.swift +++ b/Example/Modules/Services/Services/AuthService/AuthURLProvider.swift @@ -8,8 +8,8 @@ import Foundation import NodeKit -enum AuthURLProvider: UrlRouteProvider { - private static var base: UrlRouteProvider = NavigationURLProvider.auth +enum AuthURLProvider: URLRouteProvider { + private static var base: URLRouteProvider = NavigationURLProvider.auth case login case logout diff --git a/Example/Modules/Services/Services/GroupService/GroupService.swift b/Example/Modules/Services/Services/GroupService/GroupService.swift index 12762c15e..adfa7913a 100644 --- a/Example/Modules/Services/Services/GroupService/GroupService.swift +++ b/Example/Modules/Services/Services/GroupService/GroupService.swift @@ -7,8 +7,8 @@ import Foundation import NodeKit -import NodeKitMock import Models +import MockServer public protocol GroupServiceProtocol { func header() async -> NodeResult @@ -35,8 +35,7 @@ public final class GroupService: GroupServiceProtocol { private func result( from route: GroupURLProvider ) async -> NodeResult where T.DTO.Raw == Json { - return await UrlChainsBuilder() - .set(session: NetworkMock().urlSession) + return await FakeChainBuilder() .route(.get, route) .build() .process() diff --git a/Example/Modules/Services/Services/GroupService/GroupURLProvider.swift b/Example/Modules/Services/Services/GroupService/GroupURLProvider.swift index 22d39384f..00644feae 100644 --- a/Example/Modules/Services/Services/GroupService/GroupURLProvider.swift +++ b/Example/Modules/Services/Services/GroupService/GroupURLProvider.swift @@ -8,8 +8,8 @@ import Foundation import NodeKit -enum GroupURLProvider: UrlRouteProvider { - private static var base: UrlRouteProvider = NavigationURLProvider.group +enum GroupURLProvider: URLRouteProvider { + private static var base: URLRouteProvider = NavigationURLProvider.group case header case body diff --git a/Example/Modules/Services/Services/PaginationService/PaginationContentDataProvider.swift b/Example/Modules/Services/Services/PaginationService/PaginationContentDataProvider.swift index 330614224..876cf98d1 100644 --- a/Example/Modules/Services/Services/PaginationService/PaginationContentDataProvider.swift +++ b/Example/Modules/Services/Services/PaginationService/PaginationContentDataProvider.swift @@ -6,7 +6,7 @@ import Models import NodeKit -import NodeKitMock +import MockServer public struct PaginationContentDataProvider: AsyncPagerDataProvider { public typealias Value = [PaginationResponseEntity] @@ -14,8 +14,7 @@ public struct PaginationContentDataProvider: AsyncPagerDataProvider { public init() { } public func provide(for index: Int, with pageSize: Int) async -> NodeResult> { - return await UrlChainsBuilder() - .set(session: NetworkMock().urlSession) + return await FakeChainBuilder() .encode(as: .urlQuery) .route(.get, .list) .build() diff --git a/Example/Modules/Services/Services/PaginationService/PaginationURLProvider.swift b/Example/Modules/Services/Services/PaginationService/PaginationURLProvider.swift index 56e0307a2..0146e02c3 100644 --- a/Example/Modules/Services/Services/PaginationService/PaginationURLProvider.swift +++ b/Example/Modules/Services/Services/PaginationService/PaginationURLProvider.swift @@ -8,8 +8,8 @@ import Foundation import NodeKit -enum PaginationURLProvider: UrlRouteProvider { - private static var base: UrlRouteProvider = NavigationURLProvider.pagination +enum PaginationURLProvider: URLRouteProvider { + private static var base: URLRouteProvider = NavigationURLProvider.pagination case list diff --git a/Example/Modules/Services/Services/URLProviders.swift b/Example/Modules/Services/Services/URLProviders.swift index ed6ddb4c0..cfdb24cfe 100644 --- a/Example/Modules/Services/Services/URLProviders.swift +++ b/Example/Modules/Services/Services/URLProviders.swift @@ -7,7 +7,7 @@ import Foundation import NodeKit -enum RootURLProvider: UrlRouteProvider { +enum RootURLProvider: URLRouteProvider { case root func url() throws -> URL { @@ -15,8 +15,8 @@ enum RootURLProvider: UrlRouteProvider { } } -enum NavigationURLProvider: UrlRouteProvider { - private static var base: UrlRouteProvider = RootURLProvider.root +enum NavigationURLProvider: URLRouteProvider { + private static var base: URLRouteProvider = RootURLProvider.root case auth case pagination diff --git a/NodeKit/NodeKit.xcodeproj/project.pbxproj b/NodeKit/NodeKit.xcodeproj/project.pbxproj index 6936db764..ab860fcc8 100644 --- a/NodeKit/NodeKit.xcodeproj/project.pbxproj +++ b/NodeKit/NodeKit.xcodeproj/project.pbxproj @@ -9,15 +9,20 @@ /* Begin PBXBuildFile section */ 390E696C2A13654A007F2304 /* RequestSenderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390E696B2A13654A007F2304 /* RequestSenderNode.swift */; }; 390E69712A136586007F2304 /* RequestEncodingNodeError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390E696E2A136586007F2304 /* RequestEncodingNodeError.swift */; }; - 390E69722A136586007F2304 /* UrlJsonRequestEncodingNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390E696F2A136586007F2304 /* UrlJsonRequestEncodingNode.swift */; }; + 390E69722A136586007F2304 /* URLJsonRequestEncodingNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390E696F2A136586007F2304 /* URLJsonRequestEncodingNode.swift */; }; 390E69752A136591007F2304 /* RequestEncodingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 390E69742A136591007F2304 /* RequestEncodingModel.swift */; }; 5005EB1C2BB88EC500B670CD /* CombineStreamNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB1B2BB88EC500B670CD /* CombineStreamNode.swift */; }; 5005EB212BB8A6D000B670CD /* AsyncNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB202BB8A6D000B670CD /* AsyncNode.swift */; }; 5005EB232BB8A6D900B670CD /* AsyncStreamNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB222BB8A6D900B670CD /* AsyncStreamNode.swift */; }; 5005EB3C2BB9B1C800B670CD /* AsyncNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB3B2BB9B1C800B670CD /* AsyncNodeTests.swift */; }; 5005EB3E2BB9B4A300B670CD /* AsyncStreamNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB3D2BB9B4A300B670CD /* AsyncStreamNodeTests.swift */; }; + 5013490F2BE3CB10002CC3DA /* ServiceChainProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5013490E2BE3CB10002CC3DA /* ServiceChainProviderMock.swift */; }; + 501349112BE3CBFD002CC3DA /* ChainBuilderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501349102BE3CBFD002CC3DA /* ChainBuilderMock.swift */; }; + 501349132BE3D790002CC3DA /* ChainConfigBuilderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501349122BE3D790002CC3DA /* ChainConfigBuilderMock.swift */; }; + 501349152BE3E6D2002CC3DA /* AnyAsyncNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501349142BE3E6D2002CC3DA /* AnyAsyncNode.swift */; }; + 501349172BE3E770002CC3DA /* AnyAsyncStreamNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 501349162BE3E770002CC3DA /* AnyAsyncStreamNode.swift */; }; 5019CCE42BC00CDC0050B6DF /* RawEncoderNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5019CCE32BC00CDC0050B6DF /* RawEncoderNodeTests.swift */; }; - 5019CCE82BC018630050B6DF /* MultipartUrlRequestTrasformatorNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5019CCE72BC018630050B6DF /* MultipartUrlRequestTrasformatorNodeTests.swift */; }; + 5019CCE82BC018630050B6DF /* MultipartURLRequestTrasformatorNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5019CCE72BC018630050B6DF /* MultipartURLRequestTrasformatorNodeTests.swift */; }; 5019CCEC2BC01DDB0050B6DF /* RequestEncoderNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5019CCEB2BC01DDB0050B6DF /* RequestEncoderNodeTests.swift */; }; 5019CCEE2BC020DC0050B6DF /* MultipartRequestCreatorNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5019CCED2BC020DC0050B6DF /* MultipartRequestCreatorNodeTests.swift */; }; 5019CCF02BC024D60050B6DF /* MultipartFormDataFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5019CCEF2BC024D60050B6DF /* MultipartFormDataFactory.swift */; }; @@ -30,7 +35,7 @@ 50528E292BAE162600E86CB6 /* LoggerStreamNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50528E282BAE162600E86CB6 /* LoggerStreamNode.swift */; }; 50528E372BAE34A400E86CB6 /* TokenRefresherActorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50528E362BAE34A400E86CB6 /* TokenRefresherActorTests.swift */; }; 5060A45C2BC3D8D2004E84E2 /* EntryinputDtoOutputNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A45B2BC3D8D2004E84E2 /* EntryinputDtoOutputNodeTests.swift */; }; - 5060A4622BC3E386004E84E2 /* UrlCacheWriterNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4612BC3E386004E84E2 /* UrlCacheWriterNodeTests.swift */; }; + 5060A4622BC3E386004E84E2 /* URLCacheWriterNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4612BC3E386004E84E2 /* URLCacheWriterNodeTests.swift */; }; 5060A4642BC3E660004E84E2 /* RequestSenderNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4632BC3E660004E84E2 /* RequestSenderNodeTests.swift */; }; 5060A4662BC3E6E8004E84E2 /* URLSessionDataTaskActor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4652BC3E6E8004E84E2 /* URLSessionDataTaskActor.swift */; }; 5060A4792BC402C0004E84E2 /* URLSessionDataTaskActorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4782BC402C0004E84E2 /* URLSessionDataTaskActorTests.swift */; }; @@ -38,11 +43,10 @@ 5060A4802BC4164E004E84E2 /* RequestRouterNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A47F2BC4164E004E84E2 /* RequestRouterNodeTests.swift */; }; 5060A4822BC4184F004E84E2 /* ResponseProcessorNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4812BC4184F004E84E2 /* ResponseProcessorNodeTests.swift */; }; 5060A4842BC41C89004E84E2 /* VoidIONodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4832BC41C89004E84E2 /* VoidIONodeTests.swift */; }; - 5060A4862BC4213E004E84E2 /* LoadIndicatableNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4852BC4213E004E84E2 /* LoadIndicatableNodeTests.swift */; }; 5060A4882BC42538004E84E2 /* ModelInputNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4872BC42538004E84E2 /* ModelInputNodeTests.swift */; }; 5060A48A2BC42A0A004E84E2 /* ResponseHttpErrorProcessorNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4892BC42A0A004E84E2 /* ResponseHttpErrorProcessorNodeTests.swift */; }; 5060A48C2BC42FD3004E84E2 /* VoidInputNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A48B2BC42FD3004E84E2 /* VoidInputNodeTests.swift */; }; - 5060A48E2BC43116004E84E2 /* UrlRequestTrasformatorNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A48D2BC43116004E84E2 /* UrlRequestTrasformatorNodeTests.swift */; }; + 5060A48E2BC43116004E84E2 /* URLRequestTrasformatorNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A48D2BC43116004E84E2 /* URLRequestTrasformatorNodeTests.swift */; }; 5060A4902BC43A4A004E84E2 /* VoidOutputNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A48F2BC43A4A004E84E2 /* VoidOutputNodeTests.swift */; }; 5060A4922BC43D71004E84E2 /* LoggerStreamNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4912BC43D71004E84E2 /* LoggerStreamNodeTests.swift */; }; 5060A4942BC43FBD004E84E2 /* LoggerNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5060A4932BC43FBD004E84E2 /* LoggerNodeTests.swift */; }; @@ -52,7 +56,7 @@ 508169D72BC56B9200A43F3D /* RawDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508169D62BC56B9200A43F3D /* RawDecodableTests.swift */; }; 508169D92BC56F5C00A43F3D /* ServerRequestsManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508169D82BC56F5C00A43F3D /* ServerRequestsManagerTests.swift */; }; 508169DB2BC5707100A43F3D /* MultipartModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508169DA2BC5707100A43F3D /* MultipartModelTests.swift */; }; - 508169E12BC57CDF00A43F3D /* UrlChainConfigModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508169E02BC57CDF00A43F3D /* UrlChainConfigModelTests.swift */; }; + 508169E12BC57CDF00A43F3D /* URLChainConfigModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508169E02BC57CDF00A43F3D /* URLChainConfigModelTests.swift */; }; 508169E32BC57E4800A43F3D /* ArrayRawMappableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508169E22BC57E4800A43F3D /* ArrayRawMappableTests.swift */; }; 508169E52BC582EA00A43F3D /* DictionaryDTOConvertibleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508169E42BC582EA00A43F3D /* DictionaryDTOConvertibleTests.swift */; }; 508169E72BC584B300A43F3D /* DTODecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508169E62BC584B300A43F3D /* DTODecodableTests.swift */; }; @@ -71,7 +75,7 @@ 50816AAA2BC6FE6700A43F3D /* AuthModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609EA283E16DC006F4309 /* AuthModel.swift */; }; 50816AAB2BC6FE6A00A43F3D /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609EB283E16DC006F4309 /* User.swift */; }; 50816AAC2BC6FE7000A43F3D /* Credentials.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609EC283E16DC006F4309 /* Credentials.swift */; }; - 50816B072BC7077C00A43F3D /* TransportUrlRequest+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B683912BBF3816001F7EA3 /* TransportUrlRequest+Equatable.swift */; }; + 50816B072BC7077C00A43F3D /* TransportURLRequest+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B683912BBF3816001F7EA3 /* TransportURLRequest+Equatable.swift */; }; 50816B082BC7077E00A43F3D /* Log+Equatalbe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 502F9D9C2BAA39F400151A8D /* Log+Equatalbe.swift */; }; 50816B092BC7078000A43F3D /* Result+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5005EB432BB9BC5B00B670CD /* Result+Extension.swift */; }; 50816B0A2BC7079000A43F3D /* DispatchQueue+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB3D2BBEC1E700C5CB93 /* DispatchQueue+Extension.swift */; }; @@ -81,12 +85,12 @@ 50816B0E2BC7079900A43F3D /* RawEncodableMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A6C2BC6F85C00A43F3D /* RawEncodableMock.swift */; }; 50816B0F2BC7079B00A43F3D /* RawMappableMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A6B2BC6F85C00A43F3D /* RawMappableMock.swift */; }; 50816B102BC7079D00A43F3D /* TokenRefresherActorMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A6A2BC6F85C00A43F3D /* TokenRefresherActorMock.swift */; }; - 50816B112BC7079F00A43F3D /* UrlRouteProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A6D2BC6F85C00A43F3D /* UrlRouteProviderMock.swift */; }; + 50816B112BC7079F00A43F3D /* URLRouteProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A6D2BC6F85C00A43F3D /* URLRouteProviderMock.swift */; }; 50816B122BC707A100A43F3D /* URLSessionDataTaskActorMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A6F2BC6F85C00A43F3D /* URLSessionDataTaskActorMock.swift */; }; 50816B132BC707A300A43F3D /* CancellableTaskMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A632BC6F85200A43F3D /* CancellableTaskMock.swift */; }; 50816B142BC707A600A43F3D /* NetworkMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A602BC6F85200A43F3D /* NetworkMock.swift */; }; 50816B152BC707A800A43F3D /* URLProtocolMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A5E2BC6F85200A43F3D /* URLProtocolMock.swift */; }; - 50816B162BC707AA00A43F3D /* UrlServiceChainBuilderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A612BC6F85200A43F3D /* UrlServiceChainBuilderMock.swift */; }; + 50816B162BC707AA00A43F3D /* URLServiceChainProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A612BC6F85200A43F3D /* URLServiceChainProviderMock.swift */; }; 50816B172BC707AC00A43F3D /* URLSessionDataTaskMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A622BC6F85200A43F3D /* URLSessionDataTaskMock.swift */; }; 50816B182BC707AE00A43F3D /* AborterMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A4D2BC6F83D00A43F3D /* AborterMock.swift */; }; 50816B192BC707B000A43F3D /* AsyncNodeMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50816A4B2BC6F83D00A43F3D /* AsyncNodeMock.swift */; }; @@ -105,6 +109,11 @@ 5097DFAE2BCDFA8300D422EE /* NodeKitThirdParty in Frameworks */ = {isa = PBXBuildFile; productRef = 5097DFAD2BCDFA8300D422EE /* NodeKitThirdParty */; }; 5097DFB02BCDFB5200D422EE /* CancellableTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5097DFAF2BCDFB5200D422EE /* CancellableTask.swift */; }; 50B6838F2BBF3615001F7EA3 /* AccessSafeNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B6838E2BBF3615001F7EA3 /* AccessSafeNodeTests.swift */; }; + 50C57AB72BE3871D004C344E /* ServiceChainProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C57AB62BE3871D004C344E /* ServiceChainProvider.swift */; }; + 50C57AB92BE388C6004C344E /* ChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C57AB82BE388C6004C344E /* ChainBuilder.swift */; }; + 50C57ABB2BE3A3C0004C344E /* DataChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C57ABA2BE3A3C0004C344E /* DataChainBuilder.swift */; }; + 50C57ABD2BE3A551004C344E /* VoidChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C57ABC2BE3A551004C344E /* VoidChainBuilder.swift */; }; + 50C57ABF2BE3A62D004C344E /* MultipartChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C57ABE2BE3A62D004C344E /* MultipartChainBuilder.swift */; }; 50C8EB282BBD7A2200C5CB93 /* AsyncStreamCombineNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB272BBD7A2200C5CB93 /* AsyncStreamCombineNode.swift */; }; 50C8EB2A2BBD7DEA00C5CB93 /* CombineNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB292BBD7DEA00C5CB93 /* CombineNode.swift */; }; 50C8EB302BBD90DE00C5CB93 /* CombineNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB2F2BBD90DE00C5CB93 /* CombineNodeTests.swift */; }; @@ -120,17 +129,15 @@ 50C8EB502BBF216C00C5CB93 /* ResponseDataParserNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB4F2BBF216C00C5CB93 /* ResponseDataParserNodeTests.swift */; }; 50C8EB522BBF302E00C5CB93 /* ResponseDataPreprocessorNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C8EB512BBF302E00C5CB93 /* ResponseDataPreprocessorNodeTests.swift */; }; 90B608DA283E1110006F4309 /* NodeKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 90B608CE283E1110006F4309 /* NodeKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 90B6090E283E1268006F4309 /* UrlCacheReaderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608E4283E1268006F4309 /* UrlCacheReaderNode.swift */; }; + 90B6090E283E1268006F4309 /* URLCacheReaderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608E4283E1268006F4309 /* URLCacheReaderNode.swift */; }; 90B6090F283E1268006F4309 /* FirstCachePolicyNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608E5283E1268006F4309 /* FirstCachePolicyNode.swift */; }; - 90B60910283E1268006F4309 /* UrlNotModifiedTriggerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608E6283E1268006F4309 /* UrlNotModifiedTriggerNode.swift */; }; - 90B60911283E1268006F4309 /* UrlCacheWriterNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608E7283E1268006F4309 /* UrlCacheWriterNode.swift */; }; + 90B60910283E1268006F4309 /* URLNotModifiedTriggerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608E6283E1268006F4309 /* URLNotModifiedTriggerNode.swift */; }; + 90B60911283E1268006F4309 /* URLCacheWriterNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608E7283E1268006F4309 /* URLCacheWriterNode.swift */; }; 90B60912283E1268006F4309 /* IfServerFailsFromCacheNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608E8283E1268006F4309 /* IfServerFailsFromCacheNode.swift */; }; - 90B60913283E1268006F4309 /* UrlETagSaverNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608EA283E1268006F4309 /* UrlETagSaverNode.swift */; }; + 90B60913283E1268006F4309 /* URLETagSaverNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608EA283E1268006F4309 /* URLETagSaverNode.swift */; }; 90B60914283E1268006F4309 /* ETagConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608EB283E1268006F4309 /* ETagConstants.swift */; }; - 90B60915283E1268006F4309 /* UrlETagReaderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608EC283E1268006F4309 /* UrlETagReaderNode.swift */; }; - 90B60916283E1268006F4309 /* UrlServiceChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608EE283E1268006F4309 /* UrlServiceChainBuilder.swift */; }; - 90B60917283E1268006F4309 /* UrlChainsBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608EF283E1268006F4309 /* UrlChainsBuilder.swift */; }; - 90B60918283E1268006F4309 /* UrlChainConfigModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608F0283E1268006F4309 /* UrlChainConfigModel.swift */; }; + 90B60915283E1268006F4309 /* URLETagReaderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608EC283E1268006F4309 /* URLETagReaderNode.swift */; }; + 90B60918283E1268006F4309 /* URLChainConfigModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608F0283E1268006F4309 /* URLChainConfigModel.swift */; }; 90B60919283E1268006F4309 /* RawMappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608F3283E1268006F4309 /* RawMappable.swift */; }; 90B6091A283E1268006F4309 /* RawMappable+Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608F5283E1268006F4309 /* RawMappable+Dictionary.swift */; }; 90B6091B283E1268006F4309 /* Array+RawMappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608F6283E1268006F4309 /* Array+RawMappable.swift */; }; @@ -140,8 +147,8 @@ 90B60920283E1268006F4309 /* MultipartFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608FC283E1268006F4309 /* MultipartFileProvider.swift */; }; 90B60921283E1268006F4309 /* MultipartModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608FD283E1268006F4309 /* MultipartModel.swift */; }; 90B60922283E1268006F4309 /* DTOConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B608FE283E1268006F4309 /* DTOConvertible.swift */; }; - 90B60923283E1268006F4309 /* LoggableNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60900283E1268006F4309 /* LoggableNode.swift */; }; - 90B60985283E1287006F4309 /* UrlRequestTrasformatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60930283E1287006F4309 /* UrlRequestTrasformatorNode.swift */; }; + 90B60923283E1268006F4309 /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60900283E1268006F4309 /* Node.swift */; }; + 90B60985283E1287006F4309 /* URLRequestTrasformatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60930283E1287006F4309 /* URLRequestTrasformatorNode.swift */; }; 90B60986283E1287006F4309 /* RequestRouterNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60931283E1287006F4309 /* RequestRouterNode.swift */; }; 90B60987283E1287006F4309 /* URLQueryDictionaryKeyEncodingStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60933283E1287006F4309 /* URLQueryDictionaryKeyEncodingStrategy.swift */; }; 90B60988283E1287006F4309 /* URLQueryArrayKeyEncodingStartegy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60934283E1287006F4309 /* URLQueryArrayKeyEncodingStartegy.swift */; }; @@ -154,8 +161,8 @@ 90B6098F283E1287006F4309 /* RequestModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6093C283E1287006F4309 /* RequestModel.swift */; }; 90B60990283E1287006F4309 /* RequestEncoderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6093D283E1287006F4309 /* RequestEncoderNode.swift */; }; 90B60991283E1287006F4309 /* URLQueryInjectorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6093E283E1287006F4309 /* URLQueryInjectorNode.swift */; }; - 90B60992283E1287006F4309 /* MultipartUrlRequestTrasformatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6093F283E1287006F4309 /* MultipartUrlRequestTrasformatorNode.swift */; }; - 90B60993283E1287006F4309 /* UrlRouteProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60941283E1287006F4309 /* UrlRouteProvider.swift */; }; + 90B60992283E1287006F4309 /* MultipartURLRequestTrasformatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6093F283E1287006F4309 /* MultipartURLRequestTrasformatorNode.swift */; }; + 90B60993283E1287006F4309 /* URLRouteProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60941283E1287006F4309 /* URLRouteProvider.swift */; }; 90B60994283E1287006F4309 /* MetadataConnectorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60942283E1287006F4309 /* MetadataConnectorNode.swift */; }; 90B60995283E1287006F4309 /* DTOEncoderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60944283E1287006F4309 /* DTOEncoderNode.swift */; }; 90B60996283E1287006F4309 /* VoidIONode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60945283E1287006F4309 /* VoidIONode.swift */; }; @@ -163,12 +170,11 @@ 90B60998283E1287006F4309 /* ModelInputNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60947283E1287006F4309 /* ModelInputNode.swift */; }; 90B6099A283E1287006F4309 /* VoidInputNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60949283E1287006F4309 /* VoidInputNode.swift */; }; 90B6099B283E1287006F4309 /* RequestAborterNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6094B283E1287006F4309 /* RequestAborterNode.swift */; }; - 90B6099C283E1287006F4309 /* LoadIndicatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6094C283E1287006F4309 /* LoadIndicatorNode.swift */; }; 90B6099D283E1287006F4309 /* TokenRefresherNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6094E283E1287006F4309 /* TokenRefresherNode.swift */; }; 90B6099E283E1287006F4309 /* AccessSafeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6094F283E1287006F4309 /* AccessSafeNode.swift */; }; 90B6099F283E1287006F4309 /* HeaderInjectorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60950283E1287006F4309 /* HeaderInjectorNode.swift */; }; 90B609A0283E1287006F4309 /* ResponseHttpErrorProcessorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60952283E1287006F4309 /* ResponseHttpErrorProcessorNode.swift */; }; - 90B609A1283E1287006F4309 /* UrlDataResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60954283E1287006F4309 /* UrlDataResponse.swift */; }; + 90B609A1283E1287006F4309 /* URLDataResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60954283E1287006F4309 /* URLDataResponse.swift */; }; 90B609A2283E1287006F4309 /* ResponseDataParserNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60955283E1287006F4309 /* ResponseDataParserNode.swift */; }; 90B609A3283E1287006F4309 /* DataLoadingResponseProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60957283E1287006F4309 /* DataLoadingResponseProcessor.swift */; }; 90B609A4283E1287006F4309 /* ResponseDataPreprocessorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60958283E1287006F4309 /* ResponseDataPreprocessorNode.swift */; }; @@ -176,14 +182,14 @@ 90B609A6283E1287006F4309 /* DTOMapperNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6095B283E1287006F4309 /* DTOMapperNode.swift */; }; 90B609A7283E1287006F4309 /* RawEncoderNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6095C283E1287006F4309 /* RawEncoderNode.swift */; }; 90B609A8283E1287006F4309 /* TechnicaErrorMapperNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6095E283E1287006F4309 /* TechnicaErrorMapperNode.swift */; }; - 90B609A9283E1287006F4309 /* TransportUrlRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60960283E1287006F4309 /* TransportUrlRequest.swift */; }; - 90B609AA283E1287006F4309 /* TransportUrlParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60961283E1287006F4309 /* TransportUrlParameters.swift */; }; - 90B609AB283E1287006F4309 /* UrlProcessedResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60964283E1287006F4309 /* UrlProcessedResponse.swift */; }; + 90B609A9283E1287006F4309 /* TransportURLRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60960283E1287006F4309 /* TransportURLRequest.swift */; }; + 90B609AA283E1287006F4309 /* TransportURLParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60961283E1287006F4309 /* TransportURLParameters.swift */; }; + 90B609AB283E1287006F4309 /* URLProcessedResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60964283E1287006F4309 /* URLProcessedResponse.swift */; }; 90B609AC283E1287006F4309 /* DefaultLogOrder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60965283E1287006F4309 /* DefaultLogOrder.swift */; }; 90B609AE283E1287006F4309 /* LayerTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60968283E1287006F4309 /* LayerTypes.swift */; }; 90B609AF283E1287006F4309 /* RequestCreatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6096A283E1287006F4309 /* RequestCreatorNode.swift */; }; 90B609B1283E1287006F4309 /* MultipartRequestCreatorNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6096C283E1287006F4309 /* MultipartRequestCreatorNode.swift */; }; - 90B609B3283E1287006F4309 /* RawUrlRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6096F283E1287006F4309 /* RawUrlRequest.swift */; }; + 90B609B3283E1287006F4309 /* RawURLRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B6096F283E1287006F4309 /* RawURLRequest.swift */; }; 90B609B4283E1287006F4309 /* ServerRequestsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60970283E1287006F4309 /* ServerRequestsManager.swift */; }; 90B609B5283E1287006F4309 /* ParametersEncoding+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60971283E1287006F4309 /* ParametersEncoding+Alamofire.swift */; }; 90B609B6283E1287006F4309 /* CodableRawMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B60974283E1287006F4309 /* CodableRawMapper.swift */; }; @@ -208,10 +214,10 @@ 90B609F9283E16DC006F4309 /* CacheReaderNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609D7283E16DC006F4309 /* CacheReaderNodeTests.swift */; }; 90B609FA283E16DC006F4309 /* FirstCachePolicyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609D8283E16DC006F4309 /* FirstCachePolicyTests.swift */; }; 90B609FB283E16DC006F4309 /* TestUtls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DA283E16DC006F4309 /* TestUtls.swift */; }; - 90B609FC283E16DC006F4309 /* UrlETagSaverNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DB283E16DC006F4309 /* UrlETagSaverNodeTests.swift */; }; - 90B609FD283E16DC006F4309 /* UrlETagReaderNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DC283E16DC006F4309 /* UrlETagReaderNodeTests.swift */; }; - 90B609FE283E16DC006F4309 /* UrlWithOrderedQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DD283E16DC006F4309 /* UrlWithOrderedQuery.swift */; }; - 90B609FF283E16DC006F4309 /* UrlETagUrlCacheTriggerNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DE283E16DC006F4309 /* UrlETagUrlCacheTriggerNodeTests.swift */; }; + 90B609FC283E16DC006F4309 /* URLETagSaverNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DB283E16DC006F4309 /* URLETagSaverNodeTests.swift */; }; + 90B609FD283E16DC006F4309 /* URLETagReaderNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DC283E16DC006F4309 /* URLETagReaderNodeTests.swift */; }; + 90B609FE283E16DC006F4309 /* URLWithOrderedQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DD283E16DC006F4309 /* URLWithOrderedQuery.swift */; }; + 90B609FF283E16DC006F4309 /* URLNotModifiedTriggerNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DE283E16DC006F4309 /* URLNotModifiedTriggerNodeTests.swift */; }; 90B60A00283E16DC006F4309 /* IfConnectionFailedFromCacheNodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609DF283E16DC006F4309 /* IfConnectionFailedFromCacheNodeTests.swift */; }; 90B60A09283E16DC006F4309 /* AbortingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90B609EE283E16DC006F4309 /* AbortingTests.swift */; }; 90B60A1C283E19C5006F4309 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = 90B60A1B283E19C5006F4309 /* LICENSE.txt */; }; @@ -244,7 +250,7 @@ /* Begin PBXFileReference section */ 390E696B2A13654A007F2304 /* RequestSenderNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestSenderNode.swift; sourceTree = ""; }; 390E696E2A136586007F2304 /* RequestEncodingNodeError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestEncodingNodeError.swift; sourceTree = ""; }; - 390E696F2A136586007F2304 /* UrlJsonRequestEncodingNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlJsonRequestEncodingNode.swift; sourceTree = ""; }; + 390E696F2A136586007F2304 /* URLJsonRequestEncodingNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLJsonRequestEncodingNode.swift; sourceTree = ""; }; 390E69742A136591007F2304 /* RequestEncodingModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestEncodingModel.swift; sourceTree = ""; }; 5005EB1B2BB88EC500B670CD /* CombineStreamNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineStreamNode.swift; sourceTree = ""; }; 5005EB202BB8A6D000B670CD /* AsyncNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncNode.swift; sourceTree = ""; }; @@ -252,8 +258,13 @@ 5005EB3B2BB9B1C800B670CD /* AsyncNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncNodeTests.swift; sourceTree = ""; }; 5005EB3D2BB9B4A300B670CD /* AsyncStreamNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncStreamNodeTests.swift; sourceTree = ""; }; 5005EB432BB9BC5B00B670CD /* Result+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Result+Extension.swift"; sourceTree = ""; }; + 5013490E2BE3CB10002CC3DA /* ServiceChainProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceChainProviderMock.swift; sourceTree = ""; }; + 501349102BE3CBFD002CC3DA /* ChainBuilderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChainBuilderMock.swift; sourceTree = ""; }; + 501349122BE3D790002CC3DA /* ChainConfigBuilderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChainConfigBuilderMock.swift; sourceTree = ""; }; + 501349142BE3E6D2002CC3DA /* AnyAsyncNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyAsyncNode.swift; sourceTree = ""; }; + 501349162BE3E770002CC3DA /* AnyAsyncStreamNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyAsyncStreamNode.swift; sourceTree = ""; }; 5019CCE32BC00CDC0050B6DF /* RawEncoderNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawEncoderNodeTests.swift; sourceTree = ""; }; - 5019CCE72BC018630050B6DF /* MultipartUrlRequestTrasformatorNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartUrlRequestTrasformatorNodeTests.swift; sourceTree = ""; }; + 5019CCE72BC018630050B6DF /* MultipartURLRequestTrasformatorNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartURLRequestTrasformatorNodeTests.swift; sourceTree = ""; }; 5019CCEB2BC01DDB0050B6DF /* RequestEncoderNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestEncoderNodeTests.swift; sourceTree = ""; }; 5019CCED2BC020DC0050B6DF /* MultipartRequestCreatorNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartRequestCreatorNodeTests.swift; sourceTree = ""; }; 5019CCEF2BC024D60050B6DF /* MultipartFormDataFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartFormDataFactory.swift; sourceTree = ""; }; @@ -268,7 +279,7 @@ 50528E302BAE1F9800E86CB6 /* LoggingContextMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingContextMock.swift; sourceTree = ""; }; 50528E362BAE34A400E86CB6 /* TokenRefresherActorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenRefresherActorTests.swift; sourceTree = ""; }; 5060A45B2BC3D8D2004E84E2 /* EntryinputDtoOutputNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryinputDtoOutputNodeTests.swift; sourceTree = ""; }; - 5060A4612BC3E386004E84E2 /* UrlCacheWriterNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlCacheWriterNodeTests.swift; sourceTree = ""; }; + 5060A4612BC3E386004E84E2 /* URLCacheWriterNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLCacheWriterNodeTests.swift; sourceTree = ""; }; 5060A4632BC3E660004E84E2 /* RequestSenderNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestSenderNodeTests.swift; sourceTree = ""; }; 5060A4652BC3E6E8004E84E2 /* URLSessionDataTaskActor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionDataTaskActor.swift; sourceTree = ""; }; 5060A4782BC402C0004E84E2 /* URLSessionDataTaskActorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionDataTaskActorTests.swift; sourceTree = ""; }; @@ -276,11 +287,10 @@ 5060A47F2BC4164E004E84E2 /* RequestRouterNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestRouterNodeTests.swift; sourceTree = ""; }; 5060A4812BC4184F004E84E2 /* ResponseProcessorNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResponseProcessorNodeTests.swift; sourceTree = ""; }; 5060A4832BC41C89004E84E2 /* VoidIONodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoidIONodeTests.swift; sourceTree = ""; }; - 5060A4852BC4213E004E84E2 /* LoadIndicatableNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadIndicatableNodeTests.swift; sourceTree = ""; }; 5060A4872BC42538004E84E2 /* ModelInputNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelInputNodeTests.swift; sourceTree = ""; }; 5060A4892BC42A0A004E84E2 /* ResponseHttpErrorProcessorNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResponseHttpErrorProcessorNodeTests.swift; sourceTree = ""; }; 5060A48B2BC42FD3004E84E2 /* VoidInputNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoidInputNodeTests.swift; sourceTree = ""; }; - 5060A48D2BC43116004E84E2 /* UrlRequestTrasformatorNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlRequestTrasformatorNodeTests.swift; sourceTree = ""; }; + 5060A48D2BC43116004E84E2 /* URLRequestTrasformatorNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRequestTrasformatorNodeTests.swift; sourceTree = ""; }; 5060A48F2BC43A4A004E84E2 /* VoidOutputNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoidOutputNodeTests.swift; sourceTree = ""; }; 5060A4912BC43D71004E84E2 /* LoggerStreamNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerStreamNodeTests.swift; sourceTree = ""; }; 5060A4932BC43FBD004E84E2 /* LoggerNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerNodeTests.swift; sourceTree = ""; }; @@ -290,7 +300,7 @@ 508169D62BC56B9200A43F3D /* RawDecodableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawDecodableTests.swift; sourceTree = ""; }; 508169D82BC56F5C00A43F3D /* ServerRequestsManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerRequestsManagerTests.swift; sourceTree = ""; }; 508169DA2BC5707100A43F3D /* MultipartModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartModelTests.swift; sourceTree = ""; }; - 508169E02BC57CDF00A43F3D /* UrlChainConfigModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlChainConfigModelTests.swift; sourceTree = ""; }; + 508169E02BC57CDF00A43F3D /* URLChainConfigModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLChainConfigModelTests.swift; sourceTree = ""; }; 508169E22BC57E4800A43F3D /* ArrayRawMappableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayRawMappableTests.swift; sourceTree = ""; }; 508169E42BC582EA00A43F3D /* DictionaryDTOConvertibleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryDTOConvertibleTests.swift; sourceTree = ""; }; 508169E62BC584B300A43F3D /* DTODecodableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DTODecodableTests.swift; sourceTree = ""; }; @@ -317,13 +327,13 @@ 50816A5E2BC6F85200A43F3D /* URLProtocolMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLProtocolMock.swift; sourceTree = ""; }; 50816A5F2BC6F85200A43F3D /* URLResponsesStub.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLResponsesStub.swift; sourceTree = ""; }; 50816A602BC6F85200A43F3D /* NetworkMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkMock.swift; sourceTree = ""; }; - 50816A612BC6F85200A43F3D /* UrlServiceChainBuilderMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlServiceChainBuilderMock.swift; sourceTree = ""; }; + 50816A612BC6F85200A43F3D /* URLServiceChainProviderMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLServiceChainProviderMock.swift; sourceTree = ""; }; 50816A622BC6F85200A43F3D /* URLSessionDataTaskMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionDataTaskMock.swift; sourceTree = ""; }; 50816A632BC6F85200A43F3D /* CancellableTaskMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CancellableTaskMock.swift; sourceTree = ""; }; 50816A6A2BC6F85C00A43F3D /* TokenRefresherActorMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenRefresherActorMock.swift; sourceTree = ""; }; 50816A6B2BC6F85C00A43F3D /* RawMappableMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawMappableMock.swift; sourceTree = ""; }; 50816A6C2BC6F85C00A43F3D /* RawEncodableMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawEncodableMock.swift; sourceTree = ""; }; - 50816A6D2BC6F85C00A43F3D /* UrlRouteProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlRouteProviderMock.swift; sourceTree = ""; }; + 50816A6D2BC6F85C00A43F3D /* URLRouteProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLRouteProviderMock.swift; sourceTree = ""; }; 50816A6E2BC6F85C00A43F3D /* RawDecodableMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawDecodableMock.swift; sourceTree = ""; }; 50816A6F2BC6F85C00A43F3D /* URLSessionDataTaskActorMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionDataTaskActorMock.swift; sourceTree = ""; }; 50816AE42BC706D100A43F3D /* NodeKitMock.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NodeKitMock.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -331,7 +341,12 @@ 5097DF452BCD628300D422EE /* AsyncPagerDataProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncPagerDataProvider.swift; sourceTree = ""; }; 5097DFAF2BCDFB5200D422EE /* CancellableTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CancellableTask.swift; sourceTree = ""; }; 50B6838E2BBF3615001F7EA3 /* AccessSafeNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessSafeNodeTests.swift; sourceTree = ""; }; - 50B683912BBF3816001F7EA3 /* TransportUrlRequest+Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransportUrlRequest+Equatable.swift"; sourceTree = ""; }; + 50B683912BBF3816001F7EA3 /* TransportURLRequest+Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TransportURLRequest+Equatable.swift"; sourceTree = ""; }; + 50C57AB62BE3871D004C344E /* ServiceChainProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceChainProvider.swift; sourceTree = ""; }; + 50C57AB82BE388C6004C344E /* ChainBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChainBuilder.swift; sourceTree = ""; }; + 50C57ABA2BE3A3C0004C344E /* DataChainBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataChainBuilder.swift; sourceTree = ""; }; + 50C57ABC2BE3A551004C344E /* VoidChainBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoidChainBuilder.swift; sourceTree = ""; }; + 50C57ABE2BE3A62D004C344E /* MultipartChainBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipartChainBuilder.swift; sourceTree = ""; }; 50C8EB272BBD7A2200C5CB93 /* AsyncStreamCombineNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncStreamCombineNode.swift; sourceTree = ""; }; 50C8EB292BBD7DEA00C5CB93 /* CombineNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineNode.swift; sourceTree = ""; }; 50C8EB2F2BBD90DE00C5CB93 /* CombineNodeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineNodeTests.swift; sourceTree = ""; }; @@ -350,17 +365,15 @@ 90B608CB283E1110006F4309 /* NodeKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NodeKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 90B608CE283E1110006F4309 /* NodeKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NodeKit.h; sourceTree = ""; }; 90B608D3283E1110006F4309 /* NodeKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NodeKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 90B608E4283E1268006F4309 /* UrlCacheReaderNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlCacheReaderNode.swift; sourceTree = ""; }; + 90B608E4283E1268006F4309 /* URLCacheReaderNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLCacheReaderNode.swift; sourceTree = ""; }; 90B608E5283E1268006F4309 /* FirstCachePolicyNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FirstCachePolicyNode.swift; sourceTree = ""; }; - 90B608E6283E1268006F4309 /* UrlNotModifiedTriggerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlNotModifiedTriggerNode.swift; sourceTree = ""; }; - 90B608E7283E1268006F4309 /* UrlCacheWriterNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlCacheWriterNode.swift; sourceTree = ""; }; + 90B608E6283E1268006F4309 /* URLNotModifiedTriggerNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLNotModifiedTriggerNode.swift; sourceTree = ""; }; + 90B608E7283E1268006F4309 /* URLCacheWriterNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLCacheWriterNode.swift; sourceTree = ""; }; 90B608E8283E1268006F4309 /* IfServerFailsFromCacheNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IfServerFailsFromCacheNode.swift; sourceTree = ""; }; - 90B608EA283E1268006F4309 /* UrlETagSaverNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlETagSaverNode.swift; sourceTree = ""; }; + 90B608EA283E1268006F4309 /* URLETagSaverNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLETagSaverNode.swift; sourceTree = ""; }; 90B608EB283E1268006F4309 /* ETagConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ETagConstants.swift; sourceTree = ""; }; - 90B608EC283E1268006F4309 /* UrlETagReaderNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlETagReaderNode.swift; sourceTree = ""; }; - 90B608EE283E1268006F4309 /* UrlServiceChainBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlServiceChainBuilder.swift; sourceTree = ""; }; - 90B608EF283E1268006F4309 /* UrlChainsBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlChainsBuilder.swift; sourceTree = ""; }; - 90B608F0283E1268006F4309 /* UrlChainConfigModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlChainConfigModel.swift; sourceTree = ""; }; + 90B608EC283E1268006F4309 /* URLETagReaderNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLETagReaderNode.swift; sourceTree = ""; }; + 90B608F0283E1268006F4309 /* URLChainConfigModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLChainConfigModel.swift; sourceTree = ""; }; 90B608F3283E1268006F4309 /* RawMappable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawMappable.swift; sourceTree = ""; }; 90B608F5283E1268006F4309 /* RawMappable+Dictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "RawMappable+Dictionary.swift"; sourceTree = ""; }; 90B608F6283E1268006F4309 /* Array+RawMappable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+RawMappable.swift"; sourceTree = ""; }; @@ -370,8 +383,8 @@ 90B608FC283E1268006F4309 /* MultipartFileProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipartFileProvider.swift; sourceTree = ""; }; 90B608FD283E1268006F4309 /* MultipartModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipartModel.swift; sourceTree = ""; }; 90B608FE283E1268006F4309 /* DTOConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DTOConvertible.swift; sourceTree = ""; }; - 90B60900283E1268006F4309 /* LoggableNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoggableNode.swift; sourceTree = ""; }; - 90B60930283E1287006F4309 /* UrlRequestTrasformatorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlRequestTrasformatorNode.swift; sourceTree = ""; }; + 90B60900283E1268006F4309 /* Node.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Node.swift; sourceTree = ""; }; + 90B60930283E1287006F4309 /* URLRequestTrasformatorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequestTrasformatorNode.swift; sourceTree = ""; }; 90B60931283E1287006F4309 /* RequestRouterNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestRouterNode.swift; sourceTree = ""; }; 90B60933283E1287006F4309 /* URLQueryDictionaryKeyEncodingStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLQueryDictionaryKeyEncodingStrategy.swift; sourceTree = ""; }; 90B60934283E1287006F4309 /* URLQueryArrayKeyEncodingStartegy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLQueryArrayKeyEncodingStartegy.swift; sourceTree = ""; }; @@ -384,8 +397,8 @@ 90B6093C283E1287006F4309 /* RequestModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestModel.swift; sourceTree = ""; }; 90B6093D283E1287006F4309 /* RequestEncoderNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestEncoderNode.swift; sourceTree = ""; }; 90B6093E283E1287006F4309 /* URLQueryInjectorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLQueryInjectorNode.swift; sourceTree = ""; }; - 90B6093F283E1287006F4309 /* MultipartUrlRequestTrasformatorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipartUrlRequestTrasformatorNode.swift; sourceTree = ""; }; - 90B60941283E1287006F4309 /* UrlRouteProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlRouteProvider.swift; sourceTree = ""; }; + 90B6093F283E1287006F4309 /* MultipartURLRequestTrasformatorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipartURLRequestTrasformatorNode.swift; sourceTree = ""; }; + 90B60941283E1287006F4309 /* URLRouteProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRouteProvider.swift; sourceTree = ""; }; 90B60942283E1287006F4309 /* MetadataConnectorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetadataConnectorNode.swift; sourceTree = ""; }; 90B60944283E1287006F4309 /* DTOEncoderNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DTOEncoderNode.swift; sourceTree = ""; }; 90B60945283E1287006F4309 /* VoidIONode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VoidIONode.swift; sourceTree = ""; }; @@ -393,12 +406,11 @@ 90B60947283E1287006F4309 /* ModelInputNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModelInputNode.swift; sourceTree = ""; }; 90B60949283E1287006F4309 /* VoidInputNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VoidInputNode.swift; sourceTree = ""; }; 90B6094B283E1287006F4309 /* RequestAborterNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestAborterNode.swift; sourceTree = ""; }; - 90B6094C283E1287006F4309 /* LoadIndicatorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadIndicatorNode.swift; sourceTree = ""; }; 90B6094E283E1287006F4309 /* TokenRefresherNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenRefresherNode.swift; sourceTree = ""; }; 90B6094F283E1287006F4309 /* AccessSafeNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccessSafeNode.swift; sourceTree = ""; }; 90B60950283E1287006F4309 /* HeaderInjectorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderInjectorNode.swift; sourceTree = ""; }; 90B60952283E1287006F4309 /* ResponseHttpErrorProcessorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResponseHttpErrorProcessorNode.swift; sourceTree = ""; }; - 90B60954283E1287006F4309 /* UrlDataResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlDataResponse.swift; sourceTree = ""; }; + 90B60954283E1287006F4309 /* URLDataResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLDataResponse.swift; sourceTree = ""; }; 90B60955283E1287006F4309 /* ResponseDataParserNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResponseDataParserNode.swift; sourceTree = ""; }; 90B60957283E1287006F4309 /* DataLoadingResponseProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataLoadingResponseProcessor.swift; sourceTree = ""; }; 90B60958283E1287006F4309 /* ResponseDataPreprocessorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResponseDataPreprocessorNode.swift; sourceTree = ""; }; @@ -406,14 +418,14 @@ 90B6095B283E1287006F4309 /* DTOMapperNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DTOMapperNode.swift; sourceTree = ""; }; 90B6095C283E1287006F4309 /* RawEncoderNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawEncoderNode.swift; sourceTree = ""; }; 90B6095E283E1287006F4309 /* TechnicaErrorMapperNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TechnicaErrorMapperNode.swift; sourceTree = ""; }; - 90B60960283E1287006F4309 /* TransportUrlRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransportUrlRequest.swift; sourceTree = ""; }; - 90B60961283E1287006F4309 /* TransportUrlParameters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransportUrlParameters.swift; sourceTree = ""; }; - 90B60964283E1287006F4309 /* UrlProcessedResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlProcessedResponse.swift; sourceTree = ""; }; + 90B60960283E1287006F4309 /* TransportURLRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransportURLRequest.swift; sourceTree = ""; }; + 90B60961283E1287006F4309 /* TransportURLParameters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransportURLParameters.swift; sourceTree = ""; }; + 90B60964283E1287006F4309 /* URLProcessedResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLProcessedResponse.swift; sourceTree = ""; }; 90B60965283E1287006F4309 /* DefaultLogOrder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultLogOrder.swift; sourceTree = ""; }; 90B60968283E1287006F4309 /* LayerTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayerTypes.swift; sourceTree = ""; }; 90B6096A283E1287006F4309 /* RequestCreatorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestCreatorNode.swift; sourceTree = ""; }; 90B6096C283E1287006F4309 /* MultipartRequestCreatorNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipartRequestCreatorNode.swift; sourceTree = ""; }; - 90B6096F283E1287006F4309 /* RawUrlRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawUrlRequest.swift; sourceTree = ""; }; + 90B6096F283E1287006F4309 /* RawURLRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawURLRequest.swift; sourceTree = ""; }; 90B60970283E1287006F4309 /* ServerRequestsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServerRequestsManager.swift; sourceTree = ""; }; 90B60971283E1287006F4309 /* ParametersEncoding+Alamofire.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ParametersEncoding+Alamofire.swift"; sourceTree = ""; }; 90B60974283E1287006F4309 /* CodableRawMapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodableRawMapper.swift; sourceTree = ""; }; @@ -438,10 +450,10 @@ 90B609D7283E16DC006F4309 /* CacheReaderNodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CacheReaderNodeTests.swift; sourceTree = ""; }; 90B609D8283E16DC006F4309 /* FirstCachePolicyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FirstCachePolicyTests.swift; sourceTree = ""; }; 90B609DA283E16DC006F4309 /* TestUtls.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestUtls.swift; sourceTree = ""; }; - 90B609DB283E16DC006F4309 /* UrlETagSaverNodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlETagSaverNodeTests.swift; sourceTree = ""; }; - 90B609DC283E16DC006F4309 /* UrlETagReaderNodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlETagReaderNodeTests.swift; sourceTree = ""; }; - 90B609DD283E16DC006F4309 /* UrlWithOrderedQuery.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlWithOrderedQuery.swift; sourceTree = ""; }; - 90B609DE283E16DC006F4309 /* UrlETagUrlCacheTriggerNodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UrlETagUrlCacheTriggerNodeTests.swift; sourceTree = ""; }; + 90B609DB283E16DC006F4309 /* URLETagSaverNodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLETagSaverNodeTests.swift; sourceTree = ""; }; + 90B609DC283E16DC006F4309 /* URLETagReaderNodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLETagReaderNodeTests.swift; sourceTree = ""; }; + 90B609DD283E16DC006F4309 /* URLWithOrderedQuery.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLWithOrderedQuery.swift; sourceTree = ""; }; + 90B609DE283E16DC006F4309 /* URLNotModifiedTriggerNodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLNotModifiedTriggerNodeTests.swift; sourceTree = ""; }; 90B609DF283E16DC006F4309 /* IfConnectionFailedFromCacheNodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IfConnectionFailedFromCacheNodeTests.swift; sourceTree = ""; }; 90B609E3283E16DC006F4309 /* Infrastructure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Infrastructure.swift; sourceTree = ""; }; 90B609E6283E16DC006F4309 /* CredentialsEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CredentialsEntry.swift; sourceTree = ""; }; @@ -503,7 +515,9 @@ isa = PBXGroup; children = ( 5005EB202BB8A6D000B670CD /* AsyncNode.swift */, + 501349142BE3E6D2002CC3DA /* AnyAsyncNode.swift */, 5005EB222BB8A6D900B670CD /* AsyncStreamNode.swift */, + 501349162BE3E770002CC3DA /* AnyAsyncStreamNode.swift */, ); path = Async; sourceTree = ""; @@ -517,6 +531,16 @@ name = Async; sourceTree = ""; }; + 5013490D2BE3CB05002CC3DA /* Builder */ = { + isa = PBXGroup; + children = ( + 5013490E2BE3CB10002CC3DA /* ServiceChainProviderMock.swift */, + 501349102BE3CBFD002CC3DA /* ChainBuilderMock.swift */, + 501349122BE3D790002CC3DA /* ChainConfigBuilderMock.swift */, + ); + path = Builder; + sourceTree = ""; + }; 50528E2A2BAE18DD00E86CB6 /* Core */ = { isa = PBXGroup; children = ( @@ -541,9 +565,9 @@ 508169F02BC58D3000A43F3D /* Nodes */ = { isa = PBXGroup; children = ( - 90B609DE283E16DC006F4309 /* UrlETagUrlCacheTriggerNodeTests.swift */, - 90B609DB283E16DC006F4309 /* UrlETagSaverNodeTests.swift */, - 90B609DC283E16DC006F4309 /* UrlETagReaderNodeTests.swift */, + 90B609DE283E16DC006F4309 /* URLNotModifiedTriggerNodeTests.swift */, + 90B609DB283E16DC006F4309 /* URLETagSaverNodeTests.swift */, + 90B609DC283E16DC006F4309 /* URLETagReaderNodeTests.swift */, 90B609DF283E16DC006F4309 /* IfConnectionFailedFromCacheNodeTests.swift */, 90B609D7283E16DC006F4309 /* CacheReaderNodeTests.swift */, 90B609D3283E16DC006F4309 /* TokenRefresherNodeTests.swift */, @@ -558,22 +582,21 @@ 50C8EB512BBF302E00C5CB93 /* ResponseDataPreprocessorNodeTests.swift */, 50B6838E2BBF3615001F7EA3 /* AccessSafeNodeTests.swift */, 5019CCE32BC00CDC0050B6DF /* RawEncoderNodeTests.swift */, - 5019CCE72BC018630050B6DF /* MultipartUrlRequestTrasformatorNodeTests.swift */, + 5019CCE72BC018630050B6DF /* MultipartURLRequestTrasformatorNodeTests.swift */, 5019CCEB2BC01DDB0050B6DF /* RequestEncoderNodeTests.swift */, 5019CCED2BC020DC0050B6DF /* MultipartRequestCreatorNodeTests.swift */, 5019CCF92BC05D360050B6DF /* DTOEncoderNodeTests.swift */, 5060A45B2BC3D8D2004E84E2 /* EntryinputDtoOutputNodeTests.swift */, - 5060A4612BC3E386004E84E2 /* UrlCacheWriterNodeTests.swift */, + 5060A4612BC3E386004E84E2 /* URLCacheWriterNodeTests.swift */, 5060A4632BC3E660004E84E2 /* RequestSenderNodeTests.swift */, 5060A47C2BC41343004E84E2 /* MetadataConnectorNodeTests.swift */, 5060A47F2BC4164E004E84E2 /* RequestRouterNodeTests.swift */, 5060A4812BC4184F004E84E2 /* ResponseProcessorNodeTests.swift */, 5060A4832BC41C89004E84E2 /* VoidIONodeTests.swift */, - 5060A4852BC4213E004E84E2 /* LoadIndicatableNodeTests.swift */, 5060A4872BC42538004E84E2 /* ModelInputNodeTests.swift */, 5060A4892BC42A0A004E84E2 /* ResponseHttpErrorProcessorNodeTests.swift */, 5060A48B2BC42FD3004E84E2 /* VoidInputNodeTests.swift */, - 5060A48D2BC43116004E84E2 /* UrlRequestTrasformatorNodeTests.swift */, + 5060A48D2BC43116004E84E2 /* URLRequestTrasformatorNodeTests.swift */, 5060A48F2BC43A4A004E84E2 /* VoidOutputNodeTests.swift */, 5060A4912BC43D71004E84E2 /* LoggerStreamNodeTests.swift */, 5060A4932BC43FBD004E84E2 /* LoggerNodeTests.swift */, @@ -589,7 +612,7 @@ 5060A4782BC402C0004E84E2 /* URLSessionDataTaskActorTests.swift */, 508169D82BC56F5C00A43F3D /* ServerRequestsManagerTests.swift */, 508169DA2BC5707100A43F3D /* MultipartModelTests.swift */, - 508169E02BC57CDF00A43F3D /* UrlChainConfigModelTests.swift */, + 508169E02BC57CDF00A43F3D /* URLChainConfigModelTests.swift */, 508169EC2BC5891700A43F3D /* URLRoutingTests.swift */, ); path = Network; @@ -620,18 +643,19 @@ 50816AE52BC706D100A43F3D /* NodeKitMock */ = { isa = PBXGroup; children = ( + 5013490D2BE3CB05002CC3DA /* Builder */, 50816B002BC7071800A43F3D /* Utils */, 50528E302BAE1F9800E86CB6 /* LoggingContextMock.swift */, 50816A6E2BC6F85C00A43F3D /* RawDecodableMock.swift */, 50816A6C2BC6F85C00A43F3D /* RawEncodableMock.swift */, 50816A6B2BC6F85C00A43F3D /* RawMappableMock.swift */, 50816A6A2BC6F85C00A43F3D /* TokenRefresherActorMock.swift */, - 50816A6D2BC6F85C00A43F3D /* UrlRouteProviderMock.swift */, + 50816A6D2BC6F85C00A43F3D /* URLRouteProviderMock.swift */, 50816A6F2BC6F85C00A43F3D /* URLSessionDataTaskActorMock.swift */, 50816A632BC6F85200A43F3D /* CancellableTaskMock.swift */, 50816A602BC6F85200A43F3D /* NetworkMock.swift */, 50816A5E2BC6F85200A43F3D /* URLProtocolMock.swift */, - 50816A612BC6F85200A43F3D /* UrlServiceChainBuilderMock.swift */, + 50816A612BC6F85200A43F3D /* URLServiceChainProviderMock.swift */, 50816A622BC6F85200A43F3D /* URLSessionDataTaskMock.swift */, 50816A4D2BC6F83D00A43F3D /* AborterMock.swift */, 50816A4B2BC6F83D00A43F3D /* AsyncNodeMock.swift */, @@ -664,7 +688,7 @@ 50816B012BC7072A00A43F3D /* Equatable */ = { isa = PBXGroup; children = ( - 50B683912BBF3816001F7EA3 /* TransportUrlRequest+Equatable.swift */, + 50B683912BBF3816001F7EA3 /* TransportURLRequest+Equatable.swift */, 502F9D9C2BAA39F400151A8D /* Log+Equatalbe.swift */, ); path = Equatable; @@ -727,10 +751,10 @@ isa = PBXGroup; children = ( 90B608E9283E1268006F4309 /* ETag */, - 90B608E4283E1268006F4309 /* UrlCacheReaderNode.swift */, + 90B608E4283E1268006F4309 /* URLCacheReaderNode.swift */, 90B608E5283E1268006F4309 /* FirstCachePolicyNode.swift */, - 90B608E6283E1268006F4309 /* UrlNotModifiedTriggerNode.swift */, - 90B608E7283E1268006F4309 /* UrlCacheWriterNode.swift */, + 90B608E6283E1268006F4309 /* URLNotModifiedTriggerNode.swift */, + 90B608E7283E1268006F4309 /* URLCacheWriterNode.swift */, 90B608E8283E1268006F4309 /* IfServerFailsFromCacheNode.swift */, ); path = CacheNode; @@ -739,9 +763,9 @@ 90B608E9283E1268006F4309 /* ETag */ = { isa = PBXGroup; children = ( - 90B608EA283E1268006F4309 /* UrlETagSaverNode.swift */, + 90B608EA283E1268006F4309 /* URLETagSaverNode.swift */, 90B608EB283E1268006F4309 /* ETagConstants.swift */, - 90B608EC283E1268006F4309 /* UrlETagReaderNode.swift */, + 90B608EC283E1268006F4309 /* URLETagReaderNode.swift */, ); path = ETag; sourceTree = ""; @@ -749,9 +773,12 @@ 90B608ED283E1268006F4309 /* Chains */ = { isa = PBXGroup; children = ( - 90B608EE283E1268006F4309 /* UrlServiceChainBuilder.swift */, - 90B608EF283E1268006F4309 /* UrlChainsBuilder.swift */, - 90B608F0283E1268006F4309 /* UrlChainConfigModel.swift */, + 90B608F0283E1268006F4309 /* URLChainConfigModel.swift */, + 50C57AB62BE3871D004C344E /* ServiceChainProvider.swift */, + 50C57AB82BE388C6004C344E /* ChainBuilder.swift */, + 50C57ABA2BE3A3C0004C344E /* DataChainBuilder.swift */, + 50C57ABC2BE3A551004C344E /* VoidChainBuilder.swift */, + 50C57ABE2BE3A62D004C344E /* MultipartChainBuilder.swift */, ); path = Chains; sourceTree = ""; @@ -802,7 +829,7 @@ children = ( 5005EB1F2BB8A6C500B670CD /* Async */, 5005EB182BB88DD500B670CD /* Combine */, - 90B60900283E1268006F4309 /* LoggableNode.swift */, + 90B60900283E1268006F4309 /* Node.swift */, 50528E262BADF64F00E86CB6 /* NodeResult.swift */, ); path = Node; @@ -814,7 +841,7 @@ 508169EE2BC58B9E00A43F3D /* ParameterEncoding.swift */, 390E69732A136591007F2304 /* Models */, 390E696E2A136586007F2304 /* RequestEncodingNodeError.swift */, - 390E696F2A136586007F2304 /* UrlJsonRequestEncodingNode.swift */, + 390E696F2A136586007F2304 /* URLJsonRequestEncodingNode.swift */, ); path = Encodings; sourceTree = ""; @@ -839,13 +866,13 @@ 90B6092F283E1287006F4309 /* RequestBuildingLayer */ = { isa = PBXGroup; children = ( - 90B60930283E1287006F4309 /* UrlRequestTrasformatorNode.swift */, + 90B60930283E1287006F4309 /* URLRequestTrasformatorNode.swift */, 90B60931283E1287006F4309 /* RequestRouterNode.swift */, 90B60932283E1287006F4309 /* URLQueryEncoding */, 90B60936283E1287006F4309 /* Models */, 90B6093D283E1287006F4309 /* RequestEncoderNode.swift */, 90B6093E283E1287006F4309 /* URLQueryInjectorNode.swift */, - 90B6093F283E1287006F4309 /* MultipartUrlRequestTrasformatorNode.swift */, + 90B6093F283E1287006F4309 /* MultipartURLRequestTrasformatorNode.swift */, 90B60940283E1287006F4309 /* Protocols */, 90B60942283E1287006F4309 /* MetadataConnectorNode.swift */, ); @@ -878,7 +905,7 @@ 90B60940283E1287006F4309 /* Protocols */ = { isa = PBXGroup; children = ( - 90B60941283E1287006F4309 /* UrlRouteProvider.swift */, + 90B60941283E1287006F4309 /* URLRouteProvider.swift */, ); path = Protocols; sourceTree = ""; @@ -900,7 +927,6 @@ isa = PBXGroup; children = ( 90B6094B283E1287006F4309 /* RequestAborterNode.swift */, - 90B6094C283E1287006F4309 /* LoadIndicatorNode.swift */, 90B6094D283E1287006F4309 /* AccessSafe */, 90B60950283E1287006F4309 /* HeaderInjectorNode.swift */, ); @@ -933,7 +959,7 @@ 90B60953283E1287006F4309 /* Models */ = { isa = PBXGroup; children = ( - 90B60954283E1287006F4309 /* UrlDataResponse.swift */, + 90B60954283E1287006F4309 /* URLDataResponse.swift */, ); path = Models; sourceTree = ""; @@ -967,8 +993,8 @@ 90B6095F283E1287006F4309 /* Models */ = { isa = PBXGroup; children = ( - 90B60960283E1287006F4309 /* TransportUrlRequest.swift */, - 90B60961283E1287006F4309 /* TransportUrlParameters.swift */, + 90B60960283E1287006F4309 /* TransportURLRequest.swift */, + 90B60961283E1287006F4309 /* TransportURLParameters.swift */, ); path = Models; sourceTree = ""; @@ -984,7 +1010,7 @@ 90B60963283E1287006F4309 /* Models */ = { isa = PBXGroup; children = ( - 90B60964283E1287006F4309 /* UrlProcessedResponse.swift */, + 90B60964283E1287006F4309 /* URLProcessedResponse.swift */, ); path = Models; sourceTree = ""; @@ -1005,7 +1031,7 @@ 90B6096D283E1287006F4309 /* Support */ = { isa = PBXGroup; children = ( - 90B6096F283E1287006F4309 /* RawUrlRequest.swift */, + 90B6096F283E1287006F4309 /* RawURLRequest.swift */, 90B60970283E1287006F4309 /* ServerRequestsManager.swift */, 90B60971283E1287006F4309 /* ParametersEncoding+Alamofire.swift */, ); @@ -1141,7 +1167,7 @@ isa = PBXGroup; children = ( 90B609DA283E16DC006F4309 /* TestUtls.swift */, - 90B609DD283E16DC006F4309 /* UrlWithOrderedQuery.swift */, + 90B609DD283E16DC006F4309 /* URLWithOrderedQuery.swift */, ); path = ETag; sourceTree = ""; @@ -1355,17 +1381,20 @@ 5097DF3C2BCD556E00D422EE /* AsyncPagerDataProviderMock.swift in Sources */, 50816B0E2BC7079900A43F3D /* RawEncodableMock.swift in Sources */, 50816B182BC707AE00A43F3D /* AborterMock.swift in Sources */, + 501349112BE3CBFD002CC3DA /* ChainBuilderMock.swift in Sources */, 50816B0A2BC7079000A43F3D /* DispatchQueue+Extension.swift in Sources */, 50816B0C2BC7079500A43F3D /* LoggingContextMock.swift in Sources */, - 50816B112BC7079F00A43F3D /* UrlRouteProviderMock.swift in Sources */, + 50816B112BC7079F00A43F3D /* URLRouteProviderMock.swift in Sources */, 50816B1F2BC707BB00A43F3D /* DTOEncodableMock.swift in Sources */, - 50816B162BC707AA00A43F3D /* UrlServiceChainBuilderMock.swift in Sources */, + 50816B162BC707AA00A43F3D /* URLServiceChainProviderMock.swift in Sources */, + 5013490F2BE3CB10002CC3DA /* ServiceChainProviderMock.swift in Sources */, 50816B142BC707A600A43F3D /* NetworkMock.swift in Sources */, - 50816B072BC7077C00A43F3D /* TransportUrlRequest+Equatable.swift in Sources */, + 50816B072BC7077C00A43F3D /* TransportURLRequest+Equatable.swift in Sources */, 50816B082BC7077E00A43F3D /* Log+Equatalbe.swift in Sources */, 50816B0D2BC7079700A43F3D /* RawDecodableMock.swift in Sources */, 50816B192BC707B000A43F3D /* AsyncNodeMock.swift in Sources */, 50816B1B2BC707B400A43F3D /* CombineNodeMock.swift in Sources */, + 501349132BE3D790002CC3DA /* ChainConfigBuilderMock.swift in Sources */, 50816B232BC707C300A43F3D /* MultipartFormDataMock.swift in Sources */, 50816B152BC707A800A43F3D /* URLProtocolMock.swift in Sources */, 50816B212BC707BF00A43F3D /* MockError.swift in Sources */, @@ -1389,38 +1418,40 @@ files = ( 90B60922283E1268006F4309 /* DTOConvertible.swift in Sources */, 90B6099B283E1287006F4309 /* RequestAborterNode.swift in Sources */, - 90B6090E283E1268006F4309 /* UrlCacheReaderNode.swift in Sources */, - 90B609B3283E1287006F4309 /* RawUrlRequest.swift in Sources */, + 90B6090E283E1268006F4309 /* URLCacheReaderNode.swift in Sources */, + 90B609B3283E1287006F4309 /* RawURLRequest.swift in Sources */, 5005EB232BB8A6D900B670CD /* AsyncStreamNode.swift in Sources */, 90B609AC283E1287006F4309 /* DefaultLogOrder.swift in Sources */, + 50C57AB72BE3871D004C344E /* ServiceChainProvider.swift in Sources */, 90B609BD283E1287006F4309 /* UrlRouting.swift in Sources */, - 90B609A1283E1287006F4309 /* UrlDataResponse.swift in Sources */, - 90B609AA283E1287006F4309 /* TransportUrlParameters.swift in Sources */, + 90B609A1283E1287006F4309 /* URLDataResponse.swift in Sources */, + 90B609AA283E1287006F4309 /* TransportURLParameters.swift in Sources */, 5097DF462BCD628400D422EE /* AsyncPagerDataProvider.swift in Sources */, 90B60987283E1287006F4309 /* URLQueryDictionaryKeyEncodingStrategy.swift in Sources */, 90B609BA283E1287006F4309 /* AsyncIterator.swift in Sources */, - 90B6099C283E1287006F4309 /* LoadIndicatorNode.swift in Sources */, - 90B60992283E1287006F4309 /* MultipartUrlRequestTrasformatorNode.swift in Sources */, + 90B60992283E1287006F4309 /* MultipartURLRequestTrasformatorNode.swift in Sources */, + 50C57ABB2BE3A3C0004C344E /* DataChainBuilder.swift in Sources */, 90B609A3283E1287006F4309 /* DataLoadingResponseProcessor.swift in Sources */, - 90B60911283E1268006F4309 /* UrlCacheWriterNode.swift in Sources */, + 90B60911283E1268006F4309 /* URLCacheWriterNode.swift in Sources */, 90B6099E283E1287006F4309 /* AccessSafeNode.swift in Sources */, - 90B60923283E1268006F4309 /* LoggableNode.swift in Sources */, + 90B60923283E1268006F4309 /* Node.swift in Sources */, 90B60991283E1287006F4309 /* URLQueryInjectorNode.swift in Sources */, 90B6098E283E1287006F4309 /* RoutableRequestModel.swift in Sources */, 90B6098B283E1287006F4309 /* URLQueryConfigModel.swift in Sources */, 90B60921283E1268006F4309 /* MultipartModel.swift in Sources */, - 90B609A9283E1287006F4309 /* TransportUrlRequest.swift in Sources */, + 90B609A9283E1287006F4309 /* TransportURLRequest.swift in Sources */, 390E69712A136586007F2304 /* RequestEncodingNodeError.swift in Sources */, 90B609B1283E1287006F4309 /* MultipartRequestCreatorNode.swift in Sources */, - 90B60918283E1268006F4309 /* UrlChainConfigModel.swift in Sources */, + 90B60918283E1268006F4309 /* URLChainConfigModel.swift in Sources */, 90B6098A283E1287006F4309 /* ParametersEncoding.swift in Sources */, - 90B60913283E1268006F4309 /* UrlETagSaverNode.swift in Sources */, + 90B60913283E1268006F4309 /* URLETagSaverNode.swift in Sources */, 90B609BF283E1287006F4309 /* Logable.swift in Sources */, 5097DFB02BCDFB5200D422EE /* CancellableTask.swift in Sources */, 90B609BB283E1287006F4309 /* StateStorable.swift in Sources */, 90B6098F283E1287006F4309 /* RequestModel.swift in Sources */, 90B6091C283E1268006F4309 /* Array+DtoConvertible.swift in Sources */, 90B60919283E1268006F4309 /* RawMappable.swift in Sources */, + 50C57ABF2BE3A62D004C344E /* MultipartChainBuilder.swift in Sources */, 90B6099D283E1287006F4309 /* TokenRefresherNode.swift in Sources */, 90B609B6283E1287006F4309 /* CodableRawMapper.swift in Sources */, 90B6099A283E1287006F4309 /* VoidInputNode.swift in Sources */, @@ -1438,7 +1469,8 @@ 90B60996283E1287006F4309 /* VoidIONode.swift in Sources */, 90B60912283E1268006F4309 /* IfServerFailsFromCacheNode.swift in Sources */, 90B6091E283E1268006F4309 /* MultipartModel + Convertion.swift in Sources */, - 90B60910283E1268006F4309 /* UrlNotModifiedTriggerNode.swift in Sources */, + 90B60910283E1268006F4309 /* URLNotModifiedTriggerNode.swift in Sources */, + 50C57AB92BE388C6004C344E /* ChainBuilder.swift in Sources */, 90B6098C283E1287006F4309 /* EncodableRequestModel.swift in Sources */, 90B609A0283E1287006F4309 /* ResponseHttpErrorProcessorNode.swift in Sources */, 508169EF2BC58B9E00A43F3D /* ParameterEncoding.swift in Sources */, @@ -1447,7 +1479,7 @@ 50C8EB2A2BBD7DEA00C5CB93 /* CombineNode.swift in Sources */, 90B609A5283E1287006F4309 /* ResponseProcessorNode.swift in Sources */, 90B60995283E1287006F4309 /* DTOEncoderNode.swift in Sources */, - 390E69722A136586007F2304 /* UrlJsonRequestEncodingNode.swift in Sources */, + 390E69722A136586007F2304 /* URLJsonRequestEncodingNode.swift in Sources */, 90B60914283E1268006F4309 /* ETagConstants.swift in Sources */, 50528E292BAE162600E86CB6 /* LoggerStreamNode.swift in Sources */, 90B609A2283E1287006F4309 /* ResponseDataParserNode.swift in Sources */, @@ -1463,26 +1495,27 @@ 90B60920283E1268006F4309 /* MultipartFileProvider.swift in Sources */, 90B6091B283E1268006F4309 /* Array+RawMappable.swift in Sources */, 5060A4662BC3E6E8004E84E2 /* URLSessionDataTaskActor.swift in Sources */, - 90B609AB283E1287006F4309 /* UrlProcessedResponse.swift in Sources */, - 90B60993283E1287006F4309 /* UrlRouteProvider.swift in Sources */, + 90B609AB283E1287006F4309 /* URLProcessedResponse.swift in Sources */, + 90B60993283E1287006F4309 /* URLRouteProvider.swift in Sources */, 90B6098D283E1287006F4309 /* Method.swift in Sources */, 90B609C2283E1287006F4309 /* MockerProxyConfigNode.swift in Sources */, 502F9D972BAA36CF00151A8D /* LoggingContext.swift in Sources */, 90B60988283E1287006F4309 /* URLQueryArrayKeyEncodingStartegy.swift in Sources */, 390E69752A136591007F2304 /* RequestEncodingModel.swift in Sources */, + 501349152BE3E6D2002CC3DA /* AnyAsyncNode.swift in Sources */, 90B609AF283E1287006F4309 /* RequestCreatorNode.swift in Sources */, 90B60994283E1287006F4309 /* MetadataConnectorNode.swift in Sources */, 90B609B7283E1287006F4309 /* MetadataProvider.swift in Sources */, 90B60997283E1287006F4309 /* VoidOutputNode.swift in Sources */, 50C8EB382BBDBA3B00C5CB93 /* AsyncCombineNode.swift in Sources */, + 501349172BE3E770002CC3DA /* AnyAsyncStreamNode.swift in Sources */, 90B609B5283E1287006F4309 /* ParametersEncoding+Alamofire.swift in Sources */, - 90B60917283E1268006F4309 /* UrlChainsBuilder.swift in Sources */, - 90B60915283E1268006F4309 /* UrlETagReaderNode.swift in Sources */, - 90B60985283E1287006F4309 /* UrlRequestTrasformatorNode.swift in Sources */, + 90B60915283E1268006F4309 /* URLETagReaderNode.swift in Sources */, + 90B60985283E1287006F4309 /* URLRequestTrasformatorNode.swift in Sources */, 5060A4962BC44225004E84E2 /* EntryInputDtoOutputNode.swift in Sources */, 502F9DA92BAB0CF000151A8D /* TokenRefresherActor.swift in Sources */, + 50C57ABD2BE3A551004C344E /* VoidChainBuilder.swift in Sources */, 90B609C1283E1287006F4309 /* Log.swift in Sources */, - 90B60916283E1268006F4309 /* UrlServiceChainBuilder.swift in Sources */, 90B6091D283E1268006F4309 /* DTOConvertible+Dictionary.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1495,7 +1528,7 @@ 50816AAA2BC6FE6700A43F3D /* AuthModel.swift in Sources */, 90B609F5283E16DC006F4309 /* URLQueryBoolEncodingDefaultStartegyTests.swift in Sources */, 50C8EB322BBD932D00C5CB93 /* CombineStreamNodeTests.swift in Sources */, - 90B609FE283E16DC006F4309 /* UrlWithOrderedQuery.swift in Sources */, + 90B609FE283E16DC006F4309 /* URLWithOrderedQuery.swift in Sources */, 50816AA52BC6FE2D00A43F3D /* URLResponsesStub.swift in Sources */, 50C8EB362BBD9CBF00C5CB93 /* NodeResultTests.swift in Sources */, 5060A4942BC43FBD004E84E2 /* LoggerNodeTests.swift in Sources */, @@ -1503,10 +1536,10 @@ 508169D52BC566D000A43F3D /* ArrayDTODecodableTests.swift in Sources */, 90B609F9283E16DC006F4309 /* CacheReaderNodeTests.swift in Sources */, 5060A4882BC42538004E84E2 /* ModelInputNodeTests.swift in Sources */, - 508169E12BC57CDF00A43F3D /* UrlChainConfigModelTests.swift in Sources */, + 508169E12BC57CDF00A43F3D /* URLChainConfigModelTests.swift in Sources */, 5019CCF82BC03EF90050B6DF /* AlamofireMultipartFormDataFactoryTests.swift in Sources */, 5060A48A2BC42A0A004E84E2 /* ResponseHttpErrorProcessorNodeTests.swift in Sources */, - 5060A4622BC3E386004E84E2 /* UrlCacheWriterNodeTests.swift in Sources */, + 5060A4622BC3E386004E84E2 /* URLCacheWriterNodeTests.swift in Sources */, 50C8EB342BBD951500C5CB93 /* AsyncStreamCombineNodeTests.swift in Sources */, 508169E92BC5861500A43F3D /* LogableTests.swift in Sources */, 5019CCEC2BC01DDB0050B6DF /* RequestEncoderNodeTests.swift in Sources */, @@ -1515,11 +1548,11 @@ 508169E52BC582EA00A43F3D /* DictionaryDTOConvertibleTests.swift in Sources */, 50816AA62BC6FE5100A43F3D /* Infrastructure.swift in Sources */, 50B6838F2BBF3615001F7EA3 /* AccessSafeNodeTests.swift in Sources */, - 90B609FC283E16DC006F4309 /* UrlETagSaverNodeTests.swift in Sources */, + 90B609FC283E16DC006F4309 /* URLETagSaverNodeTests.swift in Sources */, 50C8EB302BBD90DE00C5CB93 /* CombineNodeTests.swift in Sources */, 5019CCEE2BC020DC0050B6DF /* MultipartRequestCreatorNodeTests.swift in Sources */, 508169D72BC56B9200A43F3D /* RawDecodableTests.swift in Sources */, - 90B609FF283E16DC006F4309 /* UrlETagUrlCacheTriggerNodeTests.swift in Sources */, + 90B609FF283E16DC006F4309 /* URLNotModifiedTriggerNodeTests.swift in Sources */, 5060A45C2BC3D8D2004E84E2 /* EntryinputDtoOutputNodeTests.swift in Sources */, 508169D92BC56F5C00A43F3D /* ServerRequestsManagerTests.swift in Sources */, 50816AAB2BC6FE6A00A43F3D /* User.swift in Sources */, @@ -1528,7 +1561,7 @@ 508169ED2BC5891700A43F3D /* URLRoutingTests.swift in Sources */, 5060A4822BC4184F004E84E2 /* ResponseProcessorNodeTests.swift in Sources */, 508169FB2BC5C01B00A43F3D /* MultipartRequestTests.swift in Sources */, - 5060A48E2BC43116004E84E2 /* UrlRequestTrasformatorNodeTests.swift in Sources */, + 5060A48E2BC43116004E84E2 /* URLRequestTrasformatorNodeTests.swift in Sources */, 90B609F8283E16DC006F4309 /* EncodingTests.swift in Sources */, 5019CCE42BC00CDC0050B6DF /* RawEncoderNodeTests.swift in Sources */, 5005EB3E2BB9B4A300B670CD /* AsyncStreamNodeTests.swift in Sources */, @@ -1540,7 +1573,7 @@ 50C8EB4E2BBF1E9700C5CB93 /* HeaderInjectorNodeTests.swift in Sources */, 50C8EB3C2BBEB5E300C5CB93 /* AsyncPagerIteratorTests.swift in Sources */, 502F9D9A2BAA389500151A8D /* LoggingContextTests.swift in Sources */, - 90B609FD283E16DC006F4309 /* UrlETagReaderNodeTests.swift in Sources */, + 90B609FD283E16DC006F4309 /* URLETagReaderNodeTests.swift in Sources */, 50816AA82BC6FE6200A43F3D /* AuthModelEntry.swift in Sources */, 90B609F7283E16DC006F4309 /* TokenRefresherNodeTests.swift in Sources */, 508169FD2BC5D0ED00A43F3D /* SimpleURLChainTests.swift in Sources */, @@ -1549,7 +1582,7 @@ 5060A48C2BC42FD3004E84E2 /* VoidInputNodeTests.swift in Sources */, 90B609EF283E16DC006F4309 /* DTOMapperNodeTests.swift in Sources */, 508169DB2BC5707100A43F3D /* MultipartModelTests.swift in Sources */, - 5019CCE82BC018630050B6DF /* MultipartUrlRequestTrasformatorNodeTests.swift in Sources */, + 5019CCE82BC018630050B6DF /* MultipartURLRequestTrasformatorNodeTests.swift in Sources */, 50C8EB502BBF216C00C5CB93 /* ResponseDataParserNodeTests.swift in Sources */, 50816AAC2BC6FE7000A43F3D /* Credentials.swift in Sources */, 90B60A09283E16DC006F4309 /* AbortingTests.swift in Sources */, @@ -1567,7 +1600,6 @@ 90B609FA283E16DC006F4309 /* FirstCachePolicyTests.swift in Sources */, 5060A4982BC44B61004E84E2 /* DataLoadingResponseProcessorTests.swift in Sources */, 50816AA92BC6FE6400A43F3D /* UserEntry.swift in Sources */, - 5060A4862BC4213E004E84E2 /* LoadIndicatableNodeTests.swift in Sources */, 5060A4922BC43D71004E84E2 /* LoggerStreamNodeTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/NodeKit/NodeKit/CacheNode/ETag/UrlETagReaderNode.swift b/NodeKit/NodeKit/CacheNode/ETag/UrlETagReaderNode.swift deleted file mode 100644 index e9771f3af..000000000 --- a/NodeKit/NodeKit/CacheNode/ETag/UrlETagReaderNode.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// EtagReaderNode.swift -// CoreNetKit -// -// Created by Александр Кравченков on 05/03/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -import Foundation - -/// Этот узел читает eTag-токен из хранилища и добавляет его к запросу. -open class UrlETagReaderNode: AsyncNode { - - // Следующий узел для обработки. - public var next: any TransportLayerNode - - /// Ключ, по которому необходимо получить eTag-токен из хедеров. - /// По-молчанию имеет значение `eTagRequestHeaderKey` - public var etagHeaderKey: String - - /// Инициаллизирует узел. - /// - /// - Parameters: - /// - next: Следующий узел для обработки. - /// - eTagHeaderKey: Ключ, по которому необходимо добавить eTag-токен к запросу. - public init(next: some TransportLayerNode, - etagHeaderKey: String = ETagConstants.eTagRequestHeaderKey) { - self.next = next - self.etagHeaderKey = etagHeaderKey - } - - /// Пытается прочесть eTag-токен из хранилища и добавить его к запросу. - /// В случае, если прочесть токен не удалось, то управление просто передается дальше. - open func process( - _ data: TransportUrlRequest, - logContext: LoggingContextProtocol - ) async -> NodeResult { - guard - let key = data.url.withOrderedQuery(), - let tag = UserDefaults.etagStorage?.value(forKey: key) as? String - else { - return await next.process(data, logContext: logContext) - } - - var headers = data.headers - headers[self.etagHeaderKey] = tag - - let params = TransportUrlParameters(method: data.method, - url: data.url, - headers: headers) - - let newData = TransportUrlRequest(with: params, raw: data.raw) - - return await next.process(newData, logContext: logContext) - } - -} diff --git a/NodeKit/NodeKit/CacheNode/ETag/UrlETagSaverNode.swift b/NodeKit/NodeKit/CacheNode/ETag/UrlETagSaverNode.swift deleted file mode 100644 index efbddc605..000000000 --- a/NodeKit/NodeKit/CacheNode/ETag/UrlETagSaverNode.swift +++ /dev/null @@ -1,98 +0,0 @@ -// -// eTagSaverNode.swift -// CoreNetKit -// -// Created by Александр Кравченков on 04/03/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -import Foundation - -public - -// MARK: - UserDefaults eTag storage - -/// Содержит указатель на UserDefaults-хранилище для eTag токенов. -extension UserDefaults { - /// Хранилище для eTag-токенов - static var etagStorage = UserDefaults(suiteName: "\(String(describing: self.self))") -} - -/// Этот узел сохраняет пришедшие eTag-токены. -/// В качестве ключа используется абсолютный URL до endpoint-a. -open class UrlETagSaverNode: AsyncNode { - - /// Следующий узел для обработки. - public var next: (any ResponsePostprocessorLayerNode)? - - /// Ключ, по которому необходимо получить eTag-токен из хедеров. - /// По-молчанию имеет значение `ETagConstants.eTagResponseHeaderKey` - public var eTagHeaderKey: String - - /// Инициаллизирует узел. - /// - /// - Parameters: - /// - next: Следующий узел для обработки. - /// - eTagHeaderKey: Ключ, по которому необходимо получить eTag-токен из хедеров. - public init(next: (any ResponsePostprocessorLayerNode)?, eTagHeaderKey: String = ETagConstants.eTagResponseHeaderKey) { - self.next = next - self.eTagHeaderKey = eTagHeaderKey - } - - /// Пытается получить eTag-токен по ключу. - /// В любом случае передает управление дальше. - open func process( - _ data: UrlProcessedResponse, - logContext: LoggingContextProtocol - ) async -> NodeResult { - guard let tag = data.response.allHeaderFields[self.eTagHeaderKey] as? String, - let url = data.request.url, - let urlAsKey = url.withOrderedQuery() - else { - return await next?.process(data, logContext: logContext) ?? .success(()) - } - - UserDefaults.etagStorage?.set(tag, forKey: urlAsKey) - - return await next?.process(data, logContext: logContext) ?? .success(()) - } -} - -public extension URL { - - /// Берет исходный URL - /// Получает словарь параметров query - /// Если параметров нет - возвращает `self.absoluteString` - /// Если параметры есть - сортирует их соединяет в одну строку - /// Удаляет query параметры из исходного URL - /// Склеивает строковое представление URL без парамтеров со сторокой параметров - /// - /// **ВАЖНО** - /// - /// Полученная строка может быть невалидным URL - т.к. задача этого метода - получить уникальный идентификатор из URL - /// Причем так, чтобы порядок перечисления query парамтеров был не важен. - func withOrderedQuery() -> String? { - guard var comp = URLComponents(string: self.absoluteString) else { - return nil - } - - // ели нет query параметров, то просто возвращаем этот url т.к. ничего сортировать не надо - if comp.queryItems == nil || comp.queryItems?.isEmpty == true { - return self.absoluteString - } - - let ordereedQueryString = comp.queryItems! - .map { $0.description } - .sorted() - .reduce("", { $1 + $0 }) - - // если в компонентах сбросить query в nil, то в итоговом URL не будет query - comp.query = nil - - guard let url = comp.url else { - return nil - } - - return url.absoluteString + ordereedQueryString - } -} diff --git a/NodeKit/NodeKit/CacheNode/FirstCachePolicyNode.swift b/NodeKit/NodeKit/CacheNode/FirstCachePolicyNode.swift index 438e9a771..55eaab5ef 100644 --- a/NodeKit/NodeKit/CacheNode/FirstCachePolicyNode.swift +++ b/NodeKit/NodeKit/CacheNode/FirstCachePolicyNode.swift @@ -12,9 +12,9 @@ import Foundation /// /// - SeeAlso: `FirstCachePolicyNode` /// -/// - cantGetUrlRequest: Возникает в случае, если запрос отправленный в сеть не содержит `UrlRequest` +/// - cantGetURLRequest: Возникает в случае, если запрос отправленный в сеть не содержит `URLRequest` public enum BaseFirstCachePolicyNodeError: Error { - case cantGetUrlRequest + case cantGetURLRequest } /// Этот узел реализует политику кэширования @@ -24,10 +24,10 @@ open class FirstCachePolicyNode: AsyncStreamNode { // MARK: - Nested /// Тип для читающего из URL кэша узла - public typealias CacheReaderNode = AsyncNode + public typealias CacheReaderNode = AsyncNode /// Тип для следующего узла - public typealias NextProcessorNode = AsyncNode + public typealias NextProcessorNode = AsyncNode // MARK: - Properties @@ -56,12 +56,12 @@ open class FirstCachePolicyNode: AsyncStreamNode { /// В случае, если получить `URLRequest` не удалось, /// то управление просто передается следующему узлу public func process( - _ data: RawUrlRequest, + _ data: RawURLRequest, logContext: LoggingContextProtocol ) -> AsyncStream> { return AsyncStream { continuation in Task { - if let request = data.toUrlRequest() { + if let request = data.toURLRequest() { let cacheResult = await cacheReaderNode.process(request, logContext: logContext) continuation.yield(cacheResult) } diff --git a/NodeKit/NodeKit/CacheNode/IfServerFailsFromCacheNode.swift b/NodeKit/NodeKit/CacheNode/IfServerFailsFromCacheNode.swift index b6a6a8de7..b6003e665 100644 --- a/NodeKit/NodeKit/CacheNode/IfServerFailsFromCacheNode.swift +++ b/NodeKit/NodeKit/CacheNode/IfServerFailsFromCacheNode.swift @@ -15,14 +15,14 @@ open class IfConnectionFailedFromCacheNode: AsyncNode { /// Следующий узел для обработки. public var next: any AsyncNode /// Узел, считывающий данные из URL кэша. - public var cacheReaderNode: any AsyncNode + public var cacheReaderNode: any AsyncNode /// Инициаллизирует узел. /// /// - Parameters: /// - next: Следующий узел для обработки. /// - cacheReaderNode: Узел, считывающий данные из URL кэша. - public init(next: any AsyncNode, cacheReaderNode: any AsyncNode) { + public init(next: any AsyncNode, cacheReaderNode: any AsyncNode) { self.next = next self.cacheReaderNode = cacheReaderNode } @@ -36,7 +36,7 @@ open class IfConnectionFailedFromCacheNode: AsyncNode { ) async -> NodeResult { return await next.process(data, logContext: logContext) .asyncFlatMapError { error in - let request = UrlNetworkRequest(urlRequest: data) + let request = URLNetworkRequest(urlRequest: data) if error is BaseTechnicalError { await logContext.add(makeBaseTechinalLog(with: error)) return await cacheReaderNode.process(request, logContext: logContext) @@ -57,7 +57,7 @@ open class IfConnectionFailedFromCacheNode: AsyncNode { ) } - private func makeLog(with error: Error, from request: UrlNetworkRequest) -> Log { + private func makeLog(with error: Error, from request: URLNetworkRequest) -> Log { return Log( logViewObjectName + "Catching \(error)" + .lineTabDeilimeter + diff --git a/NodeKit/NodeKit/CacheNode/UrlCacheReaderNode.swift b/NodeKit/NodeKit/CacheNode/UrlCacheReaderNode.swift deleted file mode 100644 index 792d088c3..000000000 --- a/NodeKit/NodeKit/CacheNode/UrlCacheReaderNode.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// UrlCacheReaderNode.swift -// CoreNetKitWithExample -// -// Created by Александр Кравченков on 28/11/2018. -// Copyright © 2018 Александр Кравченков. All rights reserved. -// - -import Foundation - -/// Ошибки для узла `UrlCacheReaderNode` -/// -/// - cantLoadDataFromCache: Случается, если запрос в кэш завершился с ошибкой -/// - cantSerializeJson: Случается, если запрос в кэш завершился успешно, но не удалось сериализовать ответ в JSON -/// - cantCastToJson: Случается, если сериализовать ответ удалось, но каст к `Json` или к `[Json]` завершился с ошибкой -public enum BaseUrlCacheReaderError: Error { - case cantLoadDataFromCache - case cantSerializeJson - case cantCastToJson -} - -/// Этот узел отвечает за чтение данных из URL кэша. -/// Сам по себе узел является листом и не может быть встроен в сквозную цепочку. -open class UrlCacheReaderNode: AsyncNode { - - public var needsToThrowError: Bool - - public init(needsToThrowError: Bool) { - self.needsToThrowError = needsToThrowError - } - - /// Посылает запрос в кэш и пытается сериализовать данные в JSON. - open func process( - _ data: UrlNetworkRequest, - logContext: LoggingContextProtocol - ) async -> NodeResult { - guard let cachedResponse = extractCachedUrlResponse(data.urlRequest) else { - return .failure(BaseUrlCacheReaderError.cantLoadDataFromCache) - } - - guard let jsonObjsect = try? JSONSerialization.jsonObject( - with: cachedResponse.data, - options: .allowFragments - ) else { - return .failure(BaseUrlCacheReaderError.cantSerializeJson) - } - - guard let json = jsonObjsect as? Json else { - guard let json = jsonObjsect as? [Json] else { - return .failure(BaseUrlCacheReaderError.cantCastToJson) - } - return .success([MappingUtils.arrayJsonKey: json]) - } - - return .success(json) - } - - private func extractCachedUrlResponse(_ request: URLRequest) -> CachedURLResponse? { - if let response = URLCache.shared.cachedResponse(for: request) { - return response - } - return nil - } -} diff --git a/NodeKit/NodeKit/CacheNode/UrlCacheWriterNode.swift b/NodeKit/NodeKit/CacheNode/UrlCacheWriterNode.swift deleted file mode 100644 index b0d51fec8..000000000 --- a/NodeKit/NodeKit/CacheNode/UrlCacheWriterNode.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// UrlCacheWriterNode.swift -// CoreNetKitWithExample -// -// Created by Александр Кравченков on 28/11/2018. -// Copyright © 2018 Александр Кравченков. All rights reserved. -// - -import Foundation - -/// Этот узел занимается записью данных в URL кэш. -/// - Important: это "глупая" реализация, -/// в которой не учитываются server-side политики и прочее. -/// Подразумечается, что этот узел не входит в цепочку, а является листом одного из узлов. -open class UrlCacheWriterNode: AsyncNode { - - /// Формирует `CachedURLResponse` с политикой `.allowed`, сохраняет его в кэш, - /// а затем возвращает сообщение об успешной операции. - open func process( - _ data: UrlProcessedResponse, - logContext: LoggingContextProtocol - ) async -> NodeResult { - let cached = CachedURLResponse( - response: data.response, - data: data.data, - storagePolicy: .allowed - ) - URLCache.shared.storeCachedResponse(cached, for: data.request) - return .success(()) - } -} diff --git a/NodeKit/NodeKit/CacheNode/UrlNotModifiedTriggerNode.swift b/NodeKit/NodeKit/CacheNode/UrlNotModifiedTriggerNode.swift deleted file mode 100644 index cfcf9b9ea..000000000 --- a/NodeKit/NodeKit/CacheNode/UrlNotModifiedTriggerNode.swift +++ /dev/null @@ -1,74 +0,0 @@ -// -// ETagRederNode.swift -// CoreNetKit -// -// Created by Александр Кравченков on 04/03/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -import Foundation - -/// Этот узел проверяет код ответа от сервера и в случае, если код равен 304 (NotModified) -/// Узел посылает запрос в URL кэш. -open class UrlNotModifiedTriggerNode: AsyncNode { - - // MARK: - Properties - - /// Следующий узел для обратки. - public var next: any ResponseProcessingLayerNode - - /// Узел для чтения данных из кэша. - public var cacheReader: any AsyncNode - - // MARK: - Init and deinit - - /// Инициаллизирует узел. - /// - /// - Parameters: - /// - next: Следующий узел для обратки. - /// - cacheReader: Узел для чтения данных из кэша. - public init(next: some ResponseProcessingLayerNode, - cacheReader: some AsyncNode) { - self.next = next - self.cacheReader = cacheReader - } - - // MARK: - Node - - /// Проверяет http status-code. Если код соовуетствует NotModified, то возвращает запрос из кэша. - /// В протвином случае передает управление дальше. - open func process( - _ data: UrlDataResponse, - logContext: LoggingContextProtocol - ) async -> NodeResult { - guard data.response.statusCode == 304 else { - await logContext.add(makeErrorLog(code: data.response.statusCode)) - return await next.process(data, logContext: logContext) - } - - await logContext.add(makeSuccessLog()) - - return await cacheReader.process( - UrlNetworkRequest(urlRequest: data.request), - logContext: logContext - ) - } - - // MARK: - Private Methods - - private func makeErrorLog(code: Int) -> Log { - let msg = "Response status code = \(code) != 304 -> skip cache reading" - return Log( - logViewObjectName + msg, - id: objectName - ) - } - - private func makeSuccessLog() -> Log { - let msg = "Response status code == 304 -> read cache" - return Log( - logViewObjectName + msg, - id: objectName - ) - } -} diff --git a/NodeKit/NodeKit/Chains/ChainBuilder.swift b/NodeKit/NodeKit/Chains/ChainBuilder.swift new file mode 100644 index 000000000..8cdaa9912 --- /dev/null +++ b/NodeKit/NodeKit/Chains/ChainBuilder.swift @@ -0,0 +1,252 @@ +// +// ChainBuilder.swift +// NodeKit +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Foundation + +public protocol ChainConfigBuilder { + func set(query: [String: Any]) -> Self + func set(boolEncodingStartegy: URLQueryBoolEncodingStartegy) -> Self + func set(arrayEncodingStrategy: URLQueryArrayKeyEncodingStartegy) -> Self + func set(dictEncodindStrategy: URLQueryDictionaryKeyEncodingStrategy) -> Self + func set(boolEncodingStartegy: URLQueryBoolEncodingDefaultStartegy) -> Self + func set(arrayEncodingStrategy: URLQueryArrayKeyEncodingBracketsStartegy) -> Self +} + +public protocol ChainBuilder { + associatedtype Route: URLRouteProvider + + func route(_ method: Method, _ route: Route) -> Self + func encode(as encoding: ParametersEncoding) -> Self + func add(provider: MetadataProvider) -> Self + func set(metadata: [String: String]) -> Self + + func build() -> AnyAsyncNode + where I.DTO.Raw == Json, O.DTO.Raw == Json + + func build() -> AnyAsyncNode + where O.DTO.Raw == Json + + func build() -> AnyAsyncNode + where I.DTO.Raw == Json + + func build() -> AnyAsyncNode + + func build() -> AnyAsyncNode + where O.DTO.Raw == Json, I.DTO.Raw == MultipartModel<[String : Data]> + + func buildDataLoading() -> AnyAsyncNode + + func buildDataLoading() -> AnyAsyncNode + where I.DTO.Raw == Json +} + +open class URLChainBuilder: ChainConfigBuilder, ChainBuilder { + + // MARK: - Public Properties + + public let serviceChainProvider: ServiceChainProvider + public let logFilter: [String] + + /// Модель для конфигурирования URL-query в запросе. + public var config: URLQueryConfigModel + + /// Массив провайдеров заголовков для запроса. + /// Эти провайдеры используются перед непосредственной отправкой запроса. + public var headersProviders: [MetadataProvider] + + /// HTTP метод, который будет использован цепочкой + /// По-умолчанию GET + public var method: Method + + /// Кодировка данных для запроса. + /// + /// По умолчанию`.json` + public var encoding: ParametersEncoding + + /// В случае классического HTTP это Header'ы запроса. + /// По-умолчанию пустой. + public var metadata: [String: String] + + /// Маршрут до удаленного метода (в частном случае - URL endpoint'a) + public var route: Route? + + + // MARK: - Initialization + + public init( + serviceChainProvider: ServiceChainProvider = URLServiceChainProvider(), + config: URLQueryConfigModel = URLQueryConfigModel(query: [:]), + logFilter: [String] = [] + ) { + self.serviceChainProvider = serviceChainProvider + self.config = config + self.logFilter = logFilter + self.metadata = [:] + self.encoding = .json + self.method = .get + self.headersProviders = [] + } + + // MARK: - Public Methods + + open func requestRouterNode( + next: some AsyncNode, Output> + ) -> RequestRouterNode { + guard let route else { + preconditionFailure("\(self.self) URLRoute is nil") + } + + return RequestRouterNode(next: next, route: route) + } + + /// Создает цепочку узлов, описывающих слой построения запроса. + /// + /// - Parameter config: Конфигурация для запроса + open func metadataConnectorNode( + root: any AsyncNode + ) -> some AsyncNode { + let urlRequestEncodingNode = URLJsonRequestEncodingNode(next: root) + let urlRequestTrasformatorNode = URLRequestTrasformatorNode(next: urlRequestEncodingNode, method: method) + let requestEncoderNode = RequestEncoderNode(next: urlRequestTrasformatorNode, encoding: encoding) + let queryInjector = URLQueryInjectorNode(next: requestEncoderNode, config: config) + let requestRouterNode = requestRouterNode(next: queryInjector) + return MetadataConnectorNode(next: requestRouterNode, metadata: metadata) + } + + /// Создает цепочку узлов, описывающих слой построения запроса. + /// + /// - Parameter config: Конфигурация для запроса + open func metadataConnectorNode( + root: any AsyncNode + ) -> any AsyncNode, Json> { + let creator = MultipartRequestCreatorNode(next: root) + let transformator = MultipartURLRequestTrasformatorNode(next: creator, method: method) + let queryInjector = URLQueryInjectorNode(next: transformator, config: config) + let router = requestRouterNode(next: queryInjector) + return MetadataConnectorNode(next: router, metadata: metadata) + } + + // MARK: - ChainConfigBuilder + + open func set(query: [String: Any]) -> Self { + config.query = query + return self + } + + open func set(boolEncodingStartegy: URLQueryBoolEncodingStartegy) -> Self { + config.boolEncodingStartegy = boolEncodingStartegy + return self + } + + open func set(arrayEncodingStrategy: URLQueryArrayKeyEncodingStartegy) -> Self { + config.arrayEncodingStrategy = arrayEncodingStrategy + return self + } + + open func set(dictEncodindStrategy: URLQueryDictionaryKeyEncodingStrategy) -> Self { + config.dictEncodindStrategy = dictEncodindStrategy + return self + } + + open func set(boolEncodingStartegy: URLQueryBoolEncodingDefaultStartegy) -> Self { + config.boolEncodingStartegy = boolEncodingStartegy + return self + } + + open func set(arrayEncodingStrategy: URLQueryArrayKeyEncodingBracketsStartegy) -> Self { + config.arrayEncodingStrategy = arrayEncodingStrategy + return self + } + + // MARK: - ChainBuilder + + open func route(_ method: Method, _ route: Route) -> Self { + self.route = route + self.method = method + return self + } + + open func encode(as encoding: ParametersEncoding) -> Self { + self.encoding = encoding + return self + } + + open func add(provider: any MetadataProvider) -> Self { + self.headersProviders.append(provider) + return self + } + + open func set(metadata: [String: String]) -> Self { + self.metadata = metadata + return self + } + + open func build() -> AnyAsyncNode + where I.DTO.Raw == Json, O.DTO.Raw == Json { + let root = serviceChainProvider.provideRequestJsonChain(with: headersProviders) + let connector = metadataConnectorNode(root: root) + let dtoConverter = DTOMapperNode(next: connector) + let modelInputNode = ModelInputNode(next: dtoConverter) + return LoggerNode(next: modelInputNode, filters: logFilter) + .eraseToAnyNode() + } + + open func build() -> AnyAsyncNode + where O.DTO.Raw == Json { + let root = serviceChainProvider.provideRequestJsonChain(with: headersProviders) + let metadataConnectorNode = metadataConnectorNode(root: root) + let dtoConverter = DTOMapperNode(next: metadataConnectorNode) + let modelInput = ModelInputNode(next: dtoConverter) + let voidNode = VoidInputNode(next: modelInput) + return LoggerNode(next: voidNode, filters: logFilter) + .eraseToAnyNode() + } + + open func build() -> AnyAsyncNode where I.DTO.Raw == Json { + let root = serviceChainProvider.provideRequestJsonChain(with: headersProviders) + let metadataConnectorNode = metadataConnectorNode(root: root) + let voidOutput = VoidOutputNode(next: metadataConnectorNode) + return LoggerNode(next: voidOutput, filters: logFilter) + .eraseToAnyNode() + } + + open func build() -> AnyAsyncNode { + let root = serviceChainProvider.provideRequestJsonChain(with: headersProviders) + let metadataConnectorNode = metadataConnectorNode(root: root) + let voidOutput = VoidIONode(next: metadataConnectorNode) + return LoggerNode(next: voidOutput, filters: logFilter) + .eraseToAnyNode() + } + + open func build() -> AnyAsyncNode + where O.DTO.Raw == Json, I.DTO.Raw == MultipartModel<[String : Data]> { + let root = serviceChainProvider.provideRequestMultipartChain() + let metadataConnectorNode = metadataConnectorNode(root: root) + let rawEncoder = DTOMapperNode(next: metadataConnectorNode) + let dtoEncoder = ModelInputNode(next: rawEncoder) + return LoggerNode(next: dtoEncoder, filters: logFilter) + .eraseToAnyNode() + } + + open func buildDataLoading() -> AnyAsyncNode { + let root = serviceChainProvider.provideRequestDataChain(with: headersProviders) + let metadataConnectorNode = metadataConnectorNode(root: root) + let voidInput = VoidInputNode(next: metadataConnectorNode) + return LoggerNode(next: voidInput, filters: logFilter) + .eraseToAnyNode() + } + + open func buildDataLoading() -> AnyAsyncNode where I.DTO.Raw == Json { + let root = serviceChainProvider.provideRequestDataChain(with: headersProviders) + let metadataConnectorNode = metadataConnectorNode(root: root) + let rawEncoder = RawEncoderNode(next: metadataConnectorNode) + let dtoEncoder = DTOEncoderNode(rawEncodable: rawEncoder) + return LoggerNode(next: dtoEncoder, filters: logFilter) + .eraseToAnyNode() + } +} diff --git a/NodeKit/NodeKit/Chains/DataChainBuilder.swift b/NodeKit/NodeKit/Chains/DataChainBuilder.swift new file mode 100644 index 000000000..cc6cb4227 --- /dev/null +++ b/NodeKit/NodeKit/Chains/DataChainBuilder.swift @@ -0,0 +1,45 @@ +// +// DataChainBuilder.swift +// NodeKit +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Foundation + +public protocol DataChainBuilder { + func build() -> any AsyncNode + func build() -> any AsyncNode where I.DTO.Raw == Json +} + +open class URLDataChainBuilder: DataChainBuilder { + + // MARK: - Public Properties + + public let metadataConnectorNode: any AsyncNode + public let logFilter: [String] + + // MARK: - Initialization + + public init( + metadataConnectorNode: any AsyncNode, + logFilter: [String] + ) { + self.metadataConnectorNode = metadataConnectorNode + self.logFilter = logFilter + } + + // MARK: - DataChainBuilder + + open func build() -> any AsyncNode { + let voidInput = VoidInputNode(next: metadataConnectorNode) + return LoggerNode(next: voidInput, filters: logFilter) + } + + open func build() -> any AsyncNode where I : DTOEncodable, I.DTO.Raw == Json { + let rawEncoder = RawEncoderNode(next: metadataConnectorNode) + let dtoEncoder = DTOEncoderNode(rawEncodable: rawEncoder) + return LoggerNode(next: dtoEncoder, filters: logFilter) + } +} diff --git a/NodeKit/NodeKit/Chains/MultipartChainBuilder.swift b/NodeKit/NodeKit/Chains/MultipartChainBuilder.swift new file mode 100644 index 000000000..cf2c5269a --- /dev/null +++ b/NodeKit/NodeKit/Chains/MultipartChainBuilder.swift @@ -0,0 +1,41 @@ +// +// MultipartChainBuilder.swift +// NodeKit +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Foundation + +public protocol MultipartChainBuilder { + func build() -> any AsyncNode + where O.DTO.Raw == Json, I.DTO.Raw == MultipartModel<[String : Data]> +} + +open class URLMultipartChainBuilder: MultipartChainBuilder { + + // MARK: - Public Properties + + public let metadataConnectorNode: any AsyncNode, Json> + public let logFilter: [String] + + // MARK: - Initialization + + public init( + metadataConnectorNode: any AsyncNode, Json>, + logFilter: [String] + ) { + self.metadataConnectorNode = metadataConnectorNode + self.logFilter = logFilter + } + + // MARK: - MultipartChainBuilder + + open func build() -> any AsyncNode + where I.DTO.Raw == MultipartModel<[String : Data]>, O.DTO.Raw == Json { + let rawEncoder = DTOMapperNode(next: metadataConnectorNode) + let dtoEncoder = ModelInputNode(next: rawEncoder) + return LoggerNode(next: dtoEncoder, filters: logFilter) + } +} diff --git a/NodeKit/NodeKit/Chains/ServiceChainProvider.swift b/NodeKit/NodeKit/Chains/ServiceChainProvider.swift new file mode 100644 index 000000000..57c01c83e --- /dev/null +++ b/NodeKit/NodeKit/Chains/ServiceChainProvider.swift @@ -0,0 +1,77 @@ +// +// ServiceChainProvider.swift +// NodeKit +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Foundation + +public protocol ServiceChainProvider { + func provideRequestJsonChain( + with providers: [MetadataProvider] + ) -> any AsyncNode + + func provideRequestDataChain( + with providers: [MetadataProvider] + ) -> any AsyncNode + + func provideRequestMultipartChain() -> any AsyncNode +} + +open class URLServiceChainProvider: ServiceChainProvider { + + // MARK: - Public Properties + + public let session: URLSession? + + // MARK: - Initialization + + public init(session: URLSession? = nil) { + self.session = session + } + + // MARK: - ServiceChainProvider + + open func provideResponseJsonChain() -> any AsyncNode { + let responseDataParserNode = ResponseDataParserNode() + let responseDataPreprocessorNode = ResponseDataPreprocessorNode(next: responseDataParserNode) + let responseHttpErrorProcessorNode = ResponseHttpErrorProcessorNode(next: responseDataPreprocessorNode) + return ResponseProcessorNode(next: responseHttpErrorProcessorNode) + } + + open func provideRequestJsonChain( + with providers: [MetadataProvider] + ) -> any AsyncNode { + let requestSenderNode = RequestSenderNode( + rawResponseProcessor: provideResponseJsonChain(), + manager: session + ) + let technicalErrorMapperNode = TechnicaErrorMapperNode(next: requestSenderNode) + let aborterNode = AborterNode(next: technicalErrorMapperNode, aborter: requestSenderNode) + return RequestCreatorNode(next: aborterNode, providers: providers) + } + + open func provideResponseDataChain() -> any AsyncNode { + let loaderParser = DataLoadingResponseProcessor() + let errorProcessor = ResponseHttpErrorProcessorNode(next: loaderParser) + return ResponseProcessorNode(next: errorProcessor) + } + + open func provideRequestDataChain( + with providers: [MetadataProvider] + ) -> any AsyncNode { + let requestSenderNode = RequestSenderNode( + rawResponseProcessor: provideResponseDataChain(), + manager: session + ) + let aborterNode = AborterNode(next: requestSenderNode, aborter: requestSenderNode) + return RequestCreatorNode(next: aborterNode, providers: providers) + } + + open func provideRequestMultipartChain() -> any AsyncNode { + let responseChain = provideResponseJsonChain() + return RequestSenderNode(rawResponseProcessor: responseChain, manager: session) + } +} diff --git a/NodeKit/NodeKit/Chains/UrlChainConfigModel.swift b/NodeKit/NodeKit/Chains/UrlChainConfigModel.swift deleted file mode 100644 index 0f95c8c43..000000000 --- a/NodeKit/NodeKit/Chains/UrlChainConfigModel.swift +++ /dev/null @@ -1,36 +0,0 @@ -import Foundation - -/// Модель данных для конфигурироания цепочки преобразований для запроса в сеть. -public struct UrlChainConfigModel { - - /// HTTP метод, который будет использован цепочкой - public let method: Method - - /// Маршрут до удаленного метода (в частном случае - URL endpoint'a) - public let route: UrlRouteProvider - - /// В случае классического HTTP это Header'ы запроса. - /// По-умолчанию пустой. - public let metadata: [String: String] - - /// Кодировка данных для запроса. - /// По умолчанию`.json` - public let encoding: ParametersEncoding - - /// Инициаллизирует объект. - /// - /// - Parameters: - /// - method: HTTP метод, который будет использован цепочкой - /// - route: Маршрут до удаленного метод - /// - metadata: В случае классического HTTP это Header'ы запроса. По-умолчанию пустой. - /// - encoding: Кодировка данных для запроса. По-умолчанию `.json` - public init(method: Method, - route: UrlRouteProvider, - metadata: [String: String] = [:], - encoding: ParametersEncoding = .json) { - self.method = method - self.route = route - self.metadata = metadata - self.encoding = encoding - } -} diff --git a/NodeKit/NodeKit/Chains/UrlChainsBuilder.swift b/NodeKit/NodeKit/Chains/UrlChainsBuilder.swift deleted file mode 100644 index 1aede47c1..000000000 --- a/NodeKit/NodeKit/Chains/UrlChainsBuilder.swift +++ /dev/null @@ -1,291 +0,0 @@ -import Foundation - -/// Реулизует набор цепочек для отправки URL запросов. -open class UrlChainsBuilder { - - // MARK: - Properties / State - - /// Конструктор для создания сервисных цепочек. - public var serviceChain: UrlServiceChainBuilder - - /// Модель для конфигурирования URL-query в запросе. - public var urlQueryConfig: URLQueryConfigModel - - /// Массив провайдеров заголовков для запроса. - /// Эти провайдеры используются перед непосредственной отправкой запроса. - public var headersProviders: [MetadataProvider] - - /// HTTP метод, который будет использован цепочкой - /// По-умолчанию GET - public var method: Method - - /// Кодировка данных для запроса. - /// - /// По умолчанию`.json` - public var encoding: ParametersEncoding - - /// В случае классического HTTP это Header'ы запроса. - /// По-умолчанию пустой. - public var metadata: [String: String] - - /// Маршрут до удаленного метода (в частном случае - URL endpoint'a) - public var route: Route? - - /// Менеджер сессий - public var session: URLSession? - - /// Массив с ID логов, которые нужно исключить из выдачи. - public var logFilter: [String] - - // MARK: - Init - - /// Инициаллизирует объект. - /// - /// - Parameter serviceChain: Конструктор для создания сервисных цепочек. - public init(serviceChain: UrlServiceChainBuilder = UrlServiceChainBuilder()) { - self.serviceChain = serviceChain - self.urlQueryConfig = .init( - query: [:] - ) - - self.metadata = [:] - self.method = .get - self.encoding = .json - self.headersProviders = [] - self.logFilter = [] - } - - // MARK: - State mutators - - // MARK: -- URLQueryConfigModel - - open func set(query: [String: Any]) -> Self { - self.urlQueryConfig.query = query - return self - } - - open func set(boolEncodingStartegy: URLQueryBoolEncodingStartegy) -> Self { - self.urlQueryConfig.boolEncodingStartegy = boolEncodingStartegy - return self - } - - open func set(arrayEncodingStrategy: URLQueryArrayKeyEncodingStartegy) -> Self { - self.urlQueryConfig.arrayEncodingStrategy = arrayEncodingStrategy - return self - } - - open func set(dictEncodindStrategy: URLQueryDictionaryKeyEncodingStrategy) -> Self { - self.urlQueryConfig.dictEncodindStrategy = dictEncodindStrategy - return self - } - - open func set(boolEncodingStartegy: URLQueryBoolEncodingDefaultStartegy) -> Self { - self.urlQueryConfig.boolEncodingStartegy = boolEncodingStartegy - return self - } - - open func set(arrayEncodingStrategy: URLQueryArrayKeyEncodingBracketsStartegy) -> Self { - self.urlQueryConfig.arrayEncodingStrategy = arrayEncodingStrategy - return self - } - - // MARK: - Session config - - open func set(session: URLSession) -> Self { - self.session = session - return self - } - - - // MARK: - Request config - - open func set(metadata: [String: String]) -> Self { - self.metadata = metadata - return self - } - - open func route(_ method: Method, _ route: Route) -> Self { - self.method = method - self.route = route - return self - } - - open func encode(as encoding: ParametersEncoding) -> Self { - self.encoding = encoding - return self - } - - open func add(provider: MetadataProvider) -> Self { - self.headersProviders.append(provider) - return self - } - - // MARK: - Infrastructure Config - - open func log(exclude: [String]) -> Self { - self.logFilter += exclude - return self - } - - // MARK: - Public methods - - /// Создает цепочку узлов, описывающих слой построения запроса. - /// - /// - Parameter config: Конфигурация для запроса - open func requestBuildingChain() -> some AsyncNode { - let transportChain = self.serviceChain.requestTrasportChain( - providers: self.headersProviders, - session: session - ) - - let urlRequestEncodingNode = UrlJsonRequestEncodingNode(next: transportChain) - let urlRequestTrasformatorNode = UrlRequestTrasformatorNode(next: urlRequestEncodingNode, method: self.method) - let requestEncoderNode = RequestEncoderNode(next: urlRequestTrasformatorNode, encoding: self.encoding) - - let queryInjector = URLQueryInjectorNode(next: requestEncoderNode, config: self.urlQueryConfig) - - let requestRouterNode = self.requestRouterNode(next: queryInjector) - - return MetadataConnectorNode(next: requestRouterNode, metadata: self.metadata) - } - - /// Создает цепочку для отправки DTO моделей данных. - open func defaultInput() -> some AsyncNode - where Input: DTOEncodable, Output: DTODecodable, - Input.DTO.Raw == Json, Output.DTO.Raw == Json { - let buildingChain = self.requestBuildingChain() - let dtoConverter = DTOMapperNode(next: buildingChain) - return ModelInputNode(next: dtoConverter) - } - - func supportNodes() -> some AsyncNode - where Input: DTOEncodable, Output: DTODecodable, - Input.DTO.Raw == Json, Output.DTO.Raw == Json { - let loadIndicator = LoadIndicatableNode(next: self.defaultInput()) - return loadIndicator - } - - open func requestRouterNode(next: some AsyncNode, Output>) -> RequestRouterNode { - - guard let url = self.route else { - preconditionFailure("\(self.self) URLRoute is nil") - } - - return .init(next: next, route: url) - } - - /// Создает цепочку по-умолчанию. Подразумеается работа с DTO-моделями. - open func build() -> some AsyncNode - where Input: DTOEncodable, Output: DTODecodable, - Input.DTO.Raw == Json, Output.DTO.Raw == Json { - let input: some AsyncNode = self.supportNodes() - return LoggerNode(next: input, filters: self.logFilter) - } - - /// Создает обычную цепочку, только в качестве входных данных принимает `Void` - open func build() -> some AsyncNode - where Output: DTODecodable, Output.DTO.Raw == Json { - let input: some AsyncNode = self.supportNodes() - let voidNode = VoidInputNode(next: input) - return LoggerNode(next: voidNode, filters: self.logFilter) - } - - /// Создает обычную цепочку, только в качестве входных данных принимает `Void` - open func build() -> some AsyncNode - where Input: DTOEncodable, Input.DTO.Raw == Json { - let input = self.requestBuildingChain() - let indicator = LoadIndicatableNode(next: input) - let voidOutput = VoidOutputNode(next: indicator) - return LoggerNode(next: voidOutput, filters: self.logFilter) - } - - /// Создает обычную цепочку, только в качестве входных и вызодных данных имеет `Void` - open func build() -> some AsyncNode { - let input = self.requestBuildingChain() - let indicator = LoadIndicatableNode(next: input) - let voidOutput = VoidIONode(next: indicator) - return LoggerNode(next: voidOutput, filters: self.logFilter) - } - - /// Формирует цепочку для отправки multipart-запроса. - /// Для работы с этой цепочкой в качестве модели необходимо использовать `MultipartModel` - /// - /// - Returns: Корневой узел цепочки . - open func build() -> some AsyncNode where O: DTODecodable, O.DTO.Raw == Json, I: DTOEncodable, I.DTO.Raw == MultipartModel<[String : Data]> { - - let reponseProcessor = self.serviceChain.urlResponseProcessingLayerChain() - - let requestSenderNode = RequestSenderNode(rawResponseProcessor: reponseProcessor, manager: session) - - let creator = MultipartRequestCreatorNode(next: requestSenderNode) - - let transformator = MultipartUrlRequestTrasformatorNode(next: creator, method: self.method) - - let queryInjector = URLQueryInjectorNode(next: transformator, config: self.urlQueryConfig) - - let router = self.requestRouterNode(next: queryInjector) - let connector = MetadataConnectorNode(next: router, metadata: self.metadata) - - let rawEncoder = DTOMapperNode(next: connector) - let dtoEncoder = ModelInputNode(next: rawEncoder) - - let indicator = LoadIndicatableNode(next: dtoEncoder) - - return LoggerNode(next: indicator, filters: self.logFilter) - } - - /// Позволяет загрузить бинарные данные (файл) с сервера без отправки какой-то модели на сервер. - /// - Returns: Корневой узел цепочки. - open func loadData() -> some AsyncNode { - let loaderParser = DataLoadingResponseProcessor() - let errorProcessor = ResponseHttpErrorProcessorNode(next: loaderParser) - let responseProcessor = ResponseProcessorNode(next: errorProcessor) - let sender = RequestSenderNode(rawResponseProcessor: responseProcessor, manager: session) - - let creator = RequestCreatorNode(next: sender, providers: headersProviders) - - let encoding = UrlJsonRequestEncodingNode(next: creator) - let tranformator = UrlRequestTrasformatorNode(next: encoding, method: self.method) - let encoder = RequestEncoderNode(next: tranformator, encoding: self.encoding) - - let queryInjector = URLQueryInjectorNode(next: encoder, config: self.urlQueryConfig) - - let router = self.requestRouterNode(next: queryInjector) - let connector = MetadataConnectorNode(next: router, metadata: self.metadata) - - let indicator = LoadIndicatableNode(next: connector) - - let voidInput = VoidInputNode(next: indicator) - - return LoggerNode(next: voidInput, filters: self.logFilter) - } - - /// Позволяет загрузить бинарные данные (файл) с сервера. - /// - Returns: Корневой узел цепочки. - open func loadData() -> some AsyncNode where Input: DTOEncodable, Input.DTO.Raw == Json { - - let loaderParser = DataLoadingResponseProcessor() - let errorProcessor = ResponseHttpErrorProcessorNode(next: loaderParser) - let responseProcessor = ResponseProcessorNode(next: errorProcessor) - let sender = RequestSenderNode(rawResponseProcessor: responseProcessor, manager: session) - - let creator = RequestCreatorNode(next: sender, providers: headersProviders) - - let encoding = UrlJsonRequestEncodingNode(next: creator) - let tranformator = UrlRequestTrasformatorNode(next: encoding, method: self.method) - let encoder = RequestEncoderNode(next: tranformator, encoding: self.encoding) - - let queryInjector = URLQueryInjectorNode(next: encoder, config: self.urlQueryConfig) - - let router = self.requestRouterNode(next: queryInjector) - let connector = MetadataConnectorNode(next: router, metadata: self.metadata) - - let rawEncoder = RawEncoderNode(next: connector) - let dtoEncoder = DTOEncoderNode(rawEncodable: rawEncoder) - - let indicator = LoadIndicatableNode(next: dtoEncoder) - - return LoggerNode(next: indicator, filters: self.logFilter) - } - -} diff --git a/NodeKit/NodeKit/Chains/UrlServiceChainBuilder.swift b/NodeKit/NodeKit/Chains/UrlServiceChainBuilder.swift deleted file mode 100644 index 054f8850f..000000000 --- a/NodeKit/NodeKit/Chains/UrlServiceChainBuilder.swift +++ /dev/null @@ -1,28 +0,0 @@ -import Foundation - -/// Умеет создавать цепочки -open class UrlServiceChainBuilder { - - /// Конструктор по-умолчанию. - public init() { } - - /// Создает цепочку для слоя обработки ответа. - open func urlResponseProcessingLayerChain() -> any AsyncNode { - let responseDataParserNode = ResponseDataParserNode() - let responseDataPreprocessorNode = ResponseDataPreprocessorNode(next: responseDataParserNode) - let responseHttpErrorProcessorNode = ResponseHttpErrorProcessorNode(next: responseDataPreprocessorNode) - return ResponseProcessorNode(next: responseHttpErrorProcessorNode) - } - - /// Создает цепочку узлов, описывающих транспортный слой обработки. - open func requestTrasportChain(providers: [MetadataProvider], session: URLSession?) -> any TransportLayerNode { - let requestSenderNode = RequestSenderNode( - rawResponseProcessor: self.urlResponseProcessingLayerChain(), - manager: session - ) - let technicalErrorMapperNode = TechnicaErrorMapperNode(next: requestSenderNode) - let aborterNode = AborterNode(next: technicalErrorMapperNode, aborter: requestSenderNode) - return RequestCreatorNode(next: aborterNode, providers: providers) - } - -} diff --git a/NodeKit/NodeKit/Chains/VoidChainBuilder.swift b/NodeKit/NodeKit/Chains/VoidChainBuilder.swift new file mode 100644 index 000000000..ef620895e --- /dev/null +++ b/NodeKit/NodeKit/Chains/VoidChainBuilder.swift @@ -0,0 +1,56 @@ +// +// VoidChainBuilder.swift +// NodeKit +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Foundation + +public protocol VoidChainBuilder { + func build() -> any AsyncNode + where O.DTO.Raw == Json + + func build() -> any AsyncNode + where I.DTO.Raw == Json + + func build() -> any AsyncNode +} + +open class URLVoidChainBuilder: VoidChainBuilder { + + // MARK: - Public Properties + + public let metadataConnectorNode: any AsyncNode + public let logFilter: [String] + + // MARK: - Initialization + + public init( + metadataConnectorNode: any AsyncNode, + logFilter: [String] + ) { + self.metadataConnectorNode = metadataConnectorNode + self.logFilter = logFilter + } + + // MARK: - VoidChainBuilder + + open func build() -> any AsyncNode where O.DTO.Raw == Json { + let dtoConverter = DTOMapperNode(next: metadataConnectorNode) + let modelInput = ModelInputNode(next: dtoConverter) + let voidNode = VoidInputNode(next: modelInput) + return LoggerNode(next: voidNode, filters: logFilter) + } + + open func build() -> any AsyncNode where I.DTO.Raw == Json { + let voidOutput = VoidOutputNode(next: metadataConnectorNode) + return LoggerNode(next: voidOutput, filters: logFilter) + } + + open func build() -> any AsyncNode { + let voidOutput = VoidIONode(next: metadataConnectorNode) + return LoggerNode(next: voidOutput, filters: logFilter) + } +} diff --git a/NodeKit/NodeKit/Core/Convertion/Multipart/MultipartFileProvider.swift b/NodeKit/NodeKit/Core/Convertion/Multipart/MultipartFileProvider.swift index 35e213f93..8b9eeb76a 100644 --- a/NodeKit/NodeKit/Core/Convertion/Multipart/MultipartFileProvider.swift +++ b/NodeKit/NodeKit/Core/Convertion/Multipart/MultipartFileProvider.swift @@ -5,9 +5,9 @@ import Foundation /// /// - data: Поставляет файл как бинарные данные, включая имя и тип. /// - url: Поставляет файл как путь до файла. В дальнейшем он будет загружен. Для запроса будут использованы оригинальные имя и тип. -/// - customWithUrl: Как и в `url` за тем исколючением, что имя файла и тип файла можно указать самостоятельно. +/// - customWithURL: Как и в `url` за тем исколючением, что имя файла и тип файла можно указать самостоятельно. public enum MultipartFileProvider { case data(data: Data, filename: String, mimetype: String) case url(url: URL) - case customWithUrl(url: URL, filename: String, mimetype: String) + case customWithURL(url: URL, filename: String, mimetype: String) } diff --git a/NodeKit/NodeKit/Core/Node/Async/AnyAsyncNode.swift b/NodeKit/NodeKit/Core/Node/Async/AnyAsyncNode.swift new file mode 100644 index 000000000..485219c9d --- /dev/null +++ b/NodeKit/NodeKit/Core/Node/Async/AnyAsyncNode.swift @@ -0,0 +1,28 @@ +// +// AnyAsyncNode.swift +// NodeKit +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Foundation + +public struct AnyAsyncNode: AsyncNode { + + // MARK: - Private Properties + + private let node: any AsyncNode + + // MARK: - Initialization + + init(node: any AsyncNode) { + self.node = node + } + + // MARK: - AsyncNode + + public func process(_ data: Input, logContext: LoggingContextProtocol) async -> NodeResult { + return await node.process(data, logContext: logContext) + } +} diff --git a/NodeKit/NodeKit/Core/Node/Async/AnyAsyncStreamNode.swift b/NodeKit/NodeKit/Core/Node/Async/AnyAsyncStreamNode.swift new file mode 100644 index 000000000..9e6452276 --- /dev/null +++ b/NodeKit/NodeKit/Core/Node/Async/AnyAsyncStreamNode.swift @@ -0,0 +1,28 @@ +// +// AnyAsyncStreamNode.swift +// NodeKit +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +import Foundation + +public struct AnyAsyncStreamNode: AsyncStreamNode { + + // MARK: - Private Properties + + private let node: any AsyncStreamNode + + // MARK: - Initialization + + init(node: any AsyncStreamNode) { + self.node = node + } + + // MARK: - AsyncNode + + public func process(_ data: Input, logContext: LoggingContextProtocol) -> AsyncStream> { + return node.process(data, logContext: logContext) + } +} diff --git a/NodeKit/NodeKit/Core/Node/Async/AsyncNode.swift b/NodeKit/NodeKit/Core/Node/Async/AsyncNode.swift index 27e0258fe..856eb46f3 100644 --- a/NodeKit/NodeKit/Core/Node/Async/AsyncNode.swift +++ b/NodeKit/NodeKit/Core/Node/Async/AsyncNode.swift @@ -22,10 +22,16 @@ public protocol AsyncNode: Node { @discardableResult func process(_ data: Input, logContext: LoggingContextProtocol) async -> NodeResult - /// Метод возвращающий объект для обработки результатов с помощью Combine. + /// Метод, возвращающий объект для обработки результатов с помощью Combine. /// /// - Returns: Узел, поддерживающий обработку результатов с помощью Combine. func combineNode() -> any CombineNode + + /// Метод, возвращающий структуру-обертку текущей ноды. + /// Необходим для избежания проблем, возникающих при использовании any AsyncNode + /// + /// - Returns: Cтруктура-обертку текущей ноды ``AnyAsyncNode``. + func eraseToAnyNode() -> AnyAsyncNode } public extension AsyncNode { @@ -42,6 +48,14 @@ public extension AsyncNode { func combineNode() -> any CombineNode { return AsyncCombineNode(node: self) } + + /// Метод, возвращающий структуру-обертку текущей ноды. + /// Необходим для избежания проблем, возникающих при использовании any AsyncNode + /// + /// - Returns: Cтруктура-обертку текущей ноды ``AnyAsyncNode``. + func eraseToAnyNode() -> AnyAsyncNode { + return AnyAsyncNode(node: self) + } } /// Содержит синтаксический сахар для работы с узлами, у которых входящий тип = `Void` diff --git a/NodeKit/NodeKit/Core/Node/Async/AsyncStreamNode.swift b/NodeKit/NodeKit/Core/Node/Async/AsyncStreamNode.swift index 034436c50..48670050a 100644 --- a/NodeKit/NodeKit/Core/Node/Async/AsyncStreamNode.swift +++ b/NodeKit/NodeKit/Core/Node/Async/AsyncStreamNode.swift @@ -26,6 +26,12 @@ public protocol AsyncStreamNode: Node { /// /// - Returns: Узел, поддерживающий обработку результатов с помощью Combine. func combineStreamNode() -> any CombineStreamNode + + /// Метод, возвращающий структуру-обертку текущей ноды. + /// Необходим для избежания проблем, возникающих при использовании any AsyncStreamNode + /// + /// - Returns: Cтруктура-обертку текущей ноды ``AnyAsyncStreamNode``. + func eraseToAnyNode() -> AnyAsyncStreamNode } public extension AsyncStreamNode { @@ -41,6 +47,14 @@ public extension AsyncStreamNode { func combineStreamNode() -> any CombineStreamNode { return AsyncStreamCombineNode(node: self) } + + /// Метод, возвращающий структуру-обертку текущей ноды. + /// Необходим для избежания проблем, возникающих при использовании any AsyncStreamNode + /// + /// - Returns: Cтруктура-обертку текущей ноды ``AnyAsyncStreamNode``. + func eraseToAnyNode() -> AnyAsyncStreamNode { + return AnyAsyncStreamNode(node: self) + } } /// Содержит синтаксический сахар для работы с узлами, у которых входящий тип = `Void` diff --git a/NodeKit/NodeKit/Core/Node/LoggableNode.swift b/NodeKit/NodeKit/Core/Node/Node.swift similarity index 100% rename from NodeKit/NodeKit/Core/Node/LoggableNode.swift rename to NodeKit/NodeKit/Core/Node/Node.swift diff --git a/NodeKit/NodeKit/Encodings/Models/RequestEncodingModel.swift b/NodeKit/NodeKit/Encodings/Models/RequestEncodingModel.swift index 5e83d50da..440eb976d 100644 --- a/NodeKit/NodeKit/Encodings/Models/RequestEncodingModel.swift +++ b/NodeKit/NodeKit/Encodings/Models/RequestEncodingModel.swift @@ -8,11 +8,11 @@ import Foundation -/// Модель слоя `Encoding`, собирает все данные для реквеста. Используется в `UrlRequestEncodingNode` +/// Модель слоя `Encoding`, собирает все данные для реквеста. Используется в `URLRequestEncodingNode` public struct RequestEncodingModel { /// Параметры для формирования запроса. - public let urlParameters: TransportUrlParameters + public let urlParameters: TransportURLParameters /// Данные в виде `BSON` или `JSON` public let raw: Json /// Кодировка данных запроса @@ -22,7 +22,7 @@ public struct RequestEncodingModel { /// - Parameter urlParameters: Параметры для формирования запроса. /// - Parameter raw: Данные в виде `JSON` /// - Parameter encoding: Кодировка данных запроса - public init(urlParameters: TransportUrlParameters, + public init(urlParameters: TransportURLParameters, raw: Json, encoding: ParametersEncoding?) { self.urlParameters = urlParameters diff --git a/NodeKit/NodeKit/Encodings/ParameterEncoding.swift b/NodeKit/NodeKit/Encodings/ParameterEncoding.swift index 9d2fa57c9..927a6ff1f 100644 --- a/NodeKit/NodeKit/Encodings/ParameterEncoding.swift +++ b/NodeKit/NodeKit/Encodings/ParameterEncoding.swift @@ -31,15 +31,15 @@ public typealias Parameters = [String: Any] /// A type used to define how a set of parameters are applied to a `URLRequest`. public protocol ParameterEncoding { - /// Create a TransportUrlRequest model by encoding parameters and apply them into an exisiting url parameters + /// Create a TransportURLRequest model by encoding parameters and apply them into an exisiting url parameters /// /// - parameter urlParameters: The request parameters that should by applied /// - parameter parameters: Raw `Json` parameters to apply /// /// - throws: An `AFError.parameterEncodingFailed` error if encoding fails. /// - /// - returns: The encoded TransportUrlRequest. - func encode(urlParameters: TransportUrlParameters, parameters: Json?) throws -> TransportUrlRequest + /// - returns: The encoded TransportURLRequest. + func encode(urlParameters: TransportURLParameters, parameters: Json?) throws -> TransportURLRequest } // MARK: - @@ -148,9 +148,9 @@ public struct URLEncoding: ParameterEncoding { } // MARK: Encoding - public func encode(urlParameters: TransportUrlParameters, parameters: Json?) throws -> TransportUrlRequest { + public func encode(urlParameters: TransportURLParameters, parameters: Json?) throws -> TransportURLRequest { guard let parameters = parameters else { - return TransportUrlRequest(with: urlParameters, raw: nil) + return TransportURLRequest(with: urlParameters, raw: nil) } var body: Data? = nil @@ -161,10 +161,10 @@ public struct URLEncoding: ParameterEncoding { if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty { let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters) urlComponents.percentEncodedQuery = percentEncodedQuery - guard let unwrapedUrl = urlComponents.url else { + guard let unwrapedURL = urlComponents.url else { throw AFError.parameterEncodingFailed(reason: .missingURL) } - url = unwrapedUrl + url = unwrapedURL } } else { if headers["Content-Type"] == nil { @@ -172,7 +172,7 @@ public struct URLEncoding: ParameterEncoding { } body = Data(query(parameters).utf8) } - return TransportUrlRequest(method: urlParameters.method, + return TransportURLRequest(method: urlParameters.method, url: url, headers: headers, raw: body) @@ -256,9 +256,9 @@ public struct JSONEncoding: ParameterEncoding { } // MARK: Encoding - public func encode(urlParameters: TransportUrlParameters, parameters: Json?) throws -> TransportUrlRequest { + public func encode(urlParameters: TransportURLParameters, parameters: Json?) throws -> TransportURLRequest { guard let parameters = parameters else { - return TransportUrlRequest(with: urlParameters, raw: nil) + return TransportURLRequest(with: urlParameters, raw: nil) } let body: Data @@ -280,7 +280,7 @@ public struct JSONEncoding: ParameterEncoding { throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error)) } - return TransportUrlRequest(method: urlParameters.method, + return TransportURLRequest(method: urlParameters.method, url: urlParameters.url, headers: headers, raw: body) diff --git a/NodeKit/NodeKit/Encodings/UrlJsonRequestEncodingNode.swift b/NodeKit/NodeKit/Encodings/UrlJsonRequestEncodingNode.swift deleted file mode 100644 index 6dc31586d..000000000 --- a/NodeKit/NodeKit/Encodings/UrlJsonRequestEncodingNode.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// UrlJsonRequestEncodingNode.swift -// NodeKit -// -// Created by Vladislav Krupenko on 06.05.2020. -// Copyright © 2020 Кравченков Александр. All rights reserved. -// - -import Foundation - -open class UrlJsonRequestEncodingNode: AsyncNode { - - /// Следующий узел для обработки. - public var next: any AsyncNode - - /// Инициаллизирует узел. - /// - /// - Parameters: - /// - next: Следйющий узел для обработки. - public init(next: some AsyncNode) { - self.next = next - } - - open func process( - _ data: RequestEncodingModel, - logContext: LoggingContextProtocol - ) async -> NodeResult { - var log = getLogMessage(data) - let paramEncoding = parameterEncoding(from: data) - - guard let encoding = paramEncoding else { - log += "Missed encoding type -> terminate with error" - await logContext.add(log) - return .failure(RequestEncodingNodeError.missedJsonEncodingType) - } - do { - let request = try encoding.encode(urlParameters: data.urlParameters, parameters: data.raw) - log += "type: Json" - return await next.process(request, logContext: logContext) - } catch { - log += "But can't encode data -> terminate with error" - await logContext.add(log) - return .failure(RequestEncodingNodeError.unsupportedDataType) - } - } - - // MARK: - Private Methods - - private func parameterEncoding(from data: RequestEncodingModel) -> ParameterEncoding? { - if data.urlParameters.method == .get { - return URLEncoding.default - } - return data.encoding?.raw - - } - - private func getLogMessage(_ data: RequestEncodingModel) -> Log { - let message = "<<<===\(self.objectName)===>>>\n" + - "input: \(type(of: data))" + - "encoding: \(String(describing: data.encoding))" + - "raw: \(String(describing: data.raw))" - return Log(message, id: self.objectName, order: LogOrder.requestEncodingNode) - } -} diff --git a/NodeKit/NodeKit/Layers/LayerTypes.swift b/NodeKit/NodeKit/Layers/LayerTypes.swift index 7f6a069fe..5320810c8 100644 --- a/NodeKit/NodeKit/Layers/LayerTypes.swift +++ b/NodeKit/NodeKit/Layers/LayerTypes.swift @@ -9,10 +9,10 @@ import Foundation /// Явный тип для слоя транспорта. -public typealias TransportLayerNode = AsyncNode +public typealias TransportLayerNode = AsyncNode /// Явный тип для слоя обработки запроса. public typealias RequestProcessingLayerNode = AsyncNode /// Явный тип для слоя обработки ответа `JSON` -public typealias ResponseProcessingLayerNode = AsyncNode +public typealias ResponseProcessingLayerNode = AsyncNode /// Явный тип для слоя постобработки ответа с `JSON` -public typealias ResponsePostprocessorLayerNode = AsyncNode +public typealias ResponsePostprocessorLayerNode = AsyncNode diff --git a/NodeKit/NodeKit/Layers/RequestBuildingLayer/Models/ParametersEncoding.swift b/NodeKit/NodeKit/Layers/RequestBuildingLayer/Models/ParametersEncoding.swift index 16ceaac7b..b8f1fbc18 100644 --- a/NodeKit/NodeKit/Layers/RequestBuildingLayer/Models/ParametersEncoding.swift +++ b/NodeKit/NodeKit/Layers/RequestBuildingLayer/Models/ParametersEncoding.swift @@ -12,10 +12,10 @@ import Foundation /// /// - json: Потыается закодировать данные в формате JSON и кладет их в тело запроса. /// - jsonArray: Для кодировки массивов в Json. ИСпользуется если нужно получить Json вида `[ {}, {}, ...]` -/// - formUrl: Пытается закодировать данные в формате FormUrl и кладет из в тело запроса. +/// - formURL: Пытается закодировать данные в формате FormURL и кладет из в тело запроса. /// - urlQuery: Получает из данных строку,кодирует в URL-строку и добавляет к URL запроса. public enum ParametersEncoding { case json - case formUrl + case formURL case urlQuery } diff --git a/NodeKit/NodeKit/Layers/RequestBuildingLayer/MultipartUrlRequestTrasformatorNode.swift b/NodeKit/NodeKit/Layers/RequestBuildingLayer/MultipartUrlRequestTrasformatorNode.swift deleted file mode 100644 index aaa7a0d16..000000000 --- a/NodeKit/NodeKit/Layers/RequestBuildingLayer/MultipartUrlRequestTrasformatorNode.swift +++ /dev/null @@ -1,41 +0,0 @@ -import Foundation - -/// Этот узел переводит Generic запрос в конкретную реализацию. -/// Данный узел работает с URL-запросами, по HTTP протоколу с JSON -open class MultipartUrlRequestTrasformatorNode: AsyncNode { - - /// Следйющий узел для обработки. - open var next: any AsyncNode - - /// HTTP метод для запроса. - open var method: Method - - /// Инициаллизирует узел. - /// - /// - Parameters: - /// - next: Следйющий узел для обработки. - /// - method: HTTP метод для запроса. - public init(next: any AsyncNode, method: Method) { - self.next = next - self.method = method - } - - /// Конструирует модель для для работы на транспортном уровне цепочки. - /// - /// - Parameter data: Данные для дальнейшей обработки. - open func process( - _ data: RoutableRequestModel>, - logContext: LoggingContextProtocol - ) async -> NodeResult { - return await .withMappedExceptions { - let url = try data.route.url() - let request = MultipartUrlRequest( - method: method, - url: url, - headers: data.metadata, - data: data.raw - ) - return await next.process(request, logContext: logContext) - } - } -} diff --git a/NodeKit/NodeKit/Layers/RequestBuildingLayer/Protocols/UrlRouteProvider.swift b/NodeKit/NodeKit/Layers/RequestBuildingLayer/Protocols/UrlRouteProvider.swift deleted file mode 100644 index 3373e3b92..000000000 --- a/NodeKit/NodeKit/Layers/RequestBuildingLayer/Protocols/UrlRouteProvider.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// UrlProvider.swift -// CoreNetKit -// -// Created by Александр Кравченков on 05/03/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -import Foundation - -/// ИНтерфей для провайдера URL маршрутов -public protocol UrlRouteProvider { - - /// Возвращает URL - /// - /// - Returns: URL-маршрут этого объекта - /// - Throws: Может вызвать исключение в случае, если состояние объекта не позволяет вернуть маршрут. - func url() throws -> URL -} diff --git a/NodeKit/NodeKit/Layers/RequestBuildingLayer/RequestEncoderNode.swift b/NodeKit/NodeKit/Layers/RequestBuildingLayer/RequestEncoderNode.swift index 7f8ece17a..14c759b37 100644 --- a/NodeKit/NodeKit/Layers/RequestBuildingLayer/RequestEncoderNode.swift +++ b/NodeKit/NodeKit/Layers/RequestBuildingLayer/RequestEncoderNode.swift @@ -16,7 +16,7 @@ import Foundation /// - `Node` /// - `RequestRouterNode` /// - `EncodableRequestModel` -/// - `UrlRequestTrasformatorNode` +/// - `URLRequestTrasformatorNode` open class RequestEncoderNode: AsyncNode { /// Тип для следюущего узла. diff --git a/NodeKit/NodeKit/Layers/RequestBuildingLayer/URLQueryInjectorNode.swift b/NodeKit/NodeKit/Layers/RequestBuildingLayer/URLQueryInjectorNode.swift index 14fe68dc4..0532856f9 100644 --- a/NodeKit/NodeKit/Layers/RequestBuildingLayer/URLQueryInjectorNode.swift +++ b/NodeKit/NodeKit/Layers/RequestBuildingLayer/URLQueryInjectorNode.swift @@ -3,9 +3,9 @@ import Foundation /// Ошибки для узла `URLQueryInjectorNode` public enum URLQueryInjectorNodeError: Error { /// Возникает в случае, если не удалось создать URLComponents из URL - case cantCreateUrlComponentsFromUrlString + case cantCreateURLComponentsFromURLString /// Возникает в случае, если построить URLComponents удалось, а вот получить из него URL - нет. - case cantCreateUrlFromUrlComponents + case cantCreateURLFromURLComponents } /// Узел, который позволяет добавить данные в URL-Query. @@ -25,7 +25,7 @@ open class URLQueryInjectorNode: AsyncNode { // MARK: - Properties /// Следующий по порядку узел. - open var next: any AsyncNode, Output> + open var next: any AsyncNode, Output> open var config: URLQueryConfigModel @@ -35,7 +35,7 @@ open class URLQueryInjectorNode: AsyncNode { /// - Parameter next: Следующий по порядку узел. /// - Parameter config: Конфигурация для узла. public init( - next: any AsyncNode, Output>, + next: any AsyncNode, Output>, config: URLQueryConfigModel ) { self.next = next @@ -45,10 +45,10 @@ open class URLQueryInjectorNode: AsyncNode { // MARK: - Public methods /// Добавляет URL-query если может и передает управление следующему узлу. - /// В случае, если не удалось обработать URL, то возвращает ошибку `cantCreateUrlComponentsFromUrlString` + /// В случае, если не удалось обработать URL, то возвращает ошибку `cantCreateURLComponentsFromURLString` /// - SeeAlso: ``URLQueryInjectorNodeError`` open func process( - _ data: RoutableRequestModel, + _ data: RoutableRequestModel, logContext: LoggingContextProtocol ) async -> NodeResult { return await .withMappedExceptions { @@ -88,20 +88,20 @@ open class URLQueryInjectorNode: AsyncNode { } private func transform( - from data: RoutableRequestModel - ) async throws -> NodeResult> { + from data: RoutableRequestModel + ) async throws -> NodeResult> { guard !config.query.isEmpty else { return .success(data) } return await urlComponents(try data.route.url()) .flatMap { guard let url = $0.url else { - return .failure(NodeError.cantCreateUrlFromUrlComponents) + return .failure(NodeError.cantCreateURLFromURLComponents) } return .success(url) } .map { - return RoutableRequestModel( + return RoutableRequestModel( metadata: data.metadata, raw: data.raw, route: $0 @@ -111,7 +111,7 @@ open class URLQueryInjectorNode: AsyncNode { private func urlComponents(_ url: URL) async -> NodeResult { guard var urlComponents = URLComponents(string: url.absoluteString) else { - return .failure(NodeError.cantCreateUrlComponentsFromUrlString) + return .failure(NodeError.cantCreateURLComponentsFromURLString) } urlComponents.queryItems = config.query .map { makeQueryComponents(from: $1, by: $0) } diff --git a/NodeKit/NodeKit/Layers/RequestBuildingLayer/UrlRequestTrasformatorNode.swift b/NodeKit/NodeKit/Layers/RequestBuildingLayer/UrlRequestTrasformatorNode.swift deleted file mode 100644 index 33afbe6fc..000000000 --- a/NodeKit/NodeKit/Layers/RequestBuildingLayer/UrlRequestTrasformatorNode.swift +++ /dev/null @@ -1,45 +0,0 @@ -import Foundation - -/// Этот узел переводит Generic запрос в конкретную реализацию. -/// Данный узел работает с URL-запросами, по HTTP протоколу с JSON -open class UrlRequestTrasformatorNode: AsyncNode { - - /// Следйющий узел для обработки. - public var next: any AsyncNode - - /// HTTP метод для запроса. - public var method: Method - - /// Инициаллизирует узел. - /// - /// - Parameters: - /// - next: Следйющий узел для обработки. - /// - method: HTTP метод для запроса. - public init(next: some AsyncNode, method: Method) { - self.next = next - self.method = method - } - - /// Конструирует модель для для работы на транспортном уровне цепочки. - /// - /// - Parameter data: Данные для дальнейшей обработки. - open func process( - _ data: EncodableRequestModel, - logContext: LoggingContextProtocol - ) async -> NodeResult { - return await .withMappedExceptions { - let url = try data.route.url() - let params = TransportUrlParameters( - method: method, - url: url, - headers: data.metadata - ) - let encodingModel = RequestEncodingModel( - urlParameters: params, - raw: data.raw, - encoding: data.encoding ?? nil - ) - return await next.process(encodingModel, logContext: logContext) - } - } -} diff --git a/NodeKit/NodeKit/Layers/RequestProcessingLayer/MultipartRequestCreatorNode.swift b/NodeKit/NodeKit/Layers/RequestProcessingLayer/MultipartRequestCreatorNode.swift index 21156f139..659389783 100644 --- a/NodeKit/NodeKit/Layers/RequestProcessingLayer/MultipartRequestCreatorNode.swift +++ b/NodeKit/NodeKit/Layers/RequestProcessingLayer/MultipartRequestCreatorNode.swift @@ -2,7 +2,7 @@ import Foundation import NodeKitThirdParty /// Модель для внутреннего представления multipart запроса. -public struct MultipartUrlRequest { +public struct MultipartURLRequest { /// HTTP метод. public let method: Method @@ -51,7 +51,7 @@ open class MultipartRequestCreatorNode: AsyncNode { /// /// - Parameter data: Данные для конфигурирования и последующей отправки запроса. open func process( - _ data: MultipartUrlRequest, + _ data: MultipartURLRequest, logContext: LoggingContextProtocol ) async -> NodeResult { return await .withMappedExceptions { @@ -73,7 +73,7 @@ open class MultipartRequestCreatorNode: AsyncNode { } } - private func getLogMessage(_ data: MultipartUrlRequest) -> Log { + private func getLogMessage(_ data: MultipartURLRequest) -> Log { var message = "<<<===\(self.objectName)===>>>\n" message += "input: \(type(of: data))\n\t" message += "method: \(data.method.rawValue)\n\t" @@ -84,7 +84,7 @@ open class MultipartRequestCreatorNode: AsyncNode { return Log(message, id: self.objectName, order: LogOrder.requestCreatorNode) } - open func append(multipartForm: MultipartFormDataProtocol, with request: MultipartUrlRequest) { + open func append(multipartForm: MultipartFormDataProtocol, with request: MultipartURLRequest) { request.data.payloadModel.forEach { key, value in multipartForm.append(value, withName: key) } @@ -94,7 +94,7 @@ open class MultipartRequestCreatorNode: AsyncNode { multipartForm.append(data, withName: key, fileName: filename, mimeType: mimetype) case .url(url: let url): multipartForm.append(url, withName: key) - case .customWithUrl(url: let url, filename: let filename, mimetype: let mimetype): + case .customWithURL(url: let url, filename: let filename, mimetype: let mimetype): multipartForm.append(url, withName: key, fileName: filename, mimeType: mimetype) } } diff --git a/NodeKit/NodeKit/Layers/RequestProcessingLayer/RequestCreatorNode.swift b/NodeKit/NodeKit/Layers/RequestProcessingLayer/RequestCreatorNode.swift index 3eecd985a..f137e4a0e 100644 --- a/NodeKit/NodeKit/Layers/RequestProcessingLayer/RequestCreatorNode.swift +++ b/NodeKit/NodeKit/Layers/RequestProcessingLayer/RequestCreatorNode.swift @@ -21,7 +21,7 @@ open class RequestCreatorNode: AsyncNode { /// /// - Parameter data: Данные для конфигурирования и последующей отправки запроса. open func process( - _ data: TransportUrlRequest, + _ data: TransportURLRequest, logContext: LoggingContextProtocol ) async -> NodeResult { var mergedHeaders = data.headers @@ -39,7 +39,7 @@ open class RequestCreatorNode: AsyncNode { return await next.process(request, logContext: logContext) } - private func getLogMessage(_ data: TransportUrlRequest) -> Log { + private func getLogMessage(_ data: TransportURLRequest) -> Log { var message = "<<<===\(self.objectName)===>>>\n" message += "input: \(type(of: data))\n\t" message += "method: \(data.method.rawValue)\n\t" diff --git a/NodeKit/NodeKit/Layers/RequestProcessingLayer/Support/ParametersEncoding+Alamofire.swift b/NodeKit/NodeKit/Layers/RequestProcessingLayer/Support/ParametersEncoding+Alamofire.swift index 12c9b21b7..7ab0f4ac2 100644 --- a/NodeKit/NodeKit/Layers/RequestProcessingLayer/Support/ParametersEncoding+Alamofire.swift +++ b/NodeKit/NodeKit/Layers/RequestProcessingLayer/Support/ParametersEncoding+Alamofire.swift @@ -14,7 +14,7 @@ extension NodeKit.ParametersEncoding { switch self { case .json: return JSONEncoding() - case .formUrl: + case .formURL: return URLEncoding.default case .urlQuery: return URLEncoding.queryString diff --git a/NodeKit/NodeKit/Layers/RequestProcessingLayer/Support/RawUrlRequest.swift b/NodeKit/NodeKit/Layers/RequestProcessingLayer/Support/RawUrlRequest.swift deleted file mode 100644 index 0768d19b9..000000000 --- a/NodeKit/NodeKit/Layers/RequestProcessingLayer/Support/RawUrlRequest.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// RawUrlRequest.swift -// CoreNetKit -// -// Created by Александр Кравченков on 23/03/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -import Foundation - -/// Обертка над URLRequest. -public struct UrlNetworkRequest { - /// Данные запроса. - public let urlRequest: URLRequest - - public init(urlRequest: URLRequest) { - self.urlRequest = urlRequest - } -} - -/// Обертка над `Alamofire.DataRequest` -public struct RawUrlRequest { - - /// Alamifire запрос. - public let dataRequest: URLRequest? - - public init(dataRequest: URLRequest?) { - self.dataRequest = dataRequest - } - - /// Конвертирвет себя в `UrlNetworkRequest` - /// - /// - Returns: Новое представление запроса. - public func toUrlRequest() -> UrlNetworkRequest? { - guard let request = dataRequest else { - return nil - } - return UrlNetworkRequest(urlRequest: request) - } - -} diff --git a/NodeKit/NodeKit/Layers/ResponsePostprocessingNode/Models/UrlProcessedResponse.swift b/NodeKit/NodeKit/Layers/ResponsePostprocessingNode/Models/UrlProcessedResponse.swift deleted file mode 100644 index 85723058f..000000000 --- a/NodeKit/NodeKit/Layers/ResponsePostprocessingNode/Models/UrlProcessedResponse.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// UrlProcessedResponse.swift -// CoreNetKit -// -// Created by Александр Кравченков on 04/02/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -import Foundation - -/// Используется для передачи данных внутри слоя постпроцессинга запроса. -public struct UrlProcessedResponse { - - private let _dataResponse: UrlDataResponse - - /// URL запрос, отправленный серверу. - public var request: URLRequest { - return self._dataResponse.request - } - - /// Ответ, полученный от сервера. - public var response: HTTPURLResponse { - return self._dataResponse.response - } - - /// Метрики запроса. - public var metrics: URLSessionTaskMetrics? { - return self._dataResponse.metrics - } - - /// Время, затраченное на сериализацию овтета. - public var serializationDuration: TimeInterval { - return self._dataResponse.serializationDuration - } - - /// Ответ, возвращенный сервером. - public var data: Data { - return self._dataResponse.data - } - - /// JSON сериализованный после обработки ответа. - public let json: Json - - /// Инициаллизирует объект. - /// - /// - Parameters: - /// - dataResponse: Модель полученная после обрабокти ответа. - /// - json: Сериализованный JSON - public init(dataResponse: UrlDataResponse, json: Json) { - self._dataResponse = dataResponse - self.json = json - } -} diff --git a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/DataLoading/DataLoadingResponseProcessor.swift b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/DataLoading/DataLoadingResponseProcessor.swift index 649692cb6..77459f0e9 100644 --- a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/DataLoading/DataLoadingResponseProcessor.swift +++ b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/DataLoading/DataLoadingResponseProcessor.swift @@ -15,18 +15,18 @@ import Foundation open class DataLoadingResponseProcessor: AsyncNode { /// Узел для постобработки загруженных данных. - open var next: (any AsyncNode)? + open var next: (any AsyncNode)? /// Инициаллизирует узел. /// /// - Parameter next: Узел для постобработки загруженных данных. По-умолчанию nil. - public init(next: (any AsyncNode)? = nil) { + public init(next: (any AsyncNode)? = nil) { self.next = next } /// В случае, если узел для постобработки существует, то вызывает его, если нет - возвращает данные. open func process( - _ data: UrlDataResponse, + _ data: URLDataResponse, logContext: LoggingContextProtocol ) async -> NodeResult { return await next?.process(data, logContext: logContext) diff --git a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/Models/UrlDataResponse.swift b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/Models/UrlDataResponse.swift deleted file mode 100644 index 5807c5e6f..000000000 --- a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/Models/UrlDataResponse.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// UrlDataResponse.swift -// CoreNetKit -// -// Created by Александр Кравченков on 04/02/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -import Foundation - -/// Модель представления ответа сервера. -/// Используется для передачи информации внутри цепочки обработки ответа. -public struct UrlDataResponse: Equatable { - /// Запрос, отправленный на сервер. - public let request: URLRequest - /// Ответ, полученный от сервера - public let response: HTTPURLResponse - /// Данные, возвращенные сервером. - public let data: Data - /// Метрики запроса. - public let metrics: URLSessionTaskMetrics? - /// Время, затраченное на сериализацию овтета. - public let serializationDuration: TimeInterval - - public init(request: URLRequest, - response: HTTPURLResponse, - data: Data, - metrics: URLSessionTaskMetrics?, - serializationDuration: TimeInterval) { - self.request = request - self.response = response - self.data = data - self.metrics = metrics - self.serializationDuration = serializationDuration - } -} diff --git a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseDataParserNode.swift b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseDataParserNode.swift index 0faa8d092..b134e92b1 100644 --- a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseDataParserNode.swift +++ b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseDataParserNode.swift @@ -35,7 +35,7 @@ open class ResponseDataParserNode: AsyncNode { /// /// - Parameter data: Модель ответа сервера. open func process( - _ data: UrlDataResponse, + _ data: URLDataResponse, logContext: LoggingContextProtocol ) async -> NodeResult { return await parse(with: data, logContext: logContext) @@ -49,7 +49,7 @@ open class ResponseDataParserNode: AsyncNode { return .success(json) } - let networkResponse = UrlProcessedResponse(dataResponse: data, json: json) + let networkResponse = URLProcessedResponse(dataResponse: data, json: json) log += "Have next node \(next.objectName) -> call `process`" @@ -68,7 +68,7 @@ open class ResponseDataParserNode: AsyncNode { /// - Throws: /// - `ResponseDataParserNodeError.cantCastDesirializedDataToJson` /// - `ResponseDataParserNodeError.cantDeserializeJson` - open func json(from responseData: UrlDataResponse) throws -> (Json, String) { + open func json(from responseData: URLDataResponse) throws -> (Json, String) { var log = "" @@ -108,7 +108,7 @@ open class ResponseDataParserNode: AsyncNode { // MARK: - Private Methods private func parse( - with data: UrlDataResponse, + with data: URLDataResponse, logContext: LoggingContextProtocol ) async -> NodeResult<(Json, String)> { do { diff --git a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseDataPreprocessorNode.swift b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseDataPreprocessorNode.swift index f2455eb48..1d3c55b6f 100644 --- a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseDataPreprocessorNode.swift +++ b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseDataPreprocessorNode.swift @@ -27,7 +27,7 @@ open class ResponseDataPreprocessorNode: AsyncNode { /// /// - Parameter data: Представление ответа. open func process( - _ data: UrlDataResponse, + _ data: URLDataResponse, logContext: LoggingContextProtocol ) async -> NodeResult { var log = Log(logViewObjectName, id: objectName, order: LogOrder.responseDataPreprocessorNode) diff --git a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseHttpErrorProcessorNode.swift b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseHttpErrorProcessorNode.swift index 57a0d0fe5..500d29342 100644 --- a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseHttpErrorProcessorNode.swift +++ b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseHttpErrorProcessorNode.swift @@ -31,12 +31,12 @@ open class ResponseHttpErrorProcessorNode: AsyncNode { public typealias HttpError = ResponseHttpErrorProcessorNodeError /// Следующий узел для обработки. - public var next: any AsyncNode + public var next: any AsyncNode /// Инициаллизирует объект. /// /// - Parameter next: Следующий узел для обработки. - public init(next: some AsyncNode) { + public init(next: some AsyncNode) { self.next = next } @@ -45,7 +45,7 @@ open class ResponseHttpErrorProcessorNode: AsyncNode { /// /// - Parameter data: Модель ответа сервера. open func process( - _ data: UrlDataResponse, + _ data: URLDataResponse, logContext: LoggingContextProtocol ) async -> NodeResult { switch data.response.statusCode { diff --git a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseProcessorNode.swift b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseProcessorNode.swift index c21052649..7bc477604 100644 --- a/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseProcessorNode.swift +++ b/NodeKit/NodeKit/Layers/ResponseProcessingLayer/ResponseProcessorNode.swift @@ -19,12 +19,12 @@ public enum ResponseProcessorNodeError: Error { open class ResponseProcessorNode: AsyncNode { /// Следующий узел для обратки. - public let next: any AsyncNode + public let next: any AsyncNode /// Инициаллизирует узел. /// /// - Parameter next: Следующий узел для обратки. - public init(next: some AsyncNode) { + public init(next: some AsyncNode) { self.next = next } @@ -48,12 +48,10 @@ open class ResponseProcessorNode: AsyncNode { log += "Skip cause can extract parameters -> continue processing" - let response = UrlDataResponse( + let response = URLDataResponse( request: urlRequest, response: urlResponse, - data: Data(), - metrics: nil, - serializationDuration: -1 + data: Data() ) log += "🌍 " + (urlRequest.httpMethod ?? "UNDEF") + " " @@ -75,13 +73,11 @@ open class ResponseProcessorNode: AsyncNode { return .failure(ResponseProcessorNodeError.rawResponseNotHaveMetaData) } - let dataResponse = UrlDataResponse( + let dataResponse = URLDataResponse( request: urlRequest, response: urlResponse, - data: value, - metrics: nil, // ?? почему nil - serializationDuration: -1 - ) // почему -1? + data: value + ) log += " --> \(urlResponse.statusCode)" + .lineTabDeilimeter log += String(data: value, encoding: .utf8) ?? "CURRUPTED" diff --git a/NodeKit/NodeKit/Layers/TrasportLayer/Models/TransportUrlParameters.swift b/NodeKit/NodeKit/Layers/TrasportLayer/Models/TransportUrlParameters.swift deleted file mode 100644 index ed9102f3c..000000000 --- a/NodeKit/NodeKit/Layers/TrasportLayer/Models/TransportUrlParameters.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// TransportUrlParameters.swift -// CoreNetKit -// -// Created by Александр Кравченков on 16/03/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -import Foundation - -/// Модель для передачи параметров на транспортном слое цепочки. -public struct TransportUrlParameters { - /// HTTP метод. - public let method: Method - /// URL эндпоинта. - public let url: URL - /// Хедеры запроса. - public let headers: [String: String] - - /// Инициаллизирует объект. - /// - /// - Parameters: - /// - method: HTTP метод. - /// - url: URL эндпоинта. - /// - headers: Хедеры запроса. - public init(method: Method, url: URL, headers: [String: String] = [:]) { - self.method = method - self.url = url - self.headers = headers - } - -} diff --git a/NodeKit/NodeKit/Layers/TrasportLayer/Models/TransportUrlRequest.swift b/NodeKit/NodeKit/Layers/TrasportLayer/Models/TransportUrlRequest.swift deleted file mode 100644 index cf48b703b..000000000 --- a/NodeKit/NodeKit/Layers/TrasportLayer/Models/TransportUrlRequest.swift +++ /dev/null @@ -1,37 +0,0 @@ -import Foundation - -/// Модель для внутреннего представления запроса. -public struct TransportUrlRequest { - - /// HTTP метод. - public let method: Method - /// URL эндпоинта. - public let url: URL - /// Хедеры запроса. - public let headers: [String: String] - /// Данные для запроса в чистой `Data` - public let raw: Data? - - /// Инициаллизирует объект. - /// - /// - Parameters: - /// - params: Параметры для формирования запроса. - /// - raw: Данные для запроса в формате `Data` - public init(with params: TransportUrlParameters, raw: Data?) { - self.init(method: params.method, - url: params.url, - headers: params.headers, - raw: raw) - } - - public init(method: Method, - url: URL, - headers: [String: String], - raw: Data?) { - self.method = method - self.url = url - self.headers = headers - self.raw = raw - } - -} diff --git a/NodeKit/NodeKit/Layers/Utils/AccessSafe/AccessSafeNode.swift b/NodeKit/NodeKit/Layers/Utils/AccessSafe/AccessSafeNode.swift index 69987e1af..b83c88620 100644 --- a/NodeKit/NodeKit/Layers/Utils/AccessSafe/AccessSafeNode.swift +++ b/NodeKit/NodeKit/Layers/Utils/AccessSafe/AccessSafeNode.swift @@ -70,7 +70,7 @@ open class AccessSafeNode: AsyncNode { /// Просто передает управление следующему узлу. /// В случае если вернулась доступа, то обноляет токен и повторяет запрос. open func process( - _ data: TransportUrlRequest, + _ data: TransportURLRequest, logContext: LoggingContextProtocol ) async -> NodeResult { return await next.process(data, logContext: logContext) @@ -87,7 +87,7 @@ open class AccessSafeNode: AsyncNode { // MARK: - Private Methods private func processWithTokenUpdate( - _ data: TransportUrlRequest, + _ data: TransportURLRequest, logContext: LoggingContextProtocol ) async -> NodeResult { return await updateTokenChain.process((), logContext: logContext) diff --git a/NodeKit/NodeKit/Layers/Utils/HeaderInjectorNode.swift b/NodeKit/NodeKit/Layers/Utils/HeaderInjectorNode.swift index cbf8e2349..7556b8078 100644 --- a/NodeKit/NodeKit/Layers/Utils/HeaderInjectorNode.swift +++ b/NodeKit/NodeKit/Layers/Utils/HeaderInjectorNode.swift @@ -31,7 +31,7 @@ open class HeaderInjectorNode: AsyncNode { /// Добавляет хедеры к запросу и отправляет его слудующему в цепочке узлу. open func process( - _ data: TransportUrlRequest, + _ data: TransportURLRequest, logContext: LoggingContextProtocol ) async -> NodeResult { var resultHeaders = headers @@ -39,7 +39,7 @@ open class HeaderInjectorNode: AsyncNode { log += "Add headers \(headers)" + .lineTabDeilimeter log += "To headers \(data.headers)" + .lineTabDeilimeter data.headers.forEach { resultHeaders[$0.key] = $0.value } - let newData = TransportUrlRequest( + let newData = TransportURLRequest( method: data.method, url: data.url, headers: resultHeaders, diff --git a/NodeKit/NodeKit/Layers/Utils/LoadIndicatorNode.swift b/NodeKit/NodeKit/Layers/Utils/LoadIndicatorNode.swift deleted file mode 100644 index 5546bc78a..000000000 --- a/NodeKit/NodeKit/Layers/Utils/LoadIndicatorNode.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// LoadIndicatorNode.swift -// CoreNetKit -// -// Created by Александр Кравченков on 14/04/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -#if canImport(UIKit) -import UIKit -#endif -import Dispatch - -enum LoadIndicatableNodeStatic { - static var requestConter: Int = 0 { - didSet { - #if canImport(UIKit) - DispatchQueue.main.async { - UIApplication.shared.isNetworkActivityIndicatorVisible = requestConter != 0 - } - #endif - } - } -} - -/// Показыает спиннер загрзки в статус-баре. -open class LoadIndicatableNode: AsyncNode { - - /// Следующий узел в цепочке. - open var next: any AsyncNode - - /// Инциаллизирует узел. - /// - /// - Parameter next: Следующий узел в цепочке. - public init(next: some AsyncNode ) { - self.next = next - } - - /// Показывает индикатор и передает управление дальше. - /// По окнчании работы цепочки скрывает индикатор. - open func process( - _ data: Input, - logContext: LoggingContextProtocol - ) async -> NodeResult { - DispatchQueue.global().async(flags: .barrier) { - LoadIndicatableNodeStatic.requestConter += 1 - } - - let decrementRequestCounter: (() -> Void) = { - DispatchQueue.global().async(flags: .barrier) { - LoadIndicatableNodeStatic.requestConter -= 1 - } - } - - let result = await next.process(data, logContext: logContext) - decrementRequestCounter() - return result - } -} diff --git a/NodeKit/NodeKit/Utils/UrlRouting/UrlRouting.swift b/NodeKit/NodeKit/Utils/UrlRouting/UrlRouting.swift index 148146c33..b0f745716 100644 --- a/NodeKit/NodeKit/Utils/UrlRouting/UrlRouting.swift +++ b/NodeKit/NodeKit/Utils/UrlRouting/UrlRouting.swift @@ -1,5 +1,5 @@ // -// UrlRouting.swift +// URLRouting.swift // CoreNetKit // // Created by Александр Кравченков on 03/04/2019. @@ -10,9 +10,9 @@ import Foundation /// Содержит ошибки для маршрутизатора URL запросов. /// -/// - cantBuildUrl: Возникает в случае, если не удалось создать URL. -public enum UrlRouteError: Error { - case cantBuildUrl +/// - cantBuildURL: Возникает в случае, если не удалось создать URL. +public enum URLRouteError: Error { + case cantBuildURL } public extension Optional where Wrapped == URL { @@ -23,19 +23,19 @@ public extension Optional where Wrapped == URL { /// - lhs: Базовый URL, относительно которого нужно построить итоговый. /// - rhs: Относительный путь, который нужно добавить к базовому URL /// - Returns: Итоговый URL маршрут. - /// - Throws: `UrlRouteError.cantBuildUrl` + /// - Throws: `URLRouteError.cantBuildURL` static func + (lhs: URL?, rhs: String) throws -> URL { guard let url = lhs?.appendingPathComponent(rhs) else { - throw UrlRouteError.cantBuildUrl + throw URLRouteError.cantBuildURL } return url } } -/// Расширение для удобства оборачивания `UrlRouteProvider` +/// Расширение для удобства оборачивания `URLRouteProvider` /// - Warning: /// Это используется исключительно для работы между узлами. -extension URL: UrlRouteProvider { +extension URL: URLRouteProvider { /// Просто возвращает себя public func url() throws -> URL { return self diff --git a/NodeKit/NodeKitMock/Builder/ChainBuilderMock.swift b/NodeKit/NodeKitMock/Builder/ChainBuilderMock.swift new file mode 100644 index 000000000..1dc75c9f3 --- /dev/null +++ b/NodeKit/NodeKitMock/Builder/ChainBuilderMock.swift @@ -0,0 +1,141 @@ +// +// ChainBuilderMock.swift +// NodeKitMock +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +@testable import NodeKit + +import Foundation + +open class ChainBuilderMock: ChainBuilder { + + public init() { } + + public var invokedRoute = false + public var invokedRouteCount = 0 + public var invokedRouteParameter: (method: NodeKit.Method, route: Route)? + public var invokedRouteParameterList: [(method: NodeKit.Method, route: Route)] = [] + + open func route(_ method: NodeKit.Method, _ route: Route) -> Self { + invokedRoute = true + invokedRouteCount += 1 + invokedRouteParameter = (method, route) + invokedRouteParameterList.append((method, route)) + return self + } + + public var invokedEncode = false + public var invokedEncodeCount = 0 + public var invokedEncodeParameter: ParametersEncoding? + public var invokedEncodeParameterList: [ParametersEncoding] = [] + + open func encode(as encoding: ParametersEncoding) -> Self { + invokedEncode = true + invokedEncodeCount += 1 + invokedEncodeParameter = encoding + invokedEncodeParameterList.append(encoding) + return self + } + + public var invokedAddProvider = false + public var invokedAddProviderCount = 0 + public var invokedAddProviderParameter: MetadataProvider? + public var invokedAddProviderParameterList: [MetadataProvider] = [] + + open func add(provider: MetadataProvider) -> Self { + invokedAddProvider = true + invokedAddProviderCount += 1 + invokedAddProviderParameter = provider + invokedAddProviderParameterList.append(provider) + return self + } + + public var invokedSetMetadata = false + public var invokedSetMetadataCount = 0 + public var invokedSetMetadataParameter: [String: String]? + public var invokedSetMetadataParameterList: [[String: String]] = [] + + open func set(metadata: [String: String]) -> Self { + invokedSetMetadata = true + invokedSetMetadataCount += 1 + invokedSetMetadataParameter = metadata + invokedSetMetadataParameterList.append(metadata) + return self + } + + public var invokedBuildWithInputOutput = false + public var invokedBuildWithInputOutputCount = 0 + public var stubbedBuildWithInputOutputResult: AsyncNodeMock! + + open func build() -> AnyAsyncNode + where I.DTO.Raw == Json, O.DTO.Raw == Json { + invokedBuildWithInputOutput = true + invokedBuildWithInputOutputCount += 1 + return (stubbedBuildWithInputOutputResult as! AsyncNodeMock).eraseToAnyNode() + } + + public var invokedBuildWithVoidInput = false + public var invokedBuildWithVoidInputCount = 0 + public var stubbedBuildWithVoidInputResult: AsyncNodeMock! + + open func build() -> AnyAsyncNode + where O.DTO.Raw == Json { + invokedBuildWithVoidInput = true + invokedBuildWithVoidInputCount += 1 + return (stubbedBuildWithVoidInputResult as! AsyncNodeMock).eraseToAnyNode() + } + + public var invokedBuildWithVoidOutput = false + public var invokedBuildWithVoidOutputCount = 0 + public var stubbedBuildWithVoidOutputResult: AsyncNodeMock! + + open func build() -> AnyAsyncNode where I.DTO.Raw == Json { + invokedBuildWithVoidOutput = true + invokedBuildWithVoidOutputCount += 1 + return (stubbedBuildWithVoidOutputResult as! AsyncNodeMock).eraseToAnyNode() + } + + public var invokedBuildWithVoidInputOutput = false + public var invokedBuildWithVoidInputOutputCount = 0 + public var stubbedBuildWithVoidInputOutputResult: AsyncNodeMock! + + open func build() -> AnyAsyncNode { + invokedBuildWithVoidInputOutput = true + invokedBuildWithVoidInputOutputCount += 1 + return stubbedBuildWithVoidInputOutputResult.eraseToAnyNode() + } + + public var invokedBuildMultipart = false + public var invokedBuildMultipartCount = 0 + public var stubbedBuildMultipartResult: AsyncNodeMock! + + open func build() -> AnyAsyncNode + where O.DTO.Raw == Json, I.DTO.Raw == MultipartModel<[String : Data]> { + invokedBuildMultipart = true + invokedBuildMultipartCount += 1 + return (stubbedBuildMultipartResult as! AsyncNodeMock).eraseToAnyNode() + } + + public var invokedBuildDataLoadingWithVoidInput = false + public var invokedBuildDataLoadingWithVoidInputCount = 0 + public var stubbedBuildDataLoadingWithVoidInputResult: AsyncNodeMock! + + open func buildDataLoading() -> AnyAsyncNode { + invokedBuildDataLoadingWithVoidInput = true + invokedBuildDataLoadingWithVoidInputCount += 1 + return stubbedBuildDataLoadingWithVoidInputResult.eraseToAnyNode() + } + + public var invokedBuildDataLoading = false + public var invokedBuildDataLoadingCount = 0 + public var stubbedBuildDataLoadingResult: AsyncNodeMock! + + open func buildDataLoading() -> AnyAsyncNode where I.DTO.Raw == Json { + invokedBuildDataLoading = true + invokedBuildDataLoadingCount += 1 + return (stubbedBuildDataLoadingResult as! AsyncNodeMock).eraseToAnyNode() + } +} diff --git a/NodeKit/NodeKitMock/Builder/ChainConfigBuilderMock.swift b/NodeKit/NodeKitMock/Builder/ChainConfigBuilderMock.swift new file mode 100644 index 000000000..4642b8d3f --- /dev/null +++ b/NodeKit/NodeKitMock/Builder/ChainConfigBuilderMock.swift @@ -0,0 +1,92 @@ +// +// ChainConfigBuilderMock.swift +// NodeKitMock +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +@testable import NodeKit + +open class ChainConfigBuilderMock: ChainConfigBuilder { + + public init() { } + + public var invokedSetQuery = false + public var invokedSetQueryCount = 0 + public var invokedSetQueryParameter: [String: Any]? + public var invokedSetQueryParameterList: [[String: Any]] = [] + + open func set(query: [String: Any]) -> Self { + invokedSetQuery = true + invokedSetQueryCount += 1 + invokedSetQueryParameter = query + invokedSetQueryParameterList.append(query) + return self + } + + public var invokedSetBoolEncodingStartegy = false + public var invokedSetBoolEncodingStartegyCount = 0 + public var invokedSetBoolEncodingStartegyParameter: URLQueryBoolEncodingStartegy? + public var invokedSetBoolEncodingStartegyParameterList: [URLQueryBoolEncodingStartegy] = [] + + open func set(boolEncodingStartegy: URLQueryBoolEncodingStartegy) -> Self { + invokedSetBoolEncodingStartegy = true + invokedSetBoolEncodingStartegyCount += 1 + invokedSetBoolEncodingStartegyParameter = boolEncodingStartegy + invokedSetBoolEncodingStartegyParameterList.append(boolEncodingStartegy) + return self + } + + public var invokedSetArrayEncodingStrategy = false + public var invokedSetArrayEncodingStrategyCount = 0 + public var invokedSetArrayEncodingStrategyParameter: URLQueryArrayKeyEncodingStartegy? + public var invokedSetArrayEncodingStrategyParameterList: [URLQueryArrayKeyEncodingStartegy] = [] + + open func set(arrayEncodingStrategy: URLQueryArrayKeyEncodingStartegy) -> Self { + invokedSetArrayEncodingStrategy = true + invokedSetArrayEncodingStrategyCount += 1 + invokedSetArrayEncodingStrategyParameter = arrayEncodingStrategy + invokedSetArrayEncodingStrategyParameterList.append(arrayEncodingStrategy) + return self + } + + public var invokedSetDictEncodindStrategy = false + public var invokedSetDictEncodindStrategyCount = 0 + public var invokedSetDictEncodindStrategyParameter: URLQueryDictionaryKeyEncodingStrategy? + public var invokedSetDictEncodindStrategyParameterList: [URLQueryDictionaryKeyEncodingStrategy] = [] + + open func set(dictEncodindStrategy: URLQueryDictionaryKeyEncodingStrategy) -> Self { + invokedSetDictEncodindStrategy = true + invokedSetDictEncodindStrategyCount += 1 + invokedSetDictEncodindStrategyParameter = dictEncodindStrategy + invokedSetDictEncodindStrategyParameterList.append(dictEncodindStrategy) + return self + } + + public var invokedSetBoolEncodingDefaultStartegy = false + public var invokedSetBoolEncodingDefaultStartegyCount = 0 + public var invokedSetBoolEncodingDefaultStartegyParameter: URLQueryBoolEncodingDefaultStartegy? + public var invokedSetBoolEncodingDefaultStartegyParameterList: [URLQueryBoolEncodingDefaultStartegy] = [] + + open func set(boolEncodingStartegy: URLQueryBoolEncodingDefaultStartegy) -> Self { + invokedSetBoolEncodingDefaultStartegy = true + invokedSetBoolEncodingDefaultStartegyCount += 1 + invokedSetBoolEncodingDefaultStartegyParameter = boolEncodingStartegy + invokedSetBoolEncodingDefaultStartegyParameterList.append(boolEncodingStartegy) + return self + } + + public var invokedSetArrayEncodingBracketsStrategy = false + public var invokedSetArrayEncodingBracketsStrategyCount = 0 + public var invokedSetArrayEncodingBracketsStrategyParameter: URLQueryArrayKeyEncodingBracketsStartegy? + public var invokedSetArrayEncodingBracketsStrategyParameterList: [URLQueryArrayKeyEncodingBracketsStartegy] = [] + + open func set(arrayEncodingStrategy: URLQueryArrayKeyEncodingBracketsStartegy) -> Self { + invokedSetArrayEncodingBracketsStrategy = true + invokedSetArrayEncodingBracketsStrategyCount += 1 + invokedSetArrayEncodingBracketsStrategyParameter = arrayEncodingStrategy + invokedSetArrayEncodingBracketsStrategyParameterList.append(arrayEncodingStrategy) + return self + } +} diff --git a/NodeKit/NodeKitMock/Builder/ServiceChainProviderMock.swift b/NodeKit/NodeKitMock/Builder/ServiceChainProviderMock.swift new file mode 100644 index 000000000..5519d02d0 --- /dev/null +++ b/NodeKit/NodeKitMock/Builder/ServiceChainProviderMock.swift @@ -0,0 +1,58 @@ +// +// ServiceChainProviderMock.swift +// NodeKitMock +// +// Created by Andrei Frolov on 02.05.24. +// Copyright © 2024 Surf. All rights reserved. +// + +@testable import NodeKit + +import Foundation + +open class ServiceChainProviderMock: ServiceChainProvider { + + public init() { } + + public var invokedProvideRequestJsonChain = false + public var invokedProvideRequestJsonChainCount = 0 + public var invokedProvideRequestJsonChainParameter: [MetadataProvider]? + public var invokedProvideRequestJsonChainParameterList: [[MetadataProvider]] = [] + public var stubbedProvideRequestJsonChainResult: (any AsyncNode)! + + open func provideRequestJsonChain( + with providers: [MetadataProvider] + ) -> any AsyncNode { + invokedProvideRequestJsonChain = true + invokedProvideRequestJsonChainCount += 1 + invokedProvideRequestJsonChainParameter = providers + invokedProvideRequestJsonChainParameterList.append(providers) + return stubbedProvideRequestJsonChainResult + } + + public var invokedProvideRequestDataChain = false + public var invokedProvideRequestDataChainCount = 0 + public var invokedProvideRequestDataChainParameter: [MetadataProvider]? + public var invokedProvideRequestDataChainParameterList: [[MetadataProvider]] = [] + public var stubbedProvideRequestDataChainResult: (any AsyncNode)! + + open func provideRequestDataChain( + with providers: [MetadataProvider] + ) -> any AsyncNode { + invokedProvideRequestDataChain = true + invokedProvideRequestDataChainCount += 1 + invokedProvideRequestDataChainParameter = providers + invokedProvideRequestDataChainParameterList.append(providers) + return stubbedProvideRequestDataChainResult + } + + public var invokedProvideRequestMultipartChain = false + public var invokedProvideRequestMultipartChainCount = 0 + public var stubbedProvideRequestMultipartChainResult: (any AsyncNode)! + + open func provideRequestMultipartChain() -> any AsyncNode { + invokedProvideRequestMultipartChain = true + invokedProvideRequestMultipartChainCount += 1 + return stubbedProvideRequestMultipartChainResult + } +} diff --git a/NodeKit/NodeKitMock/MultipartFormDataMock.swift b/NodeKit/NodeKitMock/MultipartFormDataMock.swift index 000f38868..54bda6dd0 100644 --- a/NodeKit/NodeKitMock/MultipartFormDataMock.swift +++ b/NodeKit/NodeKitMock/MultipartFormDataMock.swift @@ -13,12 +13,12 @@ import NodeKitThirdParty public class MultipartFormDataMock: MultipartFormDataProtocol { public struct AppendURLParameters { - public let fileUrl: URL + public let fileURL: URL public let name: String } public struct AppendCustomURLParameters { - public let fileUrl: URL + public let fileURL: URL public let name: String public let fileName: String public let mimeType: String @@ -58,7 +58,7 @@ public class MultipartFormDataMock: MultipartFormDataProtocol { public var invokedAppendURLParametersList: [AppendURLParameters] = [] public func append(_ fileURL: URL, withName name: String) { - let parameters = AppendURLParameters(fileUrl: fileURL, name: name) + let parameters = AppendURLParameters(fileURL: fileURL, name: name) invokedAppendURL = true invokedAppendURLCount += 1 invokedAppendURLParameters = parameters @@ -71,7 +71,7 @@ public class MultipartFormDataMock: MultipartFormDataProtocol { public var invokedAppendCustomURLParametersList: [AppendCustomURLParameters] = [] public func append(_ fileURL: URL, withName name: String, fileName: String, mimeType: String) { - let parameters = AppendCustomURLParameters(fileUrl: fileURL, name: name, fileName: fileName, mimeType: mimeType) + let parameters = AppendCustomURLParameters(fileURL: fileURL, name: name, fileName: fileName, mimeType: mimeType) invokedAppendCustomURL = true invokedAppendCustomURLCount += 1 invokedAppendCustomURLParameters = parameters diff --git a/NodeKit/NodeKitMock/URLServiceChainProviderMock.swift b/NodeKit/NodeKitMock/URLServiceChainProviderMock.swift new file mode 100644 index 000000000..2663da30b --- /dev/null +++ b/NodeKit/NodeKitMock/URLServiceChainProviderMock.swift @@ -0,0 +1,41 @@ +// +// URLServiceChainProviderMock.swift +// NodeKitTests +// +// Created by Andrei Frolov on 09.04.24. +// Copyright © 2024 Surf. All rights reserved. +// + +@testable import NodeKit + +import Foundation + +class URLServiceChainProviderMock: URLServiceChainProvider { + + override func provideRequestJsonChain( + with providers: [MetadataProvider] + ) -> any AsyncNode { + let requestSenderNode = RequestSenderNode( + rawResponseProcessor: provideResponseJsonChain(), + manager: NetworkMock().urlSession + ) + let technicalErrorMapperNode = TechnicaErrorMapperNode(next: requestSenderNode) + return RequestCreatorNode(next: technicalErrorMapperNode, providers: providers) + } + + override func provideRequestDataChain( + with providers: [MetadataProvider] + ) -> any AsyncNode { + let requestSenderNode = RequestSenderNode( + rawResponseProcessor: provideResponseDataChain(), + manager: NetworkMock().urlSession + ) + let aborterNode = AborterNode(next: requestSenderNode, aborter: requestSenderNode) + return RequestCreatorNode(next: aborterNode, providers: providers) + } + + override func provideRequestMultipartChain() -> any AsyncNode { + let responseChain = provideResponseJsonChain() + return RequestSenderNode(rawResponseProcessor: responseChain, manager: NetworkMock().urlSession) + } +} diff --git a/NodeKit/NodeKitMock/UrlRouteProviderMock.swift b/NodeKit/NodeKitMock/UrlRouteProviderMock.swift deleted file mode 100644 index 4cb65b00d..000000000 --- a/NodeKit/NodeKitMock/UrlRouteProviderMock.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// UrlRouteProviderMock.swift -// NodeKitTests -// -// Created by Andrei Frolov on 05.04.24. -// Copyright © 2024 Surf. All rights reserved. -// - -import Foundation -import NodeKit - -public class UrlRouteProviderMock: UrlRouteProvider { - - public init() { } - - public var invokedUrl = false - public var invokedUrlCount = 0 - public var stubbedUrlResult: Result! - - public func url() throws -> URL { - invokedUrl = true - invokedUrlCount += 1 - switch stubbedUrlResult! { - case .success(let url): - return url - case .failure(let error): - throw error - } - } -} diff --git a/NodeKit/NodeKitMock/UrlServiceChainBuilderMock.swift b/NodeKit/NodeKitMock/UrlServiceChainBuilderMock.swift deleted file mode 100644 index 6a4474f98..000000000 --- a/NodeKit/NodeKitMock/UrlServiceChainBuilderMock.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// UrlServiceChainBuilderMock.swift -// NodeKitTests -// -// Created by Andrei Frolov on 09.04.24. -// Copyright © 2024 Surf. All rights reserved. -// - -import Foundation -import NodeKit - -public class UrlServiceChainBuilderMock: UrlServiceChainBuilder { - - /// Создает цепочку узлов, описывающих транспортный слой обработки. - override public func requestTrasportChain(providers: [MetadataProvider], session: URLSession?) -> any TransportLayerNode { - let requestSenderNode = RequestSenderNode( - rawResponseProcessor: self.urlResponseProcessingLayerChain(), - manager: NetworkMock().urlSession - ) - let technicalErrorMapperNode = TechnicaErrorMapperNode(next: requestSenderNode) - return RequestCreatorNode(next: technicalErrorMapperNode, providers: providers) - } - -} diff --git a/NodeKit/NodeKitMock/Utils/Equatable/TransportUrlRequest+Equatable.swift b/NodeKit/NodeKitMock/Utils/Equatable/TransportUrlRequest+Equatable.swift deleted file mode 100644 index 73d49d2d7..000000000 --- a/NodeKit/NodeKitMock/Utils/Equatable/TransportUrlRequest+Equatable.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// TransportUrlRequest+Equatable.swift -// NodeKitTests -// -// Created by Andrei Frolov on 04.04.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit - -extension TransportUrlRequest: Equatable { - public static func == (lhs: TransportUrlRequest, rhs: TransportUrlRequest) -> Bool { - return lhs.headers == rhs.headers && - lhs.url == rhs.url && - lhs.method == rhs.method && - lhs.raw == rhs.raw - } -} diff --git a/NodeKit/NodeKitTests/IntegrationTests/EmptyResponseMappingTests.swift b/NodeKit/NodeKitTests/IntegrationTests/EmptyResponseMappingTests.swift index fde4ffbe7..7ecc28536 100644 --- a/NodeKit/NodeKitTests/IntegrationTests/EmptyResponseMappingTests.swift +++ b/NodeKit/NodeKitTests/IntegrationTests/EmptyResponseMappingTests.swift @@ -33,13 +33,14 @@ final class EmptyResponseMappingTests: XCTestCase { func testDefaultChainArrSucessParseResponseInCaseOfEmptyArray() async throws { // given - let chainRoot: any AsyncNode = UrlChainsBuilder(serviceChain: UrlServiceChainBuilderMock()) - .route(.get, Routes.emptyUsers) + let builder = URLChainBuilder(serviceChainProvider: URLServiceChainProviderMock()) + let chainRoot: AnyAsyncNode = builder + .route(.get, .emptyUsers) .build() // when - let result = await chainRoot.process() + let result: NodeResult<[User]> = await chainRoot.process() // then @@ -51,13 +52,14 @@ final class EmptyResponseMappingTests: XCTestCase { func testArraySuccessMappingWithNoContentResponse() async throws { // given - let chainRoot: any AsyncNode = UrlChainsBuilder(serviceChain: UrlServiceChainBuilderMock()) + let builder = URLChainBuilder(serviceChainProvider: URLServiceChainProviderMock()) + let chainRoot: AnyAsyncNode = builder .route(.get, Routes.emptyUsersWith204) .build() // when - let result = await chainRoot.process() + let result: NodeResult<[User]> = await chainRoot.process() // then diff --git a/NodeKit/NodeKitTests/IntegrationTests/FromURLCodingTests.swift b/NodeKit/NodeKitTests/IntegrationTests/FromURLCodingTests.swift index e1500e389..b5136f60f 100644 --- a/NodeKit/NodeKitTests/IntegrationTests/FromURLCodingTests.swift +++ b/NodeKit/NodeKitTests/IntegrationTests/FromURLCodingTests.swift @@ -28,19 +28,19 @@ final class FromURLCodingTests: XCTestCase { // MARK: - Tests - func testChain_withFormUrlEncoded_thenSuccessReceived() async throws { + func testChain_withFormURLEncoded_thenSuccessReceived() async throws { // given - let sut: any AsyncNode = UrlChainsBuilder(serviceChain: UrlServiceChainBuilderMock()) - .route(.post, Routes.authWithFormUrl) - .encode(as: .urlQuery) - .build() - + let builder = URLChainBuilder(serviceChainProvider: URLServiceChainProviderMock()) let authModel = AuthModel(type: "type", secret: "secret") - + // when - - let result = await sut.process(authModel) + + let result: NodeResult = await builder + .route(.post, .authWithFormURL) + .encode(as: .urlQuery) + .build() + .process(authModel) // then @@ -50,18 +50,18 @@ final class FromURLCodingTests: XCTestCase { XCTAssertEqual(value.refreshToken, "stubbedRefreshToken") } - func testChain_withFormUrlEncodedBadRequest_thenFailureReceived() async throws { + func testChain_withFormURLEncodedBadRequest_thenFailureReceived() async throws { // given - let sut: any AsyncNode = UrlChainsBuilder(serviceChain: UrlServiceChainBuilderMock()) - .route(.post, Routes.authWithFormUrl) - .build() - + let builder = URLChainBuilder(serviceChainProvider: URLServiceChainProviderMock()) let authModel = AuthModel(type: "badType", secret: "BadSecret") // when - let result = await sut.process(authModel) + let result: NodeResult = await builder + .route(.post, .authWithFormURL) + .build() + .process(authModel) // then diff --git a/NodeKit/NodeKitTests/IntegrationTests/Infrastructure/Infrastructure.swift b/NodeKit/NodeKitTests/IntegrationTests/Infrastructure/Infrastructure.swift index 2d81e0201..de66b0643 100644 --- a/NodeKit/NodeKitTests/IntegrationTests/Infrastructure/Infrastructure.swift +++ b/NodeKit/NodeKitTests/IntegrationTests/Infrastructure/Infrastructure.swift @@ -13,31 +13,31 @@ import Foundation public enum Routes { public enum Exception: Error { - case badUrl + case badURL } case users case emptyUsers case emptyUsersWith204 - case authWithFormUrl + case authWithFormURL case multipartPing } -extension Routes: UrlRouteProvider { +extension Routes: URLRouteProvider { private static var base: URL? { return URL(string: "http://localhost:8118/nkt") } public func url() throws -> URL { - guard let url = self.tryToGetUrl() else { - throw Exception.badUrl + guard let url = self.tryToGetURL() else { + throw Exception.badURL } return url } - private func tryToGetUrl() -> URL? { + private func tryToGetURL() -> URL? { switch self { case .users: return try? Routes.base + "/users" @@ -45,8 +45,8 @@ extension Routes: UrlRouteProvider { return try? Routes.base + "/userEmptyArr" case .emptyUsersWith204: return try? Routes.base + "/Get204UserArr" - case .authWithFormUrl: - return try? Routes.base + "/authWithFormUrl" + case .authWithFormURL: + return try? Routes.base + "/authWithFormURL" case .multipartPing: return try? Routes.base + "/multipartPing" } diff --git a/NodeKit/NodeKitTests/IntegrationTests/MultipartRequestTests.swift b/NodeKit/NodeKitTests/IntegrationTests/MultipartRequestTests.swift index 4805bd405..5d506678e 100644 --- a/NodeKit/NodeKitTests/IntegrationTests/MultipartRequestTests.swift +++ b/NodeKit/NodeKitTests/IntegrationTests/MultipartRequestTests.swift @@ -65,14 +65,12 @@ final class MultipartRequestTests: XCTestCase { ]) let model = MultipartModel(payloadModel: data) - let chainsBuilder = UrlChainsBuilder() - .route(.post, Routes.multipartPing) - - chainsBuilder.session = NetworkMock().urlSession + let chainsBuilder = URLChainBuilder(serviceChainProvider: URLServiceChainProviderMock()) // when let result: NodeResult = await chainsBuilder + .route(.post, .multipartPing) .build() .process(model) @@ -92,14 +90,12 @@ final class MultipartRequestTests: XCTestCase { ]) let model = MultipartModel(payloadModel: data) - let chainsBuilder = UrlChainsBuilder() - .route(.post, Routes.multipartPing) + let chainsBuilder = URLChainBuilder(serviceChainProvider: URLServiceChainProviderMock()) - chainsBuilder.session = NetworkMock().urlSession - // when let result: NodeResult = await chainsBuilder + .route(.post, .multipartPing) .build() .process(model) @@ -117,14 +113,12 @@ final class MultipartRequestTests: XCTestCase { let model = MultipartModel(payloadModel: TestData(data: [:]) ,files: [ "file": .url(url: url) ]) - let chainsBuilder = UrlChainsBuilder() - .route(.post, Routes.multipartPing) - - chainsBuilder.session = NetworkMock().urlSession + let chainsBuilder = URLChainBuilder(serviceChainProvider: URLServiceChainProviderMock()) // when let result: NodeResult = await chainsBuilder + .route(.post, .multipartPing) .build() .process(model) diff --git a/NodeKit/NodeKitTests/IntegrationTests/SimpleURLChainTests.swift b/NodeKit/NodeKitTests/IntegrationTests/SimpleURLChainTests.swift index 5ef9cd98e..73c27406a 100644 --- a/NodeKit/NodeKitTests/IntegrationTests/SimpleURLChainTests.swift +++ b/NodeKit/NodeKitTests/IntegrationTests/SimpleURLChainTests.swift @@ -31,9 +31,10 @@ final class SimpleURLChainTests: XCTestCase { func testDefaultURLChainWorkSuccess() async throws { // given - let chainRoot: any AsyncNode = UrlChainsBuilder(serviceChain: UrlServiceChainBuilderMock()) + let builder = URLChainBuilder(serviceChainProvider: URLServiceChainProviderMock()) + let chainRoot: AnyAsyncNode = builder .set(metadata: ["TestHeader":"testHeaderValue"]) - .route(.get, Routes.users) + .route(.get, .users) .build() let id = "id" @@ -42,7 +43,7 @@ final class SimpleURLChainTests: XCTestCase { // when - let result = await chainRoot.process() + let result: NodeResult<[User]> = await chainRoot.process() // then @@ -66,7 +67,8 @@ final class SimpleURLChainTests: XCTestCase { // when - let result: NodeResult<[User]> = await UrlChainsBuilder(serviceChain: UrlServiceChainBuilderMock()) + let builder = URLChainBuilder(serviceChainProvider: URLServiceChainProviderMock()) + let result: NodeResult<[User]> = await builder .set(query: ["stack": "left", "sort": false]) .set(boolEncodingStartegy: .asBool) .route(.get, .users) @@ -86,4 +88,3 @@ final class SimpleURLChainTests: XCTestCase { } } } - diff --git a/NodeKit/NodeKitTests/IntegrationTests/URLResponsesStub.swift b/NodeKit/NodeKitTests/IntegrationTests/URLResponsesStub.swift index 2fcb3944f..fd4228c44 100644 --- a/NodeKit/NodeKitTests/IntegrationTests/URLResponsesStub.swift +++ b/NodeKit/NodeKitTests/IntegrationTests/URLResponsesStub.swift @@ -35,8 +35,8 @@ public enum URLResponsesStub { return try makeUserEmptyArrResponse(request: request) case "Get204UserArr": return try makeGet204UserArrResponse(request: request) - case "authWithFormUrl": - return try makeAuthWithFormUrlResponse(request: request) + case "authWithFormURL": + return try makeAuthWithFormURLResponse(request: request) case "multipartPing": return try makeMultipartPingResponse(request: request) default: @@ -147,7 +147,7 @@ private extension URLResponsesStub { ) } - private static func makeAuthWithFormUrlResponse(request: URLRequest) throws -> (HTTPURLResponse, Data) { + private static func makeAuthWithFormURLResponse(request: URLRequest) throws -> (HTTPURLResponse, Data) { guard let url = request.url, let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: true)?.queryItems, diff --git a/NodeKit/NodeKitTests/UnitTests/Cache/ETag/TestUtls.swift b/NodeKit/NodeKitTests/UnitTests/Cache/ETag/TestUtls.swift index 7f10426e6..d26e81fa5 100644 --- a/NodeKit/NodeKitTests/UnitTests/Cache/ETag/TestUtls.swift +++ b/NodeKit/NodeKitTests/UnitTests/Cache/ETag/TestUtls.swift @@ -11,40 +11,36 @@ import Foundation @testable import NodeKit enum Utils { - static func getMockUrlProcessedResponse(url: URL, + static func getMockURLProcessedResponse(url: URL, statusCode: Int = 200, httpVersion: String = "1.1", headers: [String: String] = [:], data: Data = Data(), - json: Json = Json()) -> UrlProcessedResponse { + json: Json = Json()) -> URLProcessedResponse { let httpResponse = HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: httpVersion, headerFields: headers)! - let dataResponse = UrlDataResponse(request: URLRequest(url: url), + let dataResponse = URLDataResponse(request: URLRequest(url: url), response: httpResponse, - data: Data(), - metrics: nil, - serializationDuration: 0) + data: Data()) - return UrlProcessedResponse(dataResponse: dataResponse, json: json) + return URLProcessedResponse(dataResponse: dataResponse, json: json) } - static func getMockUrlDataResponse(url: URL, + static func getMockURLDataResponse(url: URL, statusCode: Int = 200, httpVersion: String = "1.1", headers: [String: String] = [:], - data: Data = Data()) -> UrlDataResponse{ + data: Data = Data()) -> URLDataResponse{ let httpResponse = HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: httpVersion, headerFields: headers)! - return UrlDataResponse(request: URLRequest(url: url), + return URLDataResponse(request: URLRequest(url: url), response: httpResponse, - data: Data(), - metrics: nil, - serializationDuration: 0) + data: Data()) } } diff --git a/NodeKit/NodeKitTests/UnitTests/Cache/ETag/UrlWithOrderedQuery.swift b/NodeKit/NodeKitTests/UnitTests/Cache/ETag/UrlWithOrderedQuery.swift deleted file mode 100644 index 8d5431ade..000000000 --- a/NodeKit/NodeKitTests/UnitTests/Cache/ETag/UrlWithOrderedQuery.swift +++ /dev/null @@ -1,68 +0,0 @@ -import Foundation -import XCTest - -/// Проверяет: -/// 1. Если у URL нет query, то вернется тот же самый URL -/// 2. Для двух URL с разным порядком query вернется одна и та же строка -final class UrlWithOrderedQuery: XCTestCase { - - /// Если у URL нет query, то вернется тот же самый URL - func testUrlDoesntHaveQuery() throws { - // Arrange - - let url = try XCTUnwrap(URL(string: "https://test.test")) - - // Act - - let res = url.withOrderedQuery() - - // Assert - - XCTAssertEqual(url.absoluteString, - res, - "Result should be equal to given url, but res: \(res ?? "nil") and given: \(url.absoluteString)") - } - - // Для двух URL с разным порядком query вернется одна и та же строка - func testUrlWithDifferentParamsOrder() throws { - // Arrange - - // кол-во парамтров в URL - let capacity = 100 - - var params = [String: String]() - - (0...capacity).forEach { params["q\($0)"] = "\($0)" } - - let base = "https://test.test/test" - - let urls = try (0...capacity).map { _ -> URL in - var localParams = params - var query = [URLQueryItem]() - // пока список с парамтерами не опустеет - while !localParams.isEmpty { - // получаем слуайный параметр - let (key, value) = try XCTUnwrap(localParams.randomElement()) - // добавляем его в query - query.append(.init(name: key, value: value)) - // удаляем параметр чтоб в следующий раз он не вернулся из `randomElement` - localParams.removeValue(forKey: key) - } - var cmp = try XCTUnwrap(URLComponents(string: base)) - cmp.queryItems = query - return try XCTUnwrap(cmp.url) - } - - print(urls) - - // Act - - let res = urls.map { $0.withOrderedQuery() } - print(res) - // Assert - - res.forEach { url in - res.forEach { XCTAssertEqual(url, $0) } - } - } -} diff --git a/NodeKit/NodeKitTests/UnitTests/Cache/FirstCachePolicyTests.swift b/NodeKit/NodeKitTests/UnitTests/Cache/FirstCachePolicyTests.swift index f2106a434..e44b3bf31 100644 --- a/NodeKit/NodeKitTests/UnitTests/Cache/FirstCachePolicyTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Cache/FirstCachePolicyTests.swift @@ -16,8 +16,8 @@ final class FirstCachePolicyTests: XCTestCase { // MARK: - Dependencies - private var nextNodeMock: AsyncNodeMock! - private var readerNodeMock: AsyncNodeMock! + private var nextNodeMock: AsyncNodeMock! + private var readerNodeMock: AsyncNodeMock! private var logContextMock: LoggingContextMock! // MARK: - Sut @@ -48,7 +48,7 @@ final class FirstCachePolicyTests: XCTestCase { // given let exepctedNextResult = ["test0": "value0"] - let request = RawUrlRequest(dataRequest: nil) + let request = RawURLRequest(dataRequest: nil) var results: [NodeResult] = [] @@ -75,7 +75,7 @@ final class FirstCachePolicyTests: XCTestCase { let exepctedNextResult = ["test": "value"] let expectedReaderResult = ["test1": "value1"] - let request = RawUrlRequest(dataRequest: URLRequest(url: URL(string: "test.ex.temp")!)) + let request = RawURLRequest(dataRequest: URLRequest(url: URL(string: "test.ex.temp")!)) var results: [NodeResult] = [] diff --git a/NodeKit/NodeKitTests/UnitTests/Coding/EncodingTests.swift b/NodeKit/NodeKitTests/UnitTests/Coding/EncodingTests.swift index 5b12edf11..8dd0db619 100644 --- a/NodeKit/NodeKitTests/UnitTests/Coding/EncodingTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Coding/EncodingTests.swift @@ -1,5 +1,5 @@ // -// FormUrlEncodingTests.swift +// FormURLEncodingTests.swift // CoreNetKit // // Created by Александр Кравченков on 31/03/2019. @@ -22,7 +22,7 @@ final class EncodingTests: XCTestCase { // MARK: - Sut - private var sut: UrlJsonRequestEncodingNode! + private var sut: URLJsonRequestEncodingNode! // MARK: - Lifecycle @@ -31,7 +31,7 @@ final class EncodingTests: XCTestCase { nextNodeMock = AsyncNodeMock() logContextMock = LoggingContextMock() requestCreatorNode = RequestCreatorNode(next: nextNodeMock) - sut = UrlJsonRequestEncodingNode(next: requestCreatorNode) + sut = URLJsonRequestEncodingNode(next: requestCreatorNode) } public override func tearDown() { @@ -44,7 +44,7 @@ final class EncodingTests: XCTestCase { // MARK: - Tests - func testAsyncProcess_thenFormUrlConvertinWork() async throws { + func testAsyncProcess_thenFormURLConvertinWork() async throws { // given let url = "http://test.com/usr" @@ -52,11 +52,11 @@ final class EncodingTests: XCTestCase { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" ] let dataRaw: Json = ["id": "123455"] - let urlParameters = TransportUrlParameters(method: .post, url: URL(string: url)!) + let urlParameters = TransportURLParameters(method: .post, url: URL(string: url)!) let encodingModel = RequestEncodingModel( urlParameters: urlParameters, raw: dataRaw, - encoding: .formUrl + encoding: .formURL ) let expectedResult = ["Test": "Value"] @@ -79,12 +79,12 @@ final class EncodingTests: XCTestCase { XCTAssertEqual(unwrappedResult, expectedResult) } - public func testAsyncProcess_thenUrlQueryConvertionWork() async throws { + public func testAsyncProcess_thenURLQueryConvertionWork() async throws { // given let url = "http://test.com/usr" let dataRaw: Json = ["id": "12345"] - let urlParameters = TransportUrlParameters(method: .post, url: URL(string: url)!) + let urlParameters = TransportURLParameters(method: .post, url: URL(string: url)!) let encodingModel = RequestEncodingModel( urlParameters: urlParameters, raw: dataRaw, @@ -117,7 +117,7 @@ final class EncodingTests: XCTestCase { let url = "http://test.com/usr" let headersArray: [String: String] = ["Content-Type": "application/json"] let dataRaw: Json = ["id": "12345"] - let urlParameters = TransportUrlParameters(method: .post, url: URL(string: url)!) + let urlParameters = TransportURLParameters(method: .post, url: URL(string: url)!) let encodingModel = RequestEncodingModel( urlParameters: urlParameters, raw: dataRaw, @@ -150,7 +150,7 @@ final class EncodingTests: XCTestCase { let url = "http://test.com/usr" let dataRaw: Json = ["id": "12345"] - let urlParameters = TransportUrlParameters(method: .get, url: URL(string: url)!) + let urlParameters = TransportURLParameters(method: .get, url: URL(string: url)!) let encodingModel = RequestEncodingModel( urlParameters: urlParameters, raw: dataRaw, @@ -158,7 +158,7 @@ final class EncodingTests: XCTestCase { ) let expectedResult = ["Test2": "Value2"] - let expectedUrl = url + "?id=12345" + let expectedURL = url + "?id=12345" nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) @@ -171,7 +171,7 @@ final class EncodingTests: XCTestCase { let unwrappedResult = try XCTUnwrap(try result.get() as? [String: String]) XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nextNodeMock.invokedAsyncProcessParameters?.data.url!.absoluteString, expectedUrl) + XCTAssertEqual(nextNodeMock.invokedAsyncProcessParameters?.data.url!.absoluteString, expectedURL) XCTAssertEqual(nextNodeMock.invokedAsyncProcessParameters?.data.headers.dictionary.isEmpty, true) XCTAssertEqual(unwrappedResult, expectedResult) } @@ -182,7 +182,7 @@ final class EncodingTests: XCTestCase { let wrongString = String(bytes: [0xD8, 0x00] as [UInt8], encoding: String.Encoding.utf16BigEndian)! let url = "http://test.com/usr" let dataRaw: Json = ["id": wrongString] - let urlParameters = TransportUrlParameters(method: .head, url: URL(string: url)!) + let urlParameters = TransportURLParameters(method: .head, url: URL(string: url)!) let encodingModel = RequestEncodingModel( urlParameters: urlParameters, raw: dataRaw, @@ -208,7 +208,7 @@ final class EncodingTests: XCTestCase { let url = "http://test.com/usr" let dataRaw: Json = ["id": "12345"] - let urlParameters = TransportUrlParameters(method: .post, url: URL(string: url)!) + let urlParameters = TransportURLParameters(method: .post, url: URL(string: url)!) let encodingModel = RequestEncodingModel( urlParameters: urlParameters, raw: dataRaw, diff --git a/NodeKit/NodeKitTests/UnitTests/Network/URLRoutingTests.swift b/NodeKit/NodeKitTests/UnitTests/Network/URLRoutingTests.swift index 7079ea90a..a47387ebe 100644 --- a/NodeKit/NodeKitTests/UnitTests/Network/URLRoutingTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Network/URLRoutingTests.swift @@ -33,10 +33,10 @@ final class URLRoutingTests: XCTestCase { // then - let error = try XCTUnwrap(receivedError as? UrlRouteError) + let error = try XCTUnwrap(receivedError as? URLRouteError) XCTAssertNil(result) - XCTAssertEqual(error, .cantBuildUrl) + XCTAssertEqual(error, .cantBuildURL) } func testAppend_whenURLIsNotNil_thenNewURLReceived() throws { diff --git a/NodeKit/NodeKitTests/UnitTests/Network/UrlChainConfigModelTests.swift b/NodeKit/NodeKitTests/UnitTests/Network/UrlChainConfigModelTests.swift deleted file mode 100644 index 4662e2985..000000000 --- a/NodeKit/NodeKitTests/UnitTests/Network/UrlChainConfigModelTests.swift +++ /dev/null @@ -1,72 +0,0 @@ -// -// UrlChainConfigModelTests.swift -// NodeKitTests -// -// Created by Andrei Frolov on 09.04.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit -@testable import NodeKitMock - -import XCTest - -final class UrlChainConfigModelTests: XCTestCase { - - // MARK: - Tests - - func testUrlChainConfigModel_withCustomParameters_thenCustomParametersReceived() throws { - // given - - let model = UrlChainConfigModel( - method: .options, - route: UrlRouteProviderMock(), - metadata: ["TestKey": "TestValue"], - encoding: .urlQuery - ) - - // when - - let method = model.method - let route = model.route - let metadata = model.metadata - let encoding = model.encoding - - // then - - let receivedRoute = try XCTUnwrap(route as? UrlRouteProviderMock) - let expectedRoute = try XCTUnwrap(model.route as? UrlRouteProviderMock) - - XCTAssertEqual(method, model.method) - XCTAssertTrue(receivedRoute === expectedRoute) - XCTAssertEqual(metadata, model.metadata) - XCTAssertEqual(encoding, model.encoding) - } - - func testUrlChainConfigModel_withDefaultParameters_thenDefaultParametersReceived() throws { - // given - - let model = UrlChainConfigModel( - method: .options, - route: UrlRouteProviderMock() - ) - - // when - - let method = model.method - let route = model.route - let metadata = model.metadata - let encoding = model.encoding - - // then - - - let receivedRoute = try XCTUnwrap(route as? UrlRouteProviderMock) - let expectedRoute = try XCTUnwrap(model.route as? UrlRouteProviderMock) - - XCTAssertEqual(method, model.method) - XCTAssertTrue(receivedRoute === expectedRoute) - XCTAssertTrue(metadata.isEmpty) - XCTAssertEqual(encoding, .json) - } -} diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/AccessSafeNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/AccessSafeNodeTests.swift index 9d989f855..3199ace8c 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/AccessSafeNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/AccessSafeNodeTests.swift @@ -15,7 +15,7 @@ final class AccessSafeNodeTests: XCTestCase { // MARK: - Dependencies - private var nextNodeMock: AsyncNodeMock! + private var nextNodeMock: AsyncNodeMock! private var updateTokenChainMock: AsyncNodeMock! private var logContextMock: LoggingContextMock! @@ -42,7 +42,7 @@ final class AccessSafeNodeTests: XCTestCase { let url = URL(string: "www.testprocess.com")! let headers = ["TestHeaderKey": "TestHeaderValue"] let data = "Test".data(using: .utf8)! - let request = TransportUrlRequest(method: .connect, url: url, headers: headers, raw: data) + let request = TransportURLRequest(method: .connect, url: url, headers: headers, raw: data) nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) @@ -61,7 +61,7 @@ final class AccessSafeNodeTests: XCTestCase { func testAsyncProcess_whenNextReturnsSuccess_thenUpdateTokenDidNotCalled() async { // given - let request = TransportUrlRequest( + let request = TransportURLRequest( method: .connect, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -83,7 +83,7 @@ final class AccessSafeNodeTests: XCTestCase { // given let expectedResult = ["TestKey": "TestValue"] - let request = TransportUrlRequest( + let request = TransportURLRequest( method: .connect, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -105,7 +105,7 @@ final class AccessSafeNodeTests: XCTestCase { func testAsyncProcess_whenNextReturnsCustomError_thenErrorReceived() async throws { // given - let request = TransportUrlRequest( + let request = TransportURLRequest( method: .connect, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -127,7 +127,7 @@ final class AccessSafeNodeTests: XCTestCase { func testAsyncProcess_whenNextReturnsCustomError_thenTokenDidNotUpdate() async { // given - let request = TransportUrlRequest( + let request = TransportURLRequest( method: .connect, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -148,7 +148,7 @@ final class AccessSafeNodeTests: XCTestCase { func testAsyncProcess_whenForbidenErrorReceived_thenUpdateTokenStarted() async { // given - let request = TransportUrlRequest( + let request = TransportURLRequest( method: .connect, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -170,7 +170,7 @@ final class AccessSafeNodeTests: XCTestCase { func testAsyncProcess_whenUnauthorizedErrorReceived_thenUpdateTokenStarted() async { // given - let request = TransportUrlRequest( + let request = TransportURLRequest( method: .connect, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -194,7 +194,7 @@ final class AccessSafeNodeTests: XCTestCase { func testAsyncProcess_whenTokenUpdateReturnsError_thenRequestDidNotRepeat() async { // given - let request = TransportUrlRequest( + let request = TransportURLRequest( method: .connect, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -216,7 +216,7 @@ final class AccessSafeNodeTests: XCTestCase { func testAsyncProcess_whenTokenUpdateReturnsError_thenErrorReceived() async throws { // given - let request = TransportUrlRequest( + let request = TransportURLRequest( method: .connect, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -239,7 +239,7 @@ final class AccessSafeNodeTests: XCTestCase { func testAsyncProcess_whenTokenUpdateReturnsSuccess_thenRequestRepeated() async throws { // given - let request = TransportUrlRequest( + let request = TransportURLRequest( method: .connect, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/CacheReaderNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/CacheReaderNodeTests.swift index c7e9886ae..0847ca86f 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/CacheReaderNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/CacheReaderNodeTests.swift @@ -20,14 +20,14 @@ final class CacheReaderNodeTests: XCTestCase { // MARK: - Sut - private var sut: UrlCacheReaderNode! + private var sut: URLCacheReaderNode! // MARK: - Lifecycle override func setUp() { super.setUp() logContextMock = LoggingContextMock() - sut = UrlCacheReaderNode(needsToThrowError: true) + sut = URLCacheReaderNode(needsToThrowError: true) } override func tearDown() { @@ -44,7 +44,7 @@ final class CacheReaderNodeTests: XCTestCase { let url = URL(string: "http://example.test")! let request = URLRequest(url: url) - let model = UrlNetworkRequest(urlRequest: request) + let model = URLNetworkRequest(urlRequest: request) let responseKey = "name" let responseValue = "test" let response = [responseKey: responseValue] @@ -73,7 +73,7 @@ final class CacheReaderNodeTests: XCTestCase { let url = URL(string: "http://example.test")! let request = URLRequest(url: url) - let model = UrlNetworkRequest(urlRequest: request) + let model = URLNetworkRequest(urlRequest: request) let responseKey = "name" let responseValue = "test" let response = [[responseKey: responseValue], [responseKey: responseValue]] @@ -115,7 +115,7 @@ final class CacheReaderNodeTests: XCTestCase { )! let cachedRequest = CachedURLResponse(response: urlResponse, data: responseData) let notOwnRequest = URLRequest(url: URL(string: "http://example.test/usr?ud=321")!) - let model = UrlNetworkRequest(urlRequest: notOwnRequest) + let model = URLNetworkRequest(urlRequest: notOwnRequest) URLCache.shared.storeCachedResponse(cachedRequest, for: request) @@ -125,7 +125,7 @@ final class CacheReaderNodeTests: XCTestCase { // ghen - let error = try XCTUnwrap(result.error as? BaseUrlCacheReaderError) + let error = try XCTUnwrap(result.error as? BaseURLCacheReaderError) XCTAssertEqual(error, .cantLoadDataFromCache) } @@ -135,7 +135,7 @@ final class CacheReaderNodeTests: XCTestCase { let url = URL(string: "http://example.test")! let request = URLRequest(url: url) - let model = UrlNetworkRequest(urlRequest: request) + let model = URLNetworkRequest(urlRequest: request) let responseData = "{1:1}".data(using: .utf8)! let urlResponse = HTTPURLResponse(url: url, statusCode: 200, httpVersion: "1.1", headerFields: nil)! let cachedRequest = CachedURLResponse(response: urlResponse, data: responseData) @@ -148,7 +148,7 @@ final class CacheReaderNodeTests: XCTestCase { // ghen - let error = try XCTUnwrap(result.error as? BaseUrlCacheReaderError) + let error = try XCTUnwrap(result.error as? BaseURLCacheReaderError) XCTAssertEqual(error, .cantSerializeJson) } @@ -158,7 +158,7 @@ final class CacheReaderNodeTests: XCTestCase { let url = URL(string: "http://example.test")! let request = URLRequest(url: url) - let model = UrlNetworkRequest(urlRequest: request) + let model = URLNetworkRequest(urlRequest: request) let responseData = "12345".data(using: .utf8)! let urlResponse = HTTPURLResponse(url: url, statusCode: 200, httpVersion: "1.1", headerFields: nil)! let cachedRequest = CachedURLResponse(response: urlResponse, data: responseData) @@ -171,7 +171,7 @@ final class CacheReaderNodeTests: XCTestCase { // ghen - let error = try XCTUnwrap(result.error as? BaseUrlCacheReaderError) + let error = try XCTUnwrap(result.error as? BaseURLCacheReaderError) XCTAssertEqual(error, .cantCastToJson) } diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/DataLoadingResponseProcessorTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/DataLoadingResponseProcessorTests.swift index b4ccabaa7..529bdb97a 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/DataLoadingResponseProcessorTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/DataLoadingResponseProcessorTests.swift @@ -15,7 +15,7 @@ final class DataLoadingResponseProcessorTests: XCTestCase { // MARK: - Dependencies - private var nextNodeMock: AsyncNodeMock! + private var nextNodeMock: AsyncNodeMock! private var logContextMock: LoggingContextMock! // MARK: - Sut @@ -46,12 +46,10 @@ final class DataLoadingResponseProcessorTests: XCTestCase { let expectedData = "TestData".data(using: .utf8)! let sut = DataLoadingResponseProcessor() let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 1, httpVersion: nil, headerFields: [:])!, - data: expectedData, - metrics: nil, - serializationDuration: 1 + data: expectedData ) // when @@ -70,12 +68,10 @@ final class DataLoadingResponseProcessorTests: XCTestCase { let url = URL(string: "www.test.com")! let headers = ["TestHeaderKey": "TestHeaderValue"] - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 1, httpVersion: nil, headerFields: headers)!, - data: "TestData".data(using: .utf8)!, - metrics: nil, - serializationDuration: 1 + data: "TestData".data(using: .utf8)! ) nextNodeMock.stubbedAsyncProccessResult = .success(()) @@ -97,12 +93,10 @@ final class DataLoadingResponseProcessorTests: XCTestCase { let expectedData = "TestExpectedData".data(using: .utf8)! let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 1, httpVersion: nil, headerFields: [:])!, - data: expectedData, - metrics: nil, - serializationDuration: 1 + data: expectedData ) nextNodeMock.stubbedAsyncProccessResult = .success(()) @@ -121,12 +115,10 @@ final class DataLoadingResponseProcessorTests: XCTestCase { // given let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 1, httpVersion: nil, headerFields: [:])!, - data: Data(), - metrics: nil, - serializationDuration: 1 + data: Data() ) nextNodeMock.stubbedAsyncProccessResult = .failure(MockError.firstError) diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/HeaderInjectorNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/HeaderInjectorNodeTests.swift index 241e89476..b563159ae 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/HeaderInjectorNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/HeaderInjectorNodeTests.swift @@ -15,7 +15,7 @@ final class HeaderInjectorNodeTests: XCTestCase { // MARK: - Dependencies - private var nextNodeMock: AsyncNodeMock! + private var nextNodeMock: AsyncNodeMock! private var logContextMock: LoggingContextMock! // MARK: - Lifecycle @@ -42,9 +42,9 @@ final class HeaderInjectorNodeTests: XCTestCase { let expectedURL = URL(string: "www.testprocess.com")! let expectedHeaders = ["TestKey": "TestValue"] let expectedMethod: NodeKit.Method = .options - let requestParameters = TransportUrlParameters(method: expectedMethod, url: expectedURL, headers: expectedHeaders) + let requestParameters = TransportURLParameters(method: expectedMethod, url: expectedURL, headers: expectedHeaders) let expectedData = "TestData".data(using: .utf8)! - let request = TransportUrlRequest( + let request = TransportURLRequest( with: requestParameters, raw: expectedData) nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) @@ -77,12 +77,12 @@ final class HeaderInjectorNodeTests: XCTestCase { let expectedURL = URL(string: "www.testprocess.com")! let expectedMethod: NodeKit.Method = .options let expectedData = "TestData".data(using: .utf8)! - let requestParameters = TransportUrlParameters( + let requestParameters = TransportURLParameters( method: expectedMethod, url: expectedURL, headers: ["TestKey": "TestValue"] ) - let request = TransportUrlRequest( + let request = TransportURLRequest( with: requestParameters, raw: expectedData) let expectedHeaders = [ @@ -121,12 +121,12 @@ final class HeaderInjectorNodeTests: XCTestCase { let expectedURL = URL(string: "www.testprocess.com")! let expectedMethod: NodeKit.Method = .options let expectedData = "TestData".data(using: .utf8)! - let requestParameters = TransportUrlParameters( + let requestParameters = TransportURLParameters( method: expectedMethod, url: expectedURL, headers: ["TestKey": "TestValue"] ) - let request = TransportUrlRequest( + let request = TransportURLRequest( with: requestParameters, raw: expectedData) let expectedHeaders = [ diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/IfConnectionFailedFromCacheNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/IfConnectionFailedFromCacheNodeTests.swift index 94c896a9c..5ca65b0d6 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/IfConnectionFailedFromCacheNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/IfConnectionFailedFromCacheNodeTests.swift @@ -17,7 +17,7 @@ final class IfConnectionFailedFromCacheNodeTests: XCTestCase { // MARK: - Dependencies private var logContextMock: LoggingContextMock! - private var cacheReaderNodeMock: AsyncNodeMock! + private var cacheReaderNodeMock: AsyncNodeMock! private var mapperNode: TechnicaErrorMapperNode! private var mapperNextNodeMock: AsyncNodeMock! diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/LoadIndicatableNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/LoadIndicatableNodeTests.swift deleted file mode 100644 index a7b08f928..000000000 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/LoadIndicatableNodeTests.swift +++ /dev/null @@ -1,142 +0,0 @@ -// -// LoadIndicatableNodeTests.swift -// NodeKitTests -// -// Created by Andrei Frolov on 08.04.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit -@testable import NodeKitMock - -import XCTest - -final class LoadIndicatableNodeTests: XCTestCase { - - // MARK: - Dependencies - - private var nextNodeMock: AsyncNodeMock! - private var logContextMock: LoggingContextMock! - - // MARK: - Sut - - private var sut: LoadIndicatableNode! - - // MARK: - Lifecycle - - override func setUp() { - super.setUp() - nextNodeMock = AsyncNodeMock() - logContextMock = LoggingContextMock() - sut = LoadIndicatableNode(next: nextNodeMock) - } - - override func tearDown() { - super.tearDown() - nextNodeMock = nil - logContextMock = nil - sut = nil - } - - // MARK: - Tests - - func testAsyncProcess_thenNextCalled() async throws { - // given - - let expectedInput = 006 - nextNodeMock.stubbedAsyncProccessResult = .success(1) - - // when - - _ = await sut.process(expectedInput, logContext: logContextMock) - - // then - - let input = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameters?.data) - - XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(input, expectedInput) - } - - func testAsyncProcess_whenNextReturnsSuccess_thenSuccessReceived() async throws { - // given - - let expectedResult = 0089 - nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) - - // when - - let result = await sut.process(1, logContext: logContextMock) - - // then - - let value = try XCTUnwrap(result.value) - - XCTAssertEqual(value, expectedResult) - } - - func testAsyncProcess_whenNextReturnsFailure_thenFailureReceived() async throws { - // given - - nextNodeMock.stubbedAsyncProccessResult = .failure(MockError.firstError) - - // when - - let result = await sut.process(1, logContext: logContextMock) - - // then - - let error = try XCTUnwrap(result.error as? MockError) - - XCTAssertEqual(error, .firstError) - } - - @MainActor - func testAsyncProcess_thenIndicatorIncremented() async { - // given - - var count = 0 - let expectation = expectation(description: #function) - nextNodeMock.stubbedAsyncProccessResult = .success(1) - nextNodeMock.stubbedAsyncProcessRunFunction = { - count += 1 - if count == 2 { - expectation.fulfill() - } - try? await Task.sleep(nanoseconds: 5000000000) - } - - // when - - Task { - _ = await sut.process(1, logContext: logContextMock) - } - - Task { - _ = await sut.process(1, logContext: logContextMock) - } - - await fulfillment(of: [expectation], timeout: 3) - - // then - - XCTAssertEqual(LoadIndicatableNodeStatic.requestConter, 2) - } - - func testAsyncProcess_thenIndicatorDecremented() async { - // given - - nextNodeMock.stubbedAsyncProccessResult = .success(1) - - // when - - _ = await sut.process(1, logContext: logContextMock) - _ = await sut.process(1, logContext: logContextMock) - - try? await Task.sleep(nanoseconds: 100000000) - - // then - - XCTAssertEqual(LoadIndicatableNodeStatic.requestConter, 0) - } -} diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/MultipartRequestCreatorNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/MultipartRequestCreatorNodeTests.swift index bb2ae45db..d2b0b731c 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/MultipartRequestCreatorNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/MultipartRequestCreatorNodeTests.swift @@ -61,7 +61,7 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { ] ) - let model = MultipartUrlRequest( + let model = MultipartURLRequest( method: .delete, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -90,17 +90,17 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { XCTAssertFalse(multipartFormDataMock.invokedAppendCustomURL) } - func testAsyncProcess_withMultipartFormFileUrl_thenMultipartFormDataAppendCalled() async throws { + func testAsyncProcess_withMultipartFormFileURL_thenMultipartFormDataAppendCalled() async throws { // given let fileKey = "TestFileKey1" - let fileUrl = URL(string: "www.testfirstfile.com")! + let fileURL = URL(string: "www.testfirstfile.com")! let multipartModel = MultipartModel<[String: Data]>( payloadModel: [:], - files: [fileKey: .url(url: fileUrl)] + files: [fileKey: .url(url: fileURL)] ) - let model = MultipartUrlRequest( + let model = MultipartURLRequest( method: .delete, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -122,7 +122,7 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { XCTAssertEqual(multipartFormDataFactoryMock.invokedProduceCount, 1) XCTAssertEqual(multipartFormDataMock.invokedAppendURLCount, 1) XCTAssertEqual(multipartDataInput.name, fileKey) - XCTAssertEqual(multipartDataInput.fileUrl, fileUrl) + XCTAssertEqual(multipartDataInput.fileURL, fileURL) XCTAssertFalse(multipartFormDataMock.invokedAppendData) XCTAssertFalse(multipartFormDataMock.invokedAppendCustomURL) } @@ -139,7 +139,7 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { files: [fileKey: .data(data: fileData, filename: fileName, mimetype: fileMimeType)] ) - let model = MultipartUrlRequest( + let model = MultipartURLRequest( method: .delete, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -168,19 +168,19 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { XCTAssertFalse(multipartFormDataMock.invokedAppendCustomURL) } - func testAsyncProcess_withMultipartFormFileCustomUrl_thenMultipartFormDataAppendCalled() async throws { + func testAsyncProcess_withMultipartFormFileCustomURL_thenMultipartFormDataAppendCalled() async throws { // given let fileKey = "TestFileKey3" - let fileUrl = URL(string: "www.testthirdfile.com")! + let fileURL = URL(string: "www.testthirdfile.com")! let fileName = "TestThirdFile.name" let fileMimeType = "TestThirdFileMimeType" let multipartModel = MultipartModel<[String: Data]>( payloadModel: [:], - files: [fileKey: .customWithUrl(url: fileUrl, filename: fileName, mimetype: fileMimeType)] + files: [fileKey: .customWithURL(url: fileURL, filename: fileName, mimetype: fileMimeType)] ) - let model = MultipartUrlRequest( + let model = MultipartURLRequest( method: .delete, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -202,7 +202,7 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { XCTAssertEqual(multipartFormDataFactoryMock.invokedProduceCount, 1) XCTAssertEqual(multipartFormDataMock.invokedAppendCustomURLCount, 1) XCTAssertEqual(multipartDataInput.name, fileKey) - XCTAssertEqual(multipartDataInput.fileUrl, fileUrl) + XCTAssertEqual(multipartDataInput.fileURL, fileURL) XCTAssertEqual(multipartDataInput.fileName, fileName) XCTAssertEqual(multipartDataInput.mimeType, fileMimeType) XCTAssertFalse(multipartFormDataMock.invokedAppendURL) @@ -212,7 +212,7 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { func testAsyncProcess_withEncodingError_thenNextDidNotCall() async throws { // given - let model = MultipartUrlRequest( + let model = MultipartURLRequest( method: .delete, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -235,7 +235,7 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { func testAsyncProcess_withEncodingError_thenErrorReceived() async throws { // given - let model = MultipartUrlRequest( + let model = MultipartURLRequest( method: .delete, url: URL(string: "www.testprocess.com")!, headers: ["TestHeaderKey": "TestHeaderValue"], @@ -258,12 +258,12 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { func testAsyncProcess_withEncodingSuccess_thenNextCalled() async throws { // given - let expectedUrl = URL(string: "www.testprocess.com")! + let expectedURL = URL(string: "www.testprocess.com")! let stubbedContentType = "TestContentType" let headers = ["TestHeaderKey": "TestHeaderValue"] - let model = MultipartUrlRequest( + let model = MultipartURLRequest( method: .delete, - url: expectedUrl, + url: expectedURL, headers: headers, data: MultipartModel<[String: Data]>(payloadModel: [:]) ) @@ -287,7 +287,7 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { let httpHeaders = try XCTUnwrap(nextNodeInput.allHTTPHeaderFields) XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nextNodeInput.url, expectedUrl) + XCTAssertEqual(nextNodeInput.url, expectedURL) XCTAssertEqual(nextNodeInput.httpMethod, NodeKit.Method.delete.rawValue) XCTAssertEqual(nextNodeInput.httpBody, multipartData) XCTAssertEqual(httpHeaders, expectedHeaders) @@ -296,7 +296,7 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { func testAsyncProcess_withSuccess_thenSuccessReceived() async throws { // given - let model = MultipartUrlRequest( + let model = MultipartURLRequest( method: .get, url: URL(string: "www.testprocess.com")!, headers: [:], @@ -321,7 +321,7 @@ final class MultipartRequestCreatorNodeTest: XCTestCase { func testAsyncProcess_withError_thenErrorReceived() async throws { // given - let model = MultipartUrlRequest( + let model = MultipartURLRequest( method: .get, url: URL(string: "www.testprocess.com")!, headers: [:], diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/MultipartUrlRequestTrasformatorNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/MultipartUrlRequestTrasformatorNodeTests.swift deleted file mode 100644 index 7c4cfbd08..000000000 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/MultipartUrlRequestTrasformatorNodeTests.swift +++ /dev/null @@ -1,185 +0,0 @@ -// -// MultipartUrlRequestTrasformatorNodeTests.swift -// NodeKitTests -// -// Created by Andrei Frolov on 05.04.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit -@testable import NodeKitMock - -import XCTest - -final class MultipartUrlRequestTrasformatorNodeTests: XCTestCase { - - // MARK: - Dependencies - - private var nextNodeMock: AsyncNodeMock! - private var logContextMock: LoggingContextMock! - private var urlRouteProviderMock: UrlRouteProviderMock! - - // MARK: - Lifecycle - - override func setUp() { - super.setUp() - nextNodeMock = AsyncNodeMock() - logContextMock = LoggingContextMock() - urlRouteProviderMock = UrlRouteProviderMock() - } - - override func tearDown() { - super.tearDown() - nextNodeMock = nil - logContextMock = nil - urlRouteProviderMock = nil - } - - // MARK: - Tests - - func testAsyncProcess_withoutUrl_thenNextDidNotCall() async { - // given - - let sut = MultipartUrlRequestTrasformatorNode(next: nextNodeMock, method: .trace) - let model = RoutableRequestModel>( - metadata: [:], - raw: MultipartModel<[String : Data]>(payloadModel: [:]), - route: urlRouteProviderMock - ) - - urlRouteProviderMock.stubbedUrlResult = .failure(MockError.thirdError) - - // when - - _ = await sut.process(model, logContext: logContextMock) - - // then - - XCTAssertFalse(nextNodeMock.invokedAsyncProcess) - } - - func testAsyncProcess_withoutUrl_thenErrorReceived() async throws { - // given - - let sut = MultipartUrlRequestTrasformatorNode(next: nextNodeMock, method: .trace) - let model = RoutableRequestModel>( - metadata: [:], - raw: MultipartModel<[String : Data]>(payloadModel: [:]), - route: urlRouteProviderMock - ) - - urlRouteProviderMock.stubbedUrlResult = .failure(MockError.thirdError) - - // when - - let result = await sut.process(model, logContext: logContextMock) - - // then - - let error = try XCTUnwrap(result.error as? MockError) - XCTAssertEqual(error, .thirdError) - } - - func testAsyncProcess_withCorrentURL_thenNextCalled() async { - // given - - let sut = MultipartUrlRequestTrasformatorNode(next: nextNodeMock, method: .options) - let model = RoutableRequestModel>( - metadata: [:], - raw: MultipartModel<[String : Data]>(payloadModel: [:]), - route: urlRouteProviderMock - ) - - nextNodeMock.stubbedAsyncProccessResult = .success(1) - urlRouteProviderMock.stubbedUrlResult = .success(URL(string: "www.test.com")!) - - // when - - _ = await sut.process(model, logContext: logContextMock) - - // then - - XCTAssertEqual(urlRouteProviderMock.invokedUrlCount, 1) - XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - } - - func testAsyncProcess_withSuccessResponse_thenMultipartRequestCreated() async throws { - // given - - let sut = MultipartUrlRequestTrasformatorNode(next: nextNodeMock, method: .options) - let expectedResult = 15 - let expectedUrl = URL(string: "www.test.com")! - let multipartModel = MultipartModel<[String : Data]>(payloadModel: [ - "TestMultipartKey": "TestMultipartValue".data(using: .utf8)! - ]) - let metadata = ["TestMetadataKey": "TestMetadataValue"] - let model = RoutableRequestModel>( - metadata: metadata, - raw: multipartModel, - route: urlRouteProviderMock - ) - - nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) - urlRouteProviderMock.stubbedUrlResult = .success(expectedUrl) - - // when - - _ = await sut.process(model, logContext: logContextMock) - - // then - - let input = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameters?.data) - - XCTAssertEqual(input.headers , metadata) - XCTAssertEqual(input.method, .options) - XCTAssertEqual(input.url, expectedUrl) - XCTAssertEqual(input.data.payloadModel, multipartModel.payloadModel) - } - - func testAsyncProcess_withSuccessResponse_thenSuccessReceived() async throws { - // given - - let sut = MultipartUrlRequestTrasformatorNode(next: nextNodeMock, method: .options) - let expectedResult = 99 - let model = RoutableRequestModel>( - metadata: [:], - raw: MultipartModel<[String : Data]>(payloadModel: [:]), - route: urlRouteProviderMock - ) - - nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) - urlRouteProviderMock.stubbedUrlResult = .success(URL(string: "www.test.com")!) - - // when - - let result = await sut.process(model, logContext: logContextMock) - - // then - - let value = try XCTUnwrap(result.value) - XCTAssertEqual(value, expectedResult) - } - - func testAsyncProcess_withFailureResponse_thenFailureReceived() async throws { - // given - - let sut = MultipartUrlRequestTrasformatorNode(next: nextNodeMock, method: .options) - let model = RoutableRequestModel>( - metadata: [:], - raw: MultipartModel<[String : Data]>(payloadModel: [:]), - route: urlRouteProviderMock - ) - - nextNodeMock.stubbedAsyncProccessResult = .failure(MockError.secondError) - urlRouteProviderMock.stubbedUrlResult = .success(URL(string: "www.test.com")!) - - // when - - let result = await sut.process(model, logContext: logContextMock) - - // then - - let error = try XCTUnwrap(result.error as? MockError) - XCTAssertEqual(error, .secondError) - } -} diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/RequestCreatorNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/RequestCreatorNodeTests.swift index e13a9d2a5..25bd1c7cf 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/RequestCreatorNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/RequestCreatorNodeTests.swift @@ -42,9 +42,9 @@ final class RequestCreatorNodeTests: XCTestCase { let expectedURL = URL(string: "www.testprocess.com")! let expectedHeaders = ["TestKey": "TestValue"] let expectedMethod: NodeKit.Method = .options - let requestParameters = TransportUrlParameters(method: expectedMethod, url: expectedURL, headers: expectedHeaders) + let requestParameters = TransportURLParameters(method: expectedMethod, url: expectedURL, headers: expectedHeaders) let expectedData = "TestData".data(using: .utf8)! - let request = TransportUrlRequest( + let request = TransportURLRequest( with: requestParameters, raw: expectedData) nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) @@ -80,12 +80,12 @@ final class RequestCreatorNodeTests: XCTestCase { let expectedURL = URL(string: "www.testprocess.com")! let expectedMethod: NodeKit.Method = .options let expectedData = "TestData".data(using: .utf8)! - let requestParameters = TransportUrlParameters( + let requestParameters = TransportURLParameters( method: expectedMethod, url: expectedURL, headers: ["TestKey": "TestValue"] ) - let request = TransportUrlRequest( + let request = TransportURLRequest( with: requestParameters, raw: expectedData) let expectedHeaders = [ @@ -129,12 +129,12 @@ final class RequestCreatorNodeTests: XCTestCase { let expectedURL = URL(string: "www.testprocess.com")! let expectedMethod: NodeKit.Method = .options let expectedData = "TestData".data(using: .utf8)! - let requestParameters = TransportUrlParameters( + let requestParameters = TransportURLParameters( method: expectedMethod, url: expectedURL, headers: ["TestKey": "TestValue"] ) - let request = TransportUrlRequest( + let request = TransportURLRequest( with: requestParameters, raw: expectedData) let expectedHeaders = [ diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseDataParserNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseDataParserNodeTests.swift index ce15df56b..078e14fd5 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseDataParserNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseDataParserNodeTests.swift @@ -15,7 +15,7 @@ final class ResponseDataParserNodeTests: XCTestCase { // MARK: - Dependencies - private var nextNodeMock: AsyncNodeMock! + private var nextNodeMock: AsyncNodeMock! private var logContextMock: LoggingContextMock! // MARK: - Lifecycle @@ -42,13 +42,10 @@ final class ResponseDataParserNodeTests: XCTestCase { let expectedRequest = URLRequest(url: url) let expectedData = Data() let expectedResponse = HTTPURLResponse(url: url, mimeType: nil, expectedContentLength: .zero, textEncodingName: nil) - let expectedSerializationDuration: TimeInterval = 42 - let response = UrlDataResponse( + let response = URLDataResponse( request: expectedRequest, response: expectedResponse, - data: expectedData, - metrics: nil, - serializationDuration: expectedSerializationDuration + data: expectedData ) nextNodeMock.stubbedAsyncProccessResult = .success(()) @@ -66,8 +63,6 @@ final class ResponseDataParserNodeTests: XCTestCase { XCTAssertEqual(parameter.request, expectedRequest) XCTAssertEqual(parameter.response, expectedResponse) XCTAssertEqual(parameter.data, expectedData) - XCTAssertEqual(parameter.metrics, nil) - XCTAssertEqual(parameter.serializationDuration, expectedSerializationDuration) XCTAssertTrue(parameter.json.isEmpty) XCTAssertTrue(value.isEmpty) } @@ -80,13 +75,10 @@ final class ResponseDataParserNodeTests: XCTestCase { let expectedRequest = URLRequest(url: url) let expectedData = "{1:1}".data(using: .utf8)! let expectedResponse = HTTPURLResponse(url: url, mimeType: nil, expectedContentLength: .zero, textEncodingName: nil) - let expectedSerializationDuration: TimeInterval = 42 - let response = UrlDataResponse( + let response = URLDataResponse( request: expectedRequest, response: expectedResponse, - data: expectedData, - metrics: nil, - serializationDuration: expectedSerializationDuration + data: expectedData ) nextNodeMock.stubbedAsyncProccessResult = .success(()) @@ -116,13 +108,10 @@ final class ResponseDataParserNodeTests: XCTestCase { let expectedRequest = URLRequest(url: url) let expectedData = "15".data(using: .utf8)! let expectedResponse = HTTPURLResponse(url: url, mimeType: nil, expectedContentLength: .zero, textEncodingName: nil) - let expectedSerializationDuration: TimeInterval = 42 - let response = UrlDataResponse( + let response = URLDataResponse( request: expectedRequest, response: expectedResponse, - data: expectedData, - metrics: nil, - serializationDuration: expectedSerializationDuration + data: expectedData ) nextNodeMock.stubbedAsyncProccessResult = .success(()) @@ -153,13 +142,10 @@ final class ResponseDataParserNodeTests: XCTestCase { let expectedResult = ["TestKey1": "TestValue1", "TestKey2": "TestValue2"] let jsonData = try JSONSerialization.data(withJSONObject: expectedResult) let expectedResponse = HTTPURLResponse(url: url, mimeType: nil, expectedContentLength: .zero, textEncodingName: nil) - let expectedSerializationDuration: TimeInterval = 42 - let response = UrlDataResponse( + let response = URLDataResponse( request: expectedRequest, response: expectedResponse, - data: jsonData, - metrics: nil, - serializationDuration: expectedSerializationDuration + data: jsonData ) nextNodeMock.stubbedAsyncProccessResult = .success(()) @@ -178,8 +164,6 @@ final class ResponseDataParserNodeTests: XCTestCase { XCTAssertEqual(parameter.request, expectedRequest) XCTAssertEqual(parameter.response, expectedResponse) XCTAssertEqual(parameter.data, jsonData) - XCTAssertEqual(parameter.metrics, nil) - XCTAssertEqual(parameter.serializationDuration, expectedSerializationDuration) XCTAssertEqual(inputJson, expectedResult) XCTAssertEqual(value, expectedResult) } @@ -193,13 +177,10 @@ final class ResponseDataParserNodeTests: XCTestCase { let expectedResult = ["TestKey1": "TestValue1", "TestKey2": "TestValue2"] let jsonData = try JSONSerialization.data(withJSONObject: expectedResult) let expectedResponse = HTTPURLResponse(url: url, mimeType: nil, expectedContentLength: .zero, textEncodingName: nil) - let expectedSerializationDuration: TimeInterval = 42 - let response = UrlDataResponse( + let response = URLDataResponse( request: expectedRequest, response: expectedResponse, - data: jsonData, - metrics: nil, - serializationDuration: expectedSerializationDuration + data: jsonData ) nextNodeMock.stubbedAsyncProccessResult = .success(()) @@ -225,13 +206,10 @@ final class ResponseDataParserNodeTests: XCTestCase { let expectedResult = [["TestKey1": "TestValue1"], ["TestKey2": "TestValue2"]] let jsonData = try JSONSerialization.data(withJSONObject: expectedResult) let expectedResponse = HTTPURLResponse(url: url, mimeType: nil, expectedContentLength: .zero, textEncodingName: nil) - let expectedSerializationDuration: TimeInterval = 42 - let response = UrlDataResponse( + let response = URLDataResponse( request: expectedRequest, response: expectedResponse, - data: jsonData, - metrics: nil, - serializationDuration: expectedSerializationDuration + data: jsonData ) nextNodeMock.stubbedAsyncProccessResult = .success(()) @@ -250,8 +228,6 @@ final class ResponseDataParserNodeTests: XCTestCase { XCTAssertEqual(parameter.request, expectedRequest) XCTAssertEqual(parameter.response, expectedResponse) XCTAssertEqual(parameter.data, jsonData) - XCTAssertEqual(parameter.metrics, nil) - XCTAssertEqual(parameter.serializationDuration, expectedSerializationDuration) XCTAssertEqual(inputJson, expectedResult) XCTAssertEqual(value, expectedResult) } diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseDataPreprocessorNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseDataPreprocessorNodeTests.swift index 2d5a955aa..5500f5e35 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseDataPreprocessorNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseDataPreprocessorNodeTests.swift @@ -15,7 +15,7 @@ final class ResponseDataPreprocessorNodeTests: XCTestCase { // MARK: - Dependencies - private var nextNodeMock: AsyncNodeMock! + private var nextNodeMock: AsyncNodeMock! private var logContextMock: LoggingContextMock! // MARK: - Sut @@ -46,12 +46,10 @@ final class ResponseDataPreprocessorNodeTests: XCTestCase { let url = URL(string: "www.test.com")! let request = URLRequest(url: url) let response = HTTPURLResponse(url: url, statusCode: 204, httpVersion: nil, headerFields: nil)! - let input = UrlDataResponse( + let input = URLDataResponse( request: request, response: response, - data: Data(), - metrics: nil, - serializationDuration: 0 + data: Data() ) // when @@ -72,12 +70,10 @@ final class ResponseDataPreprocessorNodeTests: XCTestCase { let url = URL(string: "www.test.com")! let request = URLRequest(url: url) let response = HTTPURLResponse(url: url, statusCode: 1, httpVersion: nil, headerFields: nil)! - let input = UrlDataResponse( + let input = URLDataResponse( request: request, response: response, - data: "null".data(using: .utf8)!, - metrics: nil, - serializationDuration: 0 + data: "null".data(using: .utf8)! ) // when @@ -99,12 +95,10 @@ final class ResponseDataPreprocessorNodeTests: XCTestCase { let request = URLRequest(url: url) let expectedResult = ["TestKey": "TestValue"] let response = HTTPURLResponse(url: url, statusCode: 1, httpVersion: nil, headerFields: nil)! - let expectedInput = UrlDataResponse( + let expectedInput = URLDataResponse( request: request, response: response, - data: "TestString".data(using: .utf8)!, - metrics: nil, - serializationDuration: 0 + data: "TestString".data(using: .utf8)! ) nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) @@ -128,12 +122,10 @@ final class ResponseDataPreprocessorNodeTests: XCTestCase { let url = URL(string: "www.test.com")! let request = URLRequest(url: url) let response = HTTPURLResponse(url: url, statusCode: 1, httpVersion: nil, headerFields: nil)! - let expectedInput = UrlDataResponse( + let expectedInput = URLDataResponse( request: request, response: response, - data: "TestString".data(using: .utf8)!, - metrics: nil, - serializationDuration: 0 + data: "TestString".data(using: .utf8)! ) nextNodeMock.stubbedAsyncProccessResult = .failure(MockError.thirdError) diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseHttpErrorProcessorNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseHttpErrorProcessorNodeTests.swift index 2f52bfb1b..2e8c13f2d 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseHttpErrorProcessorNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseHttpErrorProcessorNodeTests.swift @@ -15,7 +15,7 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { // MARK: - Dependencies - private var nextNodeMock: AsyncNodeMock! + private var nextNodeMock: AsyncNodeMock! private var logContextMock: LoggingContextMock! // MARK: - Sut @@ -44,12 +44,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { // given let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 400, httpVersion: nil, headerFields: nil)!, - data: Data(), - metrics: nil, - serializationDuration: 1 + data: Data() ) // when @@ -65,12 +63,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { // given let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 401, httpVersion: nil, headerFields: nil)!, - data: Data(), - metrics: nil, - serializationDuration: 1 + data: Data() ) // when @@ -86,12 +82,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { // given let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 403, httpVersion: nil, headerFields: nil)!, - data: Data(), - metrics: nil, - serializationDuration: 1 + data: Data() ) // when @@ -107,12 +101,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { // given let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 404, httpVersion: nil, headerFields: nil)!, - data: Data(), - metrics: nil, - serializationDuration: 1 + data: Data() ) // when @@ -128,12 +120,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { // given let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 500, httpVersion: nil, headerFields: nil)!, - data: Data(), - metrics: nil, - serializationDuration: 1 + data: Data() ) // when @@ -150,12 +140,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { let expectedData = "TestData".data(using: .utf8)! let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 400, httpVersion: nil, headerFields: nil)!, - data: expectedData, - metrics: nil, - serializationDuration: 1 + data: expectedData ) // when @@ -178,12 +166,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { let expectedData = "TestData".data(using: .utf8)! let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 401, httpVersion: nil, headerFields: nil)!, - data: expectedData, - metrics: nil, - serializationDuration: 1 + data: expectedData ) // when @@ -206,12 +192,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { let expectedData = "TestData".data(using: .utf8)! let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 403, httpVersion: nil, headerFields: nil)!, - data: expectedData, - metrics: nil, - serializationDuration: 1 + data: expectedData ) // when @@ -233,12 +217,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { // given let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 404, httpVersion: nil, headerFields: nil)!, - data: Data(), - metrics: nil, - serializationDuration: 1 + data: Data() ) // when @@ -261,12 +243,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { let expectedData = "TestData".data(using: .utf8)! let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 500, httpVersion: nil, headerFields: nil)!, - data: expectedData, - metrics: nil, - serializationDuration: 1 + data: expectedData ) // when @@ -291,12 +271,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { let url = URL(string: "www.test.com")! let expectedResponse = HTTPURLResponse(url: url, statusCode: 402, httpVersion: nil, headerFields: nil)! let expectedRequest = URLRequest(url: url) - let response = UrlDataResponse( + let response = URLDataResponse( request: expectedRequest, response: expectedResponse, - data: expectedData, - metrics: nil, - serializationDuration: 1 + data: expectedData ) nextNodeMock.stubbedAsyncProccessResult = .success(1) @@ -313,8 +291,6 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { XCTAssertEqual(input.response, expectedResponse) XCTAssertEqual(input.request, expectedRequest) XCTAssertEqual(input.data, expectedData) - XCTAssertNil(input.metrics) - XCTAssertEqual(input.serializationDuration, 1) } func testAsyncProcess_whenNextReturnsSuccess_thenSuccessReceived() async throws { @@ -322,12 +298,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { let expectedResult = 901 let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 402, httpVersion: nil, headerFields: nil)!, - data: Data(), - metrics: nil, - serializationDuration: 1 + data: Data() ) nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) @@ -347,12 +321,10 @@ final class ResponseHttpErrorProcessorNodeTests: XCTestCase { // given let url = URL(string: "www.test.com")! - let response = UrlDataResponse( + let response = URLDataResponse( request: URLRequest(url: url), response: HTTPURLResponse(url: url, statusCode: 402, httpVersion: nil, headerFields: nil)!, - data: Data(), - metrics: nil, - serializationDuration: 1 + data: Data() ) nextNodeMock.stubbedAsyncProccessResult = .failure(MockError.firstError) diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseProcessorNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseProcessorNodeTests.swift index a37937d15..ef93f4ac6 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseProcessorNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/ResponseProcessorNodeTests.swift @@ -15,7 +15,7 @@ final class ResponseProcessorNodeTests: XCTestCase { // MARK: - Dependencies - private var nextNodeMock: AsyncNodeMock! + private var nextNodeMock: AsyncNodeMock! private var logContextMock: LoggingContextMock! // MARK: - Sut @@ -145,8 +145,6 @@ final class ResponseProcessorNodeTests: XCTestCase { XCTAssertEqual(input.response, urlResponse) XCTAssertEqual(input.request, request) XCTAssertTrue(input.data.isEmpty) - XCTAssertNil(input.metrics) - XCTAssertEqual(input.serializationDuration, -1) } func testAsyncProcess_whenFailure_andNextReturnsSuccess_thenSuccessReceived() async throws { @@ -300,8 +298,6 @@ final class ResponseProcessorNodeTests: XCTestCase { XCTAssertEqual(input.response, urlResponse) XCTAssertEqual(input.request, request) XCTAssertEqual(input.data, expectedData) - XCTAssertNil(input.metrics) - XCTAssertEqual(input.serializationDuration, -1) } func testAsyncProcess_whenSuccess_andNextReturnsSuccess_thenSuccessReceived() async throws { diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlETagUrlCacheTriggerNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/URLNotModifiedTriggerNodeTests.swift similarity index 84% rename from NodeKit/NodeKitTests/UnitTests/Nodes/UrlETagUrlCacheTriggerNodeTests.swift rename to NodeKit/NodeKitTests/UnitTests/Nodes/URLNotModifiedTriggerNodeTests.swift index f2fd00529..782d1cd45 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlETagUrlCacheTriggerNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/URLNotModifiedTriggerNodeTests.swift @@ -1,5 +1,5 @@ // -// UrlETagUrlCacheTriggerNodeTests.swift +// URLNotModifiedTriggerNodeTests.swift // CoreNetKitUnitTests // // Created by Александр Кравченков on 05/03/2019. @@ -12,17 +12,17 @@ import Foundation import XCTest -final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { +final class URLNotModifiedTriggerNodeTests: XCTestCase { // MARK: - Dependencies - private var transportNodeMock: AsyncNodeMock! - private var cacheSaverMock: AsyncNodeMock! + private var transportNodeMock: AsyncNodeMock! + private var cacheSaverMock: AsyncNodeMock! private var logContextMock: LoggingContextMock! // MARK: - Sut - private var sut: UrlNotModifiedTriggerNode! + private var sut: URLNotModifiedTriggerNode! // MARK: - Lifecycle @@ -31,7 +31,7 @@ final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { transportNodeMock = AsyncNodeMock() cacheSaverMock = AsyncNodeMock() logContextMock = LoggingContextMock() - sut = UrlNotModifiedTriggerNode(next: transportNodeMock, cacheReader: cacheSaverMock) + sut = URLNotModifiedTriggerNode(next: transportNodeMock, cacheReader: cacheSaverMock) } override func tearDown() { @@ -48,7 +48,7 @@ final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { // given let url = URL(string: "http://UrlETagUrlCacheTriggerNode.test/testNextCalledIfDataIsNotNotModified")! - let response = Utils.getMockUrlDataResponse(url: url) + let response = Utils.getMockURLDataResponse(url: url) let expectedNextResult = ["Test": "Value"] transportNodeMock.stubbedAsyncProccessResult = .success(expectedNextResult) @@ -71,7 +71,7 @@ final class UrlETagUrlCacheTriggerNodeTests: XCTestCase { // given let url = URL(string: "http://UrlETagUrlCacheTriggerNode.test/testNextCAlledIfDataIsNotNotModified")! - let response = Utils.getMockUrlDataResponse(url: url, statusCode: 304) + let response = Utils.getMockURLDataResponse(url: url, statusCode: 304) let expectedCacheResult = ["Test": "Value"] cacheSaverMock.stubbedAsyncProccessResult = .success(expectedCacheResult) diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/URLQueryInjectorNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/URLQueryInjectorNodeTests.swift index 6e2bd015a..96feba839 100644 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/URLQueryInjectorNodeTests.swift +++ b/NodeKit/NodeKitTests/UnitTests/Nodes/URLQueryInjectorNodeTests.swift @@ -8,7 +8,7 @@ final class URLQueryInjectorNodeTests: XCTestCase { // MARK: - Nested - typealias Model = RoutableRequestModel + typealias Model = RoutableRequestModel // MARK: - Dependencies @@ -31,12 +31,12 @@ final class URLQueryInjectorNodeTests: XCTestCase { // MARK: - Tests - func testAsyncProcess_withEmptyQuery_thenStartUrlReceived() async throws { + func testAsyncProcess_withEmptyQuery_thenStartURLReceived() async throws { // given - let startUrl = URL(string: "http://host.dom/path")! + let startURL = URL(string: "http://host.dom/path")! - let request = Model(metadata: [:], raw: Json(), route: startUrl) + let request = Model(metadata: [:], raw: Json(), route: startURL) let sut = URLQueryInjectorNode(next: nextNodeMock, config: .init(query: [:])) @@ -51,10 +51,10 @@ final class URLQueryInjectorNodeTests: XCTestCase { let url = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameters?.data.route.url)() XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(url, startUrl) + XCTAssertEqual(url, startURL) } - func testAsyncProcess_withSimpleQeury_thenCurrectUrlReceived() async throws { + func testAsyncProcess_withSimpleQeury_thenCurrectURLReceived() async throws { // given let request = Model(metadata: [:], raw: Json(), route: URL(string: "http://host.dom/path")!) @@ -71,7 +71,7 @@ final class URLQueryInjectorNodeTests: XCTestCase { let input = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameters?.data) let url = try input.route.url() - let requestRouteUrl = try request.route.url() + let requestRouteURL = try request.route.url() let normalizedRes = url.query!.split(separator: "&").sorted() let normalizedExp = "age=23&name=bob".split(separator: "&").sorted() @@ -79,10 +79,10 @@ final class URLQueryInjectorNodeTests: XCTestCase { XCTAssertEqual(normalizedRes, normalizedExp) XCTAssertEqual(url.absoluteString.replacingOccurrences(of: url.query!, with: ""), "http://host.dom/path?") XCTAssertEqual(request.metadata, input.metadata) - XCTAssertNotEqual(requestRouteUrl, url) + XCTAssertNotEqual(requestRouteURL, url) } - func testAsyncProcess_withArrayQeury_thenCorrectUrlReceived() async throws { + func testAsyncProcess_withArrayQeury_thenCorrectURLReceived() async throws { // given let request = Model(metadata: [:], raw: Json(), route: URL(string: "http://host.dom/path")!) @@ -104,7 +104,7 @@ final class URLQueryInjectorNodeTests: XCTestCase { XCTAssertEqual(normalizedRes, normalizedExp) } - func testAsyncProcess_withDictionaryQeury_thenCorrectUrlReceived() async throws { + func testAsyncProcess_withDictionaryQeury_thenCorrectURLReceived() async throws { // given let request = Model(metadata: [:], raw: Json(), route: URL(string: "http://host.dom/path")!) @@ -126,7 +126,7 @@ final class URLQueryInjectorNodeTests: XCTestCase { XCTAssertEqual(normalizedRes, normalizedExp) } - func testAsyncProcess_withArrayAndDictionaryQuery_thenCorrectUrlReceived() async throws { + func testAsyncProcess_withArrayAndDictionaryQuery_thenCorrectURLReceived() async throws { // given let request = Model(metadata: [:], raw: Json(), route: URL(string: "http://host.dom/path")!) @@ -148,7 +148,7 @@ final class URLQueryInjectorNodeTests: XCTestCase { XCTAssertEqual(normalizedRes, normalizedExp) } - func testAsyncProcess_with2DArray_thenCorrectUrlReceived() async throws { + func testAsyncProcess_with2DArray_thenCorrectURLReceived() async throws { // given let request = Model(metadata: [:], raw: Json(), route: URL(string: "http://host.dom/path")!) diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlCacheWriterNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/UrlCacheWriterNodeTests.swift deleted file mode 100644 index c6ce5d115..000000000 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlCacheWriterNodeTests.swift +++ /dev/null @@ -1,76 +0,0 @@ -// -// UrlCacheWriterNodeTests.swift -// NodeKitTests -// -// Created by Andrei Frolov on 08.04.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit -@testable import NodeKitMock - -import XCTest - -final class UrlCacheWriterNodeTest: XCTestCase { - - // MARK: - Dependencies - - private var logContextMock: LoggingContextMock! - - // MARK: - Sut - - private var sut: UrlCacheWriterNode! - - // MARK: - Lifecycle - - override func setUp() { - super.setUp() - logContextMock = LoggingContextMock() - sut = UrlCacheWriterNode() - } - - override func tearDown() { - super.tearDown() - logContextMock = nil - sut = nil - URLCache.shared.removeAllCachedResponses() - } - - // MARK: - Tests - - func testAsyncProcess_thenCacheWriteSuccess() async throws { - // given - - let url = URL(string: "http://example.test")! - let request = URLRequest(url: url) - let responseKey = "name" - let responseValue = "test" - let response = [responseKey: responseValue] - let responseData = try! JSONSerialization.data( - withJSONObject: response, - options: .sortedKeys - ) - let urlResponse = HTTPURLResponse(url: url, statusCode: 200, httpVersion: "1.1", headerFields: nil)! - let urlDataResponse = UrlDataResponse( - request: request, - response: urlResponse, - data: responseData, - metrics: nil, - serializationDuration: 1 - ) - let input = UrlProcessedResponse(dataResponse: urlDataResponse, json: [responseKey: responseValue]) - - // when - - let result = await sut.process(input, logContext: logContextMock) - - // then - - let cachedResponse = try XCTUnwrap(URLCache.shared.cachedResponse(for: request)) - - XCTAssertEqual(cachedResponse.data, responseData) - XCTAssertEqual(cachedResponse.response, urlResponse) - XCTAssertEqual(cachedResponse.storagePolicy, .allowed) - XCTAssertNotNil(result.value) - } -} diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlETagReaderNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/UrlETagReaderNodeTests.swift deleted file mode 100644 index ae272f71f..000000000 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlETagReaderNodeTests.swift +++ /dev/null @@ -1,155 +0,0 @@ -// -// UrlETagReaderNodeTests.swift -// CoreNetKitUnitTests -// -// Created by Александр Кравченков on 05/03/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -@testable import NodeKit -@testable import NodeKitMock - -import Foundation -import XCTest - -final class UrlETagReaderNodeTests: XCTestCase { - - // MARK: - Dependencies - - private var nextNodeMock: AsyncNodeMock! - private var logContextMock: LoggingContextMock! - - // MARK: - Sut - - private var sut: UrlETagReaderNode! - - // MARK: - Lifecycle - - override func setUp() { - super.setUp() - nextNodeMock = AsyncNodeMock() - logContextMock = LoggingContextMock() - } - - override func tearDown() { - super.tearDown() - nextNodeMock = nil - logContextMock = nil - sut = nil - } - - // MARK: - Tests - - func testAsyncProcess_whenSuccess() async throws { - - // given - - buildSut() - - let tag = "\(NSObject().hash)" - let url = URL(string: "http://UrlETagReaderNodeTests/testReadSuccess")! - let params = TransportUrlParameters(method: .get, url: url) - let request = TransportUrlRequest(with:params , raw: Data()) - - nextNodeMock.stubbedAsyncProccessResult = .success(Json()) - - var expectedHeader = request.headers - expectedHeader[ETagConstants.eTagRequestHeaderKey] = tag - - defer { - UserDefaults.etagStorage?.removeObject(forKey: url.absoluteString) - } - - // when - - UserDefaults.etagStorage?.set(tag, forKey: url.absoluteString) - - _ = await sut.process(request, logContext: logContextMock) - - // then - - let nextNodeParameter = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameters?.data) - - XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nextNodeParameter.method, request.method) - XCTAssertEqual(nextNodeParameter.url, request.url) - XCTAssertEqual(nextNodeParameter.raw, request.raw) - XCTAssertEqual(nextNodeParameter.headers, expectedHeader) - } - - func testAsyncProcess_whenTagNotExist() async throws { - // given - - buildSut() - - let url = URL(string: "http://UrlETagReaderNodeTests/testNotReadIfTagNotExist")! - let params = TransportUrlParameters(method: .get, url: url) - let request = TransportUrlRequest(with:params , raw: Data()) - - nextNodeMock.stubbedAsyncProccessResult = .success(Json()) - - // when - - _ = await sut.process(request, logContext: logContextMock) - - // then - - let nextProcessInvokedParameter = try XCTUnwrap( - nextNodeMock.invokedAsyncProcessParameters?.data - ) - - XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(request.headers, nextProcessInvokedParameter.headers) - XCTAssertEqual(request.url, nextProcessInvokedParameter.url) - XCTAssertEqual(request.method, nextProcessInvokedParameter.method) - XCTAssertEqual(request.raw, nextProcessInvokedParameter.raw) - } - - func testAsyncProcess_whithCustomTag() async throws { - // given - - let key = "My-Custom-ETag-Key" - let tag = "\(NSObject().hash)" - - buildSut(with: key) - - let url = URL(string: "http://UrlETagReaderNodeTests/testReadSuccessWithCustomKey")! - let params = TransportUrlParameters(method: .get, url: url) - let request = TransportUrlRequest(with:params , raw: Data()) - - nextNodeMock.stubbedAsyncProccessResult = .success(Json()) - - var expectedHeader = request.headers - expectedHeader[key] = tag - - defer { - UserDefaults.etagStorage?.removeObject(forKey: url.absoluteString) - } - - // when - - UserDefaults.etagStorage?.set(tag, forKey: url.absoluteString) - - _ = await sut.process(request, logContext: logContextMock) - - // then - - let nextNodeParameter = try XCTUnwrap( - nextNodeMock.invokedAsyncProcessParameters?.data - ) - - XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(nextNodeParameter.method, request.method) - XCTAssertEqual(nextNodeParameter.url, request.url) - XCTAssertEqual(nextNodeParameter.raw, request.raw) - XCTAssertEqual(nextNodeParameter.headers, expectedHeader) - } - - private func buildSut(with tag: String? = nil) { - guard let tag = tag else { - sut = UrlETagReaderNode(next: nextNodeMock) - return - } - sut = UrlETagReaderNode(next: nextNodeMock, etagHeaderKey: tag) - } -} diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlETagSaverNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/UrlETagSaverNodeTests.swift deleted file mode 100644 index 1984f0b3c..000000000 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlETagSaverNodeTests.swift +++ /dev/null @@ -1,125 +0,0 @@ -// -// UrlETagSaverNodeTests.swift -// CoreNetKitUnitTests -// -// Created by Александр Кравченков on 05/03/2019. -// Copyright © 2019 Кравченков Александр. All rights reserved. -// - -@testable import NodeKit -@testable import NodeKitMock - -import Foundation -import XCTest - -final class UrlETagSaverNodeTests: XCTestCase { - - // MARK: - Tests - - func testAsyncProcess_whenHasTag_thenNodeSaveTag() async throws { - // given - - let sut = UrlETagSaverNode(next: nil) - let url = URL(string: "http://urletagsaver.tests/testNodeSaveTag")! - let tag = "\(NSObject().hash)" - let data = Utils.getMockUrlProcessedResponse(url: url, headers: [ETagConstants.eTagResponseHeaderKey: tag]) - - defer { - UserDefaults.etagStorage?.removeObject(forKey: url.absoluteString) - } - - // when - - let result = await sut.process(data, logContext: LoggingContextMock()) - let readedTag = UserDefaults.etagStorage?.string(forKey: url.absoluteString) - - // then - - let unwrappedTag = try XCTUnwrap(readedTag) - - XCTAssertNotNil(result.value) - XCTAssertEqual(unwrappedTag, tag) - } - - func testAsyncProcess_withoutTag_thenNodeNotSaveTag() async { - // given - - let sut = UrlETagSaverNode(next: nil) - let url = URL(string: "http://urletagsaver.tests/testNodeNotSaveTag")! - let data = Utils.getMockUrlProcessedResponse(url: url) - - defer { - UserDefaults.etagStorage?.removeObject(forKey: url.absoluteString) - } - - // when - - let result = await sut.process(data, logContext: LoggingContextMock()) - let readedTag = UserDefaults.etagStorage?.string(forKey: url.absoluteString) - - // then - - XCTAssertNotNil(result.value) - XCTAssertNil(readedTag) - } - - func testAsyncProcess_withCustomKey_thenTagSaved() async throws { - // given - - let url = URL(string: "http://urletagsaver.tests/testSaveWorkForCustomKey")! - let tag = "\(NSObject().hash)" - let tagKey = "My-Custom-ETag-Key" - let sut = UrlETagSaverNode(next: nil, eTagHeaderKey: tagKey) - let data = Utils.getMockUrlProcessedResponse(url: url, headers: [tagKey: tag]) - - defer { - UserDefaults.etagStorage?.removeObject(forKey: url.absoluteString) - } - - // when - - let result = await sut.process(data, logContext: LoggingContextMock()) - let readedTag = UserDefaults.etagStorage?.string(forKey: url.absoluteString) - - // then - - let unwrappedTag = try XCTUnwrap(readedTag) - - XCTAssertNotNil(result.value) - XCTAssertEqual(unwrappedTag, tag) - } - - /// Проверяет что при сохранении данных от двух одинаковых запросов с разным порядком ключей - /// Будет создана только одна запись - func testAsyncProcess_whenSaveDataForTwoSameRequestsWithDifferentOrderOfKeys_thenOnlyOneSaved() async throws { - // given - - let url1 = URL(string: "http://urletagsaver.tests/test?q1=1&q2=2")! - let url2 = URL(string: "http://urletagsaver.tests/test?q2=2&q1=1")! - let tag = "\(NSObject().hash)" - let headers = [ETagConstants.eTagResponseHeaderKey: tag] - let sut = UrlETagSaverNode(next: nil) - let data1 = Utils.getMockUrlProcessedResponse(url: url1, headers: headers) - let data2 = Utils.getMockUrlProcessedResponse(url: url2, headers: headers) - - defer { - UserDefaults.etagStorage?.removeObject(forKey: url1.absoluteString) - UserDefaults.etagStorage?.removeObject(forKey: url2.absoluteString) - } - - // when - - _ = await sut.process(data1, logContext: LoggingContextMock()) - _ = await sut.process(data2, logContext: LoggingContextMock()) - - let firstTag = UserDefaults.etagStorage?.string(forKey: url1.absoluteString) - let secondTag = UserDefaults.etagStorage?.string(forKey: url2.absoluteString) - let savedTag = UserDefaults.etagStorage?.string(forKey: url1.withOrderedQuery()!) - - // then - - XCTAssertEqual(savedTag, tag) - XCTAssertNil(firstTag) - XCTAssertNil(secondTag) - } -} diff --git a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlRequestTrasformatorNodeTests.swift b/NodeKit/NodeKitTests/UnitTests/Nodes/UrlRequestTrasformatorNodeTests.swift deleted file mode 100644 index 2dd05613d..000000000 --- a/NodeKit/NodeKitTests/UnitTests/Nodes/UrlRequestTrasformatorNodeTests.swift +++ /dev/null @@ -1,222 +0,0 @@ -// -// UrlRequestTrasformatorNodeTests.swift -// NodeKitTests -// -// Created by Andrei Frolov on 08.04.24. -// Copyright © 2024 Surf. All rights reserved. -// - -@testable import NodeKit -@testable import NodeKitMock - -import XCTest - -final class UrlRequestTrasformatorNodeTests: XCTestCase { - - // MARK: - Dependencies - - private var nextNodeMock: AsyncNodeMock! - private var logContextMock: LoggingContextMock! - private var stubbedMethod: NodeKit.Method! - private var urlRuteProviderMock: UrlRouteProviderMock! - - // MARK: - Sut - - private var sut: UrlRequestTrasformatorNode! - - // MARK: - Lifecycle - - override func setUp() { - super.setUp() - nextNodeMock = AsyncNodeMock() - logContextMock = LoggingContextMock() - stubbedMethod = .trace - urlRuteProviderMock = UrlRouteProviderMock() - sut = UrlRequestTrasformatorNode(next: nextNodeMock, method: stubbedMethod) - } - - override func tearDown() { - super.tearDown() - nextNodeMock = nil - logContextMock = nil - stubbedMethod = nil - urlRuteProviderMock = nil - sut = nil - } - - // MARK: - Tests - - func testAsyncProcess_whenURLReturnsError_thenNextDidNotCalled() async { - // given - - let model = EncodableRequestModel( - metadata: [:], - raw: [:], - route: urlRuteProviderMock - ) - - urlRuteProviderMock.stubbedUrlResult = .failure(MockError.firstError) - - // when - - _ = await sut.process(model, logContext: logContextMock) - - // then - - XCTAssertFalse(nextNodeMock.invokedAsyncProcess) - } - - func testAsyncProcess_whenURLReturnsError_thenErrorReceived() async throws { - // given - - let model = EncodableRequestModel( - metadata: [:], - raw: [:], - route: urlRuteProviderMock - ) - - urlRuteProviderMock.stubbedUrlResult = .failure(MockError.firstError) - - // when - - let result = await sut.process(model, logContext: logContextMock) - - // then - - let error = try XCTUnwrap(result.error as? MockError) - - XCTAssertEqual(error, .firstError) - } - - func testAsyncProcess_withCorrectUrl_thenNextCalled() async throws { - // given - - let expectedUrl = URL(string: "www.test.com")! - let expectedMetadata = ["TestMetadataKey": "TestMetadataValue"] - let expectedRaw = ["TestJsonKey": "TestJsonValue"] - let model = EncodableRequestModel( - metadata: expectedMetadata, - raw: expectedRaw, - route: urlRuteProviderMock, - encoding: .urlQuery - ) - - urlRuteProviderMock.stubbedUrlResult = .success(expectedUrl) - nextNodeMock.stubbedAsyncProccessResult = .success(1) - - // when - - _ = await sut.process(model, logContext: logContextMock) - - // then - - let input = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameters?.data) - let raw = try XCTUnwrap(input.raw as? [String: String]) - - XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(raw, expectedRaw) - XCTAssertEqual(input.encoding, .urlQuery) - XCTAssertEqual(input.urlParameters.method, stubbedMethod) - XCTAssertEqual(input.urlParameters.headers, expectedMetadata) - XCTAssertEqual(input.urlParameters.url, expectedUrl) - } - - func testAsyncProcess_withEncoding_thenEncodingPassed() async throws { - // given - - let model = EncodableRequestModel( - metadata: [:], - raw: [:], - route: urlRuteProviderMock, - encoding: .json - ) - - urlRuteProviderMock.stubbedUrlResult = .success(URL(string: "www.test.com")!) - nextNodeMock.stubbedAsyncProccessResult = .success(1) - - // when - - _ = await sut.process(model, logContext: logContextMock) - - // then - - let input = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameters?.data) - - XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertEqual(input.encoding, .json) - } - - func testAsyncProcess_withoutEncoding_thenEncodingIsNil() async throws { - // given - - let model = EncodableRequestModel( - metadata: [:], - raw: [:], - route: urlRuteProviderMock, - encoding: nil - ) - - urlRuteProviderMock.stubbedUrlResult = .success(URL(string: "www.test.com")!) - nextNodeMock.stubbedAsyncProccessResult = .success(1) - - // when - - _ = await sut.process(model, logContext: logContextMock) - - // then - - let input = try XCTUnwrap(nextNodeMock.invokedAsyncProcessParameters?.data) - - XCTAssertEqual(nextNodeMock.invokedAsyncProcessCount, 1) - XCTAssertNil(input.encoding) - } - - func testAsyncProcess_whenNextNodeReturnsSuccess_thenSuccessReceived() async throws { - // given - - let expectedResult = 0079 - let model = EncodableRequestModel( - metadata: [:], - raw: [:], - route: urlRuteProviderMock, - encoding: nil - ) - - urlRuteProviderMock.stubbedUrlResult = .success(URL(string: "www.test.com")!) - nextNodeMock.stubbedAsyncProccessResult = .success(expectedResult) - - // when - - let result = await sut.process(model, logContext: logContextMock) - - // then - - let value = try XCTUnwrap(result.value) - - XCTAssertEqual(value, expectedResult) - } - - func testAsyncProcess_whenNextNodeReturnsFailure_thenFailureReceived() async throws { - // given - - let model = EncodableRequestModel( - metadata: [:], - raw: [:], - route: urlRuteProviderMock, - encoding: nil - ) - - urlRuteProviderMock.stubbedUrlResult = .success(URL(string: "www.test.com")!) - nextNodeMock.stubbedAsyncProccessResult = .failure(MockError.secondError) - - // when - - let result = await sut.process(model, logContext: logContextMock) - - // then - - let error = try XCTUnwrap(result.error as? MockError) - - XCTAssertEqual(error, .secondError) - } -}