Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
disabled_rules:
- line_length
- blanket_disable_command
- discouraged_optional_collection
- file_name

excluded:
- Pods
- vendor
- .build

opt_in_rules:
- array_init
- attributes
- closure_body_length
- closure_end_indentation
- closure_spacing
- collection_alignment
- conditional_returns_on_newline
- contains_over_filter_count
- contains_over_filter_is_empty
- contains_over_first_not_nil
- contains_over_range_nil_comparison
- convenience_type
- discouraged_object_literal
- discouraged_optional_boolean
- empty_collection_literal
- empty_count
- empty_string
- empty_xctest_method
- enum_case_associated_values_count
- explicit_init
- fallthrough
- fatal_error_message
- file_name_no_space
- first_where
- flatmap_over_map_reduce
- force_unwrapping
- function_default_parameter_at_end
- identical_operands
- implicit_return
- implicitly_unwrapped_optional
- joined_default_parameter
- last_where
- legacy_multiple
- legacy_random
- let_var_whitespace
- literal_expression_end_indentation
- lower_acl_than_parent
- modifier_order
- multiline_arguments
- multiline_function_chains
- multiline_literal_brackets
- multiline_parameters
- multiline_parameters_brackets
- nimble_operator
- no_extension_access_modifier
- number_separator
- object_literal
- operator_usage_whitespace
- optional_enum_case_matching
- overridden_super_call
- override_in_extension
- pattern_matching_keywords
- prefer_self_type_over_type_of_self
- private_action
- private_outlet
- prohibited_super_call
- reduce_into
- redundant_nil_coalescing
- required_enum_case
- single_test_class
- sorted_first_last
- sorted_imports
- static_operator
- strict_fileprivate
- switch_case_on_newline
- toggle_bool
- trailing_closure
- unneeded_parentheses_in_closure_argument
- untyped_error_in_catch
- vertical_parameter_alignment_on_call
- vertical_whitespace_closing_braces
- yoda_condition

analyzer_rules:
- unused_declaration
- unused_import

identifier_name:
excluded:
- id
- x
- y
- z

cyclomatic_complexity:
warning: 10

type_name:
max_length: 50

force_cast: warning

force_try: warning

function_parameter_count: 5

large_tuple:
warning: 3
error: 4
184 changes: 184 additions & 0 deletions Tests/GraphQLAPIKitTests/GraphQLAPIAdapterErrorTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import XCTest
import Apollo
@testable import GraphQLAPIKit

