Skip to content

Commit

Permalink
[closes #10] Add ClientTests
Browse files Browse the repository at this point in the history
  • Loading branch information
ericklborges committed Feb 14, 2021
1 parent d12789e commit 15b7628
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 3 deletions.
1 change: 1 addition & 0 deletions Client/.swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ opt_in_rules:

excluded:
- Pods
- ClientTests
- Interface
- InterfaceTests
- The-Norris
Expand Down
15 changes: 15 additions & 0 deletions Client/Base/ClientError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,18 @@ public enum ClientErrorReason {
}
}
}

extension ClientErrorReason: Equatable {
public static func == (lhs: ClientErrorReason, rhs: ClientErrorReason) -> Bool {
switch (lhs, rhs) {
case (.api, .api):
return true
case (.invalidData, .invalidData):
return true
case (.decoding, .decoding):
return true
default:
return false
}
}
}
2 changes: 0 additions & 2 deletions Client/Logger/ClientLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ private extension RequestLogger {
printTagged("Headers: [")
headers.forEach { printTagged("\t\($0): \($1)") }
printTagged("]")

}

// MARK: - Response
Expand All @@ -110,6 +109,5 @@ private extension RequestLogger {
printTagged("Headers: [")
headers.forEach { printTagged("\t\($0): \($1)") }
printTagged("]")

}
}
9 changes: 8 additions & 1 deletion Client/ProjectClient/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
final class Client {

private let session: URLSession
private var logger = RequestLogger(level: .debug)
var logger = RequestLogger(level: .debug)

public init(session: URLSession = .shared) {
self.session = session
Expand Down Expand Up @@ -43,6 +43,13 @@ extension Client: ClientProtocol {

let statusCode = httpResponse.statusCode

if let error = error {
let clientError = ClientError(reason: .api(error.localizedDescription), statusCode: statusCode)
self.logger.log(error: clientError, request: request)
completion(.failure(clientError))
return
}

guard let data = data else {
let clientError = ClientError(reason: .invalidData, statusCode: statusCode)
self.logger.log(error: clientError, request: request)
Expand Down
144 changes: 144 additions & 0 deletions ClientTests/ProjectClient/ClientSpec.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
//
// ClientSpec.swift
// ClientTests
//
// Created by erick.lozano.borges on 14/02/21.
//

import Quick
import Nimble

@testable import Client

private struct Object: Decodable {
var boolean: Bool
}

class ClientSpec: QuickSpec {
override func spec() {

describe("Client") {

var sut: Client!
var sessionMock: URLSessionMock!

context("when initializex") {
beforeEach {
sessionMock = URLSessionMock()
sut = Client(session: sessionMock)
sut.logger = RequestLogger(level: .none)
}

context("and parameters are passed") {

context("using get method") {
beforeEach {
sut.request(url: .stub(), method: .get, headers: [:], parameters: ["key": "value"]) { (result: Result<String, ClientError>) in }
}

it("shold not have httpBody") {
expect(sessionMock.passedRequest?.httpBody).to(beNil())
}
}

context("using a method different from get") {
beforeEach {
sut.request(url: .stub(), method: .post, headers: [:], parameters: ["key": "value"]) { (result: Result<String, ClientError>) in }
}

it("shold have a httpBody") {
expect(sessionMock.passedRequest?.httpBody).toNot(beNil())
}
}
}

context("and a request is successful") {
beforeEach {
sessionMock.data = "{ \"boolean\": true}".data(using: .utf8)
}

it("should parsed the Object correctly") {
sut.request(url: .stub(), method: .get) { (result: Result<Object, ClientError>) in
switch result {
case let .success(object):
expect(object.boolean) == true
case .failure:
fail("The request did fail because the Object couldn't be parsed")
}
}
}
}

context("and the request fails with unknown error") {
beforeEach {
sessionMock.response = nil
}

it("should return a decoding error") {
sut.request(url: .stub(), method: .get) { (result: Result<Object, ClientError>) in
switch result {
case .success:
fail("The request should not be successfull")
case let .failure(error):
expect(error.reason) == .api(error.localizedDescription)
expect(error.statusCode) == 666
}
}
}
}

context("and the request returns an error") {
beforeEach {
sessionMock.error = NSError(domain: "ClientTests", code: 404, userInfo: [:])
}

it("should return an api error") {
sut.request(url: .stub(), method: .get) { (result: Result<Object, ClientError>) in
switch result {
case .success:
fail("The request should not be successfull")
case let .failure(error):
expect(error.reason) == .api(error.localizedDescription)
}
}
}
}

context("and the request returns an invalid data") {
beforeEach {
sessionMock.data = nil
}

it("should return an api error") {
sut.request(url: .stub(), method: .get) { (result: Result<Object, ClientError>) in
switch result {
case .success:
fail("The request should not be successfull")
case let .failure(error):
expect(error.reason) == .invalidData
}
}
}
}

context("and a request fails to decode object") {
beforeEach {
sessionMock.data = "{ \"boolean\": 100}".data(using: .utf8)
}

it("should return a decoding error") {
sut.request(url: .stub(), method: .get) { (result: Result<Object, ClientError>) in
switch result {
case .success:
fail("The request should not be successfull")
case let .failure(error):
expect(error.reason) == .decoding(error)
}
}
}
}

}
}
}
}
4 changes: 4 additions & 0 deletions The-Norris.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
371E422125D9947F00C3D8BF /* URLSessionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371E422025D9947F00C3D8BF /* URLSessionMock.swift */; };
371E422925D9964D00C3D8BF /* URL+Stub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371E422825D9964D00C3D8BF /* URL+Stub.swift */; };
371E423525D9966100C3D8BF /* HTTPURLResponse+Stub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371E423425D9966100C3D8BF /* HTTPURLResponse+Stub.swift */; };
371E423D25D9975400C3D8BF /* ClientSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371E423C25D9975400C3D8BF /* ClientSpec.swift */; };
371E424925D999C300C3D8BF /* URLSessionDataTaskMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371E424825D999C300C3D8BF /* URLSessionDataTaskMock.swift */; };
3726981525D1FE45004FD4F9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3726981425D1FE45004FD4F9 /* AppDelegate.swift */; };
3726981725D1FE45004FD4F9 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3726981625D1FE45004FD4F9 /* SceneDelegate.swift */; };
Expand Down Expand Up @@ -156,6 +157,7 @@
371E422025D9947F00C3D8BF /* URLSessionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionMock.swift; sourceTree = "<group>"; };
371E422825D9964D00C3D8BF /* URL+Stub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Stub.swift"; sourceTree = "<group>"; };
371E423425D9966100C3D8BF /* HTTPURLResponse+Stub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HTTPURLResponse+Stub.swift"; sourceTree = "<group>"; };
371E423C25D9975400C3D8BF /* ClientSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientSpec.swift; sourceTree = "<group>"; };
371E424825D999C300C3D8BF /* URLSessionDataTaskMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionDataTaskMock.swift; sourceTree = "<group>"; };
3726981125D1FE45004FD4F9 /* The-Norris.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "The-Norris.app"; sourceTree = BUILT_PRODUCTS_DIR; };
3726981425D1FE45004FD4F9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -586,6 +588,7 @@
children = (
37397E0025D89342008C2EAC /* Info.plist */,
371E421F25D9946300C3D8BF /* Mock */,
371E423B25D9974900C3D8BF /* ProjectClient */,
371E422725D9962C00C3D8BF /* Stub */,
);
path = ClientTests;
Expand Down Expand Up @@ -1366,6 +1369,7 @@
buildActionMask = 2147483647;
files = (
371E422125D9947F00C3D8BF /* URLSessionMock.swift in Sources */,
371E423D25D9975400C3D8BF /* ClientSpec.swift in Sources */,
371E422925D9964D00C3D8BF /* URL+Stub.swift in Sources */,
371E423525D9966100C3D8BF /* HTTPURLResponse+Stub.swift in Sources */,
371E424925D999C300C3D8BF /* URLSessionDataTaskMock.swift in Sources */,
Expand Down

0 comments on commit 15b7628

Please sign in to comment.