Skip to content

Commit

Permalink
Merge pull request #2 from nerdishbynature/cleanup_test_coverage
Browse files Browse the repository at this point in the history
Cleanup and test coverage
  • Loading branch information
pietbrauer committed Nov 4, 2015
2 parents 4f40d1b + f85ad3d commit 4148e0b
Show file tree
Hide file tree
Showing 19 changed files with 634 additions and 188 deletions.
44 changes: 44 additions & 0 deletions TrashCanKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@
objects = {

/* Begin PBXBuildFile section */
231B684E1BE99852007AE2A6 /* OAuthConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231B684D1BE99852007AE2A6 /* OAuthConfiguration.swift */; };
231B68501BE99886007AE2A6 /* NSURL+URLParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231B684F1BE99886007AE2A6 /* NSURL+URLParameters.swift */; };
231B68521BE9989C007AE2A6 /* TokenConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231B68511BE9989C007AE2A6 /* TokenConfiguration.swift */; };
231B68541BE998C7007AE2A6 /* OAuthRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231B68531BE998C7007AE2A6 /* OAuthRouter.swift */; };
231B68561BE9997C007AE2A6 /* ConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231B68551BE9997C007AE2A6 /* ConfigurationTests.swift */; };
231B68581BE9A13C007AE2A6 /* authorize.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B68571BE9A13C007AE2A6 /* authorize.json */; };
231B685A1BE9A3DD007AE2A6 /* TokenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231B68591BE9A3DD007AE2A6 /* TokenTests.swift */; };
231B685C1BE9A699007AE2A6 /* refresh_token_error.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B685B1BE9A699007AE2A6 /* refresh_token_error.json */; };
231B685F1BE9AAC6007AE2A6 /* Repositories.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B685D1BE9AA66007AE2A6 /* Repositories.json */; };
231B68611BE9AD30007AE2A6 /* Me.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B68601BE9AD30007AE2A6 /* Me.json */; };
231B68631BE9AD8D007AE2A6 /* Emails.json in Resources */ = {isa = PBXBuildFile; fileRef = 231B68621BE9AD8D007AE2A6 /* Emails.json */; };
236364741BE22F1000AA7104 /* TrashCanKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 236364731BE22F1000AA7104 /* TrashCanKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
2363647B1BE22F1000AA7104 /* TrashCanKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 236364701BE22F1000AA7104 /* TrashCanKit.framework */; };
2363648E1BE22FCC00AA7104 /* TrashCanKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2363648A1BE22FCC00AA7104 /* TrashCanKit.swift */; };
Expand Down Expand Up @@ -51,6 +62,17 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
231B684D1BE99852007AE2A6 /* OAuthConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OAuthConfiguration.swift; sourceTree = "<group>"; };
231B684F1BE99886007AE2A6 /* NSURL+URLParameters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSURL+URLParameters.swift"; sourceTree = "<group>"; };
231B68511BE9989C007AE2A6 /* TokenConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenConfiguration.swift; sourceTree = "<group>"; };
231B68531BE998C7007AE2A6 /* OAuthRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OAuthRouter.swift; sourceTree = "<group>"; };
231B68551BE9997C007AE2A6 /* ConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurationTests.swift; sourceTree = "<group>"; };
231B68571BE9A13C007AE2A6 /* authorize.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = authorize.json; sourceTree = "<group>"; };
231B68591BE9A3DD007AE2A6 /* TokenTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenTests.swift; sourceTree = "<group>"; };
231B685B1BE9A699007AE2A6 /* refresh_token_error.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = refresh_token_error.json; sourceTree = "<group>"; };
231B685D1BE9AA66007AE2A6 /* Repositories.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Repositories.json; path = Fixtures/Repositories.json; sourceTree = "<group>"; };
231B68601BE9AD30007AE2A6 /* Me.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Me.json; sourceTree = "<group>"; };
231B68621BE9AD8D007AE2A6 /* Emails.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = Emails.json; path = Fixtures/Emails.json; sourceTree = "<group>"; };
236364701BE22F1000AA7104 /* TrashCanKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TrashCanKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
236364731BE22F1000AA7104 /* TrashCanKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TrashCanKit.h; sourceTree = "<group>"; };
236364751BE22F1000AA7104 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -115,6 +137,10 @@
children = (
236364731BE22F1000AA7104 /* TrashCanKit.h */,
2363648A1BE22FCC00AA7104 /* TrashCanKit.swift */,
231B684F1BE99886007AE2A6 /* NSURL+URLParameters.swift */,
231B684D1BE99852007AE2A6 /* OAuthConfiguration.swift */,
231B68531BE998C7007AE2A6 /* OAuthRouter.swift */,
231B68511BE9989C007AE2A6 /* TokenConfiguration.swift */,
2363648B1BE22FCC00AA7104 /* Repositories.swift */,
2363648C1BE22FCC00AA7104 /* Token.swift */,
2363648D1BE22FCC00AA7104 /* User.swift */,
Expand All @@ -129,6 +155,8 @@
236364931BE2301200AA7104 /* TestHelper.swift */,
236364921BE2301200AA7104 /* RepositoriesTests.swift */,
236364951BE2301200AA7104 /* UserTests.swift */,
231B68551BE9997C007AE2A6 /* ConfigurationTests.swift */,
231B68591BE9A3DD007AE2A6 /* TokenTests.swift */,
236364A11BE2313200AA7104 /* Fixtures */,
236364811BE22F1000AA7104 /* Info.plist */,
);
Expand All @@ -141,6 +169,11 @@
236364A21BE2313B00AA7104 /* Email.json */,
236364A31BE2313B00AA7104 /* Repository.json */,
236364A41BE2313B00AA7104 /* User.json */,
231B68571BE9A13C007AE2A6 /* authorize.json */,
231B685B1BE9A699007AE2A6 /* refresh_token_error.json */,
231B685D1BE9AA66007AE2A6 /* Repositories.json */,
231B68601BE9AD30007AE2A6 /* Me.json */,
231B68621BE9AD8D007AE2A6 /* Emails.json */,
);
name = Fixtures;
sourceTree = "<group>";
Expand Down Expand Up @@ -253,8 +286,13 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
231B68611BE9AD30007AE2A6 /* Me.json in Resources */,
231B685F1BE9AAC6007AE2A6 /* Repositories.json in Resources */,
231B68581BE9A13C007AE2A6 /* authorize.json in Resources */,
231B685C1BE9A699007AE2A6 /* refresh_token_error.json in Resources */,
236364A51BE2313B00AA7104 /* Email.json in Resources */,
236364A71BE2313B00AA7104 /* User.json in Resources */,
231B68631BE9AD8D007AE2A6 /* Emails.json in Resources */,
236364A61BE2313B00AA7104 /* Repository.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -266,9 +304,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
231B68521BE9989C007AE2A6 /* TokenConfiguration.swift in Sources */,
231B684E1BE99852007AE2A6 /* OAuthConfiguration.swift in Sources */,
236364911BE22FCC00AA7104 /* User.swift in Sources */,
231B68501BE99886007AE2A6 /* NSURL+URLParameters.swift in Sources */,
236364901BE22FCC00AA7104 /* Token.swift in Sources */,
2363648E1BE22FCC00AA7104 /* TrashCanKit.swift in Sources */,
231B68541BE998C7007AE2A6 /* OAuthRouter.swift in Sources */,
2363648F1BE22FCC00AA7104 /* Repositories.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -278,7 +320,9 @@
buildActionMask = 2147483647;
files = (
236364991BE2301200AA7104 /* UserTests.swift in Sources */,
231B685A1BE9A3DD007AE2A6 /* TokenTests.swift in Sources */,
236364961BE2301200AA7104 /* RepositoriesTests.swift in Sources */,
231B68561BE9997C007AE2A6 /* ConfigurationTests.swift in Sources */,
236364971BE2301200AA7104 /* TestHelper.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
Expand Down
18 changes: 18 additions & 0 deletions TrashCanKit/NSURL+URLParameters.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Foundation

internal extension NSURL {
func URLParameters() -> [String: String] {
let stringParams = absoluteString.componentsSeparatedByString("?").last
let params = stringParams?.componentsSeparatedByString("&")
var returnParams: [String: String] = [:]
if let params = params {
for param in params {
let keyValue = param.componentsSeparatedByString("=")
if let key = keyValue.first, value = keyValue.last {
returnParams[key] = value
}
}
}
return returnParams
}
}
88 changes: 88 additions & 0 deletions TrashCanKit/OAuthConfiguration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import Foundation
import RequestKit

public struct OAuthConfiguration: Configuration {
public var apiEndpoint: String
public var accessToken: String?
public let token: String
public let secret: String
public let scopes: [String]
public let webEndpoint: String

public init(_ url: String = bitbucketBaseURL, webURL: String = bitbucketWebURL,
token: String, secret: String, scopes: [String]) {
apiEndpoint = url
webEndpoint = webURL
self.token = token
self.secret = secret
self.scopes = []
}

public func authenticate() -> NSURL? {
return OAuthRouter.Authorize(self).URLRequest?.URL
}

private func basicAuthenticationString() -> String {
let clientIDSecretString = [token, secret].joinWithSeparator(":")
let clientIDSecretData = clientIDSecretString.dataUsingEncoding(NSUTF8StringEncoding)
let base64 = clientIDSecretData?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
return "Basic \(base64 ?? "")"
}

public func basicAuthSession() -> NSURLSession {
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
config.HTTPAdditionalHeaders = ["Authorization" : basicAuthenticationString()]
return NSURLSession(configuration: config)
}

public func authorize(code: String, completion: (config: TokenConfiguration) -> Void) {
let request = OAuthRouter.AccessToken(self, code).URLRequest
if let request = request {
let task = basicAuthSession().dataTaskWithRequest(request) { data, response, err in
if let response = response as? NSHTTPURLResponse {
if response.statusCode != 200 {
return
} else {
if let config = self.configFromData(data) {
completion(config: config)
}
}
}
}
task.resume()
}
}

private func configFromData(data: NSData?) -> TokenConfiguration? {
guard let data = data else { return nil }
do {
guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments) as? [String: AnyObject] else { return nil }
let accessToken = json["access_token"] as? String
let refreshToken = json["refresh_token"] as? String
if let accessToken = accessToken, refreshToken = refreshToken {
let config = TokenConfiguration(accessToken, refreshToken: refreshToken)
return config
}
} catch {
return nil
}
return nil
}

public func handleOpenURL(url: NSURL, completion: (config: TokenConfiguration) -> Void) {
let params = url.URLParameters()
if let code = params["code"] {
authorize(code) { config in
completion(config: config)
}
}
}

public func accessTokenFromResponse(response: String) -> String? {
let accessTokenParam = response.componentsSeparatedByString("&").first
if let accessTokenParam = accessTokenParam {
return accessTokenParam.componentsSeparatedByString("=").last
}
return nil
}
}
61 changes: 61 additions & 0 deletions TrashCanKit/OAuthRouter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import RequestKit

public enum OAuthRouter: Router {
case Authorize(OAuthConfiguration)
case AccessToken(OAuthConfiguration, String)

public var configuration: Configuration {
switch self {
case .Authorize(let config): return config
case .AccessToken(let config, _): return config
}
}

public var method: HTTPMethod {
switch self {
case .Authorize:
return .GET
case .AccessToken:
return .POST
}
}

public var encoding: HTTPEncoding {
switch self {
case .Authorize:
return .URL
case .AccessToken:
return .FORM
}
}

public var path: String {
switch self {
case .Authorize:
return "site/oauth2/authorize"
case .AccessToken:
return "site/oauth2/access_token"
}
}

public var params: [String: String] {
switch self {
case .Authorize(let config):
return ["client_id": config.token, "response_type": "code"]
case .AccessToken(_, let code):
return ["code": code, "grant_type": "authorization_code"]
}
}

public var URLRequest: NSURLRequest? {
switch self {
case .Authorize(let config):
let URLString = config.webEndpoint.stringByAppendingURLPath(path)
return request(URLString, parameters: params)
case .AccessToken(let config, _):
let URLString = config.webEndpoint.stringByAppendingURLPath(path)
return request(URLString, parameters: params)
}
}
}

7 changes: 0 additions & 7 deletions TrashCanKit/Repositories.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,4 @@ public enum RepositoryRouter: Router {
return "/repositories/\(userName)"
}
}

public var URLRequest: NSURLRequest? {
switch self {
case .ReadRepositories(_, _):
return request()
}
}
}
13 changes: 13 additions & 0 deletions TrashCanKit/TokenConfiguration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import RequestKit

public struct TokenConfiguration: Configuration {
public var apiEndpoint: String
public var accessToken: String?
public var refreshToken: String?

public init(_ token: String? = nil, refreshToken: String? = nil, url: String = bitbucketBaseURL) {
apiEndpoint = url
accessToken = token
self.refreshToken = refreshToken
}
}
Loading

0 comments on commit 4148e0b

Please sign in to comment.