final class GraphQLAPIAdapterErrorTests: XCTestCase {
func testGraphQLAPIAdapterErrorPassthrough() {
// Given
let originalError = GraphQLAPIAdapterError.cancelled

// When
let error = GraphQLAPIAdapterError(error: originalError)

// Then
if case .cancelled = error {
// Success
} else {
XCTFail("Expected .cancelled error")
}
}

func testApolloErrorConversion() {
// Given
let graphQLErrors = [
Apollo.GraphQLError(["message": "Field error", "extensions": ["code": "FIELD_ERROR"]])
]
let apolloError = ApolloError(errors: graphQLErrors)

// When
let error = GraphQLAPIAdapterError(error: apolloError)

// Then
if case let .graphQl(errors) = error {
XCTAssertEqual(errors.count, 1)
XCTAssertEqual(errors.first?.message, "Field error")
XCTAssertEqual(errors.first?.code, "FIELD_ERROR")
XCTAssertEqual(error.errorDescription, "Field error")
} else {
XCTFail("Expected .graphQl error")
}
}

func testURLSessionClientNetworkErrorWithResponse() {
// Given
let underlyingError = NSError(
domain: "TestDomain",
code: 500,
userInfo: [NSLocalizedDescriptionKey: "Server error"]
)
let response = HTTPURLResponse(
url: URL(string: "https://example.com")!,
statusCode: 500,
httpVersion: nil,
headerFields: nil
)!
let urlSessionError = URLSessionClient.URLSessionClientError.networkError(
data: Data(),
response: response,
underlying: underlyingError
)

// When
let error = GraphQLAPIAdapterError(error: urlSessionError)

// Then
if case let .network(code, error) = error {
XCTAssertEqual(code, 500)
XCTAssertEqual(error.localizedDescription, "Server error")
} else {
XCTFail("Expected .network error")
}
}

func testURLSessionClientNetworkErrorWithoutResponse() {
// Given
let underlyingError = NSError(
domain: NSURLErrorDomain,
code: NSURLErrorNotConnectedToInternet,
userInfo: [NSLocalizedDescriptionKey: "No internet connection"]
)
let urlSessionError = URLSessionClient.URLSessionClientError.networkError(
data: Data(),
response: nil,
underlying: underlyingError
)

// When
let error = GraphQLAPIAdapterError(error: urlSessionError)

// Then
if case let .connection(error) = error {
XCTAssertEqual(error.localizedDescription, "No internet connection")
} else {
XCTFail("Expected .connection error")
}
}

func testUnhandledError() {
// Given
let unknownError = NSError(
domain: "UnknownDomain",
code: 999,
userInfo: [NSLocalizedDescriptionKey: "Unknown error"]
)

// When
let error = GraphQLAPIAdapterError(error: unknownError)

// Then
if case let .unhandled(error) = error {
XCTAssertEqual(error.localizedDescription, "Unknown error")
} else {
XCTFail("Expected .unhandled error")
}
}

func testCancelledErrorDescription() {
// Given
let error = GraphQLAPIAdapterError.cancelled

// Then
XCTAssertNil(error.errorDescription)
}

func testNetworkErrorDescription() {
// Given
let underlyingError = NSError(
domain: "TestDomain",
code: 404,
userInfo: [NSLocalizedDescriptionKey: "Not found"]
)
let error = GraphQLAPIAdapterError.network(code: 404, error: underlyingError)

// Then
XCTAssertEqual(error.errorDescription, "Not found")
}

func testConnectionErrorDescription() {
// Given
let underlyingError = NSError(
domain: NSURLErrorDomain,
code: NSURLErrorNotConnectedToInternet,
userInfo: [NSLocalizedDescriptionKey: "No internet"]
)
let error = GraphQLAPIAdapterError.connection(underlyingError)

// Then
XCTAssertEqual(error.errorDescription, "No internet")
}

func testUnhandledErrorDescription() {
// Given
let underlyingError = NSError(
domain: "TestDomain",
code: 123,
userInfo: [NSLocalizedDescriptionKey: "Test error"]
)
let error = GraphQLAPIAdapterError.unhandled(underlyingError)

// Then
XCTAssertEqual(error.errorDescription, "Test error")
}

func testGraphQLErrorDescription() {
// Given
let graphQLErrors = [
Apollo.GraphQLError(["message": "First error"]),
Apollo.GraphQLError(["message": "Second error"])
]
let apolloError = ApolloError(errors: graphQLErrors)
let error = GraphQLAPIAdapterError(error: apolloError)

// Then
// Should return the first error's message
XCTAssertEqual(error.errorDescription, "First error")
}

func testGraphQLErrorDescriptionWithEmptyArray() {
// Given
let error = GraphQLAPIAdapterError.graphQl([])

// Then
XCTAssertNil(error.errorDescription)
}
}
41 changes: 41 additions & 0 deletions Tests/GraphQLAPIKitTests/GraphQLAPIAdapterTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Apollo
import ApolloAPI
import XCTest
@testable import GraphQLAPIKit

final class GraphQLAPIAdapterTests: XCTestCase {
let testURL = URL(string: "https://api.example.com/graphql")!

// MARK: - Initialization Tests

func testAdapterInitializationWithMinimalParameters() {
let adapter = GraphQLAPIAdapter(url: testURL)
XCTAssertNotNil(adapter)
}

func testAdapterInitializationWithCustomHeaders() {
let headers = [
"Authorization": "Bearer token123",
"Content-Type": "application/json",
"X-API-Key": "secret"
]
let adapter = GraphQLAPIAdapter(
url: testURL,
defaultHeaders: headers
)
XCTAssertNotNil(adapter)
}

func testAdapterInitializationWithCustomURLSessionConfiguration() {
let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = 30
config.timeoutIntervalForResource = 60

let adapter = GraphQLAPIAdapter(
url: testURL,
urlSessionConfiguration: config
)
XCTAssertNotNil(adapter)
}

}
Loading